From 66dff952135f2e3c7d3805ed6ae2a8328b07619f Mon Sep 17 00:00:00 2001 From: anwarmoussaoui Date: Fri, 13 Jun 2025 10:40:24 +0100 Subject: [PATCH 1/2] tensorflow demo v1 --- graalwasm/graalwasm-tensorflow/.gitattributes | 2 + graalwasm/graalwasm-tensorflow/.gitignore | 34 + .../.mvn/wrapper/maven-wrapper.properties | 19 + graalwasm/graalwasm-tensorflow/README.md | 24 + graalwasm/graalwasm-tensorflow/mvnw | 259 + graalwasm/graalwasm-tensorflow/mvnw.cmd | 149 + graalwasm/graalwasm-tensorflow/pom.xml | 161 + .../example/Tensorflow/BenchmarkClass.java | 60 + .../com/example/Tensorflow/ContextPool.java | 140 + .../com/example/Tensorflow/Controller.java | 69 + .../com/example/Tensorflow/ExcelizePool.java | 72 + .../com/example/Tensorflow/MainBenchmark.java | 7 + .../Tensorflow/TensorflowApplication.java | 22 + .../graalwasm-tensorflow/src/main/js/main.mjs | 133 + .../src/main/js/package-lock.json | 11490 ++ .../src/main/js/package.json | 32 + .../src/main/js/tfjs-backend-wasm-simd.wasm | Bin 0 -> 311123 bytes .../src/main/js/webpack.config.js | 66 + .../src/main/resources/application.properties | 1 + .../src/main/resources/data.xlsx | Bin 0 -> 18271 bytes .../src/main/resources/excelize.js | 48 + .../src/main/resources/excelize.wasm | Bin 0 -> 15101146 bytes .../src/main/resources/excelize_m.js | 563 + .../src/main/resources/excelize_prep.js | 28 + .../src/main/resources/templates/index.html | 140 + .../src/main/resources/tf.es2017.js | 104780 +++++++++++++++ .../resources/tfjs-backend-wasm-simd.wasm | Bin 0 -> 311123 bytes .../TensorflowApplicationTests.java | 13 + 28 files changed, 118312 insertions(+) create mode 100644 graalwasm/graalwasm-tensorflow/.gitattributes create mode 100644 graalwasm/graalwasm-tensorflow/.gitignore create mode 100644 graalwasm/graalwasm-tensorflow/.mvn/wrapper/maven-wrapper.properties create mode 100644 graalwasm/graalwasm-tensorflow/README.md create mode 100755 graalwasm/graalwasm-tensorflow/mvnw create mode 100644 graalwasm/graalwasm-tensorflow/mvnw.cmd create mode 100644 graalwasm/graalwasm-tensorflow/pom.xml create mode 100644 graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/BenchmarkClass.java create mode 100644 graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/ContextPool.java create mode 100644 graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/Controller.java create mode 100644 graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/ExcelizePool.java create mode 100644 graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/MainBenchmark.java create mode 100644 graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/TensorflowApplication.java create mode 100644 graalwasm/graalwasm-tensorflow/src/main/js/main.mjs create mode 100644 graalwasm/graalwasm-tensorflow/src/main/js/package-lock.json create mode 100644 graalwasm/graalwasm-tensorflow/src/main/js/package.json create mode 100755 graalwasm/graalwasm-tensorflow/src/main/js/tfjs-backend-wasm-simd.wasm create mode 100644 graalwasm/graalwasm-tensorflow/src/main/js/webpack.config.js create mode 100644 graalwasm/graalwasm-tensorflow/src/main/resources/application.properties create mode 100644 graalwasm/graalwasm-tensorflow/src/main/resources/data.xlsx create mode 100644 graalwasm/graalwasm-tensorflow/src/main/resources/excelize.js create mode 100755 graalwasm/graalwasm-tensorflow/src/main/resources/excelize.wasm create mode 100644 graalwasm/graalwasm-tensorflow/src/main/resources/excelize_m.js create mode 100644 graalwasm/graalwasm-tensorflow/src/main/resources/excelize_prep.js create mode 100644 graalwasm/graalwasm-tensorflow/src/main/resources/templates/index.html create mode 100644 graalwasm/graalwasm-tensorflow/src/main/resources/tf.es2017.js create mode 100755 graalwasm/graalwasm-tensorflow/src/main/resources/tfjs-backend-wasm-simd.wasm create mode 100644 graalwasm/graalwasm-tensorflow/src/test/java/com/example/Tensorflow/TensorflowApplicationTests.java diff --git a/graalwasm/graalwasm-tensorflow/.gitattributes b/graalwasm/graalwasm-tensorflow/.gitattributes new file mode 100644 index 00000000..3b41682a --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/graalwasm/graalwasm-tensorflow/.gitignore b/graalwasm/graalwasm-tensorflow/.gitignore new file mode 100644 index 00000000..04bff45a --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/.gitignore @@ -0,0 +1,34 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +/**/src/main/js/node_modules/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/graalwasm/graalwasm-tensorflow/.mvn/wrapper/maven-wrapper.properties b/graalwasm/graalwasm-tensorflow/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000..d58dfb70 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/graalwasm/graalwasm-tensorflow/README.md b/graalwasm/graalwasm-tensorflow/README.md new file mode 100644 index 00000000..e9c63711 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/README.md @@ -0,0 +1,24 @@ +# 🏠 House Price Prediction Demo (Spring Boot + Thymeleaf + GraalVM JS WASM) + +This is a simple Spring Boot application that predicts house prices using a JavaScript function executed via GraalVM, with a web frontend built using Thymeleaf. + +## 📦 Prerequisites + +- Java 21+ (GraalVM recommended) +- Maven 3.x +- GraalVM setup (with JavaScript support) +- Internet browser + +## 🚀 How to Run + +### 1. Build the project +```bash +mvn clean package +``` +### 2. Run the Spring Boot application +```bash +mvn spring-boot:run +``` + +### 3. Open your browser +Go to: http://localhost:8080 \ No newline at end of file diff --git a/graalwasm/graalwasm-tensorflow/mvnw b/graalwasm/graalwasm-tensorflow/mvnw new file mode 100755 index 00000000..19529ddf --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/graalwasm/graalwasm-tensorflow/mvnw.cmd b/graalwasm/graalwasm-tensorflow/mvnw.cmd new file mode 100644 index 00000000..249bdf38 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/graalwasm/graalwasm-tensorflow/pom.xml b/graalwasm/graalwasm-tensorflow/pom.xml new file mode 100644 index 00000000..cc4c0549 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/pom.xml @@ -0,0 +1,161 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.5 + + + com.example + Tensorflow + 0.0.1-SNAPSHOT + Tensorflow + Demo project for Spring Boot + + + + + + + + + + + + + + + 21 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + org.graalvm.polyglot + polyglot + 24.2.0 + + + org.graalvm.js + js-language + 24.2.0 + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + org.graalvm.wasm + wasm-language + 24.2.0 + + + org.graalvm.truffle + truffle-api + 24.2.0 + + + org.graalvm.truffle + truffle-runtime + 24.2.0 + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.openjdk.jmh + jmh-core + 1.37 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.37 + + + + + + + com.github.eirslett + frontend-maven-plugin + 1.15.0 + + + v21.7.2 + src/main/js + target + + + + + + install node and npm + install-node-and-npm + + + + + npm install + npm + + + + + webpack build + webpack + + --mode production + + ${project.build.outputDirectory}/bundle + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + + org.openjdk.jmh + jmh-generator-annprocess + 1.37 + + + + + + + + diff --git a/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/BenchmarkClass.java b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/BenchmarkClass.java new file mode 100644 index 00000000..34e7a35e --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/BenchmarkClass.java @@ -0,0 +1,60 @@ +package com.example.Tensorflow; + +import org.graalvm.polyglot.Context; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + +@Warmup(iterations = 6, time = 10) +@Measurement(iterations = 6, time = 10) +@Fork(1) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +public class BenchmarkClass { + ContextPool contextPool; + + public BenchmarkClass() { + try { + this.contextPool = new ContextPool(); + } catch (IOException e) { + throw new RuntimeException("Failed to initialize ContextPool", e); + } + } + + @Benchmark + public void predict(Blackhole blackhole){ + Context context = contextPool.getContext(); + try { + PredictFunction predictFn = context.getBindings("js").getMember("predictHouse").as(PredictFunction.class); + + double[] houseFeatures = new double[12]; + for (int i = 0; i < houseFeatures.length; i++) { + houseFeatures[i] = ThreadLocalRandom.current().nextDouble(1, 5000); + } + + Promise>> prediction = predictFn.apply(houseFeatures); + + prediction.then(result -> blackhole.consume(result.get(0).get(0))); + } finally { + contextPool.release(context); + } + } + + public interface PredictFunction { + Promise>> apply(double[] houseFeatures); + } + + public interface Promise { + void then(Callback callback); + } + + @FunctionalInterface + public interface Callback { + void accept(T result); + } +} \ No newline at end of file diff --git a/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/ContextPool.java b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/ContextPool.java new file mode 100644 index 00000000..92b54573 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/ContextPool.java @@ -0,0 +1,140 @@ +package com.example.Tensorflow; + +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.HostAccess; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +@Component +public class ContextPool { + private final BlockingQueue contexts; + + private static Map getLanguageOptions() { + Map options = new HashMap<>(); + options.put("js.ecmascript-version", "2023"); + options.put("js.top-level-await", "true"); + options.put("js.webassembly", "true"); + options.put("js.performance", "true"); + options.put("js.commonjs-require", "true"); + options.put("js.esm-eval-returns-exports", "true"); + options.put("js.unhandled-rejections", "throw"); + options.put("js.commonjs-require-cwd", Paths.get("./").toAbsolutePath().toString()); + return options; + } + + public ContextPool () throws IOException { + + Context context = Context.newBuilder("js", "wasm") + .allowAllAccess(true) + .options(getLanguageOptions()) + .build(); + + + ExcelizePool excelizePool = new ExcelizePool(); + Context context1 = excelizePool.getContext(); + byte[] excelBytes = Files.readAllBytes(Paths.get("./src/main/resources/data.xlsx")); + + + Value readFunc = context1.getBindings("js").getMember("readExcel"); + Value bufferArray = readFunc.execute(excelBytes); + + + byte[] tsfjswasm = Files.readAllBytes(Paths.get("./src/main/resources/tfjs-backend-wasm-simd.wasm")); + context.getBindings("js").putMember("tsfwasm", tsfjswasm); + + String polyfill= """ + (() => { + const NativeURL = globalThis.URL; + + class FakeURL { + constructor(input, base) { + this.href = input; + } + + toString() { + return this.href; + } + } + + globalThis.URL = FakeURL; + + globalThis.fetch = async function (url) { + const tsfwasm = './tfjs-backend-wasm-simd.wasm' + const target = (typeof url === 'object' && 'href' in url) ? url.href : url; + if (target === tsfwasm) { + return { + async arrayBuffer() { + return globalThis.tsfwasm; + }, + ok: true, + status: 200, + }; + } + else { + throw new Error(`Unhandled fetch to: ${target}`); + } + }; + })(); + if (typeof WebAssembly.instantiateStreaming !== "function") { + WebAssembly.instantiateStreaming = async (sourcePromise, importObject) => { + // Assume `globalThis.tsfwasm` is already a Uint8Array or ArrayBuffer + const buffer = globalThis.tsfwasm instanceof Uint8Array + ? globalThis.tsfwasm.buffer + : globalThis.tsfwasm; + + return WebAssembly.instantiate(new Uint8Array(buffer), importObject); + }; + } + globalThis.self = globalThis; + globalThis.window = globalThis; + globalThis.document = { body: {} } + globalThis.window.location = { href: '' } + """ + ; + context.eval("js",polyfill); + Source bundleSrc = Source.newBuilder("js",ContextPool.class.getResource("/bundle/bundle.mjs")).build(); + context.eval(bundleSrc); + context.getBindings("js").getMember("trainModel").execute(bufferArray); + System.out.println( context.getBindings("js").getMember("savedArtifacts")); + + + int maxThreads = Runtime.getRuntime().availableProcessors(); + contexts = new LinkedBlockingQueue<>(maxThreads); + for (int i = 0; i < maxThreads; i++) { + Context modelContext = Context.newBuilder("js", "wasm") + .allowHostAccess(HostAccess.ALL) + .allowAllAccess(true) + .options(getLanguageOptions()) + .build(); + + modelContext.getBindings("js").putMember("tsfwasm", tsfjswasm); + modelContext.eval("js",polyfill); + + modelContext.eval(bundleSrc); + Value mdl = context.getBindings("js").getMember("savedArtifacts"); + modelContext.getBindings("js").putMember("savedArtifacts",mdl); + this.contexts.add(modelContext); + + } + } + + public Context getContext() { + try { + return contexts.take(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + void release(Context context) { + contexts.add(context); + } +} diff --git a/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/Controller.java b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/Controller.java new file mode 100644 index 00000000..32af5e07 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/Controller.java @@ -0,0 +1,69 @@ +package com.example.Tensorflow; + +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Value; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.graalvm.polyglot.proxy.ProxyExecutable; +import org.springframework.web.context.request.async.DeferredResult; + +import java.util.stream.DoubleStream; + +@org.springframework.stereotype.Controller +public class Controller { + private final ContextPool contextPool; + public Controller(ContextPool contextPool){ + + this.contextPool = contextPool; + } + + @PostMapping("/predict") + public DeferredResult predictPrice( + @RequestParam double bedrooms, + @RequestParam double bathrooms, + @RequestParam double sqftLiving, + @RequestParam double sqftLot, + @RequestParam double floors, + @RequestParam double waterfront, + @RequestParam double view, + @RequestParam double condition, + @RequestParam double sqftAbove, + @RequestParam double sqftBasement, + @RequestParam double yrBuilt, + @RequestParam double yrRenovated, + Model model) { + DeferredResult deferredResult = new DeferredResult<>(); + + double[] newHouse = { + bedrooms, bathrooms, sqftLiving, sqftLot, + floors, waterfront, view, condition, + sqftAbove, sqftBasement, yrBuilt, yrRenovated + }; + + Context context = contextPool.getContext(); + try { + Value predictFn = context.getBindings("js").getMember("predictHouse"); + + Value jsArray = context.eval("js", "Array"); + Value input = jsArray.newInstance((Object[]) DoubleStream.of(newHouse).boxed().toArray()); + + Value prediction = predictFn.execute(input); + + prediction.invokeMember("then", (ProxyExecutable) result -> { + + System.out.println("results from java side" + result); + double price = result[0].getArrayElement(0).getArrayElement(0).asDouble(); + long roundedPrice = Math.round(price); + model.addAttribute("predictedPrice", roundedPrice); + deferredResult.setResult("index"); + return null; + }); + }finally { + contextPool.release(context); + } + + + return deferredResult; + } +} diff --git a/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/ExcelizePool.java b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/ExcelizePool.java new file mode 100644 index 00000000..94a3d896 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/ExcelizePool.java @@ -0,0 +1,72 @@ +package com.example.Tensorflow; + +import org.graalvm.polyglot.*; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +@Component + +public class ExcelizePool { + private final Context context; + + public ExcelizePool() throws IOException { + + // Use regular file paths + byte[] excelizeWasmBytes = Files.readAllBytes(Paths.get("src/main/resources/excelize.wasm")); + String test = Files.readString(Paths.get("src/main/resources/excelize.js"), StandardCharsets.UTF_8); + String prep = Files.readString(Paths.get("src/main/resources/excelize_prep.js"), StandardCharsets.UTF_8); + String excelizeLib = Files.readString(Paths.get("src/main/resources/excelize_m.js"), StandardCharsets.UTF_8); + + System.out.println("Executing excelize read..."); + + // Configure engine options + Map options = new HashMap<>(); + options.put("js.webassembly", "true"); + options.put("js.text-encoding","true"); + + Map engineOptions = new HashMap<>(); + //engineOptions.put("engine.CompilerThreads", "1"); + engineOptions.put("engine.MultiTier", "true"); + engineOptions.put("engine.Mode", "throughput"); + + Engine engine = Engine.newBuilder("js", "wasm") + .allowExperimentalOptions(true) + .options(engineOptions) + .build(); + + // Build the context + Context context = Context.newBuilder("js", "wasm") + .engine(engine) + .allowAllAccess(true) + .options(options) + .build(); + + + context.eval(Source.newBuilder("js", prep, "prep.js").build()); + + // Evaluate the Excelize WASM module + Source excelizeModule = Source.newBuilder("js", excelizeLib, "excelize.mjs") + .mimeType("application/javascript+module") + .uri(URI.create("excelize.mjs")) + .build(); + Value excelizeMod = context.eval(excelizeModule); + context.getPolyglotBindings().putMember("excelize", excelizeMod); + context.getBindings("js").putMember("wasmBytes", excelizeWasmBytes); + + // Evaluate test script + context.eval(Source.newBuilder("js", test, "excelize.js").build()); + + this.context = context; + } + + public Context getContext() { + return context; + } +} diff --git a/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/MainBenchmark.java b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/MainBenchmark.java new file mode 100644 index 00000000..ca79c0c1 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/MainBenchmark.java @@ -0,0 +1,7 @@ +package com.example.Tensorflow; + +public class MainBenchmark { + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } +} diff --git a/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/TensorflowApplication.java b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/TensorflowApplication.java new file mode 100644 index 00000000..1a260a91 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/java/com/example/Tensorflow/TensorflowApplication.java @@ -0,0 +1,22 @@ +package com.example.Tensorflow; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; + +@SpringBootApplication( + exclude = { + DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class, + HibernateJpaAutoConfiguration.class + } +) +public class TensorflowApplication { + + public static void main(String[] args) { + SpringApplication.run(TensorflowApplication.class, args); + } + +} diff --git a/graalwasm/graalwasm-tensorflow/src/main/js/main.mjs b/graalwasm/graalwasm-tensorflow/src/main/js/main.mjs new file mode 100644 index 00000000..217a790e --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/js/main.mjs @@ -0,0 +1,133 @@ +import 'fast-text-encoding'; +import * as tf from '@tensorflow/tfjs'; +import { setWasmPaths } from '@tensorflow/tfjs-backend-wasm'; + +// Set backend to WebAssembly +setWasmPaths('./'); +await tf.setBackend('wasm'); +await tf.ready(); +globalThis.predictHouse = async function(houseFeatures) { + const model = await tf.loadLayersModel({ + load: async () => savedArtifacts + }); + const inputTensor = tf.tensor2d([houseFeatures]); + + const prediction = model.predict(inputTensor); + prediction.print(); + return prediction.array(); +}; + +let model; // + +globalThis.savedArtifacts = null; +globalThis.trainModel = function(datasetPromise) { + datasetPromise.then(dataset => { + const inputs = []; + const prices = []; + + const dataRows = dataset.slice(1); // Skip header + dataRows.forEach(row => { + const numbers = row.map(val => { + const num = Number(val); + return isNaN(num) ? 0 : num; + }); + + const [price, ...features] = numbers; + prices.push([price]); + inputs.push(features); + }); + + const featureTensor = tf.tensor2d(inputs); + const min = featureTensor.min(0); + const max = featureTensor.max(0); + const range = max.sub(min); + const safeRange = range.add(tf.tensor1d(Array(range.shape[0]).fill(1e-7))); + const normalizedFeatures = featureTensor.sub(min).div(safeRange); + + const labelTensor = tf.tensor2d(prices); + + model = tf.sequential(); + model.add(tf.layers.dense({ inputShape: [normalizedFeatures.shape[1]], units: 12, activation: 'relu' })); + model.add(tf.layers.dense({ units: 6, activation: 'relu' })); + model.add(tf.layers.dense({ units: 1 })); + + model.compile({ optimizer: 'adam', loss: 'meanSquaredError' }); + + model.fit(normalizedFeatures, labelTensor, { + epochs: 200, + batchSize: 1, + verbose: 1, + }).then(() => { + model.save({ + async save(modelArtifacts) { + savedArtifacts = modelArtifacts; + return { + modelArtifactsInfo: { + dateSaved: new Date(), + modelTopologyType: 'JSON', + } + }; + } + }).then(() => { + Polyglot.export("savedArtifacts", savedArtifacts); + }); + }); + }); +}; + +/* +async function save(modelArtifacts) { + if (modelArtifacts.modelTopology instanceof ArrayBuffer) { + throw new Error('BrowserLocalStorage.save() does not support saving model topology ' + + 'in binary formats yet.'); + } + else { + const topology = JSON.stringify(modelArtifacts.modelTopology); + const weightSpecs = JSON.stringify(modelArtifacts.weightSpecs); + const modelArtifactsInfo = getModelArtifactsInfoForJSON(modelArtifacts); + // TODO(mattsoulanille): Support saving models over 2GB that exceed + // Chrome's ArrayBuffer size limit. + const weightBuffer = CompositeArrayBuffer.join(modelArtifacts.weightData); + try { + this.LS.setItem(this.keys.info, JSON.stringify(modelArtifactsInfo)); + this.LS.setItem(this.keys.topology, topology); + this.LS.setItem(this.keys.weightSpecs, weightSpecs); + this.LS.setItem(this.keys.weightData, arrayBufferToBase64String(weightBuffer)); + // Note that JSON.stringify doesn't write out keys that have undefined + // values, so for some keys, we set undefined instead of a null-ish + // value. + const metadata = { + format: modelArtifacts.format, + generatedBy: modelArtifacts.generatedBy, + convertedBy: modelArtifacts.convertedBy, + signature: modelArtifacts.signature != null ? + modelArtifacts.signature : + undefined, + userDefinedMetadata: modelArtifacts.userDefinedMetadata != null ? + modelArtifacts.userDefinedMetadata : + undefined, + modelInitializer: modelArtifacts.modelInitializer != null ? + modelArtifacts.modelInitializer : + undefined, + initializerSignature: modelArtifacts.initializerSignature != null ? + modelArtifacts.initializerSignature : + undefined, + trainingConfig: modelArtifacts.trainingConfig != null ? + modelArtifacts.trainingConfig : + undefined + }; + this.LS.setItem(this.keys.modelMetadata, JSON.stringify(metadata)); + return { modelArtifactsInfo }; + } + catch (err) { + // If saving failed, clean up all items saved so far. + removeItems(this.keys); + throw new Error(`Failed to save model '${this.modelPath}' to local storage: ` + + `size quota being exceeded is a possible cause of this failure: ` + + `modelTopologyBytes=${modelArtifactsInfo.modelTopologyBytes}, ` + + `weightSpecsBytes=${modelArtifactsInfo.weightSpecsBytes}, ` + + `weightDataBytes=${modelArtifactsInfo.weightDataBytes}.`); + } + } +} +*/ \ No newline at end of file diff --git a/graalwasm/graalwasm-tensorflow/src/main/js/package-lock.json b/graalwasm/graalwasm-tensorflow/src/main/js/package-lock.json new file mode 100644 index 00000000..b1554b08 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/js/package-lock.json @@ -0,0 +1,11490 @@ +{ + "name": "js", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "js", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@tensorflow/tfjs": "^4.22.0", + "@tensorflow/tfjs-backend-wasm": "^4.22.0", + "assert": "^2.1.0", + "browserify-zlib": "^0.2.0", + "fast-text-encoding": "^1.0.6", + "stream-browserify": "^3.0.0", + "util": "^0.12.5" + }, + "devDependencies": { + "@babel/core": "^7.26.10", + "@babel/preset-env": "^7.26.9", + "@webpack-cli/generators": "^3.0.7", + "babel-loader": "^10.0.0", + "ts-loader": "^9.5.2", + "typescript": "^5.8.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.10", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.8", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.0.tgz", + "integrity": "sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.27.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.0.tgz", + "integrity": "sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", + "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.26.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.26.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", + "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.26.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.26.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", + "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.0.tgz", + "integrity": "sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.26.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.26.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz", + "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.26.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", + "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.0.tgz", + "integrity": "sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.26.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz", + "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.0.tgz", + "integrity": "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/preset-env/-/preset-env-7.26.9.tgz", + "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.8", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.26.8", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.26.5", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.26.3", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.26.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.26.3", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.26.8", + "@babel/plugin-transform-typeof-symbol": "^7.26.7", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.11.0", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.40.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/template": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", + "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/arborist": { + "version": "4.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/arborist/-/arborist-4.3.1.tgz", + "integrity": "sha512-yMRgZVDpwWjplorzt9SFSaakWx6QIK248Nw4ZFgkrAy/GvJaFRaSZzE6nD7JBK5r8g/+PTxFq5Wj/sfciE7x+A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/map-workspaces": "^2.0.0", + "@npmcli/metavuln-calculator": "^2.0.0", + "@npmcli/move-file": "^1.1.0", + "@npmcli/name-from-folder": "^1.0.1", + "@npmcli/node-gyp": "^1.0.3", + "@npmcli/package-json": "^1.0.1", + "@npmcli/run-script": "^2.0.0", + "bin-links": "^3.0.0", + "cacache": "^15.0.3", + "common-ancestor-path": "^1.0.1", + "json-parse-even-better-errors": "^2.3.1", + "json-stringify-nice": "^1.1.4", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.1.5", + "npm-pick-manifest": "^6.1.0", + "npm-registry-fetch": "^12.0.1", + "pacote": "^12.0.2", + "parse-conflict-json": "^2.0.1", + "proc-log": "^1.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.1", + "read-package-json-fast": "^2.0.2", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "ssri": "^8.0.1", + "treeverse": "^1.0.4", + "walk-up-path": "^1.0.0" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "node_modules/@npmcli/git": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/git/-/git-2.1.0.tgz", + "integrity": "sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^1.3.2", + "lru-cache": "^6.0.0", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^6.1.1", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^2.0.2" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "1.0.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz", + "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "bin": { + "installed-package-contents": "index.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@npmcli/map-workspaces": { + "version": "2.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/map-workspaces/-/map-workspaces-2.0.4.tgz", + "integrity": "sha512-bMo0aAfwhVwqoVM5UzX1DJnlvVvzDCHae821jv48L1EsrYwfOZChlqWYXEtto/+BkBXetPbEWgau++/brh4oVg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^1.0.1", + "glob": "^8.0.1", + "minimatch": "^5.0.1", + "read-package-json-fast": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/metavuln-calculator": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/metavuln-calculator/-/metavuln-calculator-2.0.0.tgz", + "integrity": "sha512-VVW+JhWCKRwCTE+0xvD6p3uV4WpqocNYYtzyvenqL/u1Q3Xx6fGTJ+6UoIoii07fbuEO9U3IIyuGY0CYHDv1sg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cacache": "^15.0.5", + "json-parse-even-better-errors": "^2.3.1", + "pacote": "^12.0.0", + "semver": "^7.3.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/name-from-folder": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/name-from-folder/-/name-from-folder-1.0.1.tgz", + "integrity": "sha512-qq3oEfcLFwNfEYOQ8HLimRGKlD8WSeGEdtUa7hmzpR8Sa7haL1KVQrvgO6wqMjhWFFVjgtrh1gIxDz+P8sjUaA==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/node-gyp": { + "version": "1.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz", + "integrity": "sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/package-json": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/package-json/-/package-json-1.0.1.tgz", + "integrity": "sha512-y6jnu76E9C23osz8gEMBayZmaZ69vFOIk8vR1FJL/wbEJ54+9aVG9rLTjQKSXfgYZEr50nw1txBBFfBZZe+bYg==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^2.3.1" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "1.3.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz", + "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==", + "dev": true, + "license": "ISC", + "dependencies": { + "infer-owner": "^1.0.4" + } + }, + "node_modules/@npmcli/run-script": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/run-script/-/run-script-2.0.0.tgz", + "integrity": "sha512-fSan/Pu11xS/TdaTpTB0MRn9guwGU8dye+x56mEVgBEd/QsybBbYcAL0phPXi8SGWFEChkQd6M9qL4y6VOpFig==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^1.0.2", + "@npmcli/promise-spawn": "^1.3.2", + "node-gyp": "^8.2.0", + "read-package-json-fast": "^2.0.1" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.6.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/core/-/core-3.6.0.tgz", + "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.3", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "12.11.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", + "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.21.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", + "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.40.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.16.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", + "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.39.0", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/request/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@octokit/rest": { + "version": "18.12.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.41.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@octokit/types/-/types-6.41.0.tgz", + "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^12.11.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@sigstore/bundle": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@sigstore/bundle/-/bundle-1.1.0.tgz", + "integrity": "sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz", + "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@sigstore/sign/-/sign-1.0.0.tgz", + "integrity": "sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^1.1.0", + "@sigstore/protobuf-specs": "^0.2.0", + "make-fetch-happen": "^11.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@sigstore/sign/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/cacache": { + "version": "17.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cacache/-/cacache-17.1.4.tgz", + "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^7.0.3", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/cacache/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@sigstore/sign/node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/fs-minipass/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@sigstore/sign/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sigstore/sign/node_modules/glob/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@sigstore/sign/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sigstore/sign/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sigstore/sign/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sigstore/sign/node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/@sigstore/sign/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@sigstore/sign/node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@sigstore/sign/node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/ssri/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@sigstore/sign/node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "1.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@sigstore/tuf/-/tuf-1.0.3.tgz", + "integrity": "sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.2.0", + "tuf-js": "^1.1.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tensorflow/tfjs": { + "version": "4.22.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tensorflow/tfjs/-/tfjs-4.22.0.tgz", + "integrity": "sha512-0TrIrXs6/b7FLhLVNmfh8Sah6JgjBPH4mZ8JGb7NU6WW+cx00qK5BcAZxw7NCzxj6N8MRAIfHq+oNbPUNG5VAg==", + "license": "Apache-2.0", + "dependencies": { + "@tensorflow/tfjs-backend-cpu": "4.22.0", + "@tensorflow/tfjs-backend-webgl": "4.22.0", + "@tensorflow/tfjs-converter": "4.22.0", + "@tensorflow/tfjs-core": "4.22.0", + "@tensorflow/tfjs-data": "4.22.0", + "@tensorflow/tfjs-layers": "4.22.0", + "argparse": "^1.0.10", + "chalk": "^4.1.0", + "core-js": "3.29.1", + "regenerator-runtime": "^0.13.5", + "yargs": "^16.0.3" + }, + "bin": { + "tfjs-custom-module": "dist/tools/custom_module/cli.js" + } + }, + "node_modules/@tensorflow/tfjs-backend-cpu": { + "version": "4.22.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.22.0.tgz", + "integrity": "sha512-1u0FmuLGuRAi8D2c3cocHTASGXOmHc/4OvoVDENJayjYkS119fcTcQf4iHrtLthWyDIPy3JiPhRrZQC9EwnhLw==", + "license": "Apache-2.0", + "dependencies": { + "@types/seedrandom": "^2.4.28", + "seedrandom": "^3.0.5" + }, + "engines": { + "yarn": ">= 1.3.2" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "4.22.0" + } + }, + "node_modules/@tensorflow/tfjs-backend-wasm": { + "version": "4.22.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tensorflow/tfjs-backend-wasm/-/tfjs-backend-wasm-4.22.0.tgz", + "integrity": "sha512-/IYhReRIp4jg/wYW0OwbbJZG8ON87mbz0PgkiP3CdcACRSvUN0h8rvC0O3YcDtkTQtFWF/tcXq/KlVDyV49wmA==", + "license": "Apache-2.0", + "dependencies": { + "@tensorflow/tfjs-backend-cpu": "4.22.0", + "@types/emscripten": "~0.0.34" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "4.22.0" + } + }, + "node_modules/@tensorflow/tfjs-backend-webgl": { + "version": "4.22.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.22.0.tgz", + "integrity": "sha512-H535XtZWnWgNwSzv538czjVlbJebDl5QTMOth4RXr2p/kJ1qSIXE0vZvEtO+5EC9b00SvhplECny2yDewQb/Yg==", + "license": "Apache-2.0", + "dependencies": { + "@tensorflow/tfjs-backend-cpu": "4.22.0", + "@types/offscreencanvas": "~2019.3.0", + "@types/seedrandom": "^2.4.28", + "seedrandom": "^3.0.5" + }, + "engines": { + "yarn": ">= 1.3.2" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "4.22.0" + } + }, + "node_modules/@tensorflow/tfjs-converter": { + "version": "4.22.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tensorflow/tfjs-converter/-/tfjs-converter-4.22.0.tgz", + "integrity": "sha512-PT43MGlnzIo+YfbsjM79Lxk9lOq6uUwZuCc8rrp0hfpLjF6Jv8jS84u2jFb+WpUeuF4K33ZDNx8CjiYrGQ2trQ==", + "license": "Apache-2.0", + "peerDependencies": { + "@tensorflow/tfjs-core": "4.22.0" + } + }, + "node_modules/@tensorflow/tfjs-core": { + "version": "4.22.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tensorflow/tfjs-core/-/tfjs-core-4.22.0.tgz", + "integrity": "sha512-LEkOyzbknKFoWUwfkr59vSB68DMJ4cjwwHgicXN0DUi3a0Vh1Er3JQqCI1Hl86GGZQvY8ezVrtDIvqR1ZFW55A==", + "license": "Apache-2.0", + "dependencies": { + "@types/long": "^4.0.1", + "@types/offscreencanvas": "~2019.7.0", + "@types/seedrandom": "^2.4.28", + "@webgpu/types": "0.1.38", + "long": "4.0.0", + "node-fetch": "~2.6.1", + "seedrandom": "^3.0.5" + }, + "engines": { + "yarn": ">= 1.3.2" + } + }, + "node_modules/@tensorflow/tfjs-core/node_modules/@types/offscreencanvas": { + "version": "2019.7.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", + "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==", + "license": "MIT" + }, + "node_modules/@tensorflow/tfjs-core/node_modules/node-fetch": { + "version": "2.6.13", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@tensorflow/tfjs-data": { + "version": "4.22.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tensorflow/tfjs-data/-/tfjs-data-4.22.0.tgz", + "integrity": "sha512-dYmF3LihQIGvtgJrt382hSRH4S0QuAp2w1hXJI2+kOaEqo5HnUPG0k5KA6va+S1yUhx7UBToUKCBHeLHFQRV4w==", + "license": "Apache-2.0", + "dependencies": { + "@types/node-fetch": "^2.1.2", + "node-fetch": "~2.6.1", + "string_decoder": "^1.3.0" + }, + "peerDependencies": { + "@tensorflow/tfjs-core": "4.22.0", + "seedrandom": "^3.0.5" + } + }, + "node_modules/@tensorflow/tfjs-data/node_modules/node-fetch": { + "version": "2.6.13", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@tensorflow/tfjs-layers": { + "version": "4.22.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tensorflow/tfjs-layers/-/tfjs-layers-4.22.0.tgz", + "integrity": "sha512-lybPj4ZNj9iIAPUj7a8ZW1hg8KQGfqWLlCZDi9eM/oNKCCAgchiyzx8OrYoWmRrB+AM6VNEeIT+2gZKg5ReihA==", + "license": "Apache-2.0 AND MIT", + "peerDependencies": { + "@tensorflow/tfjs-core": "4.22.0" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@tufjs/canonical-json": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", + "integrity": "sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tufjs/models/-/models-1.0.4.tgz", + "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "1.0.0", + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/emscripten": { + "version": "0.0.34", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/emscripten/-/emscripten-0.0.34.tgz", + "integrity": "sha512-QSb9ojDincskc+uKMI0KXp8e1NALFINCrMlp8VGKGcTSxeEyRTTKyjWw75NYrCZHUsVEEEpr1tYHpbtaC++/sQ==", + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/expect": { + "version": "1.20.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/expect/-/expect-1.20.4.tgz", + "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/node/-/node-22.14.1.tgz", + "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/offscreencanvas": { + "version": "2019.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz", + "integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==", + "license": "MIT" + }, + "node_modules/@types/seedrandom": { + "version": "2.4.34", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/seedrandom/-/seedrandom-2.4.34.tgz", + "integrity": "sha512-ytDiArvrn/3Xk6/vtylys5tlY6eo7Ane0hvcx++TKo6RxQXuVfW0AF/oeWqAj9dN29SyhtawuXstgmPlwNcv/A==", + "license": "MIT" + }, + "node_modules/@types/vinyl": { + "version": "2.0.12", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/vinyl/-/vinyl-2.0.12.tgz", + "integrity": "sha512-Sr2fYMBUVGYq8kj3UthXFAu5UN6ZW+rYr4NACjZQJvHvj+c8lYv0CahmZ2P/r7iUkN44gGUBwqxZkrKXYPb7cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/expect": "^1.20.4", + "@types/node": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webgpu/types": { + "version": "0.1.38", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webgpu/types/-/types-0.1.38.tgz", + "integrity": "sha512-7LrhVKz2PRh+DD7+S+PVaFd5HxaWQvoMqBbsV9fNJO1pjUs1P8bM2vQVNfk+3URTqbuTI7gkXi0rfsN0IadoBA==", + "license": "BSD-3-Clause" + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/generators": { + "version": "3.0.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webpack-cli/generators/-/generators-3.0.7.tgz", + "integrity": "sha512-H4dlEX8CzO5EHBYYZQop9x4w6lG9FenSF/1spLRlvRAULDgTs0VfmwOuwp03tTLml9jpMsouuVw6vEN8KpwE/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "webpack-cli": "^5.1.4", + "yeoman-environment": "^3.9.1", + "yeoman-generator": "^5.7.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/argparse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-loader": { + "version": "10.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/babel-loader/-/babel-loader-10.0.0.tgz", + "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": "^18.20.0 || ^20.10.0 || >=22.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5.61.0" + } + }, + "node_modules/babel-loader/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.13", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", + "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.4", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.11.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", + "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.4" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/bin-links": { + "version": "3.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/bin-links/-/bin-links-3.0.3.tgz", + "integrity": "sha512-zKdnMPWEdh4F5INR07/eBrodC7QrF5JKvqskjz/ZZRXg5YSAZIbn8zGhbhUrElzHBZ2fvEQdOU59RHcTG3GiwA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^5.0.0", + "mkdirp-infer-owner": "^2.0.0", + "npm-normalize-package-bin": "^2.0.0", + "read-cmd-shim": "^3.0.0", + "rimraf": "^3.0.0", + "write-file-atomic": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/bin-links/node_modules/npm-normalize-package-bin": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", + "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/binaryextensions": { + "version": "4.19.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/binaryextensions/-/binaryextensions-4.19.0.tgz", + "integrity": "sha512-DRxnVbOi/1OgA5pA9EDiRT8gvVYeqfuN7TmPfLyt6cyho3KbHCi3EtDQf39TTmGDrR5dZ9CspdXhPkL/j/WGbg==", + "dev": true, + "license": "Artistic-2.0", + "engines": { + "node": ">=0.8" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "license": "MIT", + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/builtins": { + "version": "1.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cacache": { + "version": "15.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001715", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz", + "integrity": "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table": { + "version": "0.3.11", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cli-table/-/cli-table-0.3.11.tgz", + "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", + "dev": true, + "dependencies": { + "colors": "1.0.3" + }, + "engines": { + "node": ">= 0.2.0" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-buffer": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/cloneable-readable": { + "version": "1.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "node_modules/cloneable-readable/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/cloneable-readable/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/cloneable-readable/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/cmd-shim": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cmd-shim/-/cmd-shim-5.0.0.tgz", + "integrity": "sha512-qkCtZ59BidfEwHltnJwkyVZn+XQojdAySM1D1gSeh11Z4pW1Kpolkyo53L5noc0nrxmIvyFwTmJRo4xs7FFLPw==", + "dev": true, + "license": "ISC", + "dependencies": { + "mkdirp-infer-owner": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/colors": { + "version": "1.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/colors/-/colors-1.0.3.tgz", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "dev": true, + "license": "ISC" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js": { + "version": "3.29.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/core-js/-/core-js-3.29.1.tgz", + "integrity": "sha512-+jwgnhg6cQxKYIIjGtAHq2nwUOolo9eoFZ4sHfUH09BLXBgxnH4gA0zEd+t+BO2cNB8idaBtZFcFTRjQJRJmAw==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.41.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/core-js-compat/-/core-js-compat-3.41.0.tgz", + "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debuglog": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.140", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/electron-to-chromium/-/electron-to-chromium-1.5.140.tgz", + "integrity": "sha512-o82Rj+ONp4Ip7Cl1r7lrqx/pXhbp/lh9DpKcMNscFJdh8ebyRofnc7Sh01B4jx403RI0oqTBvlZ7OBIZLMr2+Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/envinfo": { + "version": "7.14.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/envinfo/-/envinfo-7.14.0.tgz", + "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/error": { + "version": "10.4.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/error/-/error-10.4.0.tgz", + "integrity": "sha512-YxIFEJuhgcICugOUvRx5th0UM+ActZ9sjY0QJmeVwsQdvosZ7kYzc9QqS0Da3R5iUmgU5meGIxh0xBeZpMVeLw==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/exponential-backoff/-/exponential-backoff-3.1.2.tgz", + "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-text-encoding": { + "version": "1.0.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", + "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==", + "license": "Apache-2.0" + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-yarn-workspace-root2": { + "version": "1.2.16", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", + "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "micromatch": "^4.0.2", + "pkg-dir": "^4.2.0" + } + }, + "node_modules/first-chunk-stream": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", + "integrity": "sha512-X8Z+b/0L4lToKYq+lwnKqi9X/Zek0NibLpsJgVsSxpoYq7JtiCtRb5HqKVEjEw/qAb/4AKKRLOwwKHlWNpm2Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/first-chunk-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/first-chunk-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/first-chunk-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-username": { + "version": "6.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/github-username/-/github-username-6.0.0.tgz", + "integrity": "sha512-7TTrRjxblSI5l6adk9zd+cV5d6i1OrJSo3Vr9xdGqFLBQo0mz5P9eIfKCDJ7eekVGGFLbce0qbPSnktXV2BjDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/rest": "^18.0.6" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/grouped-queue": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/grouped-queue/-/grouped-queue-2.0.0.tgz", + "integrity": "sha512-/PiFUa7WIsl48dUeCvhIHnwNmAAzlI/eHoJl0vu3nsFA366JleY7Ff8EVTplZu5kO0MIdZjKTTnzItL61ahbnw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "4.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ignore-walk/-/ignore-walk-4.0.1.tgz", + "integrity": "sha512-rzDQLaW4jQbh2YrOFlJdCtX8qgJTehFRYiUB2r1osqTeDzV/3+Jh8fz1oAPzUThf3iku8Ds4IDqawI5d8mUiQw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true, + "license": "ISC" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-scoped": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-scoped/-/is-scoped-2.1.0.tgz", + "integrity": "sha512-Cv4OpPTHAK9kHYzkzCrof3VJh7H/PrG2MBUMvvJebaaUMbqhm0YAtXnvh0I3Hnj2tMZWwrRROWLSgfJrKqWmlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "scoped-regex": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json-stringify-nice": { + "version": "1.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", + "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/just-diff": { + "version": "5.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/just-diff/-/just-diff-5.2.0.tgz", + "integrity": "sha512-6ufhP9SHjb7jibNFrNxyFZ6od3g+An6Ai9mhGRvcYe8UJlH0prseN64M+6ZBBUoKYHZsitDP42gAJ8+eVWr3lw==", + "dev": true, + "license": "MIT" + }, + "node_modules/just-diff-apply": { + "version": "5.5.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/just-diff-apply/-/just-diff-apply-5.5.0.tgz", + "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-yaml-file": { + "version": "0.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/load-yaml-file/-/load-yaml-file-0.2.0.tgz", + "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.13.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/load-yaml-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/load-yaml-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mem-fs": { + "version": "2.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/mem-fs/-/mem-fs-2.3.0.tgz", + "integrity": "sha512-GftCCBs6EN8sz3BoWO1bCj8t7YBtT713d8bUgbhg9Iel5kFSqnSvCK06TYIDJAtJ51cSiWkM/YemlT0dfoFycw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^15.6.2", + "@types/vinyl": "^2.0.4", + "vinyl": "^2.0.1", + "vinyl-file": "^3.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mem-fs-editor": { + "version": "9.7.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/mem-fs-editor/-/mem-fs-editor-9.7.0.tgz", + "integrity": "sha512-ReB3YD24GNykmu4WeUL/FDIQtkoyGB6zfJv60yfCo3QjKeimNcTqv2FT83bP0ccs6uu+sm5zyoBlspAzigmsdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "binaryextensions": "^4.16.0", + "commondir": "^1.0.1", + "deep-extend": "^0.6.0", + "ejs": "^3.1.8", + "globby": "^11.1.0", + "isbinaryfile": "^5.0.0", + "minimatch": "^7.2.0", + "multimatch": "^5.0.0", + "normalize-path": "^3.0.0", + "textextensions": "^5.13.0" + }, + "engines": { + "node": ">=12.10.0" + }, + "peerDependencies": { + "mem-fs": "^2.1.0" + }, + "peerDependenciesMeta": { + "mem-fs": { + "optional": true + } + } + }, + "node_modules/mem-fs-editor/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mem-fs-editor/node_modules/isbinaryfile": { + "version": "5.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/isbinaryfile/-/isbinaryfile-5.0.4.tgz", + "integrity": "sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/mem-fs-editor/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mem-fs/node_modules/@types/node": { + "version": "15.14.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@types/node/-/node-15.14.9.tgz", + "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch": { + "version": "1.4.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-json-stream": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-json-stream/-/minipass-json-stream-1.0.2.tgz", + "integrity": "sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-infer-owner": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz", + "integrity": "sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "infer-owner": "^1.0.4", + "mkdirp": "^1.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/multimatch": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp": { + "version": "8.4.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/node-gyp/-/node-gyp-8.4.1.tgz", + "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^9.1.0", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/node-gyp/node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "1.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-install-checks": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-install-checks/-/npm-install-checks-4.0.0.tgz", + "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true, + "license": "ISC" + }, + "node_modules/npm-package-arg": { + "version": "8.1.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-package-arg/-/npm-package-arg-8.1.5.tgz", + "integrity": "sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^4.0.1", + "semver": "^7.3.4", + "validate-npm-package-name": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-packlist": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-packlist/-/npm-packlist-3.0.0.tgz", + "integrity": "sha512-L/cbzmutAwII5glUcf2DBRNY/d0TFd4e/FnaZigJV6JD85RHZXJFGwCndjMWiiViiWSsWt3tiOLpI3ByTnIdFQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.6", + "ignore-walk": "^4.0.1", + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "bin": { + "npm-packlist": "bin/index.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-packlist/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm-pick-manifest": { + "version": "6.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz", + "integrity": "sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^4.0.0", + "npm-normalize-package-bin": "^1.0.1", + "npm-package-arg": "^8.1.2", + "semver": "^7.3.4" + } + }, + "node_modules/npm-registry-fetch": { + "version": "12.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-registry-fetch/-/npm-registry-fetch-12.0.2.tgz", + "integrity": "sha512-Df5QT3RaJnXYuOwtXBXS9BWs+tHH2olvkCLh6jcR/b/u3DvPMlp3J0TvvYwplPKxHMOwfg287PYih9QqaVFoKA==", + "dev": true, + "license": "ISC", + "dependencies": { + "make-fetch-happen": "^10.0.1", + "minipass": "^3.1.6", + "minipass-fetch": "^1.4.1", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^8.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/npm-registry-fetch/node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm-registry-fetch/node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm-registry-fetch/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/make-fetch-happen/node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm-registry-fetch/node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm-registry-fetch/node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-transform": { + "version": "1.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-transform/-/p-transform-1.3.0.tgz", + "integrity": "sha512-UJKdSzgd3KOnXXAtqN5+/eeHcvTn1hBkesEmElVgvO/NAYcxAvmjzIGmnNd3Tb/gRAvMBdNRFD4qAWdHxY6QXg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.3.2", + "p-queue": "^6.6.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "12.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/pacote/-/pacote-12.0.3.tgz", + "integrity": "sha512-CdYEl03JDrRO3x18uHjBYA9TyoW8gy+ThVcypcDkxPtKlw76e4ejhYB6i9lJ+/cebbjpqPW/CijjqxwDTts8Ow==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^2.1.0", + "@npmcli/installed-package-contents": "^1.0.6", + "@npmcli/promise-spawn": "^1.2.0", + "@npmcli/run-script": "^2.0.0", + "cacache": "^15.0.5", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "infer-owner": "^1.0.4", + "minipass": "^3.1.3", + "mkdirp": "^1.0.3", + "npm-package-arg": "^8.0.1", + "npm-packlist": "^3.0.0", + "npm-pick-manifest": "^6.0.0", + "npm-registry-fetch": "^12.0.0", + "promise-retry": "^2.0.1", + "read-package-json-fast": "^2.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.1.0" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/parse-conflict-json": { + "version": "2.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/parse-conflict-json/-/parse-conflict-json-2.0.2.tgz", + "integrity": "sha512-jDbRGb00TAPFsKWCpZZOT93SxVP9nONOSgES3AevqRq/CHvavEBvKAjxX9p5Y5F0RZLxH9Ufd9+RwtCsa+lFDA==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^2.3.1", + "just-diff": "^5.0.1", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/preferred-pm": { + "version": "3.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/preferred-pm/-/preferred-pm-3.1.4.tgz", + "integrity": "sha512-lEHd+yEm22jXdCphDrkvIJQU66EuLojPPtvZkpKIkiD+l0DMThF/niqZKJSoU8Vl7iuvtmzyMhir9LdVy5WMnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0", + "find-yarn-workspace-root2": "1.2.16", + "path-exists": "^4.0.0", + "which-pm": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/preferred-pm/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/preferred-pm/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/preferred-pm/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/preferred-pm/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proc-log": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/proc-log/-/proc-log-1.0.0.tgz", + "integrity": "sha512-aCk8AO51s+4JyuYGg3Q/a6gnrlDO09NpVWePtjp7xwphcoQ04x5WAfCyugcsbLooWcMJ87CLkD4+604IckEdhg==", + "dev": true, + "license": "ISC" + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/promise-all-reject-late": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-call-limit": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/promise-call-limit/-/promise-call-limit-1.0.2.tgz", + "integrity": "sha512-1vTUnfI2hzui8AEIixbdAJlFY4LFDXqQswy/2eOlThAscXCY4It8FdVuI0fMJGAB2aWGbdQf/gv0skKYXmdrHA==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-cmd-shim": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/read-cmd-shim/-/read-cmd-shim-3.0.1.tgz", + "integrity": "sha512-kEmDUoYf/CDy8yZbLTmhB1X9kkjf9Q80PCNsDMb7ufrGd6zZSQA1+UyjrO+pZm5K/S4OXCWJeiIt1JA8kAsa6g==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/read-package-json": { + "version": "6.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/read-package-json/-/read-package-json-6.0.4.tgz", + "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", + "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "2.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz", + "integrity": "sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/read-package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/read-package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/read-package-json/node_modules/hosted-git-info": { + "version": "6.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/hosted-git-info/-/hosted-git-info-6.1.3.tgz", + "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/read-package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/read-package-json/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/read-package-json/node_modules/normalize-package-data": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readable-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "license": "ISC", + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true, + "license": "ISC" + }, + "node_modules/replace-ext": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/scoped-regex": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/scoped-regex/-/scoped-regex-2.1.0.tgz", + "integrity": "sha512-g3WxHrqSWCZHGHlSrF51VXFdjImhwvH8ZO/pryFH56Qi0cDsZfylQa/t0jCzVQFNbNvM00HfHjkDPEuarKDSWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shelljs/node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/shelljs/node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sigstore": { + "version": "1.9.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/sigstore/-/sigstore-1.9.0.tgz", + "integrity": "sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^1.1.0", + "@sigstore/protobuf-specs": "^0.2.0", + "@sigstore/sign": "^1.0.0", + "@sigstore/tuf": "^1.0.3", + "make-fetch-happen": "^11.0.1" + }, + "bin": { + "sigstore": "bin/sigstore.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/sigstore/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sigstore/node_modules/cacache": { + "version": "17.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cacache/-/cacache-17.1.4.tgz", + "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^7.0.3", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/cacache/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sigstore/node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/fs-minipass/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sigstore/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore/node_modules/glob/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sigstore/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sigstore/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/sigstore/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/sigstore/node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/sigstore/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sigstore/node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sigstore/node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/ssri/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sigstore/node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/socks/-/socks-2.8.4.tgz", + "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sort-keys": { + "version": "4.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/sort-keys/-/sort-keys-4.2.0.tgz", + "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "license": "MIT", + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/stream-browserify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom-buf": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", + "integrity": "sha512-1sUIL1jck0T1mhOLP2c696BIznzT525Lkub+n4jjMHjhjhoAQA6Ye659DxdlZBr0aLDMQoTxKIpnlqxgtwjsuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-bom-stream": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", + "integrity": "sha512-yH0+mD8oahBZWnY43vxs4pSinn8SMKAdml/EOGBewoe1Y0Eitd0h2Mg3ZRiXruUW6L4P+lvZiEgbh0NgUGia1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "first-chunk-stream": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/terser": { + "version": "5.39.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/textextensions": { + "version": "5.16.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/textextensions/-/textextensions-5.16.0.tgz", + "integrity": "sha512-7D/r3s6uPZyU//MCYrX6I14nzauDwJ5CxazouuRGNuvSCihW87ufN6VLoROLCrHg6FblLuJrT6N2BVaPVzqElw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/treeverse": { + "version": "1.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/treeverse/-/treeverse-1.0.4.tgz", + "integrity": "sha512-whw60l7r+8ZU8Tu/Uc2yxtc4ZTZbR/PF3u1IPNKGQ6p8EICLb3Z2lAgoqw9bqYd8IkgnsaOcLzYHFckjqNsf0g==", + "dev": true, + "license": "ISC" + }, + "node_modules/ts-loader": { + "version": "9.5.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ts-loader/-/ts-loader-9.5.2.tgz", + "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "1.1.7", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/tuf-js/-/tuf-js-1.1.7.tgz", + "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/tuf-js/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/tuf-js/node_modules/cacache": { + "version": "17.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cacache/-/cacache-17.1.4.tgz", + "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^7.0.3", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/cacache/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/tuf-js/node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/fs-minipass/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/tuf-js/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tuf-js/node_modules/glob/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/tuf-js/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tuf-js/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/tuf-js/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tuf-js/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/tuf-js/node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/tuf-js/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/tuf-js/node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tuf-js/node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/ssri/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/tuf-js/node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", + "dev": true, + "license": "ISC", + "dependencies": { + "builtins": "^1.0.3" + } + }, + "node_modules/vinyl": { + "version": "2.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-file": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/vinyl-file/-/vinyl-file-3.0.0.tgz", + "integrity": "sha512-BoJDj+ca3D9xOuPEM6RWVtWQtvEPQiQYn82LvdxhLWplfQsBzBqtgK0yhCP0s1BNTi6dH9BO+dzybvyQIacifg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.3.0", + "strip-bom-buf": "^1.0.0", + "strip-bom-stream": "^2.0.0", + "vinyl": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/walk-up-path": { + "version": "1.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/walk-up-path/-/walk-up-path-1.0.0.tgz", + "integrity": "sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==", + "dev": true, + "license": "ISC" + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/webpack": { + "version": "5.99.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/webpack/-/webpack-5.99.6.tgz", + "integrity": "sha512-TJOLrJ6oeccsGWPl7ujCYuc0pIq2cNsuD6GZDma8i5o5Npvcco/z+NKvZSFsP0/x6SShVb0+X2JK/JHUjKY9dQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-pm": { + "version": "2.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/which-pm/-/which-pm-2.2.0.tgz", + "integrity": "sha512-MOiaDbA5ZZgUjkeMWM5EkJp4loW5ZRoa5bc3/aeMox/PJelMhE6t7S/mLuiY43DBupyxH+S0U1bTui9kWUlmsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-yaml-file": "^0.2.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8.15" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yeoman-environment": { + "version": "3.19.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/yeoman-environment/-/yeoman-environment-3.19.3.tgz", + "integrity": "sha512-/+ODrTUHtlDPRH9qIC0JREH8+7nsRcjDl3Bxn2Xo/rvAaVvixH5275jHwg0C85g4QsF4P6M2ojfScPPAl+pLAg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@npmcli/arborist": "^4.0.4", + "are-we-there-yet": "^2.0.0", + "arrify": "^2.0.1", + "binaryextensions": "^4.15.0", + "chalk": "^4.1.0", + "cli-table": "^0.3.1", + "commander": "7.1.0", + "dateformat": "^4.5.0", + "debug": "^4.1.1", + "diff": "^5.0.0", + "error": "^10.4.0", + "escape-string-regexp": "^4.0.0", + "execa": "^5.0.0", + "find-up": "^5.0.0", + "globby": "^11.0.1", + "grouped-queue": "^2.0.0", + "inquirer": "^8.0.0", + "is-scoped": "^2.1.0", + "isbinaryfile": "^4.0.10", + "lodash": "^4.17.10", + "log-symbols": "^4.0.0", + "mem-fs": "^1.2.0 || ^2.0.0", + "mem-fs-editor": "^8.1.2 || ^9.0.0", + "minimatch": "^3.0.4", + "npmlog": "^5.0.1", + "p-queue": "^6.6.2", + "p-transform": "^1.3.0", + "pacote": "^12.0.2", + "preferred-pm": "^3.0.3", + "pretty-bytes": "^5.3.0", + "readable-stream": "^4.3.0", + "semver": "^7.1.3", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0", + "text-table": "^0.2.0", + "textextensions": "^5.12.0", + "untildify": "^4.0.0" + }, + "bin": { + "yoe": "cli/index.js" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/yeoman-environment/node_modules/commander": { + "version": "7.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/commander/-/commander-7.1.0.tgz", + "integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/yeoman-environment/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yeoman-environment/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yeoman-environment/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yeoman-environment/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yeoman-generator": { + "version": "5.10.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/yeoman-generator/-/yeoman-generator-5.10.0.tgz", + "integrity": "sha512-iDUKykV7L4nDNzeYSedRmSeJ5eMYFucnKDi6KN1WNASXErgPepKqsQw55TgXPHnmpcyOh2Dd/LAZkyc+f0qaAw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "chalk": "^4.1.0", + "dargs": "^7.0.0", + "debug": "^4.1.1", + "execa": "^5.1.1", + "github-username": "^6.0.0", + "lodash": "^4.17.11", + "mem-fs-editor": "^9.0.0", + "minimist": "^1.2.5", + "pacote": "^15.2.0", + "read-pkg-up": "^7.0.1", + "run-async": "^2.0.0", + "semver": "^7.2.1", + "shelljs": "^0.8.5", + "sort-keys": "^4.2.0", + "text-table": "^0.2.0" + }, + "acceptDependencies": { + "yeoman-environment": "^4.0.0" + }, + "engines": { + "node": ">=12.10.0" + }, + "peerDependencies": { + "yeoman-environment": "^3.2.0" + }, + "peerDependenciesMeta": { + "yeoman-environment": { + "optional": true + } + } + }, + "node_modules/yeoman-generator/node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/@npmcli/git": { + "version": "4.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/git/-/git-4.1.0.tgz", + "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/@npmcli/installed-package-contents": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", + "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/@npmcli/promise-spawn": { + "version": "6.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", + "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/@npmcli/run-script": { + "version": "6.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/run-script/-/run-script-6.0.2.tgz", + "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^6.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/yeoman-generator/node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/cacache": { + "version": "17.1.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cacache/-/cacache-17.1.4.tgz", + "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^7.0.3", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/cacache/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/yeoman-generator/node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/fs-minipass/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/yeoman-generator/node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/yeoman-generator/node_modules/glob/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/yeoman-generator/node_modules/hosted-git-info": { + "version": "6.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/hosted-git-info/-/hosted-git-info-6.1.3.tgz", + "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yeoman-generator/node_modules/ignore-walk": { + "version": "6.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ignore-walk/-/ignore-walk-6.0.5.tgz", + "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen/node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen/node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen/node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen/node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/make-fetch-happen/node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/yeoman-generator/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/yeoman-generator/node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/yeoman-generator/node_modules/minipass-fetch/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yeoman-generator/node_modules/node-gyp": { + "version": "9.4.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/node-gyp/-/node-gyp-9.4.1.tgz", + "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/yeoman-generator/node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/yeoman-generator/node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/yeoman-generator/node_modules/node-gyp/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/yeoman-generator/node_modules/node-gyp/node_modules/which": { + "version": "2.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/yeoman-generator/node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/npm-bundled": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-bundled/-/npm-bundled-3.0.1.tgz", + "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/npm-package-arg": { + "version": "10.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-package-arg/-/npm-package-arg-10.1.0.tgz", + "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/npm-packlist": { + "version": "7.0.4", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-packlist/-/npm-packlist-7.0.4.tgz", + "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^6.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/npm-pick-manifest": { + "version": "8.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz", + "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/npm-registry-fetch": { + "version": "14.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", + "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/npm-registry-fetch/node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/yeoman-generator/node_modules/npm-registry-fetch/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/yeoman-generator/node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/pacote": { + "version": "15.2.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/pacote/-/pacote-15.2.0.tgz", + "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yeoman-generator/node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/yeoman-generator/node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/ssri/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/yeoman-generator/node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yeoman-generator/node_modules/which": { + "version": "3.0.1", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://artifacthub-iad.oci.oraclecorp.com/api/npm/npmjs-registry/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/graalwasm/graalwasm-tensorflow/src/main/js/package.json b/graalwasm/graalwasm-tensorflow/src/main/js/package.json new file mode 100644 index 00000000..61b48107 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/js/package.json @@ -0,0 +1,32 @@ +{ + "name": "js", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "webpack --mode=production --node-env=production", + "build:dev": "webpack --mode=development", + "build:prod": "webpack --mode=production --node-env=production", + "watch": "webpack --watch" + }, + "author": "", + "license": "ISC", + "description": "", + "devDependencies": { + "@babel/core": "^7.26.10", + "@babel/preset-env": "^7.26.9", + "@webpack-cli/generators": "^3.0.7", + "babel-loader": "^10.0.0", + "ts-loader": "^9.5.2", + "typescript": "^5.8.3" + }, + "dependencies": { + "@tensorflow/tfjs": "^4.22.0", + "@tensorflow/tfjs-backend-wasm": "^4.22.0", + "assert": "^2.1.0", + "browserify-zlib": "^0.2.0", + "fast-text-encoding": "^1.0.6", + "stream-browserify": "^3.0.0", + "util": "^0.12.5" + } +} diff --git a/graalwasm/graalwasm-tensorflow/src/main/js/tfjs-backend-wasm-simd.wasm b/graalwasm/graalwasm-tensorflow/src/main/js/tfjs-backend-wasm-simd.wasm new file mode 100755 index 0000000000000000000000000000000000000000..b515dee98b4614a42f1e44b6080fc0654cfea876 GIT binary patch literal 311123 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

L=749qpwp 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Ɋ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 jh^=7@8_?Jmh8=+d5&VMDB&^|( config; \ No newline at end of file diff --git a/graalwasm/graalwasm-tensorflow/src/main/resources/application.properties b/graalwasm/graalwasm-tensorflow/src/main/resources/application.properties new file mode 100644 index 00000000..bf0367b1 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.application.name=Tensorflow diff --git a/graalwasm/graalwasm-tensorflow/src/main/resources/data.xlsx b/graalwasm/graalwasm-tensorflow/src/main/resources/data.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..f99302f290a54de9f54799e0f0d8bfc48e04c1b5 GIT binary patch literal 18271 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%0D@^ds3zPY^0Jv+ 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 Jh}fUs{vYL;iMRj& literal 0 HcmV?d00001 diff --git a/graalwasm/graalwasm-tensorflow/src/main/resources/excelize.js b/graalwasm/graalwasm-tensorflow/src/main/resources/excelize.js new file mode 100644 index 00000000..35ecc2f4 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/resources/excelize.js @@ -0,0 +1,48 @@ +function readExcel(excelFileBytes) { + let result ; + return new Promise((resolve, reject) => { + var start = Date.now(); + const go = new Go(); + global.excelize = {}; + + WebAssembly.instantiate(new Uint8Array(wasmBytes), go.importObject) + .then((result) => { + var endInit = Date.now(); + go.run(result.instance); + + const f = excelize.OpenReader(new Uint8Array(excelFileBytes)); // No fs.readFileSync + + + const ret1 = f.GetCellValue('data', 'B2'); + if (ret1.error) { + console.error(ret1.error); + reject(ret1.error); // Reject promise in case of error + } + + // Get all rows from Sheet1 + const ret2 = f.GetRows('data'); + if (ret2.error) { + console.error(ret2.error); + reject(ret2.error); // Reject promise in case of error + } else { + // Format the rows into a simple array format for return + const resultArray = ret2.result.map(row => row.map(colCell => colCell)); + console.log("Extracted data:", resultArray); + + + // Resolve the promise with the result array + + Polyglot.export("resultArray", resultArray); + resolve(resultArray); + } + + console.log("Excel read successfully."); + }) + .catch(err => { + console.error("Error reading Excel:", err); + reject(err); // Reject promise on error + }); + }); +} + + diff --git a/graalwasm/graalwasm-tensorflow/src/main/resources/excelize.wasm b/graalwasm/graalwasm-tensorflow/src/main/resources/excelize.wasm new file mode 100755 index 0000000000000000000000000000000000000000..2837a0fa1540bf36485f16572200ee0a3e388624 GIT binary patch literal 15101146 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±TX^o|WOKto@tuMpnW*6zW>18K5<(f8G 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

-AUgf83{AC3L`xDHmgFPa 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⋙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

i!7qEz-=8s@0j^rKAn-1NAZ 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 j$$RBMTN_Yv1wQ+;`GR zquAefvUd2Le)`xMXP$Z1S!bPn&N=6td)}f)Kj!@N7hiC}g^wL?x3kAR?(t7};**}V z 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�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
UrOBpxxs8ZzF}fY4R; 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

GRo7`O*(G@Pw)^1(U{ff3R0 zV1Qg3}M!@y!^y%pMC4;vW=Jym{~5Dmv8x-8$NGG58oU2uw+%vy{I}6 zF&(NCkqHg3ax`Wjg6)oXAWjHGOi3KX#8WuJtnB}1m9SiG86fPILBj4BBrGRd<-s@C z342?Eux88KcbAk_o$`g|IX=ZIuOtJy0X8XV}+3Jy0hs#FYqpph8$ys1jB$ z3?nSFUY1|_<~KflItS-Q0K(JMmX}xVzWV)lN{GbrMY(iEm99v8S*I&Ex5HE)L)Ym9 z+*koSExMA11A~+1`v48M4$|~AUAcb**KPv&)pK7r$)L{n}vZufGflD*4#kj_{U#{K^Y$T zPqutGL653;`G3El{EB0+r1?|$;LSpZrL9Gg ziK5`CenZ^u|D-Vtf0{3f;AGgMcl$&-QlgK!JxM6i&FI2cD)@x%AQ)2ku3GhrgR%Kcw!Y2h>+4pR_EYOVxuxhpo1mkHATQQ)j0079 zlwa=E+9$LkpiY56Tecd7#Pt*tEzW&gM|$_FifowNY)tvR|33)v_=yS9K!=v|Fe;vh zc*i^5=}tJg8h_u%)2n$v3;uLO%dkw8!^!vM8u=bh^2JIbQX_*elWRFHq&DIL3N61T z%aT;=aSo<%V^FJ{-sOG>W&rl{6d?Y^<6w>Qji<@uNA}?V%@-RHA&KqyEu1>PaPV|klScQ!W0Q9ZAxd3!_OflCBHe~3&!_%BFv+i~-(y^Ru zXet`&;$4fK1Ye#(sP6B$fvR>tb_`Es7MTdhQVsoZbeqt2U07tgj}^(%KSke&Yif6 zw?kGy3TXHbYW=!3_v_QvuX~AL!9J`HHEjLr=;+7Cpa+Wi+h3k`{%sp4CV0v{GPX0F zJS|rx?I*^Iz&MZjU<_WToV8Pt=}^}4PT*dZc~^mOx?BDQiP+;!uF0G|aTk|mn4V0P zMY5=Mx-vi4jnC1sqF^xIJvgz89LZcqI#IcN-*WYWR;FeOgLo6q(mS8OM^AgcLK6F_ zvZJpvFO0&G_?^}9^>cAosqD*(Z92#NHi`)f##Lu|SDEK+JbjX@5P|tbML|PrI)9&w z-T8{Aeh+;8J>1K|CGSr8uZHV)^NufX8#*i;;SldjTUZdl`;?axtdkT*{tQ)pzM{I# zSH&t5;-5GTLOkq>Q9>MI7YBLsk3ks9{i`!+S5o|Owbe^$Y(0D;Edmkfal$f43qr?mmGfHfYAnU}7 z`w2ETN-XLBJdFi>Y``d)#myx3<3dtDE+qBi0#ct;J{+?Ej7K&(k5)pMWLH{=CV-QHTZv0Ik0Wh2{NWfs|C5xW8; z5m`0!nP7r2^FeWGo5Wyrw z5QBg3`<`=``o6EKTauXx(|)Y_wtMfn=brtZd+!*KYsaau(lU^@ry|F6u-{>lg=xNB z?H}crbep;9$qjMaQzdhZ6Ez71cdmP9|MuszNPFQ7z#K|2czyhfWFrz7R z+@q^~#DG15MkpKvSb$O#AE1mB?~=j+3rG^i0{WgHjG1iRNN-}GVm1b{bjajr6r80) zyZ^Z$G&QfdL~dLAz$cUvsYwjxJ(0^o%;ja!|(i;Vb3n-vFghSq< z>v{le6kFEy8SlFuuvxc$aXtmKm>Ak6=58rULV z2=>?oC2j-}+!0rs$l2e^dHs_HP(9@2c7&*YtP0f!6RIh}BB}{mgp+R~s_o{OP#q!Z zLUr&&O1S2WvS_`r6RUYJM>a-=fD75ptP_rSk;{}lhe=_{Z!9p(8wN)r&qx;s(W4)w#+=kM^y*^ABN*14Xeq`+s{v4*&p|AV}phhK8C$oEH!kI~}Wjc8o z<~?DPa^zh2v~NxyWD%I$UO7S74+$7gUsJLIP`^pHJDYefo>O-tS>h%5vIjSs`V(oXb3r-Ag+m< zD8B55;tOQb(=HBn3yI&=W+aQPod}A{FUw5aPdNZO%;lFDQACQDffS8B0gke_7q z!~{T3>odDwp(Pv-4n}Y}-#XmG31ETfX|MpLilh!S%tFhwo!qJmNg zb>;pAYKDF)7y4kSP%=+9GgrKq>K&M#|3ApHi);Fe@{Affrikm@@DQ3-U|LaWkeQ1! zr2m%0*-Sy4F$cOeHxLcqy+C~wXZv*Hb2fYv#hKk4n>dT0xHzL^HDcj!mpG%*9bN`H z-_?H9SU!j|?ys&zsmLmIz(w7mOA=>2dI8o94kU_p%{&DHs1|3%PEecl=!7h7f0;VL zr$j5KY(iX~k!{2)3vqcS8=p9q$K{or&nPRCca(>`tG&^AQjso(Zy?nmh#JZcLaY)1 z9AFoNTY3;T;kf9zfwCFd-U2CxM(LNZ&@1o*He1Vzs2f6eGbxtwdt!cBf#HqW32Zr+ zVyrG8CP}d!orq(XVhr*{13F1DR?Zh)Qf$tp7+-qbni*ph*<*kYgb`qv{uMDiKi+6V zRWCzN8~2{ZX=uIH&49w%CQL(@Wa@;QzMXBK>xPj`UYq|ccl++t?XIw0=q0SaP{^w2 z9thqYDD|BtYA%k`O<#yj$*{W6WE!6LBshI|EZL)^WCGw_!!ug~(GQBJmXR*O0MP8l z$UvD=E1S80PvxMI7iiTWx(z+t(D!Dbrb;ji#3X*=hXj-Jfd{l856gT|Ss*B!ssd)y z{$!yxEu{UpgnhDJ<&W_|%VF8C-O=#f6~g`2f^b(fe0LJ=d(h!1+~;)T!kurTaJQRd z6Ydcd7w%6I#u(o%JFP3NQU>EY;1cekOA_uqdU4dkz1Ruk z_{vU%0D5;P4mo+Jr{X}~xfvOZ$Jivt-~ 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 z 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

Q=jC_h_#Xb{roQlI#U3G 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

b4m5hfB$ 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

M1 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 GHO~eJ%0&*rUMfThb_w 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%0DNtAX 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

Abd#p_9&UqJc!*%>T$biFhCp3RSW(d{m2! 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�}8uGK&J~hXmn}o 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

#Z`5gmW%iz^*bya^p| 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

fj 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

g;SC#E5q3g=hNiS(&^245@MiTt zeadWzu)kl32UE$e&5{A}M21rt7JL8_PHxRz?oe2DKdosRs0KuXPi7<%TdmrAm49u* zMGats$c)Mk+7Jo`?NwGa=z75dE+1rRyef-Mv8+$Li5(7N;qVX-@kBwmzyK34u%dHc zDVCX!_d18zVwokQ6gbpQ+srwp0;TiTE1^xT#0%okD5k?r zdp!Pj_PyBwv(P3bB7q4*v)`pEvP`v9BM%_Zh6Plxr~!0FZMS>#Mr|6ni*ZkDJ(3Yq z3+x^WFQ8=*GR1Bf9&qiz-)*f|!=sBu>OkgfZVQhJ!(V|L7g)2i;3RG;7+aWJq(#e3 z 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


)yE)odJnOe7wKeT#OyvEm(8vY6UCchD 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
7Vj; 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∓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�b5XC4~3}Fnfv$+cqso}qM{0Fz8UcxJu7P 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

ES20H>j&0#^VfFcb#p<*1?ua@ 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 z

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%0A)^Q%m9A~5~!G52pCPj;C4sn6F> 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 z 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 u7q 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

3U)2xpYRPH)T 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

~c$UR?MLX@Ezb!bNR1)B9yg34XLBKx5cZODtI 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èR;d71UkM?VA~vY8UbPl`oU4A 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�BkM-{ukBxk3>n3ANl;Rx0MPW&xZ;#|4R?>zb0qa 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⋙$!}Qbi z%k(mU-K}W8O9InfJ{H=0o$5S!D*yYBOlon6+k|S#LI&Av0`7%trHl z_5o`$o6Qedi`i=V{)e#&~x&seY7XZD)|=Ah!KJZE39 zVe?D&6&o=}&9B)v>|6F78&jN>gd(k^%>^pE92||6`rp8S`1Q zi#umNZ@yr5a~I8*%$Lnq%va6V%-78x&dc2}`?#BCKX=P~+kD4-*L=@>-yGl`m>-%S znSxnOz8U9?=XT(-R8t|;59 z*DTi+f#;^>mgP0~hP!Qf%iU2-o_mVT^T6`Z^2qYo@{W7YJ+VBseBhp0o?Bj6K5{QD zuPm=EZ~jwz-djF#pScf~FWg7VSMHPLv*nBBtL2;JyX71Ao%><=Y5BqZQe2;(+%N8r z<*((Rr9u&Xs;t%4-`pRr#`>45wf^JktWLh(>f+segVn<~TAQrRiuTiLZL_vpJFLn; zqqSS{e|i=Dr{6kY9kdQ929TFmhIAAONE!XGjw>3FkN5MFiU}0pr>!&AS!#}vl8sb;2Yu0t^hBeG@TDPp*)*b7vbQ8wH35# ztXiwis<$TiByX^$c*vUOVJl)aT1{57)nd)?S>9^3Sy8Lq>ab!~g2$~+tIO)PdaPcn z&r0%sYrsnJK`YINtYK?Jv5I2WxRv2qK4DE-IX-1gTQgRk7x=7|u##5FN?RGL$V)tH zm3hvZ<9VxK6&2k`w&tvPYr$HymaJv#3F}GgDeGzL8S7c=IYmCYpx8&3{?m`HTCZ8J zTW=^T!Y%7jnNI|Izx%`q_Gk|6=`W{bv1c{bBuS{bjw(U*UgS z|5&f`*Z9BIf7S|HrQ#@E=Wp;g`D$B@?G|5atFzVHZu1ScMq87u`9EQ)&31>s%eO1i z(mnn@-)ZZzb=!Juy|z9@UQz~nY(utT+cDd5+lXz{HfB?%?`)H{DciJd#x`r4v(4KU z6zkyuzoaNlE4EeJnr+>-VcWEA*|rt4Y1g)A+qWIq4sAy^l?|||ZJ9mhHCfj_t1Pp6$Nv zfg(&jQnaZjwx_mdwzvFq+Y8%E+bi2^+Z)?k+dJEPMV|U-`(*oU`(pcQ`)2!Y`(gWO z`(^uW`(yiSd&j@$|Jf?g4}2wBg?{8e@zv;OzD9AV>d<<$0sX>%E-zx1g

hD2GycE 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%0D@&?l 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 Ry6L`q?!V*iTQ)!H{{er*1`PlJ literal 0 HcmV?d00001 diff --git a/graalwasm/graalwasm-tensorflow/src/main/resources/excelize_m.js b/graalwasm/graalwasm-tensorflow/src/main/resources/excelize_m.js new file mode 100644 index 00000000..78ad346e --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/resources/excelize_m.js @@ -0,0 +1,563 @@ +'use strict'; + +if (typeof window === 'undefined') { + global.crypto = { + getRandomValues(b) { + return nodeCrypto.randomFillSync(b); + } + }; + global.performance = { + now() { + const [sec, nsec] = process.hrtime(); + return sec * 1000 + nsec / 1000000; + } + }; +} +(() => { + const enosys = () => { + const err = new Error("not implemented"); + err.code = "ENOSYS"; + return err; + }; + + if (!globalThis.fs) { + let outputBuf = ""; + globalThis.fs = { + constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused + writeSync(fd, buf) { + outputBuf += decoder.decode(buf); + const nl = outputBuf.lastIndexOf("\n"); + if (nl != -1) { + console.log(outputBuf.substr(0, nl)); + outputBuf = outputBuf.substr(nl + 1); + } + return buf.length; + }, + write(fd, buf, offset, length, position, callback) { + if (offset !== 0 || length !== buf.length || position !== null) { + callback(enosys()); + return; + } + const n = this.writeSync(fd, buf); + callback(null, n); + }, + chmod(path, mode, callback) { callback(enosys()); }, + chown(path, uid, gid, callback) { callback(enosys()); }, + close(fd, callback) { callback(enosys()); }, + fchmod(fd, mode, callback) { callback(enosys()); }, + fchown(fd, uid, gid, callback) { callback(enosys()); }, + fstat(fd, callback) { callback(enosys()); }, + fsync(fd, callback) { callback(null); }, + ftruncate(fd, length, callback) { callback(enosys()); }, + lchown(path, uid, gid, callback) { callback(enosys()); }, + link(path, link, callback) { callback(enosys()); }, + lstat(path, callback) { callback(enosys()); }, + mkdir(path, perm, callback) { callback(enosys()); }, + open(path, flags, mode, callback) { callback(enosys()); }, + read(fd, buffer, offset, length, position, callback) { callback(enosys()); }, + readdir(path, callback) { callback(enosys()); }, + readlink(path, callback) { callback(enosys()); }, + rename(from, to, callback) { callback(enosys()); }, + rmdir(path, callback) { callback(enosys()); }, + stat(path, callback) { callback(enosys()); }, + symlink(path, link, callback) { callback(enosys()); }, + truncate(path, length, callback) { callback(enosys()); }, + unlink(path, callback) { callback(enosys()); }, + utimes(path, atime, mtime, callback) { callback(enosys()); }, + }; + } + + if (!globalThis.process) { + globalThis.process = { + getuid() { return -1; }, + getgid() { return -1; }, + geteuid() { return -1; }, + getegid() { return -1; }, + getgroups() { throw enosys(); }, + pid: -1, + ppid: -1, + umask() { throw enosys(); }, + cwd() { throw enosys(); }, + chdir() { throw enosys(); }, + } + } + + if (!globalThis.crypto) { + throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)"); + } + + if (!globalThis.performance) { + throw new Error("globalThis.performance is not available, polyfill required (performance.now only)"); + } + + if (!globalThis.TextEncoder) { + throw new Error("globalThis.TextEncoder is not available, polyfill required"); + } + + if (!globalThis.TextDecoder) { + throw new Error("globalThis.TextDecoder is not available, polyfill required"); + } + + const encoder = new TextEncoder("utf-8"); + const decoder = new TextDecoder("utf-8"); + + globalThis.Go = class { + constructor() { + this.argv = ["js"]; + this.env = {}; + this.exit = (code) => { + if (code !== 0) { + console.warn("exit code:", code); + } + }; + this._exitPromise = new Promise((resolve) => { + this._resolveExitPromise = resolve; + }); + this._pendingEvent = null; + this._scheduledTimeouts = new Map(); + this._nextCallbackTimeoutID = 1; + + const setInt64 = (addr, v) => { + this.mem.setUint32(addr + 0, v, true); + this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true); + } + + const getInt64 = (addr) => { + const low = this.mem.getUint32(addr + 0, true); + const high = this.mem.getInt32(addr + 4, true); + return low + high * 4294967296; + } + + const loadValue = (addr) => { + const f = this.mem.getFloat64(addr, true); + if (f === 0) { + return undefined; + } + if (!isNaN(f)) { + return f; + } + + const id = this.mem.getUint32(addr, true); + return this._values[id]; + } + + const storeValue = (addr, v) => { + const nanHead = 0x7FF80000; + + if (typeof v === "number" && v !== 0) { + if (isNaN(v)) { + this.mem.setUint32(addr + 4, nanHead, true); + this.mem.setUint32(addr, 0, true); + return; + } + this.mem.setFloat64(addr, v, true); + return; + } + + if (v === undefined) { + this.mem.setFloat64(addr, 0, true); + return; + } + + let id = this._ids.get(v); + if (id === undefined) { + id = this._idPool.pop(); + if (id === undefined) { + id = this._values.length; + } + this._values[id] = v; + this._goRefCounts[id] = 0; + this._ids.set(v, id); + } + this._goRefCounts[id]++; + let typeFlag = 0; + switch (typeof v) { + case "object": + if (v !== null) { + typeFlag = 1; + } + break; + case "string": + typeFlag = 2; + break; + case "symbol": + typeFlag = 3; + break; + case "function": + typeFlag = 4; + break; + } + this.mem.setUint32(addr + 4, nanHead | typeFlag, true); + this.mem.setUint32(addr, id, true); + } + + const loadSlice = (addr) => { + const array = getInt64(addr + 0); + const len = getInt64(addr + 8); + return new Uint8Array(this._inst.exports.mem.buffer, array, len); + } + + const loadSliceOfValues = (addr) => { + const array = getInt64(addr + 0); + const len = getInt64(addr + 8); + const a = new Array(len); + for (let i = 0; i < len; i++) { + a[i] = loadValue(array + i * 8); + } + return a; + } + + const loadString = (addr) => { + const saddr = getInt64(addr + 0); + const len = getInt64(addr + 8); + return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len)); + } + + const timeOrigin = Date.now() - performance.now(); + this.importObject = { + gojs: { + // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters) + // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported + // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function). + // This changes the SP, thus we have to update the SP used by the imported function. + + // func wasmExit(code int32) + "runtime.wasmExit": (sp) => { + sp >>>= 0; + const code = this.mem.getInt32(sp + 8, true); + this.exited = true; + delete this._inst; + delete this._values; + delete this._goRefCounts; + delete this._ids; + delete this._idPool; + this.exit(code); + }, + + // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32) + "runtime.wasmWrite": (sp) => { + sp >>>= 0; + const fd = getInt64(sp + 8); + const p = getInt64(sp + 16); + const n = this.mem.getInt32(sp + 24, true); + fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n)); + }, + + // func resetMemoryDataView() + "runtime.resetMemoryDataView": (sp) => { + sp >>>= 0; + this.mem = new DataView(this._inst.exports.mem.buffer); + }, + + // func nanotime1() int64 + "runtime.nanotime1": (sp) => { + sp >>>= 0; + setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000); + }, + + // func walltime() (sec int64, nsec int32) + "runtime.walltime": (sp) => { + sp >>>= 0; + const msec = (new Date).getTime(); + setInt64(sp + 8, msec / 1000); + this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true); + }, + + // func scheduleTimeoutEvent(delay int64) int32 + "runtime.scheduleTimeoutEvent": (sp) => { + sp >>>= 0; + const id = this._nextCallbackTimeoutID; + this._nextCallbackTimeoutID++; + this._scheduledTimeouts.set(id, setTimeout( + () => { + this._resume(); + while (this._scheduledTimeouts.has(id)) { + // for some reason Go failed to register the timeout event, log and try again + // (temporary workaround for https://github.com/golang/go/issues/28975) + console.warn("scheduleTimeoutEvent: missed timeout event"); + this._resume(); + } + }, + getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early + )); + this.mem.setInt32(sp + 16, id, true); + }, + + // func clearTimeoutEvent(id int32) + "runtime.clearTimeoutEvent": (sp) => { + sp >>>= 0; + const id = this.mem.getInt32(sp + 8, true); + clearTimeout(this._scheduledTimeouts.get(id)); + this._scheduledTimeouts.delete(id); + }, + + // func getRandomData(r []byte) + "runtime.getRandomData": (sp) => { + sp >>>= 0; + crypto.getRandomValues(loadSlice(sp + 8)); + }, + + // func finalizeRef(v ref) + "syscall/js.finalizeRef": (sp) => { + sp >>>= 0; + const id = this.mem.getUint32(sp + 8, true); + this._goRefCounts[id]--; + if (this._goRefCounts[id] === 0) { + const v = this._values[id]; + this._values[id] = null; + this._ids.delete(v); + this._idPool.push(id); + } + }, + + // func stringVal(value string) ref + "syscall/js.stringVal": (sp) => { + sp >>>= 0; + storeValue(sp + 24, loadString(sp + 8)); + }, + + // func valueGet(v ref, p string) ref + "syscall/js.valueGet": (sp) => { + sp >>>= 0; + const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16)); + sp = this._inst.exports.getsp() >>> 0; // see comment above + storeValue(sp + 32, result); + }, + + // func valueSet(v ref, p string, x ref) + "syscall/js.valueSet": (sp) => { + sp >>>= 0; + Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32)); + }, + + // func valueDelete(v ref, p string) + "syscall/js.valueDelete": (sp) => { + sp >>>= 0; + Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16)); + }, + + // func valueIndex(v ref, i int) ref + "syscall/js.valueIndex": (sp) => { + sp >>>= 0; + storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16))); + }, + + // valueSetIndex(v ref, i int, x ref) + "syscall/js.valueSetIndex": (sp) => { + sp >>>= 0; + Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24)); + }, + + // func valueCall(v ref, m string, args []ref) (ref, bool) + "syscall/js.valueCall": (sp) => { + sp >>>= 0; + try { + const v = loadValue(sp + 8); + const m = Reflect.get(v, loadString(sp + 16)); + const args = loadSliceOfValues(sp + 32); + const result = Reflect.apply(m, v, args); + sp = this._inst.exports.getsp() >>> 0; // see comment above + storeValue(sp + 56, result); + this.mem.setUint8(sp + 64, 1); + } catch (err) { + sp = this._inst.exports.getsp() >>> 0; // see comment above + storeValue(sp + 56, err); + this.mem.setUint8(sp + 64, 0); + } + }, + + // func valueInvoke(v ref, args []ref) (ref, bool) + "syscall/js.valueInvoke": (sp) => { + sp >>>= 0; + try { + const v = loadValue(sp + 8); + const args = loadSliceOfValues(sp + 16); + const result = Reflect.apply(v, undefined, args); + sp = this._inst.exports.getsp() >>> 0; // see comment above + storeValue(sp + 40, result); + this.mem.setUint8(sp + 48, 1); + } catch (err) { + sp = this._inst.exports.getsp() >>> 0; // see comment above + storeValue(sp + 40, err); + this.mem.setUint8(sp + 48, 0); + } + }, + + // func valueNew(v ref, args []ref) (ref, bool) + "syscall/js.valueNew": (sp) => { + sp >>>= 0; + try { + const v = loadValue(sp + 8); + const args = loadSliceOfValues(sp + 16); + const result = Reflect.construct(v, args); + sp = this._inst.exports.getsp() >>> 0; // see comment above + storeValue(sp + 40, result); + this.mem.setUint8(sp + 48, 1); + } catch (err) { + sp = this._inst.exports.getsp() >>> 0; // see comment above + storeValue(sp + 40, err); + this.mem.setUint8(sp + 48, 0); + } + }, + + // func valueLength(v ref) int + "syscall/js.valueLength": (sp) => { + sp >>>= 0; + setInt64(sp + 16, parseInt(loadValue(sp + 8).length)); + }, + + // valuePrepareString(v ref) (ref, int) + "syscall/js.valuePrepareString": (sp) => { + sp >>>= 0; + const str = encoder.encode(String(loadValue(sp + 8))); + storeValue(sp + 16, str); + setInt64(sp + 24, str.length); + }, + + // valueLoadString(v ref, b []byte) + "syscall/js.valueLoadString": (sp) => { + sp >>>= 0; + const str = loadValue(sp + 8); + loadSlice(sp + 16).set(str); + }, + + // func valueInstanceOf(v ref, t ref) bool + "syscall/js.valueInstanceOf": (sp) => { + sp >>>= 0; + this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0); + }, + + // func copyBytesToGo(dst []byte, src ref) (int, bool) + "syscall/js.copyBytesToGo": (sp) => { + sp >>>= 0; + const dst = loadSlice(sp + 8); + const src = loadValue(sp + 32); + if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) { + this.mem.setUint8(sp + 48, 0); + return; + } + const toCopy = src.subarray(0, dst.length); + dst.set(toCopy); + setInt64(sp + 40, toCopy.length); + this.mem.setUint8(sp + 48, 1); + }, + + // func copyBytesToJS(dst ref, src []byte) (int, bool) + "syscall/js.copyBytesToJS": (sp) => { + sp >>>= 0; + const dst = loadValue(sp + 8); + const src = loadSlice(sp + 16); + if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) { + this.mem.setUint8(sp + 48, 0); + return; + } + const toCopy = src.subarray(0, dst.length); + dst.set(toCopy); + setInt64(sp + 40, toCopy.length); + this.mem.setUint8(sp + 48, 1); + }, + + "debug": (value) => { + console.log(value); + }, + } + }; + } + + async run(instance) { + if (!(instance instanceof WebAssembly.Instance)) { + throw new Error("Go.run: WebAssembly.Instance expected"); + } + this._inst = instance; + this.mem = new DataView(this._inst.exports.mem.buffer); + this._values = [ // JS values that Go currently has references to, indexed by reference id + NaN, + 0, + null, + true, + false, + globalThis, + this, + ]; + this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id + this._ids = new Map([ // mapping from JS values to reference ids + [0, 1], + [null, 2], + [true, 3], + [false, 4], + [globalThis, 5], + [this, 6], + ]); + this._idPool = []; // unused ids that have been garbage collected + this.exited = false; // whether the Go program has exited + + // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory. + let offset = 4096; + + const strPtr = (str) => { + const ptr = offset; + const bytes = encoder.encode(str + "\0"); + new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes); + offset += bytes.length; + if (offset % 8 !== 0) { + offset += 8 - (offset % 8); + } + return ptr; + }; + + const argc = this.argv.length; + + const argvPtrs = []; + this.argv.forEach((arg) => { + argvPtrs.push(strPtr(arg)); + }); + argvPtrs.push(0); + + const keys = Object.keys(this.env).sort(); + keys.forEach((key) => { + argvPtrs.push(strPtr(`${key}=${this.env[key]}`)); + }); + argvPtrs.push(0); + + const argv = offset; + argvPtrs.forEach((ptr) => { + this.mem.setUint32(offset, ptr, true); + this.mem.setUint32(offset + 4, 0, true); + offset += 8; + }); + + // The linker guarantees global data starts from at least wasmMinDataAddr. + // Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr. + const wasmMinDataAddr = 4096 + 8192; + if (offset >= wasmMinDataAddr) { + throw new Error("total length of command line and environment variables exceeds limit"); + } + + this._inst.exports.run(argc, argv); + if (this.exited) { + this._resolveExitPromise(); + } + await this._exitPromise; + } + + _resume() { + if (this.exited) { + throw new Error("Go program has already exited"); + } + this._inst.exports.resume(); + if (this.exited) { + this._resolveExitPromise(); + } + } + + _makeFuncWrapper(id) { + const go = this; + return function () { + const event = { id: id, this: this, args: arguments }; + go._pendingEvent = event; + go._resume(); + return event.result; + }; + } + } +})(); \ No newline at end of file diff --git a/graalwasm/graalwasm-tensorflow/src/main/resources/excelize_prep.js b/graalwasm/graalwasm-tensorflow/src/main/resources/excelize_prep.js new file mode 100644 index 00000000..72af4369 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/resources/excelize_prep.js @@ -0,0 +1,28 @@ +(async () => { + global = globalThis; + const nowOffset = Date.now(); + const now = () => Date.now() - nowOffset; + global.process = {}; + global.nodeCrypto = {}; + global.process.hrtime = global.process.hrtime || ((previousTimestamp) => { + const baseNow = Math.floor((Date.now() - now()) * 1e-3) + const clocktime = now() * 1e-3 + let seconds = Math.floor(clocktime) + baseNow + let nanoseconds = Math.floor((clocktime % 1) * 1e9) + + if (previousTimestamp) { + seconds = seconds - previousTimestamp[0] + nanoseconds = nanoseconds - previousTimestamp[1] + if (nanoseconds < 0) { + seconds-- + nanoseconds += 1e9 + } + } + return [seconds, nanoseconds] + }); + global.nodeCrypto.randomFillSync = function(number) { + return 123; + }; +})(); + + diff --git a/graalwasm/graalwasm-tensorflow/src/main/resources/templates/index.html b/graalwasm/graalwasm-tensorflow/src/main/resources/templates/index.html new file mode 100644 index 00000000..e4c2c912 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/resources/templates/index.html @@ -0,0 +1,140 @@ + + + + House Price Prediction + + + + + +

Predict House Price

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+

Predicted Price:

+
+ + + diff --git a/graalwasm/graalwasm-tensorflow/src/main/resources/tf.es2017.js b/graalwasm/graalwasm-tensorflow/src/main/resources/tf.es2017.js new file mode 100644 index 00000000..dd339cd8 --- /dev/null +++ b/graalwasm/graalwasm-tensorflow/src/main/resources/tf.es2017.js @@ -0,0 +1,104780 @@ +/** + * @license + * Copyright 2024 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.tf = global.tf || {})); +})(this, (function (exports) { 'use strict'; + + function _mergeNamespaces(n, m) { + m.forEach(function (e) { + e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) { + if (k !== 'default' && !(k in n)) { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: function () { return e[k]; } + }); + } + }); + }); + return Object.freeze(n); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const EPSILON_FLOAT32$1 = 1e-7; + const EPSILON_FLOAT16$1 = 1e-4; + /** Convenient class for storing tensor-related data. */ + class DataStorage { + constructor(backend, dataMover) { + this.backend = backend; + this.dataMover = dataMover; + this.data = new WeakMap(); + this.dataIdsCount = 0; + } + get(dataId) { + if (!this.data.has(dataId)) { + this.dataMover.moveData(this.backend, dataId); + } + return this.data.get(dataId); + } + set(dataId, value) { + this.dataIdsCount++; + this.data.set(dataId, value); + } + has(dataId) { + return this.data.has(dataId); + } + delete(dataId) { + this.dataIdsCount--; + return this.data.delete(dataId); + } + numDataIds() { + return this.dataIdsCount; + } + } + /** + * The interface that defines the kernels that should be implemented when + * adding a new backend. New backends don't need to implement every one of the + * methods, this can be done gradually (throw an error for unimplemented + * methods). + */ + class KernelBackend { + refCount(dataId) { + return notYetImplemented('refCount'); + } + incRef(dataId) { + return notYetImplemented('incRef'); + } + timerAvailable() { + return true; + } + time(f) { + return notYetImplemented('time'); + } + read(dataId) { + return notYetImplemented('read'); + } + readSync(dataId) { + return notYetImplemented('readSync'); + } + readToGPU(dataId, options) { + return notYetImplemented('readToGPU'); + } + numDataIds() { + return notYetImplemented('numDataIds'); + } + disposeData(dataId, force) { + return notYetImplemented('disposeData'); + } + write(values, shape, dtype) { + return notYetImplemented('write'); + } + move(dataId, values, shape, dtype, refCount) { + return notYetImplemented('move'); + } + createTensorFromGPUData(values, shape, dtype) { + return notYetImplemented('createTensorFromGPUData'); + } + memory() { + return notYetImplemented('memory'); + } + /** Returns the highest precision for floats in bits (e.g. 16 or 32) */ + floatPrecision() { + return notYetImplemented('floatPrecision'); + } + /** Returns the smallest representable number. */ + epsilon() { + return this.floatPrecision() === 32 ? EPSILON_FLOAT32$1 : EPSILON_FLOAT16$1; + } + dispose() { + return notYetImplemented('dispose'); + } + } + function notYetImplemented(kernelName) { + throw new Error(`'${kernelName}' not yet implemented or not found in the registry. ` + + `This kernel may not be supported by the tfjs backend you have chosen`); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Shuffles the array in-place using Fisher-Yates algorithm. + * + * ```js + * const a = [1, 2, 3, 4, 5]; + * tf.util.shuffle(a); + * console.log(a); + * ``` + * + * @param array The array to shuffle in-place. + * + * @doc {heading: 'Util', namespace: 'util'} + */ + // tslint:disable-next-line:no-any + function shuffle(array) { + let counter = array.length; + let index = 0; + // While there are elements in the array + while (counter > 0) { + // Pick a random index + index = (Math.random() * counter) | 0; + // Decrease counter by 1 + counter--; + // And swap the last element with it + swap(array, counter, index); + } + } + /** + * Shuffles two arrays in-place the same way using Fisher-Yates algorithm. + * + * ```js + * const a = [1,2,3,4,5]; + * const b = [11,22,33,44,55]; + * tf.util.shuffleCombo(a, b); + * console.log(a, b); + * ``` + * + * @param array The first array to shuffle in-place. + * @param array2 The second array to shuffle in-place with the same permutation + * as the first array. + * + * @doc {heading: 'Util', namespace: 'util'} + */ + function shuffleCombo( + // tslint:disable-next-line:no-any + array, + // tslint:disable-next-line:no-any + array2) { + if (array.length !== array2.length) { + throw new Error(`Array sizes must match to be shuffled together ` + + `First array length was ${array.length}` + + `Second array length was ${array2.length}`); + } + let counter = array.length; + let index = 0; + // While there are elements in the array + while (counter > 0) { + // Pick a random index + index = (Math.random() * counter) | 0; + // Decrease counter by 1 + counter--; + // And swap the last element of each array with it + swap(array, counter, index); + swap(array2, counter, index); + } + } + /** Clamps a value to a specified range. */ + function clamp(min, x, max) { + return Math.max(min, Math.min(x, max)); + } + function nearestLargerEven(val) { + return val % 2 === 0 ? val : val + 1; + } + function swap(object, left, right) { + const temp = object[left]; + object[left] = object[right]; + object[right] = temp; + } + function sum$4(arr) { + let sum = 0; + for (let i = 0; i < arr.length; i++) { + sum += arr[i]; + } + return sum; + } + /** + * Returns a sample from a uniform [a, b) distribution. + * + * @param a The minimum support (inclusive). + * @param b The maximum support (exclusive). + * @return A pseudorandom number on the half-open interval [a,b). + */ + function randUniform(a, b) { + const r = Math.random(); + return (b * r) + (1 - r) * a; + } + /** Returns the squared Euclidean distance between two vectors. */ + function distSquared(a, b) { + let result = 0; + for (let i = 0; i < a.length; i++) { + const diff = Number(a[i]) - Number(b[i]); + result += diff * diff; + } + return result; + } + /** + * Asserts that the expression is true. Otherwise throws an error with the + * provided message. + * + * ```js + * const x = 2; + * tf.util.assert(x === 2, 'x is not 2'); + * ``` + * + * @param expr The expression to assert (as a boolean). + * @param msg A function that returns the message to report when throwing an + * error. We use a function for performance reasons. + * + * @doc {heading: 'Util', namespace: 'util'} + */ + function assert$1(expr, msg) { + if (!expr) { + throw new Error(typeof msg === 'string' ? msg : msg()); + } + } + function assertShapesMatch(shapeA, shapeB, errorMessagePrefix = '') { + assert$1(arraysEqual(shapeA, shapeB), () => errorMessagePrefix + ` Shapes ${shapeA} and ${shapeB} must match`); + } + function assertNonNull(a) { + assert$1(a != null, () => `The input to the tensor constructor must be a non-null value.`); + } + /** + * Returns the size (number of elements) of the tensor given its shape. + * + * ```js + * const shape = [3, 4, 2]; + * const size = tf.util.sizeFromShape(shape); + * console.log(size); + * ``` + * + * @doc {heading: 'Util', namespace: 'util'} + */ + function sizeFromShape(shape) { + if (shape.length === 0) { + // Scalar. + return 1; + } + let size = shape[0]; + for (let i = 1; i < shape.length; i++) { + size *= shape[i]; + } + return size; + } + function isScalarShape(shape) { + return shape.length === 0; + } + function arraysEqualWithNull(n1, n2) { + if (n1 === n2) { + return true; + } + if (n1 == null || n2 == null) { + return false; + } + if (n1.length !== n2.length) { + return false; + } + for (let i = 0; i < n1.length; i++) { + if (n1[i] !== null && n2[i] !== null && n1[i] !== n2[i]) { + return false; + } + } + return true; + } + function arraysEqual(n1, n2) { + if (n1 === n2) { + return true; + } + if (n1 == null || n2 == null) { + return false; + } + if (n1.length !== n2.length) { + return false; + } + for (let i = 0; i < n1.length; i++) { + if (n1[i] !== n2[i]) { + return false; + } + } + return true; + } + function isInt(a) { + return a % 1 === 0; + } + function tanh$3(x) { + // tslint:disable-next-line:no-any + if (Math.tanh != null) { + // tslint:disable-next-line:no-any + return Math.tanh(x); + } + if (x === Infinity) { + return 1; + } + else if (x === -Infinity) { + return -1; + } + else { + const e2x = Math.exp(2 * x); + return (e2x - 1) / (e2x + 1); + } + } + function sizeToSquarishShape(size) { + const width = Math.ceil(Math.sqrt(size)); + return [width, Math.ceil(size / width)]; + } + /** + * Creates a new array with randomized indices to a given quantity. + * + * ```js + * const randomTen = tf.util.createShuffledIndices(10); + * console.log(randomTen); + * ``` + * + * @param number Quantity of how many shuffled indices to create. + * + * @doc {heading: 'Util', namespace: 'util'} + */ + function createShuffledIndices(n) { + const shuffledIndices = new Uint32Array(n); + for (let i = 0; i < n; ++i) { + shuffledIndices[i] = i; + } + shuffle(shuffledIndices); + return shuffledIndices; + } + function rightPad(a, size) { + if (size <= a.length) { + return a; + } + return a + ' '.repeat(size - a.length); + } + function repeatedTry(checkFn, delayFn = (counter) => 0, maxCounter, scheduleFn) { + return new Promise((resolve, reject) => { + let tryCount = 0; + const tryFn = () => { + if (checkFn()) { + resolve(); + return; + } + tryCount++; + const nextBackoff = delayFn(tryCount); + if (maxCounter != null && tryCount >= maxCounter) { + reject(); + return; + } + if (scheduleFn != null) { + scheduleFn(tryFn, nextBackoff); + } + else { + // google3 does not allow assigning another variable to setTimeout. + // Don't refactor this so scheduleFn has a default value of setTimeout. + setTimeout(tryFn, nextBackoff); + } + }; + tryFn(); + }); + } + /** + * Given the full size of the array and a shape that may contain -1 as the + * implicit dimension, returns the inferred shape where -1 is replaced. + * E.g. For shape=[2, -1, 3] and size=24, it will return [2, 4, 3]. + * + * @param shape The shape, which may contain -1 in some dimension. + * @param size The full size (number of elements) of the array. + * @return The inferred shape where -1 is replaced with the inferred size. + */ + function inferFromImplicitShape(shape, size) { + let shapeProd = 1; + let implicitIdx = -1; + for (let i = 0; i < shape.length; ++i) { + if (shape[i] >= 0) { + shapeProd *= shape[i]; + } + else if (shape[i] === -1) { + if (implicitIdx !== -1) { + throw Error(`Shapes can only have 1 implicit size. ` + + `Found -1 at dim ${implicitIdx} and dim ${i}`); + } + implicitIdx = i; + } + else if (shape[i] < 0) { + throw Error(`Shapes can not be < 0. Found ${shape[i]} at dim ${i}`); + } + } + if (implicitIdx === -1) { + if (size > 0 && size !== shapeProd) { + throw Error(`Size(${size}) must match the product of shape ${shape}`); + } + return shape; + } + if (shapeProd === 0) { + throw Error(`Cannot infer the missing size in [${shape}] when ` + + `there are 0 elements`); + } + if (size % shapeProd !== 0) { + throw Error(`The implicit shape can't be a fractional number. ` + + `Got ${size} / ${shapeProd}`); + } + const newShape = shape.slice(); + newShape[implicitIdx] = size / shapeProd; + return newShape; + } + function parseAxisParam(axis, shape) { + const rank = shape.length; + // Normalize input + axis = axis == null ? shape.map((s, i) => i) : [].concat(axis); + // Check for valid range + assert$1(axis.every(ax => ax >= -rank && ax < rank), () => `All values in axis param must be in range [-${rank}, ${rank}) but ` + + `got axis ${axis}`); + // Check for only integers + assert$1(axis.every(ax => isInt(ax)), () => `All values in axis param must be integers but ` + + `got axis ${axis}`); + // Handle negative axis. + return axis.map(a => a < 0 ? rank + a : a); + } + /** Reduces the shape by removing all dimensions of shape 1. */ + function squeezeShape(shape, axis) { + const newShape = []; + const keptDims = []; + const isEmptyArray = axis != null && Array.isArray(axis) && axis.length === 0; + const axes = (axis == null || isEmptyArray) ? + null : + parseAxisParam(axis, shape).sort(); + let j = 0; + for (let i = 0; i < shape.length; ++i) { + if (axes != null) { + if (axes[j] === i && shape[i] !== 1) { + throw new Error(`Can't squeeze axis ${i} since its dim '${shape[i]}' is not 1`); + } + if ((axes[j] == null || axes[j] > i) && shape[i] === 1) { + newShape.push(shape[i]); + keptDims.push(i); + } + if (axes[j] <= i) { + j++; + } + } + if (shape[i] !== 1) { + newShape.push(shape[i]); + keptDims.push(i); + } + } + return { newShape, keptDims }; + } + function getTypedArrayFromDType(dtype, size) { + return getArrayFromDType(dtype, size); + } + function getArrayFromDType(dtype, size) { + let values = null; + if (dtype == null || dtype === 'float32') { + values = new Float32Array(size); + } + else if (dtype === 'int32') { + values = new Int32Array(size); + } + else if (dtype === 'bool') { + values = new Uint8Array(size); + } + else if (dtype === 'string') { + values = new Array(size); + } + else { + throw new Error(`Unknown data type ${dtype}`); + } + return values; + } + function checkConversionForErrors(vals, dtype) { + for (let i = 0; i < vals.length; i++) { + const num = vals[i]; + if (isNaN(num) || !isFinite(num)) { + throw Error(`A tensor of type ${dtype} being uploaded contains ${num}.`); + } + } + } + /** Returns true if the dtype is valid. */ + function isValidDtype(dtype) { + return dtype === 'bool' || dtype === 'complex64' || dtype === 'float32' || + dtype === 'int32' || dtype === 'string'; + } + /** + * Returns true if the new type can't encode the old type without loss of + * precision. + */ + function hasEncodingLoss(oldType, newType) { + if (newType === 'complex64') { + return false; + } + if (newType === 'float32' && oldType !== 'complex64') { + return false; + } + if (newType === 'int32' && oldType !== 'float32' && oldType !== 'complex64') { + return false; + } + if (newType === 'bool' && oldType === 'bool') { + return false; + } + return true; + } + function bytesPerElement(dtype) { + if (dtype === 'float32' || dtype === 'int32') { + return 4; + } + else if (dtype === 'complex64') { + return 8; + } + else if (dtype === 'bool') { + return 1; + } + else { + throw new Error(`Unknown dtype ${dtype}`); + } + } + /** + * Returns the approximate number of bytes allocated in the string array - 2 + * bytes per character. Computing the exact bytes for a native string in JS + * is not possible since it depends on the encoding of the html page that + * serves the website. + */ + function bytesFromStringArray(arr) { + if (arr == null) { + return 0; + } + let bytes = 0; + arr.forEach(x => bytes += x.length); + return bytes; + } + /** Returns true if the value is a string. */ + function isString(value) { + return typeof value === 'string' || value instanceof String; + } + function isBoolean(value) { + return typeof value === 'boolean'; + } + function isNumber(value) { + return typeof value === 'number'; + } + function inferDtype(values) { + if (Array.isArray(values)) { + return inferDtype(values[0]); + } + if (values instanceof Float32Array) { + return 'float32'; + } + else if (values instanceof Int32Array || values instanceof Uint8Array || + values instanceof Uint8ClampedArray) { + return 'int32'; + } + else if (isNumber(values)) { + return 'float32'; + } + else if (isString(values)) { + return 'string'; + } + else if (isBoolean(values)) { + return 'bool'; + } + return 'float32'; + } + function isFunction(f) { + return !!(f && f.constructor && f.call && f.apply); + } + function nearestDivisor(size, start) { + for (let i = start; i < size; ++i) { + if (size % i === 0) { + return i; + } + } + return size; + } + function computeStrides(shape) { + const rank = shape.length; + if (rank < 2) { + return []; + } + // Last dimension has implicit stride of 1, thus having D-1 (instead of D) + // strides. + const strides = new Array(rank - 1); + strides[rank - 2] = shape[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * shape[i + 1]; + } + return strides; + } + function createNestedArray(offset, shape, a, isComplex = false) { + const ret = new Array(); + if (shape.length === 1) { + const d = shape[0] * (isComplex ? 2 : 1); + for (let i = 0; i < d; i++) { + ret[i] = a[offset + i]; + } + } + else { + const d = shape[0]; + const rest = shape.slice(1); + const len = rest.reduce((acc, c) => acc * c) * (isComplex ? 2 : 1); + for (let i = 0; i < d; i++) { + ret[i] = createNestedArray(offset + i * len, rest, a, isComplex); + } + } + return ret; + } + // Provide a nested array of TypedArray in given shape. + function toNestedArray(shape, a, isComplex = false) { + if (shape.length === 0) { + // Scalar type should return a single number. + return a[0]; + } + const size = shape.reduce((acc, c) => acc * c) * (isComplex ? 2 : 1); + if (size === 0) { + // A tensor with shape zero should be turned into empty list. + return []; + } + if (size !== a.length) { + throw new Error(`[${shape}] does not match the input size ${a.length}${isComplex ? ' for a complex tensor' : ''}.`); + } + return createNestedArray(0, shape, a, isComplex); + } + function convertBackendValuesAndArrayBuffer(data, dtype) { + // If is type Uint8Array[], return it directly. + if (Array.isArray(data)) { + return data; + } + if (dtype === 'float32') { + return data instanceof Float32Array ? data : new Float32Array(data); + } + else if (dtype === 'int32') { + return data instanceof Int32Array ? data : new Int32Array(data); + } + else if (dtype === 'bool' || dtype === 'string') { + return Uint8Array.from(new Int32Array(data)); + } + else { + throw new Error(`Unknown dtype ${dtype}`); + } + } + function makeOnesTypedArray(size, dtype) { + const array = makeZerosTypedArray(size, dtype); + for (let i = 0; i < array.length; i++) { + array[i] = 1; + } + return array; + } + function makeZerosTypedArray(size, dtype) { + if (dtype == null || dtype === 'float32' || dtype === 'complex64') { + return new Float32Array(size); + } + else if (dtype === 'int32') { + return new Int32Array(size); + } + else if (dtype === 'bool') { + return new Uint8Array(size); + } + else { + throw new Error(`Unknown data type ${dtype}`); + } + } + /** + * Make nested `TypedArray` filled with zeros. + * @param shape The shape information for the nested array. + * @param dtype dtype of the array element. + */ + function makeZerosNestedTypedArray(shape, dtype) { + const size = shape.reduce((prev, curr) => prev * curr, 1); + if (dtype == null || dtype === 'float32') { + return toNestedArray(shape, new Float32Array(size)); + } + else if (dtype === 'int32') { + return toNestedArray(shape, new Int32Array(size)); + } + else if (dtype === 'bool') { + return toNestedArray(shape, new Uint8Array(size)); + } + else { + throw new Error(`Unknown data type ${dtype}`); + } + } + function assertNonNegativeIntegerDimensions(shape) { + shape.forEach(dimSize => { + assert$1(Number.isInteger(dimSize) && dimSize >= 0, () => `Tensor must have a shape comprised of positive integers but got ` + + `shape [${shape}].`); + }); + } + /** + * Computes flat index for a given location (multidimentionsal index) in a + * Tensor/multidimensional array. + * + * @param locs Location in the tensor. + * @param rank Rank of the tensor. + * @param strides Tensor strides. + */ + function locToIndex(locs, rank, strides) { + if (rank === 0) { + return 0; + } + else if (rank === 1) { + return locs[0]; + } + let index = locs[locs.length - 1]; + for (let i = 0; i < locs.length - 1; ++i) { + index += strides[i] * locs[i]; + } + return index; + } + /** + * Computes the location (multidimensional index) in a + * tensor/multidimentional array for a given flat index. + * + * @param index Index in flat array. + * @param rank Rank of tensor. + * @param strides Strides of tensor. + */ + function indexToLoc(index, rank, strides) { + if (rank === 0) { + return []; + } + else if (rank === 1) { + return [index]; + } + const locs = new Array(rank); + for (let i = 0; i < locs.length - 1; ++i) { + locs[i] = Math.floor(index / strides[i]); + index -= locs[i] * strides[i]; + } + locs[locs.length - 1] = index; + return locs; + } + /** + * This method asserts whether an object is a Promise instance. + * @param object + */ + // tslint:disable-next-line: no-any + function isPromise(object) { + // We chose to not use 'obj instanceOf Promise' for two reasons: + // 1. It only reliably works for es6 Promise, not other Promise + // implementations. + // 2. It doesn't work with framework that uses zone.js. zone.js monkey + // patch the async calls, so it is possible the obj (patched) is + // comparing to a pre-patched Promise. + return object && object.then && typeof object.then === 'function'; + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Expects flags from URL in the format ?tfjsflags=FLAG1:1,FLAG2:true. + const TENSORFLOWJS_FLAGS_PREFIX = 'tfjsflags'; + /** + * The environment contains evaluated flags as well as the registered platform. + * This is always used as a global singleton and can be retrieved with + * `tf.env()`. + * + * @doc {heading: 'Environment'} + */ + class Environment { + // tslint:disable-next-line: no-any + constructor(global) { + this.global = global; + this.flags = {}; + this.flagRegistry = {}; + this.urlFlags = {}; + // Jasmine spies on this in 'environment_test.ts' + this.getQueryParams = getQueryParams; + this.populateURLFlags(); + } + setPlatform(platformName, platform) { + if (this.platform != null) { + if (!(env().getBool('IS_TEST') || env().getBool('PROD'))) { + console.warn(`Platform ${this.platformName} has already been set. ` + + `Overwriting the platform with ${platformName}.`); + } + } + this.platformName = platformName; + this.platform = platform; + } + registerFlag(flagName, evaluationFn, setHook) { + this.flagRegistry[flagName] = { evaluationFn, setHook }; + // Override the flag value from the URL. This has to happen here because + // the environment is initialized before flags get registered. + if (this.urlFlags[flagName] != null) { + const flagValue = this.urlFlags[flagName]; + if (!(env().getBool('IS_TEST') || env().getBool('PROD'))) { + console.warn(`Setting feature override from URL ${flagName}: ${flagValue}.`); + } + this.set(flagName, flagValue); + } + } + async getAsync(flagName) { + if (flagName in this.flags) { + return this.flags[flagName]; + } + this.flags[flagName] = await this.evaluateFlag(flagName); + return this.flags[flagName]; + } + get(flagName) { + if (flagName in this.flags) { + return this.flags[flagName]; + } + const flagValue = this.evaluateFlag(flagName); + if (isPromise(flagValue)) { + throw new Error(`Flag ${flagName} cannot be synchronously evaluated. ` + + `Please use getAsync() instead.`); + } + this.flags[flagName] = flagValue; + return this.flags[flagName]; + } + getNumber(flagName) { + return this.get(flagName); + } + getBool(flagName) { + return this.get(flagName); + } + getString(flagName) { + return this.get(flagName); + } + getFlags() { + return this.flags; + } + // For backwards compatibility. + get features() { + return this.flags; + } + set(flagName, value) { + if (this.flagRegistry[flagName] == null) { + throw new Error(`Cannot set flag ${flagName} as it has not been registered.`); + } + this.flags[flagName] = value; + if (this.flagRegistry[flagName].setHook != null) { + this.flagRegistry[flagName].setHook(value); + } + } + evaluateFlag(flagName) { + if (this.flagRegistry[flagName] == null) { + throw new Error(`Cannot evaluate flag '${flagName}': no evaluation function found.`); + } + return this.flagRegistry[flagName].evaluationFn(); + } + setFlags(flags) { + this.flags = Object.assign({}, flags); + } + reset() { + this.flags = {}; + this.urlFlags = {}; + this.populateURLFlags(); + } + populateURLFlags() { + if (typeof this.global === 'undefined' || + typeof this.global.location === 'undefined' || + typeof this.global.location.search === 'undefined') { + return; + } + const urlParams = this.getQueryParams(this.global.location.search); + if (TENSORFLOWJS_FLAGS_PREFIX in urlParams) { + const keyValues = urlParams[TENSORFLOWJS_FLAGS_PREFIX].split(','); + keyValues.forEach(keyValue => { + const [key, value] = keyValue.split(':'); + this.urlFlags[key] = parseValue(key, value); + }); + } + } + } + function getQueryParams(queryString) { + const params = {}; + queryString.replace(/[?&]([^=?&]+)(?:=([^&]*))?/g, (s, ...t) => { + decodeParam(params, t[0], t[1]); + return t.join('='); + }); + return params; + } + function decodeParam(params, name, value) { + params[decodeURIComponent(name)] = decodeURIComponent(value || ''); + } + function parseValue(flagName, value) { + const lowerCaseValue = value.toLowerCase(); + if (lowerCaseValue === 'true' || lowerCaseValue === 'false') { + return lowerCaseValue === 'true'; + } + else if (`${+lowerCaseValue}` === lowerCaseValue) { + return +lowerCaseValue; + } + else { + return value; + } + } + /** + * Returns the current environment (a global singleton). + * + * The environment object contains the evaluated feature values as well as the + * active platform. + * + * @doc {heading: 'Environment'} + */ + function env() { + return exports.ENV; + } + exports.ENV = null; + function setEnvironmentGlobal(environment) { + exports.ENV = environment; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Note that the identifier globalNameSpace is scoped to this module, but will + // always resolve to the same global object regardless of how the module is + // resolved. + // tslint:disable-next-line:no-any + let globalNameSpace; + // tslint:disable-next-line:no-any + function getGlobalNamespace() { + if (globalNameSpace == null) { + // tslint:disable-next-line:no-any + let ns; + if (typeof (window) !== 'undefined') { + ns = window; + } + else if (typeof (global) !== 'undefined') { + ns = global; + } + else if (typeof (process) !== 'undefined') { + ns = process; + } + else if (typeof (self) !== 'undefined') { + ns = self; + } + else { + throw new Error('Could not find a global object'); + } + globalNameSpace = ns; + } + return globalNameSpace; + } + // tslint:disable-next-line:no-any + function getGlobalMap() { + const ns = getGlobalNamespace(); + if (ns._tfGlobals == null) { + ns._tfGlobals = new Map(); + } + return ns._tfGlobals; + } + /** + * Returns a globally accessible 'singleton' object. + * + * @param key the name of the object + * @param init a function to initialize to initialize this object + * the first time it is fetched. + */ + function getGlobal(key, init) { + const globalMap = getGlobalMap(); + if (globalMap.has(key)) { + return globalMap.get(key); + } + else { + const singleton = init(); + globalMap.set(key, singleton); + return globalMap.get(key); + } + } + + const Abs = 'Abs'; + const Acos = 'Acos'; + const Acosh = 'Acosh'; + const Add$1 = 'Add'; + const AddN = 'AddN'; + const All = 'All'; + const Any = 'Any'; + const ArgMax = 'ArgMax'; + const ArgMin = 'ArgMin'; + const Asin = 'Asin'; + const Asinh = 'Asinh'; + const Atan = 'Atan'; + const Atanh = 'Atanh'; + const Atan2 = 'Atan2'; + const AvgPool = 'AvgPool'; + const AvgPoolGrad = 'AvgPoolGrad'; + const AvgPool3D = 'AvgPool3D'; + const AvgPool3DGrad = 'AvgPool3DGrad'; + const BatchMatMul = 'BatchMatMul'; + const BatchToSpaceND = 'BatchToSpaceND'; + const Bincount = 'Bincount'; + const BitwiseAnd = 'BitwiseAnd'; + const BroadcastTo = 'BroadcastTo'; + const BroadcastArgs = 'BroadcastArgs'; + const Cast = 'Cast'; + const Ceil = 'Ceil'; + const ClipByValue = 'ClipByValue'; + const Complex = 'Complex'; + const ComplexAbs = 'ComplexAbs'; + const Concat = 'Concat'; + const Conv2D$1 = 'Conv2D'; + const Conv2DBackpropFilter = 'Conv2DBackpropFilter'; + const Conv2DBackpropInput = 'Conv2DBackpropInput'; + const Conv3D$1 = 'Conv3D'; + const Conv3DBackpropFilterV2 = 'Conv3DBackpropFilterV2'; + const Conv3DBackpropInputV2 = 'Conv3DBackpropInputV2'; + const Cos = 'Cos'; + const Cosh = 'Cosh'; + const Cumprod = 'Cumprod'; + const Cumsum = 'Cumsum'; + const CropAndResize = 'CropAndResize'; + const DenseBincount = 'DenseBincount'; + const DepthToSpace = 'DepthToSpace'; + const DepthwiseConv2dNative = 'DepthwiseConv2dNative'; + const DepthwiseConv2dNativeBackpropFilter = 'DepthwiseConv2dNativeBackpropFilter'; + const DepthwiseConv2dNativeBackpropInput = 'DepthwiseConv2dNativeBackpropInput'; + const Diag = 'Diag'; + const Dilation2D = 'Dilation2D'; + const Dilation2DBackpropInput = 'Dilation2DBackpropInput'; + const Dilation2DBackpropFilter = 'Dilation2DBackpropFilter'; + const Draw = 'Draw'; + const RealDiv = 'RealDiv'; + const Einsum = 'Einsum'; + const Elu$1 = 'Elu'; + const EluGrad = 'EluGrad'; + const Erf = 'Erf'; + const Equal = 'Equal'; + const Exp = 'Exp'; + const ExpandDims = 'ExpandDims'; + const Expm1 = 'Expm1'; + const FFT = 'FFT'; + const Fill = 'Fill'; + const FlipLeftRight = 'FlipLeftRight'; + const Floor = 'Floor'; + const FloorDiv = 'FloorDiv'; + const FusedBatchNorm = 'FusedBatchNorm'; + const GatherV2 = 'GatherV2'; + const GatherNd = 'GatherNd'; + const Greater = 'Greater'; + const GreaterEqual = 'GreaterEqual'; + const Identity$1 = 'Identity'; + const IFFT = 'IFFT'; + const Imag = 'Imag'; + const IsFinite = 'IsFinite'; + const IsInf = 'IsInf'; + const IsNan = 'IsNan'; + const LeakyRelu = 'LeakyRelu'; + const Less = 'Less'; + const LessEqual = 'LessEqual'; + const LinSpace = 'LinSpace'; + const Log = 'Log'; + const Log1p = 'Log1p'; + const LogicalAnd = 'LogicalAnd'; + const LogicalNot = 'LogicalNot'; + const LogicalOr = 'LogicalOr'; + const LogicalXor = 'LogicalXor'; + const LogSoftmax$1 = 'LogSoftmax'; + const LowerBound = 'LowerBound'; + const LRN = 'LRN'; + const LRNGrad = 'LRNGrad'; + const MatrixBandPart = 'MatrixBandPart'; + const Max = 'Max'; + const Maximum$1 = 'Maximum'; + const MaxPool = 'MaxPool'; + const MaxPoolGrad = 'MaxPoolGrad'; + const MaxPool3D = 'MaxPool3D'; + const MaxPool3DGrad = 'MaxPool3DGrad'; + const MaxPoolWithArgmax = 'MaxPoolWithArgmax'; + const Mean = 'Mean'; + const Min = 'Min'; + const Minimum$1 = 'Minimum'; + const MirrorPad = 'MirrorPad'; + const Mod = 'Mod'; + const Multinomial = 'Multinomial'; + const Multiply$1 = 'Multiply'; + const Neg = 'Neg'; + const NotEqual = 'NotEqual'; + const NonMaxSuppressionV3 = 'NonMaxSuppressionV3'; + const NonMaxSuppressionV4 = 'NonMaxSuppressionV4'; + const NonMaxSuppressionV5 = 'NonMaxSuppressionV5'; + const OnesLike = 'OnesLike'; + const OneHot = 'OneHot'; + const Pack = 'Pack'; + const PadV2 = 'PadV2'; + const Pool = 'Pool'; + const Pow = 'Pow'; + const Prelu = 'Prelu'; + const Prod = 'Prod'; + const RaggedGather = 'RaggedGather'; + const RaggedRange = 'RaggedRange'; + const RaggedTensorToTensor = 'RaggedTensorToTensor'; + const Range = 'Range'; + const Real = 'Real'; + const Reciprocal = 'Reciprocal'; + const Relu$1 = 'Relu'; + const Reshape$1 = 'Reshape'; + const ResizeNearestNeighbor = 'ResizeNearestNeighbor'; + const ResizeNearestNeighborGrad = 'ResizeNearestNeighborGrad'; + const ResizeBilinear = 'ResizeBilinear'; + const ResizeBilinearGrad = 'ResizeBilinearGrad'; + const Relu6$1 = 'Relu6'; + const Reverse = 'Reverse'; + const Round = 'Round'; + const Rsqrt = 'Rsqrt'; + const ScatterNd = 'ScatterNd'; + const TensorScatterUpdate = 'TensorScatterUpdate'; + const SearchSorted = 'SearchSorted'; + const Select = 'Select'; + const Selu$1 = 'Selu'; + const Slice = 'Slice'; + const Sin = 'Sin'; + const Sinh = 'Sinh'; + const Sign = 'Sign'; + const Sigmoid$1 = 'Sigmoid'; + const Softplus$1 = 'Softplus'; + const Sqrt = 'Sqrt'; + const Sum = 'Sum'; + const SpaceToBatchND = 'SpaceToBatchND'; + const SplitV = 'SplitV'; + const Softmax$2 = 'Softmax'; + const SparseFillEmptyRows = 'SparseFillEmptyRows'; + const SparseReshape = 'SparseReshape'; + const SparseSegmentMean = 'SparseSegmentMean'; + const SparseSegmentSum = 'SparseSegmentSum'; + const SparseToDense = 'SparseToDense'; + const SquaredDifference = 'SquaredDifference'; + const Square = 'Square'; + const StaticRegexReplace = 'StaticRegexReplace'; + const StridedSlice = 'StridedSlice'; + const StringNGrams = 'StringNGrams'; + const StringSplit = 'StringSplit'; + const StringToHashBucketFast = 'StringToHashBucketFast'; + const Sub = 'Sub'; + const Tan = 'Tan'; + const Tanh$1 = 'Tanh'; + const Tile = 'Tile'; + const TopK = 'TopK'; + const Transform = 'Transform'; + const Transpose = 'Transpose'; + const Unique = 'Unique'; + const Unpack = 'Unpack'; + const UnsortedSegmentSum = 'UnsortedSegmentSum'; + const UpperBound = 'UpperBound'; + const ZerosLike = 'ZerosLike'; + /** + * TensorFlow.js-only kernels + */ + const Step = 'Step'; + const FromPixels = 'FromPixels'; + const RotateWithOffset = 'RotateWithOffset'; + const _FusedMatMul = '_FusedMatMul'; + const FusedConv2D = 'FusedConv2D'; + const FusedDepthwiseConv2D = 'FusedDepthwiseConv2D'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function warn(...msg) { + if (!(env().getBool('IS_TEST') || env().getBool('PROD'))) { + console.warn(...msg); + } + } + function log$3(...msg) { + if (!(env().getBool('IS_TEST') || env().getBool('PROD'))) { + console.log(...msg); + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const kernelRegistry = getGlobal('kernelRegistry', () => new Map()); + const gradRegistry = getGlobal('gradRegistry', () => new Map()); + /** + * Returns the kernel function (code) associated with the provided names. + * + * @param kernelName The official name of the kernel. + * @param backendName The official name of the backend. + */ + function getKernel(kernelName, backendName) { + const key = makeKey(kernelName, backendName); + return kernelRegistry.get(key); + } + /** + * Returns the registered gradient info associated with the provided kernel. + * @param kernelName The official TF kernel name. + */ + function getGradient(kernelName) { + return gradRegistry.get(kernelName); + } + function getKernelsForBackend(backendName) { + const it = kernelRegistry.entries(); + const result = []; + while (true) { + const { done, value } = it.next(); + if (done) { + break; + } + const [key, config] = value; + const [backend,] = key.split('_'); + if (backend === backendName) { + result.push(config); + } + } + return result; + } + /** + * Registers the function (forward pass) for the kernel in a global registry. + * + * @param config A config object with the following properties: + * - `kernelName` The official name of the kernel. + * - `backendName` The official name of the backend. + * - `kernelFunc` The function to run during the forward pass of the kernel. + * - `setupFunc` Optional. Gets called once, after the backend initializes. + * - `disposeFunc` Optional. Gets called once, right before the backend is + * disposed. + */ + function registerKernel(config) { + const { kernelName, backendName } = config; + const key = makeKey(kernelName, backendName); + if (kernelRegistry.has(key)) { + warn(`The kernel '${kernelName}' for backend ` + + `'${backendName}' is already registered`); + } + kernelRegistry.set(key, config); + } + /** + * Registers a gradient function for a given kernel in the global registry, + * to be used during the back-propagation of that kernel. + * + * @param config An object with the following properties: + * - `kernelName` The name of the kernel that the gradient function is for. + * - `gradFunc` The function to run during back-propagation. + */ + function registerGradient(config) { + const { kernelName } = config; + if (gradRegistry.has(kernelName)) { + // TODO (yassogba) after 3.0 assess whether we need to keep this gated + // to debug mode. + if (env().getBool('DEBUG')) { + warn(`Overriding the gradient for '${kernelName}'`); + } + } + gradRegistry.set(kernelName, config); + } + /** + * Removes the kernel function from the registry. + * + * @param kernelName The official name of the kernel. + * @param backendName The official name of the backend. + * + */ + function unregisterKernel(kernelName, backendName) { + const key = makeKey(kernelName, backendName); + if (!kernelRegistry.has(key)) { + throw new Error(`The kernel '${kernelName}' for backend ` + + `'${backendName}' is not registered`); + } + kernelRegistry.delete(key); + } + /** Removes the registered gradient from the global registry. */ + function unregisterGradient(kernelName) { + if (!gradRegistry.has(kernelName)) { + throw new Error(`The gradient '${kernelName}' for backend is not registered`); + } + gradRegistry.delete(kernelName); + } + /** + * Finds kernels that have already been registered to a backend and re-registers + * them for a new backend. Useful for registering custom backends. + * @param registeredBackendName Already registered backend. + * @param newBackendName New backend. + */ + function copyRegisteredKernels(registeredBackendName, newBackendName) { + const kernels = getKernelsForBackend(registeredBackendName); + kernels.forEach(kernelConfig => { + const newKernelConfig = Object.assign({}, kernelConfig, { backendName: newBackendName }); + registerKernel(newKernelConfig); + }); + } + function makeKey(kernelName, backendName) { + return `${backendName}_${kernelName}`; + } + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function isTypedArrayBrowser(a) { + return a instanceof Float32Array || a instanceof Int32Array || + a instanceof Uint8Array || a instanceof Uint8ClampedArray; + } + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function getDefaultExportFromNamespaceIfPresent (n) { + return n && Object.prototype.hasOwnProperty.call(n, 'default') ? n['default'] : n; + } + + function getDefaultExportFromNamespaceIfNotNamed (n) { + return n && Object.prototype.hasOwnProperty.call(n, 'default') && Object.keys(n).length === 1 ? n['default'] : n; + } + + function getAugmentedNamespace(n) { + if (n.__esModule) return n; + var f = n.default; + if (typeof f == "function") { + var a = function a () { + if (this instanceof a) { + var args = [null]; + args.push.apply(args, arguments); + var Ctor = Function.bind.apply(f, args); + return new Ctor(); + } + return f.apply(this, arguments); + }; + a.prototype = f.prototype; + } else a = {}; + Object.defineProperty(a, '__esModule', {value: true}); + Object.keys(n).forEach(function (k) { + var d = Object.getOwnPropertyDescriptor(n, k); + Object.defineProperty(a, k, d.get ? d : { + enumerable: true, + get: function () { + return n[k]; + } + }); + }); + return a; + } + + var long = Long$1; + + /** + * wasm optimizations, to do native i64 multiplication and divide + */ + var wasm = null; + + try { + wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([ + 0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11 + ])), {}).exports; + } catch (e) { + // no wasm support :( + } + + /** + * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers. + * See the from* functions below for more convenient ways of constructing Longs. + * @exports Long + * @class A Long class for representing a 64 bit two's-complement integer value. + * @param {number} low The low (signed) 32 bits of the long + * @param {number} high The high (signed) 32 bits of the long + * @param {boolean=} unsigned Whether unsigned or not, defaults to signed + * @constructor + */ + function Long$1(low, high, unsigned) { + + /** + * The low 32 bits as a signed value. + * @type {number} + */ + this.low = low | 0; + + /** + * The high 32 bits as a signed value. + * @type {number} + */ + this.high = high | 0; + + /** + * Whether unsigned or not. + * @type {boolean} + */ + this.unsigned = !!unsigned; + } + + // The internal representation of a long is the two given signed, 32-bit values. + // We use 32-bit pieces because these are the size of integers on which + // Javascript performs bit-operations. For operations like addition and + // multiplication, we split each number into 16 bit pieces, which can easily be + // multiplied within Javascript's floating-point representation without overflow + // or change in sign. + // + // In the algorithms below, we frequently reduce the negative case to the + // positive case by negating the input(s) and then post-processing the result. + // Note that we must ALWAYS check specially whether those values are MIN_VALUE + // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as + // a positive number, it overflows back into a negative). Not handling this + // case would often result in infinite recursion. + // + // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from* + // methods on which they depend. + + /** + * An indicator used to reliably determine if an object is a Long or not. + * @type {boolean} + * @const + * @private + */ + Long$1.prototype.__isLong__; + + Object.defineProperty(Long$1.prototype, "__isLong__", { value: true }); + + /** + * @function + * @param {*} obj Object + * @returns {boolean} + * @inner + */ + function isLong(obj) { + return (obj && obj["__isLong__"]) === true; + } + + /** + * Tests if the specified object is a Long. + * @function + * @param {*} obj Object + * @returns {boolean} + */ + Long$1.isLong = isLong; + + /** + * A cache of the Long representations of small integer values. + * @type {!Object} + * @inner + */ + var INT_CACHE = {}; + + /** + * A cache of the Long representations of small unsigned integer values. + * @type {!Object} + * @inner + */ + var UINT_CACHE = {}; + + /** + * @param {number} value + * @param {boolean=} unsigned + * @returns {!Long} + * @inner + */ + function fromInt(value, unsigned) { + var obj, cachedObj, cache; + if (unsigned) { + value >>>= 0; + if (cache = (0 <= value && value < 256)) { + cachedObj = UINT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true); + if (cache) + UINT_CACHE[value] = obj; + return obj; + } else { + value |= 0; + if (cache = (-128 <= value && value < 128)) { + cachedObj = INT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = fromBits(value, value < 0 ? -1 : 0, false); + if (cache) + INT_CACHE[value] = obj; + return obj; + } + } + + /** + * Returns a Long representing the given 32 bit integer value. + * @function + * @param {number} value The 32 bit integer in question + * @param {boolean=} unsigned Whether unsigned or not, defaults to signed + * @returns {!Long} The corresponding Long value + */ + Long$1.fromInt = fromInt; + + /** + * @param {number} value + * @param {boolean=} unsigned + * @returns {!Long} + * @inner + */ + function fromNumber(value, unsigned) { + if (isNaN(value)) + return unsigned ? UZERO : ZERO; + if (unsigned) { + if (value < 0) + return UZERO; + if (value >= TWO_PWR_64_DBL) + return MAX_UNSIGNED_VALUE; + } else { + if (value <= -TWO_PWR_63_DBL) + return MIN_VALUE; + if (value + 1 >= TWO_PWR_63_DBL) + return MAX_VALUE; + } + if (value < 0) + return fromNumber(-value, unsigned).neg(); + return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned); + } + + /** + * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. + * @function + * @param {number} value The number in question + * @param {boolean=} unsigned Whether unsigned or not, defaults to signed + * @returns {!Long} The corresponding Long value + */ + Long$1.fromNumber = fromNumber; + + /** + * @param {number} lowBits + * @param {number} highBits + * @param {boolean=} unsigned + * @returns {!Long} + * @inner + */ + function fromBits(lowBits, highBits, unsigned) { + return new Long$1(lowBits, highBits, unsigned); + } + + /** + * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is + * assumed to use 32 bits. + * @function + * @param {number} lowBits The low 32 bits + * @param {number} highBits The high 32 bits + * @param {boolean=} unsigned Whether unsigned or not, defaults to signed + * @returns {!Long} The corresponding Long value + */ + Long$1.fromBits = fromBits; + + /** + * @function + * @param {number} base + * @param {number} exponent + * @returns {number} + * @inner + */ + var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4) + + /** + * @param {string} str + * @param {(boolean|number)=} unsigned + * @param {number=} radix + * @returns {!Long} + * @inner + */ + function fromString(str, unsigned, radix) { + if (str.length === 0) + throw Error('empty string'); + if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") + return ZERO; + if (typeof unsigned === 'number') { + // For goog.math.long compatibility + radix = unsigned, + unsigned = false; + } else { + unsigned = !! unsigned; + } + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw RangeError('radix'); + + var p; + if ((p = str.indexOf('-')) > 0) + throw Error('interior hyphen'); + else if (p === 0) { + return fromString(str.substring(1), unsigned, radix).neg(); + } + + // Do several (8) digits each time through the loop, so as to + // minimize the calls to the very expensive emulated div. + var radixToPower = fromNumber(pow_dbl(radix, 8)); + + var result = ZERO; + for (var i = 0; i < str.length; i += 8) { + var size = Math.min(8, str.length - i), + value = parseInt(str.substring(i, i + size), radix); + if (size < 8) { + var power = fromNumber(pow_dbl(radix, size)); + result = result.mul(power).add(fromNumber(value)); + } else { + result = result.mul(radixToPower); + result = result.add(fromNumber(value)); + } + } + result.unsigned = unsigned; + return result; + } + + /** + * Returns a Long representation of the given string, written using the specified radix. + * @function + * @param {string} str The textual representation of the Long + * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to signed + * @param {number=} radix The radix in which the text is written (2-36), defaults to 10 + * @returns {!Long} The corresponding Long value + */ + Long$1.fromString = fromString; + + /** + * @function + * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val + * @param {boolean=} unsigned + * @returns {!Long} + * @inner + */ + function fromValue(val, unsigned) { + if (typeof val === 'number') + return fromNumber(val, unsigned); + if (typeof val === 'string') + return fromString(val, unsigned); + // Throws for non-objects, converts non-instanceof Long: + return fromBits(val.low, val.high, typeof unsigned === 'boolean' ? unsigned : val.unsigned); + } + + /** + * Converts the specified value to a Long using the appropriate from* function for its type. + * @function + * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value + * @param {boolean=} unsigned Whether unsigned or not, defaults to signed + * @returns {!Long} + */ + Long$1.fromValue = fromValue; + + // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be + // no runtime penalty for these. + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_16_DBL = 1 << 16; + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_24_DBL = 1 << 24; + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; + + /** + * @type {!Long} + * @const + * @inner + */ + var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL); + + /** + * @type {!Long} + * @inner + */ + var ZERO = fromInt(0); + + /** + * Signed zero. + * @type {!Long} + */ + Long$1.ZERO = ZERO; + + /** + * @type {!Long} + * @inner + */ + var UZERO = fromInt(0, true); + + /** + * Unsigned zero. + * @type {!Long} + */ + Long$1.UZERO = UZERO; + + /** + * @type {!Long} + * @inner + */ + var ONE = fromInt(1); + + /** + * Signed one. + * @type {!Long} + */ + Long$1.ONE = ONE; + + /** + * @type {!Long} + * @inner + */ + var UONE = fromInt(1, true); + + /** + * Unsigned one. + * @type {!Long} + */ + Long$1.UONE = UONE; + + /** + * @type {!Long} + * @inner + */ + var NEG_ONE = fromInt(-1); + + /** + * Signed negative one. + * @type {!Long} + */ + Long$1.NEG_ONE = NEG_ONE; + + /** + * @type {!Long} + * @inner + */ + var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false); + + /** + * Maximum signed value. + * @type {!Long} + */ + Long$1.MAX_VALUE = MAX_VALUE; + + /** + * @type {!Long} + * @inner + */ + var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true); + + /** + * Maximum unsigned value. + * @type {!Long} + */ + Long$1.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE; + + /** + * @type {!Long} + * @inner + */ + var MIN_VALUE = fromBits(0, 0x80000000|0, false); + + /** + * Minimum signed value. + * @type {!Long} + */ + Long$1.MIN_VALUE = MIN_VALUE; + + /** + * @alias Long.prototype + * @inner + */ + var LongPrototype = Long$1.prototype; + + /** + * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer. + * @returns {number} + */ + LongPrototype.toInt = function toInt() { + return this.unsigned ? this.low >>> 0 : this.low; + }; + + /** + * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa). + * @returns {number} + */ + LongPrototype.toNumber = function toNumber() { + if (this.unsigned) + return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0); + return this.high * TWO_PWR_32_DBL + (this.low >>> 0); + }; + + /** + * Converts the Long to a string written in the specified radix. + * @param {number=} radix Radix (2-36), defaults to 10 + * @returns {string} + * @override + * @throws {RangeError} If `radix` is out of range + */ + LongPrototype.toString = function toString(radix) { + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw RangeError('radix'); + if (this.isZero()) + return '0'; + if (this.isNegative()) { // Unsigned Longs are never negative + if (this.eq(MIN_VALUE)) { + // We need to change the Long value before it can be negated, so we remove + // the bottom-most digit in this base and then recurse to do the rest. + var radixLong = fromNumber(radix), + div = this.div(radixLong), + rem1 = div.mul(radixLong).sub(this); + return div.toString(radix) + rem1.toInt().toString(radix); + } else + return '-' + this.neg().toString(radix); + } + + // Do several (6) digits each time through the loop, so as to + // minimize the calls to the very expensive emulated div. + var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned), + rem = this; + var result = ''; + while (true) { + var remDiv = rem.div(radixToPower), + intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0, + digits = intval.toString(radix); + rem = remDiv; + if (rem.isZero()) + return digits + result; + else { + while (digits.length < 6) + digits = '0' + digits; + result = '' + digits + result; + } + } + }; + + /** + * Gets the high 32 bits as a signed integer. + * @returns {number} Signed high bits + */ + LongPrototype.getHighBits = function getHighBits() { + return this.high; + }; + + /** + * Gets the high 32 bits as an unsigned integer. + * @returns {number} Unsigned high bits + */ + LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() { + return this.high >>> 0; + }; + + /** + * Gets the low 32 bits as a signed integer. + * @returns {number} Signed low bits + */ + LongPrototype.getLowBits = function getLowBits() { + return this.low; + }; + + /** + * Gets the low 32 bits as an unsigned integer. + * @returns {number} Unsigned low bits + */ + LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() { + return this.low >>> 0; + }; + + /** + * Gets the number of bits needed to represent the absolute value of this Long. + * @returns {number} + */ + LongPrototype.getNumBitsAbs = function getNumBitsAbs() { + if (this.isNegative()) // Unsigned Longs are never negative + return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs(); + var val = this.high != 0 ? this.high : this.low; + for (var bit = 31; bit > 0; bit--) + if ((val & (1 << bit)) != 0) + break; + return this.high != 0 ? bit + 33 : bit + 1; + }; + + /** + * Tests if this Long's value equals zero. + * @returns {boolean} + */ + LongPrototype.isZero = function isZero() { + return this.high === 0 && this.low === 0; + }; + + /** + * Tests if this Long's value equals zero. This is an alias of {@link Long#isZero}. + * @returns {boolean} + */ + LongPrototype.eqz = LongPrototype.isZero; + + /** + * Tests if this Long's value is negative. + * @returns {boolean} + */ + LongPrototype.isNegative = function isNegative() { + return !this.unsigned && this.high < 0; + }; + + /** + * Tests if this Long's value is positive. + * @returns {boolean} + */ + LongPrototype.isPositive = function isPositive() { + return this.unsigned || this.high >= 0; + }; + + /** + * Tests if this Long's value is odd. + * @returns {boolean} + */ + LongPrototype.isOdd = function isOdd() { + return (this.low & 1) === 1; + }; + + /** + * Tests if this Long's value is even. + * @returns {boolean} + */ + LongPrototype.isEven = function isEven() { + return (this.low & 1) === 0; + }; + + /** + * Tests if this Long's value equals the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.equals = function equals(other) { + if (!isLong(other)) + other = fromValue(other); + if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1) + return false; + return this.high === other.high && this.low === other.low; + }; + + /** + * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.eq = LongPrototype.equals; + + /** + * Tests if this Long's value differs from the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.notEquals = function notEquals(other) { + return !this.eq(/* validates */ other); + }; + + /** + * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.neq = LongPrototype.notEquals; + + /** + * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.ne = LongPrototype.notEquals; + + /** + * Tests if this Long's value is less than the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.lessThan = function lessThan(other) { + return this.comp(/* validates */ other) < 0; + }; + + /** + * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.lt = LongPrototype.lessThan; + + /** + * Tests if this Long's value is less than or equal the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) { + return this.comp(/* validates */ other) <= 0; + }; + + /** + * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.lte = LongPrototype.lessThanOrEqual; + + /** + * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.le = LongPrototype.lessThanOrEqual; + + /** + * Tests if this Long's value is greater than the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.greaterThan = function greaterThan(other) { + return this.comp(/* validates */ other) > 0; + }; + + /** + * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.gt = LongPrototype.greaterThan; + + /** + * Tests if this Long's value is greater than or equal the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) { + return this.comp(/* validates */ other) >= 0; + }; + + /** + * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.gte = LongPrototype.greaterThanOrEqual; + + /** + * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.ge = LongPrototype.greaterThanOrEqual; + + /** + * Compares this Long's value with the specified's. + * @param {!Long|number|string} other Other value + * @returns {number} 0 if they are the same, 1 if the this is greater and -1 + * if the given one is greater + */ + LongPrototype.compare = function compare(other) { + if (!isLong(other)) + other = fromValue(other); + if (this.eq(other)) + return 0; + var thisNeg = this.isNegative(), + otherNeg = other.isNegative(); + if (thisNeg && !otherNeg) + return -1; + if (!thisNeg && otherNeg) + return 1; + // At this point the sign bits are the same + if (!this.unsigned) + return this.sub(other).isNegative() ? -1 : 1; + // Both are positive if at least one is unsigned + return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1; + }; + + /** + * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}. + * @function + * @param {!Long|number|string} other Other value + * @returns {number} 0 if they are the same, 1 if the this is greater and -1 + * if the given one is greater + */ + LongPrototype.comp = LongPrototype.compare; + + /** + * Negates this Long's value. + * @returns {!Long} Negated Long + */ + LongPrototype.negate = function negate() { + if (!this.unsigned && this.eq(MIN_VALUE)) + return MIN_VALUE; + return this.not().add(ONE); + }; + + /** + * Negates this Long's value. This is an alias of {@link Long#negate}. + * @function + * @returns {!Long} Negated Long + */ + LongPrototype.neg = LongPrototype.negate; + + /** + * Returns the sum of this and the specified Long. + * @param {!Long|number|string} addend Addend + * @returns {!Long} Sum + */ + LongPrototype.add = function add(addend) { + if (!isLong(addend)) + addend = fromValue(addend); + + // Divide each number into 4 chunks of 16 bits, and then sum the chunks. + + var a48 = this.high >>> 16; + var a32 = this.high & 0xFFFF; + var a16 = this.low >>> 16; + var a00 = this.low & 0xFFFF; + + var b48 = addend.high >>> 16; + var b32 = addend.high & 0xFFFF; + var b16 = addend.low >>> 16; + var b00 = addend.low & 0xFFFF; + + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 + b00; + c16 += c00 >>> 16; + c00 &= 0xFFFF; + c16 += a16 + b16; + c32 += c16 >>> 16; + c16 &= 0xFFFF; + c32 += a32 + b32; + c48 += c32 >>> 16; + c32 &= 0xFFFF; + c48 += a48 + b48; + c48 &= 0xFFFF; + return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned); + }; + + /** + * Returns the difference of this and the specified Long. + * @param {!Long|number|string} subtrahend Subtrahend + * @returns {!Long} Difference + */ + LongPrototype.subtract = function subtract(subtrahend) { + if (!isLong(subtrahend)) + subtrahend = fromValue(subtrahend); + return this.add(subtrahend.neg()); + }; + + /** + * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}. + * @function + * @param {!Long|number|string} subtrahend Subtrahend + * @returns {!Long} Difference + */ + LongPrototype.sub = LongPrototype.subtract; + + /** + * Returns the product of this and the specified Long. + * @param {!Long|number|string} multiplier Multiplier + * @returns {!Long} Product + */ + LongPrototype.multiply = function multiply(multiplier) { + if (this.isZero()) + return ZERO; + if (!isLong(multiplier)) + multiplier = fromValue(multiplier); + + // use wasm support if present + if (wasm) { + var low = wasm.mul(this.low, + this.high, + multiplier.low, + multiplier.high); + return fromBits(low, wasm.get_high(), this.unsigned); + } + + if (multiplier.isZero()) + return ZERO; + if (this.eq(MIN_VALUE)) + return multiplier.isOdd() ? MIN_VALUE : ZERO; + if (multiplier.eq(MIN_VALUE)) + return this.isOdd() ? MIN_VALUE : ZERO; + + if (this.isNegative()) { + if (multiplier.isNegative()) + return this.neg().mul(multiplier.neg()); + else + return this.neg().mul(multiplier).neg(); + } else if (multiplier.isNegative()) + return this.mul(multiplier.neg()).neg(); + + // If both longs are small, use float multiplication + if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24)) + return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned); + + // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products. + // We can skip products that would overflow. + + var a48 = this.high >>> 16; + var a32 = this.high & 0xFFFF; + var a16 = this.low >>> 16; + var a00 = this.low & 0xFFFF; + + var b48 = multiplier.high >>> 16; + var b32 = multiplier.high & 0xFFFF; + var b16 = multiplier.low >>> 16; + var b00 = multiplier.low & 0xFFFF; + + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 * b00; + c16 += c00 >>> 16; + c00 &= 0xFFFF; + c16 += a16 * b00; + c32 += c16 >>> 16; + c16 &= 0xFFFF; + c16 += a00 * b16; + c32 += c16 >>> 16; + c16 &= 0xFFFF; + c32 += a32 * b00; + c48 += c32 >>> 16; + c32 &= 0xFFFF; + c32 += a16 * b16; + c48 += c32 >>> 16; + c32 &= 0xFFFF; + c32 += a00 * b32; + c48 += c32 >>> 16; + c32 &= 0xFFFF; + c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; + c48 &= 0xFFFF; + return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned); + }; + + /** + * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}. + * @function + * @param {!Long|number|string} multiplier Multiplier + * @returns {!Long} Product + */ + LongPrototype.mul = LongPrototype.multiply; + + /** + * Returns this Long divided by the specified. The result is signed if this Long is signed or + * unsigned if this Long is unsigned. + * @param {!Long|number|string} divisor Divisor + * @returns {!Long} Quotient + */ + LongPrototype.divide = function divide(divisor) { + if (!isLong(divisor)) + divisor = fromValue(divisor); + if (divisor.isZero()) + throw Error('division by zero'); + + // use wasm support if present + if (wasm) { + // guard against signed division overflow: the largest + // negative number / -1 would be 1 larger than the largest + // positive number, due to two's complement. + if (!this.unsigned && + this.high === -0x80000000 && + divisor.low === -1 && divisor.high === -1) { + // be consistent with non-wasm code path + return this; + } + var low = (this.unsigned ? wasm.div_u : wasm.div_s)( + this.low, + this.high, + divisor.low, + divisor.high + ); + return fromBits(low, wasm.get_high(), this.unsigned); + } + + if (this.isZero()) + return this.unsigned ? UZERO : ZERO; + var approx, rem, res; + if (!this.unsigned) { + // This section is only relevant for signed longs and is derived from the + // closure library as a whole. + if (this.eq(MIN_VALUE)) { + if (divisor.eq(ONE) || divisor.eq(NEG_ONE)) + return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE + else if (divisor.eq(MIN_VALUE)) + return ONE; + else { + // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. + var halfThis = this.shr(1); + approx = halfThis.div(divisor).shl(1); + if (approx.eq(ZERO)) { + return divisor.isNegative() ? ONE : NEG_ONE; + } else { + rem = this.sub(divisor.mul(approx)); + res = approx.add(rem.div(divisor)); + return res; + } + } + } else if (divisor.eq(MIN_VALUE)) + return this.unsigned ? UZERO : ZERO; + if (this.isNegative()) { + if (divisor.isNegative()) + return this.neg().div(divisor.neg()); + return this.neg().div(divisor).neg(); + } else if (divisor.isNegative()) + return this.div(divisor.neg()).neg(); + res = ZERO; + } else { + // The algorithm below has not been made for unsigned longs. It's therefore + // required to take special care of the MSB prior to running it. + if (!divisor.unsigned) + divisor = divisor.toUnsigned(); + if (divisor.gt(this)) + return UZERO; + if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true + return UONE; + res = UZERO; + } + + // Repeat the following until the remainder is less than other: find a + // floating-point that approximates remainder / other *from below*, add this + // into the result, and subtract it from the remainder. It is critical that + // the approximate value is less than or equal to the real value so that the + // remainder never becomes negative. + rem = this; + while (rem.gte(divisor)) { + // Approximate the result of division. This may be a little greater or + // smaller than the actual value. + approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber())); + + // We will tweak the approximate result by changing it in the 48-th digit or + // the smallest non-fractional digit, whichever is larger. + var log2 = Math.ceil(Math.log(approx) / Math.LN2), + delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48), + + // Decrease the approximation until it is smaller than the remainder. Note + // that if it is too large, the product overflows and is negative. + approxRes = fromNumber(approx), + approxRem = approxRes.mul(divisor); + while (approxRem.isNegative() || approxRem.gt(rem)) { + approx -= delta; + approxRes = fromNumber(approx, this.unsigned); + approxRem = approxRes.mul(divisor); + } + + // We know the answer can't be zero... and actually, zero would cause + // infinite recursion since we would make no progress. + if (approxRes.isZero()) + approxRes = ONE; + + res = res.add(approxRes); + rem = rem.sub(approxRem); + } + return res; + }; + + /** + * Returns this Long divided by the specified. This is an alias of {@link Long#divide}. + * @function + * @param {!Long|number|string} divisor Divisor + * @returns {!Long} Quotient + */ + LongPrototype.div = LongPrototype.divide; + + /** + * Returns this Long modulo the specified. + * @param {!Long|number|string} divisor Divisor + * @returns {!Long} Remainder + */ + LongPrototype.modulo = function modulo(divisor) { + if (!isLong(divisor)) + divisor = fromValue(divisor); + + // use wasm support if present + if (wasm) { + var low = (this.unsigned ? wasm.rem_u : wasm.rem_s)( + this.low, + this.high, + divisor.low, + divisor.high + ); + return fromBits(low, wasm.get_high(), this.unsigned); + } + + return this.sub(this.div(divisor).mul(divisor)); + }; + + /** + * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}. + * @function + * @param {!Long|number|string} divisor Divisor + * @returns {!Long} Remainder + */ + LongPrototype.mod = LongPrototype.modulo; + + /** + * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}. + * @function + * @param {!Long|number|string} divisor Divisor + * @returns {!Long} Remainder + */ + LongPrototype.rem = LongPrototype.modulo; + + /** + * Returns the bitwise NOT of this Long. + * @returns {!Long} + */ + LongPrototype.not = function not() { + return fromBits(~this.low, ~this.high, this.unsigned); + }; + + /** + * Returns the bitwise AND of this Long and the specified. + * @param {!Long|number|string} other Other Long + * @returns {!Long} + */ + LongPrototype.and = function and(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low & other.low, this.high & other.high, this.unsigned); + }; + + /** + * Returns the bitwise OR of this Long and the specified. + * @param {!Long|number|string} other Other Long + * @returns {!Long} + */ + LongPrototype.or = function or(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low | other.low, this.high | other.high, this.unsigned); + }; + + /** + * Returns the bitwise XOR of this Long and the given one. + * @param {!Long|number|string} other Other Long + * @returns {!Long} + */ + LongPrototype.xor = function xor(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned); + }; + + /** + * Returns this Long with bits shifted to the left by the given amount. + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shiftLeft = function shiftLeft(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned); + else + return fromBits(0, this.low << (numBits - 32), this.unsigned); + }; + + /** + * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}. + * @function + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shl = LongPrototype.shiftLeft; + + /** + * Returns this Long with bits arithmetically shifted to the right by the given amount. + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shiftRight = function shiftRight(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned); + else + return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned); + }; + + /** + * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}. + * @function + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shr = LongPrototype.shiftRight; + + /** + * Returns this Long with bits logically shifted to the right by the given amount. + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + numBits &= 63; + if (numBits === 0) + return this; + else { + var high = this.high; + if (numBits < 32) { + var low = this.low; + return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned); + } else if (numBits === 32) + return fromBits(high, 0, this.unsigned); + else + return fromBits(high >>> (numBits - 32), 0, this.unsigned); + } + }; + + /** + * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}. + * @function + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shru = LongPrototype.shiftRightUnsigned; + + /** + * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}. + * @function + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shr_u = LongPrototype.shiftRightUnsigned; + + /** + * Converts this Long to signed. + * @returns {!Long} Signed long + */ + LongPrototype.toSigned = function toSigned() { + if (!this.unsigned) + return this; + return fromBits(this.low, this.high, false); + }; + + /** + * Converts this Long to unsigned. + * @returns {!Long} Unsigned long + */ + LongPrototype.toUnsigned = function toUnsigned() { + if (this.unsigned) + return this; + return fromBits(this.low, this.high, true); + }; + + /** + * Converts this Long to its byte representation. + * @param {boolean=} le Whether little or big endian, defaults to big endian + * @returns {!Array.} Byte representation + */ + LongPrototype.toBytes = function toBytes(le) { + return le ? this.toBytesLE() : this.toBytesBE(); + }; + + /** + * Converts this Long to its little endian byte representation. + * @returns {!Array.} Little endian byte representation + */ + LongPrototype.toBytesLE = function toBytesLE() { + var hi = this.high, + lo = this.low; + return [ + lo & 0xff, + lo >>> 8 & 0xff, + lo >>> 16 & 0xff, + lo >>> 24 , + hi & 0xff, + hi >>> 8 & 0xff, + hi >>> 16 & 0xff, + hi >>> 24 + ]; + }; + + /** + * Converts this Long to its big endian byte representation. + * @returns {!Array.} Big endian byte representation + */ + LongPrototype.toBytesBE = function toBytesBE() { + var hi = this.high, + lo = this.low; + return [ + hi >>> 24 , + hi >>> 16 & 0xff, + hi >>> 8 & 0xff, + hi & 0xff, + lo >>> 24 , + lo >>> 16 & 0xff, + lo >>> 8 & 0xff, + lo & 0xff + ]; + }; + + /** + * Creates a Long from its byte representation. + * @param {!Array.} bytes Byte representation + * @param {boolean=} unsigned Whether unsigned or not, defaults to signed + * @param {boolean=} le Whether little or big endian, defaults to big endian + * @returns {Long} The corresponding Long value + */ + Long$1.fromBytes = function fromBytes(bytes, unsigned, le) { + return le ? Long$1.fromBytesLE(bytes, unsigned) : Long$1.fromBytesBE(bytes, unsigned); + }; + + /** + * Creates a Long from its little endian byte representation. + * @param {!Array.} bytes Little endian byte representation + * @param {boolean=} unsigned Whether unsigned or not, defaults to signed + * @returns {Long} The corresponding Long value + */ + Long$1.fromBytesLE = function fromBytesLE(bytes, unsigned) { + return new Long$1( + bytes[0] | + bytes[1] << 8 | + bytes[2] << 16 | + bytes[3] << 24, + bytes[4] | + bytes[5] << 8 | + bytes[6] << 16 | + bytes[7] << 24, + unsigned + ); + }; + + /** + * Creates a Long from its big endian byte representation. + * @param {!Array.} bytes Big endian byte representation + * @param {boolean=} unsigned Whether unsigned or not, defaults to signed + * @returns {Long} The corresponding Long value + */ + Long$1.fromBytesBE = function fromBytesBE(bytes, unsigned) { + return new Long$1( + bytes[4] << 24 | + bytes[5] << 16 | + bytes[6] << 8 | + bytes[7], + bytes[0] << 24 | + bytes[1] << 16 | + bytes[2] << 8 | + bytes[3], + unsigned + ); + }; + + var long$1 = /*@__PURE__*/getDefaultExportFromCjs(long); + + var LongExports = /*#__PURE__*/_mergeNamespaces({ + __proto__: null, + default: long$1 + }, [long]); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // tslint:disable-next-line + const Long = + // tslint:disable-next-line + long$1 || LongExports; + function hexToLong(hex) { + return Long.fromString(hex, true, 16); + } + // Some primes between 2^63 and 2^64 for various uses. + // Hex 0xc3a5c85c97cb3127 + const k0 = hexToLong('c3a5c85c97cb3127'); + // Hex 0xb492b66fbe98f273 + const k1 = hexToLong('b492b66fbe98f273'); + // Hex 0x9ae16a3b2f90404f + const k2 = hexToLong('9ae16a3b2f90404f'); + function shiftMix(val) { + return val.xor(val.shru(47)); + } + function fetch$2(s, offset, numBytes) { + const bytes = s.slice(offset, offset + numBytes); + return Long.fromBytes(Array.from(bytes), true, true); + } + function fetch64(s, offset) { + return fetch$2(s, offset, 8); + } + function fetch32(s, offset) { + return fetch$2(s, offset, 4); + } + function rotate64(val, shift) { + // Avoid shifting by 64: doing so yields an undefined result. + return shift === 0 ? val : val.shru(shift).or(val.shl(64 - shift)); + } + function hashLen16(u, v, mul = hexToLong('9ddfea08eb382d69')) { + // Murmur-inspired hashing. + let a = u.xor(v).mul(mul); + a = a.xor(a.shru(47)); + let b = v.xor(a).mul(mul); + b = b.xor(b.shru(47)); + b = b.mul(mul); + return b; + } + // Return a 16-byte hash for 48 bytes. Quick and dirty. + // Callers do best to use "random-looking" values for a and b. + function weakHashLen32WithSeeds(w, x, y, z, a, b) { + a = a.add(w); + b = rotate64(b.add(a).add(z), 21); + const c = a; + a = a.add(x); + a = a.add(y); + b = b.add(rotate64(a, 44)); + return [a.add(z), b.add(c)]; + } + function weakHashLen32WithSeedsStr(s, offset, a, b) { + return weakHashLen32WithSeeds(fetch64(s, offset), fetch64(s, offset + 8), fetch64(s, offset + 16), fetch64(s, offset + 24), a, b); + } + function hashLen0to16(s, len = s.length) { + if (len >= 8) { + const mul = k2.add(len * 2); + const a = fetch64(s, 0).add(k2); + const b = fetch64(s, len - 8); + const c = rotate64(b, 37).mul(mul).add(a); + const d = rotate64(a, 25).add(b).mul(mul); + return hashLen16(c, d, mul); + } + if (len >= 4) { + const mul = k2.add(len * 2); + const a = fetch32(s, 0); + return hashLen16(a.shl(3).add(len), fetch32(s, len - 4), mul); + } + if (len > 0) { + const a = s[0]; + const b = s[len >> 1]; + const c = s[len - 1]; + const y = a + (b << 8); + const z = len + (c << 2); + return shiftMix(k2.mul(y).xor(k0.mul(z))).mul(k2); + } + return k2; + } + function hashLen17to32(s, len = s.length) { + const mul = k2.add(len * 2); + const a = fetch64(s, 0).mul(k1); + const b = fetch64(s, 8); + const c = fetch64(s, len - 8).mul(mul); + const d = fetch64(s, len - 16).mul(k2); + return hashLen16(rotate64(a.add(b), 43).add(rotate64(c, 30)).add(d), a.add(rotate64(b.add(k2), 18)).add(c), mul); + } + function hashLen33to64(s, len = s.length) { + const mul = k2.add(len * 2); + const a = fetch64(s, 0).mul(k2); + const b = fetch64(s, 8); + const c = fetch64(s, len - 8).mul(mul); + const d = fetch64(s, len - 16).mul(k2); + const y = rotate64(a.add(b), 43).add(rotate64(c, 30)).add(d); + const z = hashLen16(y, a.add(rotate64(b.add(k2), 18)).add(c), mul); + const e = fetch64(s, 16).mul(mul); + const f = fetch64(s, 24); + const g = y.add(fetch64(s, len - 32)).mul(mul); + const h = z.add(fetch64(s, len - 24)).mul(mul); + return hashLen16(rotate64(e.add(f), 43).add(rotate64(g, 30)).add(h), e.add(rotate64(f.add(a), 18)).add(g), mul); + } + function fingerPrint64(s, len = s.length) { + const seed = Long.fromNumber(81, true); + if (len <= 32) { + if (len <= 16) { + return hashLen0to16(s, len); + } + else { + return hashLen17to32(s, len); + } + } + else if (len <= 64) { + return hashLen33to64(s, len); + } + // For strings over 64 bytes we loop. Internal state consists of + // 56 bytes: v, w, x, y, and z. + let x = seed; + let y = seed.mul(k1).add(113); + let z = shiftMix(y.mul(k2).add(113)).mul(k2); + let v = [Long.UZERO, Long.UZERO]; + let w = [Long.UZERO, Long.UZERO]; + x = x.mul(k2).add(fetch64(s, 0)); + let offset = 0; + // Set end so that after the loop we have 1 to 64 bytes left to process. + const end = ((len - 1) >> 6) * 64; + const last64 = end + ((len - 1) & 63) - 63; + do { + x = rotate64(x.add(y).add(v[0]).add(fetch64(s, offset + 8)), 37).mul(k1); + y = rotate64(y.add(v[1]).add(fetch64(s, offset + 48)), 42).mul(k1); + x = x.xor(w[1]); + y = y.add(v[0]).add(fetch64(s, offset + 40)); + z = rotate64(z.add(w[0]), 33).mul(k1); + v = weakHashLen32WithSeedsStr(s, offset, v[1].mul(k1), x.add(w[0])); + w = weakHashLen32WithSeedsStr(s, offset + 32, z.add(w[1]), y.add(fetch64(s, offset + 16))); + [z, x] = [x, z]; + offset += 64; + } while (offset !== end); + const mul = k1.add(z.and(0xff).shl(1)); + // Point to the last 64 bytes of input. + offset = last64; + w[0] = w[0].add((len - 1) & 63); + v[0] = v[0].add(w[0]); + w[0] = w[0].add(v[0]); + x = rotate64(x.add(y).add(v[0]).add(fetch64(s, offset + 8)), 37).mul(mul); + y = rotate64(y.add(v[1]).add(fetch64(s, offset + 48)), 42).mul(mul); + x = x.xor(w[1].mul(9)); + y = y.add(v[0].mul(9).add(fetch64(s, offset + 40))); + z = rotate64(z.add(w[0]), 33).mul(mul); + v = weakHashLen32WithSeedsStr(s, offset, v[1].mul(mul), x.add(w[0])); + w = weakHashLen32WithSeedsStr(s, offset + 32, z.add(w[1]), y.add(fetch64(s, offset + 16))); + [z, x] = [x, z]; + return hashLen16(hashLen16(v[0], w[0], mul).add(shiftMix(y).mul(k0)).add(z), hashLen16(v[1], w[1], mul).add(x), mul); + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Create typed array for scalar value. Used for storing in `DataStorage`. + */ + function createScalarValue(value, dtype) { + if (dtype === 'string') { + return encodeString(value); + } + return toTypedArray([value], dtype); + } + function noConversionNeeded(a, dtype) { + return (a instanceof Float32Array && dtype === 'float32') || + (a instanceof Int32Array && dtype === 'int32') || + (a instanceof Uint8Array && dtype === 'bool'); + } + function toTypedArray(a, dtype) { + if (dtype === 'string') { + throw new Error('Cannot convert a string[] to a TypedArray'); + } + if (Array.isArray(a)) { + a = flatten$2(a); + } + if (env().getBool('DEBUG')) { + checkConversionForErrors(a, dtype); + } + if (noConversionNeeded(a, dtype)) { + return a; + } + if (dtype == null || dtype === 'float32' || dtype === 'complex64') { + return new Float32Array(a); + } + else if (dtype === 'int32') { + return new Int32Array(a); + } + else if (dtype === 'bool') { + const bool = new Uint8Array(a.length); + for (let i = 0; i < bool.length; ++i) { + if (Math.round(a[i]) !== 0) { + bool[i] = 1; + } + } + return bool; + } + else { + throw new Error(`Unknown data type ${dtype}`); + } + } + /** + * Returns the current high-resolution time in milliseconds relative to an + * arbitrary time in the past. It works across different platforms (node.js, + * browsers). + * + * ```js + * console.log(tf.util.now()); + * ``` + * + * @doc {heading: 'Util', namespace: 'util'} + */ + function now() { + return env().platform.now(); + } + /** + * Returns a platform-specific implementation of + * [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). + * + * If `fetch` is defined on the global object (`window`, `process`, etc.), + * `tf.util.fetch` returns that function. + * + * If not, `tf.util.fetch` returns a platform-specific solution. + * + * ```js + * const resource = await tf.util.fetch('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs'); + * // handle response + * ``` + * + * @doc {heading: 'Util'} + */ + function fetch$1(path, requestInits) { + return env().platform.fetch(path, requestInits); + } + /** + * Encodes the provided string into bytes using the provided encoding scheme. + * + * @param s The string to encode. + * @param encoding The encoding scheme. Defaults to utf-8. + * + * @doc {heading: 'Util'} + */ + function encodeString(s, encoding = 'utf-8') { + encoding = encoding || 'utf-8'; + return env().platform.encode(s, encoding); + } + /** + * Decodes the provided bytes into a string using the provided encoding scheme. + * @param bytes The bytes to decode. + * + * @param encoding The encoding scheme. Defaults to utf-8. + * + * @doc {heading: 'Util'} + */ + function decodeString(bytes, encoding = 'utf-8') { + encoding = encoding || 'utf-8'; + return env().platform.decode(bytes, encoding); + } + function isTypedArray(a) { + // TODO(mattsoulanille): Remove this fallback in 5.0.0 + if (env().platform.isTypedArray != null) { + return env().platform.isTypedArray(a); + } + else { + return isTypedArrayBrowser(a); + } + } + // NOTE: We explicitly type out what T extends instead of any so that + // util.flatten on a nested array of number doesn't try to infer T as a + // number[][], causing us to explicitly type util.flatten(). + /** + * Flattens an arbitrarily nested array. + * + * ```js + * const a = [[1, 2], [3, 4], [5, [6, [7]]]]; + * const flat = tf.util.flatten(a); + * console.log(flat); + * ``` + * + * @param arr The nested array to flatten. + * @param result The destination array which holds the elements. + * @param skipTypedArray If true, avoids flattening the typed arrays. Defaults + * to false. + * + * @doc {heading: 'Util', namespace: 'util'} + */ + function flatten$2(arr, result = [], skipTypedArray = false) { + if (result == null) { + result = []; + } + if (typeof arr === 'boolean' || typeof arr === 'number' || + typeof arr === 'string' || isPromise(arr) || arr == null || + isTypedArray(arr) && skipTypedArray) { + result.push(arr); + } + else if (Array.isArray(arr) || isTypedArray(arr)) { + for (let i = 0; i < arr.length; ++i) { + flatten$2(arr[i], result, skipTypedArray); + } + } + else { + let maxIndex = -1; + for (const key of Object.keys(arr)) { + // 0 or positive integer. + if (/^([1-9]+[0-9]*|0)$/.test(key)) { + maxIndex = Math.max(maxIndex, Number(key)); + } + } + for (let i = 0; i <= maxIndex; i++) { + // tslint:disable-next-line: no-unnecessary-type-assertion + flatten$2(arr[i], result, skipTypedArray); + } + } + return result; + } + + var util = /*#__PURE__*/Object.freeze({ + __proto__: null, + arraysEqual: arraysEqual, + arraysEqualWithNull: arraysEqualWithNull, + assert: assert$1, + assertNonNegativeIntegerDimensions: assertNonNegativeIntegerDimensions, + assertNonNull: assertNonNull, + assertShapesMatch: assertShapesMatch, + bytesFromStringArray: bytesFromStringArray, + bytesPerElement: bytesPerElement, + checkConversionForErrors: checkConversionForErrors, + clamp: clamp, + computeStrides: computeStrides, + convertBackendValuesAndArrayBuffer: convertBackendValuesAndArrayBuffer, + createScalarValue: createScalarValue, + createShuffledIndices: createShuffledIndices, + decodeString: decodeString, + distSquared: distSquared, + encodeString: encodeString, + fetch: fetch$1, + fingerPrint64: fingerPrint64, + flatten: flatten$2, + getArrayFromDType: getArrayFromDType, + getTypedArrayFromDType: getTypedArrayFromDType, + hasEncodingLoss: hasEncodingLoss, + hexToLong: hexToLong, + indexToLoc: indexToLoc, + inferDtype: inferDtype, + inferFromImplicitShape: inferFromImplicitShape, + isBoolean: isBoolean, + isFunction: isFunction, + isInt: isInt, + isNumber: isNumber, + isPromise: isPromise, + isScalarShape: isScalarShape, + isString: isString, + isTypedArray: isTypedArray, + isValidDtype: isValidDtype, + locToIndex: locToIndex, + makeOnesTypedArray: makeOnesTypedArray, + makeZerosNestedTypedArray: makeZerosNestedTypedArray, + makeZerosTypedArray: makeZerosTypedArray, + nearestDivisor: nearestDivisor, + nearestLargerEven: nearestLargerEven, + now: now, + parseAxisParam: parseAxisParam, + randUniform: randUniform, + repeatedTry: repeatedTry, + rightPad: rightPad, + shuffle: shuffle, + shuffleCombo: shuffleCombo, + sizeFromShape: sizeFromShape, + sizeToSquarishShape: sizeToSquarishShape, + squeezeShape: squeezeShape, + sum: sum$4, + swap: swap, + tanh: tanh$3, + toNestedArray: toNestedArray, + toTypedArray: toTypedArray + }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class Profiler { + constructor(backendTimer, logger) { + this.backendTimer = backendTimer; + this.logger = logger; + if (logger == null) { + this.logger = new Logger(); + } + } + profileKernel(kernelName, inputs, f) { + let outputs; + const holdResultWrapperFn = () => { + outputs = f(); + }; + let timer; + const start = now(); + if (this.backendTimer.timerAvailable()) { + timer = this.backendTimer.time(holdResultWrapperFn); + } + else { + holdResultWrapperFn(); + for (const output of outputs) { + output.dataSync(); + } + timer = Promise.resolve({ kernelMs: now() - start }); + } + if (env().getBool('CHECK_COMPUTATION_FOR_ERRORS')) { + for (let i = 0; i < outputs.length; i++) { + const output = outputs[i]; + // Dangling promise here because we don't want to propagate up + // asynchronicity. + output.data().then(tensorVals => { + checkComputationForErrors(tensorVals, output.dtype, kernelName); + }); + } + } + const kernelProfile = { + kernelName, + outputs, + inputs, + timeMs: timer.then(timing => timing.kernelMs), + extraInfo: timer.then(timing => timing.getExtraProfileInfo != null ? + timing.getExtraProfileInfo() : + '') + }; + return kernelProfile; + } + logKernelProfile(kernelProfile) { + const { kernelName, outputs, timeMs, inputs, extraInfo } = kernelProfile; + outputs.forEach(result => { + Promise.all([result.data(), timeMs, extraInfo]).then(valueContainer => { + this.logger.logKernelProfile(kernelName, result, valueContainer[0], valueContainer[1], inputs, valueContainer[2]); + }); + }); + } + } + function checkComputationForErrors(vals, dtype, kernelName) { + if (dtype !== 'float32') { + // Only floating point computations will generate NaN values + return false; + } + for (let i = 0; i < vals.length; i++) { + const num = vals[i]; + if (isNaN(num) || !isFinite(num)) { + // Throwing custom exception so behavior is testable. + console.warn(`Found ${num} in the result of '${kernelName}'`); + return true; + } + } + return false; + } + class Logger { + logKernelProfile(name, result, vals, timeMs, inputs, extraInfo) { + const time = typeof timeMs === 'number' ? rightPad(`${timeMs}ms`, 9) : + timeMs['error']; + const paddedName = rightPad(name, 25); + const rank = result.rank; + const size = result.size; + const shape = rightPad(result.shape.toString(), 14); + let inputShapesDescription = ''; + for (const name in inputs) { + const input = inputs[name]; + if (input != null) { + // The input might be a non-tensor (e.g HTMLImageElement), in which case + // we claim the output shape as input shape. + const inputShape = input.shape || result.shape; + const inputRank = inputShape.length; + inputShapesDescription += + `${name}: ${inputRank}D ${inputRank > 0 ? inputShape : ''} `; + } + } + console.log(`%c${paddedName}\t%c${time}\t%c${rank}D ${shape}\t%c${size}\t%c${inputShapesDescription}\t%c${extraInfo}`, 'font-weight:bold', 'color:red', 'color:blue', 'color: orange', 'color: green', 'color: steelblue'); + } + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes a list of TapeNodes that connect x to y, filtering everything else + * out and preserving the order of the original tape elements. + * + * @param tape The tape elements to filter. + * @param xs The input Tensors. + * @param y The output Tensor. + */ + function getFilteredNodesXToY(tape, xs, y) { + // Forward pass to compute all the nodes and Tensors that are transitively a + // function of x. + const tensorsFromX = {}; + const nodesFromX = {}; + for (let i = 0; i < xs.length; i++) { + tensorsFromX[xs[i].id] = true; + } + for (let i = 0; i < tape.length; i++) { + const node = tape[i]; + const nodeInputs = node.inputs; + for (const inputName in nodeInputs) { + const input = nodeInputs[inputName]; + let anyInputFromX = false; + for (let j = 0; j < xs.length; j++) { + if (tensorsFromX[input.id]) { + node.outputs.forEach(output => tensorsFromX[output.id] = true); + anyInputFromX = true; + nodesFromX[node.id] = true; + break; + } + } + if (anyInputFromX) { + break; + } + } + } + // Backward pass to find all of the nodes and Tensors that lead to y. + const tensorsLeadToY = {}; + tensorsLeadToY[y.id] = true; + const nodesToY = {}; + for (let i = tape.length - 1; i >= 0; i--) { + const node = tape[i]; + const nodeInputs = node.inputs; + // If any of the outputs lead to y, mark all of the inputs as leading to y. + for (let j = 0; j < node.outputs.length; j++) { + if (tensorsLeadToY[node.outputs[j].id]) { + for (const inputName in nodeInputs) { + tensorsLeadToY[nodeInputs[inputName].id] = true; + nodesToY[node.id] = true; + } + break; + } + } + } + // Return the paths that come from x and lead to y. + const filteredTape = []; + for (let i = 0; i < tape.length; i++) { + const node = tape[i]; + if (nodesFromX[node.id] && nodesToY[node.id]) { + // Prune the inputs from the node that aren't a function of x. + const prunedInputs = {}; + for (const inputName in node.inputs) { + const nodeInput = node.inputs[inputName]; + if (tensorsFromX[nodeInput.id]) { + prunedInputs[inputName] = nodeInput; + } + } + // Copy the node and overwrite inputsAndArgs to the pruned version. + const prunedNode = Object.assign({}, node); + prunedNode.inputs = prunedInputs; + prunedNode.outputs = node.outputs; + filteredTape.push(prunedNode); + } + } + return filteredTape; + } + /** + * Backpropagate gradients through the filtered TapeNodes. + * + * @param tensorAccumulatedGradientMap A map of Tensor to its gradient. This map + * is mutated by this method. + * @param filteredTape The filtered TapeNodes to backprop through. + */ + function backpropagateGradients(tensorAccumulatedGradientMap, filteredTape, tidy, add) { + // Walk the tape backward and keep a map of Tensor to its gradient. + for (let i = filteredTape.length - 1; i >= 0; i--) { + const node = filteredTape[i]; + const dys = []; + node.outputs.forEach(o => { + const gradTensor = tensorAccumulatedGradientMap[o.id]; + if (gradTensor != null) { + dys.push(gradTensor); + } + else { + // This particular output is not in the back-propagation subgraph, so it + // does not affect the final output, thus we put null for its dy. + dys.push(null); + } + }); + if (node.gradient == null) { + throw new Error(`Cannot compute gradient: gradient function not found ` + + `for ${node.kernelName}.`); + } + // Backprop dy through this node and accumulate gradients over the inputs. + const inputGradients = node.gradient(dys); + for (const inputName in node.inputs) { + if (!(inputName in inputGradients)) { + throw new Error(`Cannot backprop through input ${inputName}. ` + + `Available gradients found: ${Object.keys(inputGradients)}.`); + } + // Call the gradient function. + const dx = tidy(() => inputGradients[inputName]()); + if (dx.dtype !== 'float32') { + throw new Error(`Error in gradient for op ${node.kernelName}. The gradient of input ` + + `${inputName} must have 'float32' dtype, but has '${dx.dtype}'`); + } + const x = node.inputs[inputName]; + if (!arraysEqual(dx.shape, x.shape)) { + throw new Error(`Error in gradient for op ${node.kernelName}. The gradient of input ` + + `'${inputName}' has shape '${dx.shape}', which does not match ` + + `the shape of the input '${x.shape}'`); + } + if (tensorAccumulatedGradientMap[x.id] == null) { + tensorAccumulatedGradientMap[x.id] = dx; + } + else { + const curGradient = tensorAccumulatedGradientMap[x.id]; + tensorAccumulatedGradientMap[x.id] = add(curGradient, dx); + curGradient.dispose(); + } + } + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Maximum number of values before we decide to show ellipsis. + const FORMAT_LIMIT_NUM_VALS = 20; + // Number of first and last values to show when displaying a, b,...,y, z. + const FORMAT_NUM_FIRST_LAST_VALS = 3; + // Number of significant digits to show. + const FORMAT_NUM_SIG_DIGITS = 7; + function tensorToString(vals, shape, dtype, verbose) { + const strides = computeStrides(shape); + const padPerCol = computeMaxSizePerColumn(vals, shape, dtype, strides); + const rank = shape.length; + const valsLines = subTensorToString(vals, shape, dtype, strides, padPerCol); + const lines = ['Tensor']; + if (verbose) { + lines.push(` dtype: ${dtype}`); + lines.push(` rank: ${rank}`); + lines.push(` shape: [${shape}]`); + lines.push(` values:`); + } + lines.push(valsLines.map(l => ' ' + l).join('\n')); + return lines.join('\n'); + } + function computeMaxSizePerColumn(vals, shape, dtype, strides) { + const n = sizeFromShape(shape); + const numCols = strides[strides.length - 1]; + const padPerCol = new Array(numCols).fill(0); + const rank = shape.length; + const valuesOrTuples = dtype === 'complex64' ? createComplexTuples(vals) : vals; + if (rank > 1) { + for (let row = 0; row < n / numCols; row++) { + const offset = row * numCols; + for (let j = 0; j < numCols; j++) { + padPerCol[j] = Math.max(padPerCol[j], valToString(valuesOrTuples[offset + j], 0, dtype).length); + } + } + } + return padPerCol; + } + function valToString(val, pad, dtype) { + let valStr; + if (Array.isArray(val)) { + valStr = `${parseFloat(val[0].toFixed(FORMAT_NUM_SIG_DIGITS))} + ` + + `${parseFloat(val[1].toFixed(FORMAT_NUM_SIG_DIGITS))}j`; + } + else if (isString(val)) { + valStr = `'${val}'`; + } + else if (dtype === 'bool') { + valStr = boolNumToString(val); + } + else { + valStr = parseFloat(val.toFixed(FORMAT_NUM_SIG_DIGITS)).toString(); + } + return rightPad(valStr, pad); + } + function boolNumToString(v) { + return v === 0 ? 'false' : 'true'; + } + function subTensorToString(vals, shape, dtype, strides, padPerCol, isLast = true) { + const storagePerElement = dtype === 'complex64' ? 2 : 1; + const size = shape[0]; + const rank = shape.length; + if (rank === 0) { + if (dtype === 'complex64') { + const complexTuple = createComplexTuples(vals); + return [valToString(complexTuple[0], 0, dtype)]; + } + if (dtype === 'bool') { + return [boolNumToString(vals[0])]; + } + return [vals[0].toString()]; + } + if (rank === 1) { + if (size > FORMAT_LIMIT_NUM_VALS) { + const firstValsSize = FORMAT_NUM_FIRST_LAST_VALS * storagePerElement; + let firstVals = Array.from(vals.slice(0, firstValsSize)); + let lastVals = Array.from(vals.slice((size - FORMAT_NUM_FIRST_LAST_VALS) * storagePerElement, size * storagePerElement)); + if (dtype === 'complex64') { + firstVals = createComplexTuples(firstVals); + lastVals = createComplexTuples(lastVals); + } + return [ + '[' + + firstVals.map((x, i) => valToString(x, padPerCol[i], dtype)) + .join(', ') + + ', ..., ' + + lastVals + .map((x, i) => valToString(x, padPerCol[size - FORMAT_NUM_FIRST_LAST_VALS + i], dtype)) + .join(', ') + + ']' + ]; + } + const displayVals = dtype === 'complex64' ? createComplexTuples(vals) : + Array.from(vals); + return [ + '[' + + displayVals.map((x, i) => valToString(x, padPerCol[i], dtype)) + .join(', ') + + ']' + ]; + } + // The array is rank 2 or more. + const subshape = shape.slice(1); + const substrides = strides.slice(1); + const stride = strides[0] * storagePerElement; + const lines = []; + if (size > FORMAT_LIMIT_NUM_VALS) { + for (let i = 0; i < FORMAT_NUM_FIRST_LAST_VALS; i++) { + const start = i * stride; + const end = start + stride; + lines.push(...subTensorToString(vals.slice(start, end), subshape, dtype, substrides, padPerCol, false /* isLast */)); + } + lines.push('...'); + for (let i = size - FORMAT_NUM_FIRST_LAST_VALS; i < size; i++) { + const start = i * stride; + const end = start + stride; + lines.push(...subTensorToString(vals.slice(start, end), subshape, dtype, substrides, padPerCol, i === size - 1 /* isLast */)); + } + } + else { + for (let i = 0; i < size; i++) { + const start = i * stride; + const end = start + stride; + lines.push(...subTensorToString(vals.slice(start, end), subshape, dtype, substrides, padPerCol, i === size - 1 /* isLast */)); + } + } + const sep = rank === 2 ? ',' : ''; + lines[0] = '[' + (size > 0 ? lines[0] + sep : ''); + for (let i = 1; i < lines.length - 1; i++) { + lines[i] = ' ' + lines[i] + sep; + } + let newLineSep = ',\n'; + for (let i = 2; i < rank; i++) { + newLineSep += '\n'; + } + lines[lines.length - 1] = + ' ' + lines[lines.length - 1] + ']' + (isLast ? '' : newLineSep); + return lines; + } + function createComplexTuples(vals) { + const complexTuples = []; + for (let i = 0; i < vals.length; i += 2) { + complexTuples.push([vals[i], vals[i + 1]]); + } + return complexTuples; + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * A mutable object, similar to `tf.Tensor`, that allows users to set values + * at locations before converting to an immutable `tf.Tensor`. + * + * See `tf.buffer` for creating a tensor buffer. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + class TensorBuffer { + constructor(shape, dtype, values) { + this.dtype = dtype; + this.shape = shape.slice(); + this.size = sizeFromShape(shape); + if (values != null) { + const n = values.length; + assert$1(n === this.size, () => `Length of values '${n}' does not match the size ` + + `inferred by the shape '${this.size}'.`); + } + if (dtype === 'complex64') { + throw new Error(`complex64 dtype TensorBuffers are not supported. Please create ` + + `a TensorBuffer for the real and imaginary parts separately and ` + + `call tf.complex(real, imag).`); + } + this.values = values || getArrayFromDType(dtype, this.size); + this.strides = computeStrides(shape); + } + /** + * Sets a value in the buffer at a given location. + * + * @param value The value to set. + * @param locs The location indices. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + set(value, ...locs) { + if (locs.length === 0) { + locs = [0]; + } + assert$1(locs.length === this.rank, () => `The number of provided coordinates (${locs.length}) must ` + + `match the rank (${this.rank})`); + const index = this.locToIndex(locs); + this.values[index] = value; + } + /** + * Returns the value in the buffer at the provided location. + * + * @param locs The location indices. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + get(...locs) { + if (locs.length === 0) { + locs = [0]; + } + let i = 0; + for (const loc of locs) { + if (loc < 0 || loc >= this.shape[i]) { + const msg = `Requested out of range element at ${locs}. ` + + ` Buffer shape=${this.shape}`; + throw new Error(msg); + } + i++; + } + let index = locs[locs.length - 1]; + for (let i = 0; i < locs.length - 1; ++i) { + index += this.strides[i] * locs[i]; + } + return this.values[index]; + } + locToIndex(locs) { + if (this.rank === 0) { + return 0; + } + else if (this.rank === 1) { + return locs[0]; + } + let index = locs[locs.length - 1]; + for (let i = 0; i < locs.length - 1; ++i) { + index += this.strides[i] * locs[i]; + } + return index; + } + indexToLoc(index) { + if (this.rank === 0) { + return []; + } + else if (this.rank === 1) { + return [index]; + } + const locs = new Array(this.shape.length); + for (let i = 0; i < locs.length - 1; ++i) { + locs[i] = Math.floor(index / this.strides[i]); + index -= locs[i] * this.strides[i]; + } + locs[locs.length - 1] = index; + return locs; + } + get rank() { + return this.shape.length; + } + /** + * Creates an immutable `tf.Tensor` object from the buffer. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + toTensor() { + return trackerFn().makeTensor(this.values, this.shape, this.dtype); + } + } + // For tracking tensor creation and disposal. + let trackerFn = null; + // Used by chaining methods to call into ops. + let opHandler$1 = null; + // Used to warn about deprecated methods. + let deprecationWarningFn = null; + // This here so that we can use this method on dev branches and keep the + // functionality at master. + // tslint:disable-next-line:no-unused-expression + [deprecationWarningFn]; + /** + * An external consumer can register itself as the tensor tracker. This way + * the Tensor class can notify the tracker for every tensor created and + * disposed. + */ + function setTensorTracker(fn) { + trackerFn = fn; + } + /** + * An external consumer can register itself as the op handler. This way the + * Tensor class can have chaining methods that call into ops via the op + * handler. + */ + function setOpHandler(handler) { + opHandler$1 = handler; + } + /** + * Sets the deprecation warning function to be used by this file. This way the + * Tensor class can be a leaf but still use the environment. + */ + function setDeprecationWarningFn(fn) { + deprecationWarningFn = fn; + } + /** + * A `tf.Tensor` object represents an immutable, multidimensional array of + * numbers that has a shape and a data type. + * + * For performance reasons, functions that create tensors do not necessarily + * perform a copy of the data passed to them (e.g. if the data is passed as a + * `Float32Array`), and changes to the data will change the tensor. This is not + * a feature and is not supported. To avoid this behavior, use the tensor before + * changing the input data or create a copy with `copy = tf.add(yourTensor, 0)`. + * + * See `tf.tensor` for details on how to create a `tf.Tensor`. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + class Tensor { + constructor(shape, dtype, dataId, id) { + /** Whether this tensor has been globally kept. */ + this.kept = false; + this.isDisposedInternal = false; + this.shape = shape.slice(); + this.dtype = dtype || 'float32'; + this.size = sizeFromShape(shape); + this.strides = computeStrides(shape); + this.dataId = dataId; + this.id = id; + this.rankType = (this.rank < 5 ? this.rank.toString() : 'higher'); + } + get rank() { + return this.shape.length; + } + /** + * Returns a promise of `tf.TensorBuffer` that holds the underlying data. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + async buffer() { + const vals = await this.data(); + return opHandler$1.buffer(this.shape, this.dtype, vals); + } + /** + * Returns a `tf.TensorBuffer` that holds the underlying data. + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + bufferSync() { + return opHandler$1.buffer(this.shape, this.dtype, this.dataSync()); + } + /** + * Returns the tensor data as a nested array. The transfer of data is done + * asynchronously. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + async array() { + const vals = await this.data(); + return toNestedArray(this.shape, vals, this.dtype === 'complex64'); + } + /** + * Returns the tensor data as a nested array. The transfer of data is done + * synchronously. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + arraySync() { + return toNestedArray(this.shape, this.dataSync(), this.dtype === 'complex64'); + } + /** + * Asynchronously downloads the values from the `tf.Tensor`. Returns a + * promise of `TypedArray` that resolves when the computation has finished. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + async data() { + this.throwIfDisposed(); + const data = trackerFn().read(this.dataId); + if (this.dtype === 'string') { + const bytes = await data; + try { + return bytes.map(b => decodeString(b)); + } + catch (_a) { + throw new Error('Failed to decode the string bytes into utf-8. ' + + 'To get the original bytes, call tensor.bytes().'); + } + } + return data; + } + /** + * Copy the tensor's data to a new GPU resource. Comparing to the `dataSync()` + * and `data()`, this method prevents data from being downloaded to CPU. + * + * For WebGL backend, the data will be stored on a densely packed texture. + * This means that the texture will use the RGBA channels to store value. + * + * For WebGPU backend, the data will be stored on a buffer. There is no + * parameter, so can not use a user-defined size to create the buffer. + * + * @param options: + * For WebGL, + * - customTexShape: Optional. If set, will use the user defined + * texture shape to create the texture. + * + * @returns For WebGL backend, a GPUData contains the new texture and + * its information. + * { + * tensorRef: The tensor that is associated with this texture, + * texture: WebGLTexture, + * texShape: [number, number] // [height, width] + * } + * + * For WebGPU backend, a GPUData contains the new buffer. + * { + * tensorRef: The tensor that is associated with this buffer, + * buffer: GPUBuffer, + * } + * + * Remember to dispose the GPUData after it is used by + * `res.tensorRef.dispose()`. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + dataToGPU(options) { + this.throwIfDisposed(); + return trackerFn().readToGPU(this.dataId, options); + } + /** + * Synchronously downloads the values from the `tf.Tensor`. This blocks the + * UI thread until the values are ready, which can cause performance issues. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + dataSync() { + this.throwIfDisposed(); + const data = trackerFn().readSync(this.dataId); + if (this.dtype === 'string') { + try { + return data.map(b => decodeString(b)); + } + catch (_a) { + throw new Error('Failed to decode the string bytes into utf-8. ' + + 'To get the original bytes, call tensor.bytes().'); + } + } + return data; + } + /** Returns the underlying bytes of the tensor's data. */ + async bytes() { + this.throwIfDisposed(); + const data = await trackerFn().read(this.dataId); + if (this.dtype === 'string') { + return data; + } + else { + return new Uint8Array(data.buffer); + } + } + /** + * Disposes `tf.Tensor` from memory. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + dispose() { + if (this.isDisposed) { + return; + } + if (this.kerasMask) { + this.kerasMask.dispose(); + } + trackerFn().disposeTensor(this); + this.isDisposedInternal = true; + } + get isDisposed() { + return this.isDisposedInternal; + } + throwIfDisposed() { + if (this.isDisposed) { + throw new Error(`Tensor is disposed.`); + } + } + /** + * Prints the `tf.Tensor`. See `tf.print` for details. + * + * @param verbose Whether to print verbose information about the tensor, + * including dtype and size. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + print(verbose = false) { + return opHandler$1.print(this, verbose); + } + /** + * Returns a copy of the tensor. See `tf.clone` for details. + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + clone() { + this.throwIfDisposed(); + return opHandler$1.clone(this); + } + /** + * Returns a human-readable description of the tensor. Useful for logging. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + toString(verbose = false) { + const vals = this.dataSync(); + return tensorToString(vals, this.shape, this.dtype, verbose); + } + cast(dtype) { + this.throwIfDisposed(); + return opHandler$1.cast(this, dtype); + } + variable(trainable = true, name, dtype) { + this.throwIfDisposed(); + return trackerFn().makeVariable(this, trainable, name, dtype); + } + } + Object.defineProperty(Tensor, Symbol.hasInstance, { + value: (instance) => { + // Implementation note: we should use properties of the object that will be + // defined before the constructor body has finished executing (methods). + // This is because when this code is transpiled by babel, babel will call + // classCallCheck before the constructor body is run. + // See https://github.com/tensorflow/tfjs/issues/3384 for backstory. + return !!instance && instance.data != null && instance.dataSync != null && + instance.throwIfDisposed != null; + } + }); + function getGlobalTensorClass() { + // Use getGlobal so that we can augment the Tensor class across package + // boundaries because the node resolution alg may result in different modules + // being returned for this file depending on the path they are loaded from. + return getGlobal('Tensor', () => { + return Tensor; + }); + } + // Global side effect. Cache global reference to Tensor class + getGlobalTensorClass(); + /** + * A mutable `tf.Tensor`, useful for persisting state, e.g. for training. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + class Variable extends Tensor { + constructor(initialValue, trainable, name, tensorId) { + super(initialValue.shape, initialValue.dtype, initialValue.dataId, tensorId); + this.trainable = trainable; + this.name = name; + } + /** + * Assign a new `tf.Tensor` to this variable. The new `tf.Tensor` must have + * the same shape and dtype as the old `tf.Tensor`. + * + * @param newValue New tensor to be assigned to this variable. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + assign(newValue) { + if (newValue.dtype !== this.dtype) { + throw new Error(`dtype of the new value (${newValue.dtype}) and ` + + `previous value (${this.dtype}) must match`); + } + if (!arraysEqual(newValue.shape, this.shape)) { + throw new Error(`shape of the new value (${newValue.shape}) and ` + + `previous value (${this.shape}) must match`); + } + trackerFn().disposeTensor(this); + this.dataId = newValue.dataId; + trackerFn().incRef(this, null /* backend */); + } + dispose() { + trackerFn().disposeVariable(this); + this.isDisposedInternal = true; + } + } + Object.defineProperty(Variable, Symbol.hasInstance, { + value: (instance) => { + return instance instanceof Tensor && instance.assign != null && + instance.assign instanceof Function; + } + }); + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + exports.Rank = void 0; + (function (Rank) { + Rank["R0"] = "R0"; + Rank["R1"] = "R1"; + Rank["R2"] = "R2"; + Rank["R3"] = "R3"; + Rank["R4"] = "R4"; + Rank["R5"] = "R5"; + Rank["R6"] = "R6"; + })(exports.Rank || (exports.Rank = {})); + // Looks for upcasting types. Used, for example, in operations with mixed dtype + // inputs. + var UpcastInt32AndMap; + (function (UpcastInt32AndMap) { + UpcastInt32AndMap["float32"] = "float32"; + UpcastInt32AndMap["int32"] = "int32"; + UpcastInt32AndMap["bool"] = "int32"; + UpcastInt32AndMap["complex64"] = "complex64"; + })(UpcastInt32AndMap || (UpcastInt32AndMap = {})); + var UpcastBoolAndMap; + (function (UpcastBoolAndMap) { + UpcastBoolAndMap["float32"] = "float32"; + UpcastBoolAndMap["int32"] = "int32"; + UpcastBoolAndMap["bool"] = "bool"; + UpcastBoolAndMap["complex64"] = "complex64"; + })(UpcastBoolAndMap || (UpcastBoolAndMap = {})); + var UpcastFloat32AndMap; + (function (UpcastFloat32AndMap) { + UpcastFloat32AndMap["float32"] = "float32"; + UpcastFloat32AndMap["int32"] = "float32"; + UpcastFloat32AndMap["bool"] = "float32"; + UpcastFloat32AndMap["complex64"] = "complex64"; + })(UpcastFloat32AndMap || (UpcastFloat32AndMap = {})); + var UpcastComplex64AndMap; + (function (UpcastComplex64AndMap) { + UpcastComplex64AndMap["float32"] = "complex64"; + UpcastComplex64AndMap["int32"] = "complex64"; + UpcastComplex64AndMap["bool"] = "complex64"; + UpcastComplex64AndMap["complex64"] = "complex64"; + })(UpcastComplex64AndMap || (UpcastComplex64AndMap = {})); + const upcastTypeMap = { + 'float32': UpcastFloat32AndMap, + 'int32': UpcastInt32AndMap, + 'bool': UpcastBoolAndMap, + 'complex64': UpcastComplex64AndMap + }; + function upcastType(typeA, typeB) { + if (typeA === 'string' || typeB === 'string') { + if (typeA === 'string' && typeB === 'string') { + return 'string'; + } + throw new Error(`Can not upcast ${typeA} with ${typeB}`); + } + return upcastTypeMap[typeA][typeB]; + } + /** Returns the output type after summation. */ + function sumOutType(type) { + return upcastType(type, 'int32'); + } + function isWebGLData(values) { + return values != null && typeof values === 'object' && 'texture' in values && + values.texture instanceof WebGLTexture; + } + function isWebGPUData(values) { + return typeof GPUBuffer !== 'undefined' && values != null && + typeof values === 'object' && 'buffer' in values && + values.buffer instanceof GPUBuffer; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function makeTypesMatch(a, b) { + if (a.dtype === b.dtype) { + return [a, b]; + } + const dtype = upcastType(a.dtype, b.dtype); + return [a.cast(dtype), b.cast(dtype)]; + } + function assertTypesMatch(a, b) { + assert$1(a.dtype === b.dtype, () => `The dtypes of the first(${a.dtype}) and` + + ` second(${b.dtype}) input must match`); + } + function isTensorInList(tensor, tensorList) { + return tensorList.some(x => x.id === tensor.id); + } + /** + * Extracts any `Tensor`s found within the provided object. + * + * @param container an object that may be a `Tensor` or may directly contain + * `Tensor`s, such as a `Tensor[]` or `{key: Tensor, ...}`. In general it + * is safe to pass any object here, except that `Promise`s are not + * supported. + * @returns An array of `Tensors` found within the passed object. If the + * argument is simply a `Tensor', a list containing that `Tensor` is + * returned. If the object is not a `Tensor` or does not + * contain `Tensors`, an empty list is returned. + */ + function getTensorsInContainer(result) { + const list = []; + const seen = new Set(); + walkTensorContainer(result, list, seen); + return list; + } + function walkTensorContainer(container, list, seen) { + if (container == null) { + return; + } + if (container instanceof Tensor) { + list.push(container); + return; + } + if (!isIterable$1(container)) { + return; + } + // Iteration over keys works also for arrays. + const iterable = container; + for (const k in iterable) { + const val = iterable[k]; + if (!seen.has(val)) { + seen.add(val); + walkTensorContainer(val, list, seen); + } + } + } + // tslint:disable-next-line:no-any + function isIterable$1(obj) { + return Array.isArray(obj) || typeof obj === 'object'; + } + + var tensor_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + assertTypesMatch: assertTypesMatch, + getTensorsInContainer: getTensorsInContainer, + isTensorInList: isTensorInList, + makeTypesMatch: makeTypesMatch + }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function isRegisteredKernelInvocation(kernelInvocation) { + return kernelInvocation.kernelName != null; + } + class EngineState { + constructor() { + // Public since optimizers will use it. + this.registeredVariables = {}; + this.nextTapeNodeId = 0; + this.numBytes = 0; + this.numTensors = 0; + this.numStringTensors = 0; + this.numDataBuffers = 0; + // Number of nested tf.grad() statements when computing higher-order + // gradients. E.g. `1` for first-order gradients and `2` for second-order + // gradients. Used to track if the tape should be removed after a backprop. + this.gradientDepth = 0; + // Number of nested kernel calls. When kernel depth is greater than 1, we turn + // off the tape. + this.kernelDepth = 0; + this.scopeStack = []; + /** + * Keeps track of the number of data moves during a kernel execution. We + * maintain a stack since kernels can call other kernels, recursively. + */ + this.numDataMovesStack = []; + this.nextScopeId = 0; + this.tensorInfo = new WeakMap(); + this.profiling = false; + this.activeProfile = { + newBytes: 0, + newTensors: 0, + peakBytes: 0, + kernels: [], + result: null, + get kernelNames() { + return Array.from(new Set(this.kernels.map(k => k.name))); + } + }; + } + dispose() { + for (const variableName in this.registeredVariables) { + this.registeredVariables[variableName].dispose(); + } + } + } + class Engine { + constructor(ENV) { + this.ENV = ENV; + this.registry = {}; + this.registryFactory = {}; + this.pendingBackendInitId = 0; + this.state = new EngineState(); + } + async ready() { + if (this.pendingBackendInit != null) { + return this.pendingBackendInit.then(() => { }); + } + if (this.backendInstance != null) { + return; + } + const sortedBackends = this.getSortedBackends(); + for (let i = 0; i < sortedBackends.length; i++) { + const backendName = sortedBackends[i]; + const success = await this.initializeBackend(backendName).success; + if (success) { + await this.setBackend(backendName); + return; + } + } + throw new Error(`Could not initialize any backends, all backend initializations ` + + `failed.`); + } + get backend() { + if (this.pendingBackendInit != null) { + throw new Error(`Backend '${this.backendName}' has not yet been initialized. Make ` + + `sure to await tf.ready() or await tf.setBackend() before calling ` + + `other methods`); + } + if (this.backendInstance == null) { + const { name, asyncInit } = this.initializeBackendsAndReturnBest(); + if (asyncInit) { + throw new Error(`The highest priority backend '${name}' has not yet been ` + + `initialized. Make sure to await tf.ready() or ` + + `await tf.setBackend() before calling other methods`); + } + this.setBackend(name); + } + return this.backendInstance; + } + backendNames() { + return Object.keys(this.registryFactory); + } + findBackend(backendName) { + if (!(backendName in this.registry)) { + // If the backend hasn't been initialized but we have a registry entry for + // it, initialize it and return it. + if (backendName in this.registryFactory) { + const { asyncInit } = this.initializeBackend(backendName); + if (asyncInit) { + // Backend is not ready yet. + return null; + } + } + else { + return null; + } + } + return this.registry[backendName]; + } + findBackendFactory(backendName) { + if (!(backendName in this.registryFactory)) { + return null; + } + return this.registryFactory[backendName].factory; + } + registerBackend(backendName, factory, priority = 1) { + if (backendName in this.registryFactory) { + warn(`${backendName} backend was already registered. ` + + `Reusing existing backend factory.`); + return false; + } + this.registryFactory[backendName] = { factory, priority }; + return true; + } + async setBackend(backendName) { + if (this.registryFactory[backendName] == null) { + throw new Error(`Backend name '${backendName}' not found in registry`); + } + this.backendName = backendName; + if (this.registry[backendName] == null) { + this.backendInstance = null; + const { success, asyncInit } = this.initializeBackend(backendName); + const result = asyncInit ? await success : success; + if (!result) { + return false; + } + } + this.backendInstance = this.registry[backendName]; + this.setupRegisteredKernels(); + // Reset the profiler. + this.profiler = new Profiler(this.backendInstance); + return true; + } + setupRegisteredKernels() { + const kernels = getKernelsForBackend(this.backendName); + kernels.forEach(kernel => { + if (kernel.setupFunc != null) { + kernel.setupFunc(this.backendInstance); + } + }); + } + disposeRegisteredKernels(backendName) { + const kernels = getKernelsForBackend(backendName); + kernels.forEach(kernel => { + if (kernel.disposeFunc != null) { + kernel.disposeFunc(this.registry[backendName]); + } + }); + } + /** + * Initializes a backend by looking up the backend name in the factory + * registry and calling the factory method. Returns a boolean representing + * whether the initialization of the backend succeeded. Throws an error if + * there is no backend in the factory registry. + */ + initializeBackend(backendName) { + const registryFactoryEntry = this.registryFactory[backendName]; + if (registryFactoryEntry == null) { + throw new Error(`Cannot initialize backend ${backendName}, no registration found.`); + } + try { + const backend = registryFactoryEntry.factory(); + /* Test if the factory returns a promise. + Done in a more liberal way than + previous 'Promise.resolve(backend)===backend' + as we needed to account for custom Promise + implementations (e.g. Angular) */ + if (backend && !(backend instanceof KernelBackend) && + typeof backend.then === 'function') { + const promiseId = ++this.pendingBackendInitId; + const success = backend + .then(backendInstance => { + // Outdated promise. Another backend was set in the meantime. + if (promiseId < this.pendingBackendInitId) { + return false; + } + this.registry[backendName] = backendInstance; + this.pendingBackendInit = null; + return true; + }) + .catch(err => { + // Outdated promise. Another backend was set in the meantime. + if (promiseId < this.pendingBackendInitId) { + return false; + } + this.pendingBackendInit = null; + warn(`Initialization of backend ${backendName} failed`); + warn(err.stack || err.message); + return false; + }); + this.pendingBackendInit = success; + return { success, asyncInit: true }; + } + else { + this.registry[backendName] = backend; + return { success: true, asyncInit: false }; + } + } + catch (err) { + warn(`Initialization of backend ${backendName} failed`); + warn(err.stack || err.message); + return { success: false, asyncInit: false }; + } + } + removeBackend(backendName) { + if (!(backendName in this.registryFactory)) { + throw new Error(`${backendName} backend not found in registry`); + } + if (this.backendName === backendName && this.pendingBackendInit != null) { + // There is a pending promise of the backend we want to remove. Make it + // obsolete. + this.pendingBackendInitId++; + } + if (backendName in this.registry) { + this.disposeRegisteredKernels(backendName); + this.registry[backendName].dispose(); + delete this.registry[backendName]; + } + delete this.registryFactory[backendName]; + // Unset the backend if it is active. + if (this.backendName === backendName) { + this.pendingBackendInit = null; + this.backendName = null; + this.backendInstance = null; + } + } + getSortedBackends() { + if (Object.keys(this.registryFactory).length === 0) { + throw new Error('No backend found in registry.'); + } + return Object.keys(this.registryFactory).sort((a, b) => { + // Highest priority comes first. + return this.registryFactory[b].priority - + this.registryFactory[a].priority; + }); + } + initializeBackendsAndReturnBest() { + const sortedBackends = this.getSortedBackends(); + for (let i = 0; i < sortedBackends.length; i++) { + const backendName = sortedBackends[i]; + const { success, asyncInit } = this.initializeBackend(backendName); + if (asyncInit || success) { + return { name: backendName, asyncInit }; + } + } + throw new Error(`Could not initialize any backends, all backend initializations ` + + `failed.`); + } + moveData(backend, dataId) { + const info = this.state.tensorInfo.get(dataId); + const srcBackend = info.backend; + const values = this.readSync(dataId); + const refCount = srcBackend.refCount(dataId); + // Delete the tensor from the old backend and move it to the new + // backend. + srcBackend.disposeData(dataId, true); + info.backend = backend; + backend.move(dataId, values, info.shape, info.dtype, refCount); + if (this.shouldCheckForMemLeaks()) { + // Track the number of moves during a kernel execution to correctly + // detect memory leaks. + this.state.numDataMovesStack[this.state.numDataMovesStack.length - 1]++; + } + } + tidy(nameOrFn, fn) { + let name = null; + if (fn == null) { + // Called with only 1 argument. + if (typeof nameOrFn !== 'function') { + throw new Error('Please provide a function to tidy()'); + } + fn = nameOrFn; + } + else { + // Called with 2 arguments. + if (typeof nameOrFn !== 'string' && !(nameOrFn instanceof String)) { + throw new Error('When calling with two arguments, the first argument ' + + 'to tidy() must be a string'); + } + if (typeof fn !== 'function') { + throw new Error('When calling with two arguments, the 2nd argument ' + + 'to tidy() must be a function'); + } + name = nameOrFn; + // TODO(nsthorat,smilkov): Do operation logging and performance + // profiling. + } + let result; + return this.scopedRun(() => this.startScope(name), () => this.endScope(result), () => { + result = fn(); + if (result instanceof Promise) { + console.error('Cannot return a Promise inside of tidy.'); + } + return result; + }); + } + scopedRun(start, end, f) { + start(); + try { + const res = f(); + end(); + return res; + } + catch (ex) { + end(); + throw ex; + } + } + nextTensorId() { + return Engine.nextTensorId++; + } + nextVariableId() { + return Engine.nextVariableId++; + } + /** + * This method is called instead of the public-facing tensor.clone() when + * saving a tensor for backwards pass. It makes sure to add the clone + * operation to the tape regardless of being called inside a kernel + * execution. + */ + clone(x) { + const y = ENGINE.runKernel(Identity$1, { x }); + const inputs = { x }; + const grad = (dy) => ({ + x: () => { + const dtype = 'float32'; + const gradInputs = { x: dy }; + const attrs = { dtype }; + return ENGINE.runKernel(Cast, gradInputs, + // tslint:disable-next-line: no-unnecessary-type-assertion + attrs); + } + }); + const saved = []; + this.addTapeNode(this.state.activeScope.name, inputs, [y], grad, saved, {}); + return y; + } + /** + * Execute a kernel with the given name and return the output tensor. + * + * @param kernelName The name of the kernel to execute. + * @param inputs A map of input names to tensors. + * @param attrs A map of attribute names to their values. An attribute is a + * primitive (non-tensor) input to the kernel. + * @param inputsToSave A list of tensors, inputs to save for the backprop + * computation. + * @param outputsToSave A list of booleans, specifying which output to save + * for the backprop computation. These are booleans since the output + * tensors are not visible to the user. + */ + runKernel(kernelName, inputs, attrs) { + if (this.backendName == null) { + // backend has not been initialized yet (backend initialization is lazy + // can be deferred until an op/ kernel is run). + // The below getter has side effects that will try to initialize the + // backend and set properties like this.backendName + // tslint:disable-next-line: no-unused-expression + this.backend; + } + const hasKernel = getKernel(kernelName, this.backendName) != null; + if (!hasKernel) { + throw new Error(`Kernel '${kernelName}' not registered for backend '${this.backendName}'`); + } + return this.runKernelFunc({ kernelName, inputs, attrs }); + } + shouldCheckForMemLeaks() { + return this.ENV.getBool('IS_TEST'); + } + checkKernelForMemLeak(kernelName, numDataIdsBefore, outInfos) { + const numDataIdsAfter = this.backend.numDataIds(); + // Count the number of data ids associated with the result of the kernel. + let numOutputDataIds = 0; + outInfos.forEach(info => { + // Complex numbers allocate 3 data ids, one for 'real', one for + // 'imaginary', and one for the container that holds the former two. + numOutputDataIds += (info.dtype === 'complex64' ? 3 : 1); + }); + // Account for the number of moves during kernel execution. A "data move" + // can happen in the middle of a kernel execution, placing a new (key,value) + // pair in the data storage. Since data moves have net zero effect (we + // always remove the data from the old backend), we have to cancel them out + // when detecting memory leaks. + const numMoves = this.state.numDataMovesStack[this.state.numDataMovesStack.length - 1]; + const dataIdsLeaked = numDataIdsAfter - numDataIdsBefore - numOutputDataIds - numMoves; + if (dataIdsLeaked > 0) { + throw new Error(`Backend '${this.backendName}' has an internal memory leak ` + + `(${dataIdsLeaked} data ids) after running '${kernelName}'`); + } + } + /** + * Internal helper method to execute a kernel Func + * + * Use `runKernel` to execute kernels from outside of engine. + */ + runKernelFunc(kernelParams) { + let outputs; + let saved = []; + const isTapeOn = this.isTapeOn(); + const startingBytecount = this.state.numBytes; + const startingNumTensors = this.state.numTensors; + if (this.shouldCheckForMemLeaks()) { + this.state.numDataMovesStack.push(0); + } + let kernelFunc; + if (this.backendName == null) { + // backend has not been initialized yet (backend initialization is lazy + // can be deferred until an op/ kernel is run). + // The below getter has side effects that will try to initialize the + // backend and set properties like this.backendName + // tslint:disable-next-line: no-unused-expression + this.backend; + } + let out; + const kernelOrScopeName = isRegisteredKernelInvocation(kernelParams) ? + kernelParams.kernelName : + this.state.activeScope != null ? this.state.activeScope.name : ''; + // Create the kernelFunc from either a registered kernel OR passed in + // forward/backward functions (used by custom grad). In this context a + // kernelFunc wraps a kernel implementation with some bookkeeping. + if (isRegisteredKernelInvocation(kernelParams)) { + const { kernelName, inputs, attrs } = kernelParams; + if (this.backendName == null) { + // backend has not been initialized yet (backend initialization is lazy + // can be deferred until an op/ kernel is run). + // The below getter has side effects that will try to initialize the + // backend and set properties like this.backendName + // tslint:disable-next-line: no-unused-expression + this.backend; + } + const kernel = getKernel(kernelName, this.backendName); + assert$1(kernel != null, () => `Cannot find registered kernel '${kernelName}' for backend '${this.backendName}'`); + kernelFunc = () => { + const numDataIdsBefore = this.backend.numDataIds(); + out = kernel.kernelFunc({ inputs, attrs, backend: this.backend }); + const outInfos = Array.isArray(out) ? out : [out]; + if (this.shouldCheckForMemLeaks()) { + this.checkKernelForMemLeak(kernelName, numDataIdsBefore, outInfos); + } + const outTensors = outInfos.map((outInfo) => { + // todo (yassogba) remove this option (Tensor) when node backend + // methods have been modularized and they all return tensorInfo. + // TensorInfos do not have a rank attribute. + if (outInfo.rank != null) { + return outInfo; + } + return this.makeTensorFromTensorInfo(outInfo); + }); + // Save any required inputs and outputs. + // Do not save unless we are recording to the tape. Otherwise it would + // cause a mem leak since there would be no backprop for these tensors + // (which would otherwise dispose them). + if (isTapeOn) { + const tensorsToSave = this.getTensorsForGradient(kernelName, inputs, outTensors); + saved = this.saveTensorsForBackwardMode(tensorsToSave); + } + return outTensors; + }; + } + else { + const { forwardFunc } = kernelParams; + // Running a customGrad op. + const saveFunc = (tensors) => { + // Do not save unless we are recording to the tape. Otherwise it would + // cause a mem leak since we would never run backprop, which disposes + // the kept tensors. + if (!isTapeOn) { + return; + } + saved = tensors.map(tensor => this.keep(this.clone(tensor))); + }; + kernelFunc = () => { + const numDataIdsBefore = this.backend.numDataIds(); + out = this.tidy(() => forwardFunc(this.backend, saveFunc)); + const outs = (Array.isArray(out) ? out : [out]); + if (this.shouldCheckForMemLeaks()) { + // Scope name is used to print a more helpful error message if needed. + this.checkKernelForMemLeak(kernelOrScopeName, numDataIdsBefore, outs); + } + return outs; + }; + } + // + // Run the kernelFunc. Optionally profiling it. + // + const { inputs, attrs } = kernelParams; + const backwardsFunc = isRegisteredKernelInvocation(kernelParams) ? + null : + kernelParams.backwardsFunc; + let kernelProfile; + this.scopedRun( + // Stop recording to a tape when running a kernel. + () => this.state.kernelDepth++, () => this.state.kernelDepth--, () => { + if (!this.ENV.getBool('DEBUG') && !this.state.profiling) { + outputs = kernelFunc(); + } + else { + kernelProfile = this.profiler.profileKernel(kernelOrScopeName, inputs, () => kernelFunc()); + if (this.ENV.getBool('DEBUG')) { + this.profiler.logKernelProfile(kernelProfile); + } + outputs = kernelProfile.outputs; + } + }); + if (isTapeOn) { + this.addTapeNode(kernelOrScopeName, inputs, outputs, backwardsFunc, saved, attrs); + } + if (this.state.profiling) { + this.state.activeProfile.kernels.push({ + name: kernelOrScopeName, + bytesAdded: this.state.numBytes - startingBytecount, + totalBytesSnapshot: this.state.numBytes, + tensorsAdded: this.state.numTensors - startingNumTensors, + totalTensorsSnapshot: this.state.numTensors, + inputShapes: Object.keys(inputs).map(key => inputs[key] != null ? inputs[key].shape : null), + outputShapes: outputs.map(item => item.shape), + kernelTimeMs: kernelProfile.timeMs, + extraInfo: kernelProfile.extraInfo + }); + } + return (Array.isArray(out) ? outputs : outputs[0]); + } + /** + * Saves tensors used in forward mode for use in backward mode. + * + * @param tensors the list of tensors to save. + */ + saveTensorsForBackwardMode(tensors) { + const saved = tensors.map(tensor => this.keep(this.clone(tensor))); + return saved; + } + /** + * Returns a list of tensors to save for a given gradient calculation. + * + * @param kernelName name of kernel to look up gradient for. + * @param inputs a map of input tensors. + * @param outputs an array of output tensors from forward mode of kernel. + */ + getTensorsForGradient(kernelName, inputs, outputs) { + const gradConfig = getGradient(kernelName); + if (gradConfig != null) { + const inputsToSave = gradConfig.inputsToSave || []; + const outputsToSave = gradConfig.outputsToSave || []; + // If saveAllInputs is true, all inputs will be saved. Otherwise, inputs + // specified in inputsToSave will be saved. + let inputTensorsToSave; + if (gradConfig.saveAllInputs) { + assert$1(Array.isArray(inputs), () => 'saveAllInputs is true, expected inputs to be an array.'); + inputTensorsToSave = Object.keys(inputs).map((key) => inputs[key]); + } + else { + inputTensorsToSave = inputsToSave.map((inputName) => inputs[inputName]); + } + const outputTensorsToSave = outputs.filter((_, i) => outputsToSave[i]); + return inputTensorsToSave.concat(outputTensorsToSave); + } + // We return an empty list rather than throw an error because the kernel we + // are looking up may not actually be relevant to backproping through the + // overall function + // + // See 'does not error if irrelevant (pruned) ops are missing grads' test + // in gradients_test.ts for an example. + return []; + } + /** + * Internal method used by public APIs for tensor creation. Makes a new + * tensor with the provided shape, dtype and values. It always + * creates a new data id and writes the values to the underlying backend. + */ + makeTensor(values, shape, dtype, backend) { + if (values == null) { + throw new Error('Values passed to engine.makeTensor() are null'); + } + dtype = dtype || 'float32'; + backend = backend || this.backend; + let backendVals = values; + if (dtype === 'string' && isString(values[0])) { + backendVals = values.map(d => encodeString(d)); + } + const dataId = backend.write(backendVals, shape, dtype); + const t = new Tensor(shape, dtype, dataId, this.nextTensorId()); + this.trackTensor(t, backend); + // Count bytes for string tensors. + if (dtype === 'string') { + const info = this.state.tensorInfo.get(dataId); + const newBytes = bytesFromStringArray(backendVals); + this.state.numBytes += newBytes - info.bytes; + info.bytes = newBytes; + } + return t; + } + /** + * Internal method used by backends. Makes a new tensor + * that is a wrapper around an existing data id. It doesn't create + * a new data id, only increments the ref count used in memory tracking. + * @deprecated + */ + makeTensorFromDataId(dataId, shape, dtype, backend) { + dtype = dtype || 'float32'; + const tensorInfo = { dataId, shape, dtype }; + return this.makeTensorFromTensorInfo(tensorInfo, backend); + } + /** + * Internal method used by backends. Makes a new tensor that is a wrapper + * around an existing data id in TensorInfo. It doesn't create a new data id, + * only increments the ref count used in memory tracking. + */ + makeTensorFromTensorInfo(tensorInfo, backend) { + const { dataId, shape, dtype } = tensorInfo; + const t = new Tensor(shape, dtype, dataId, this.nextTensorId()); + this.trackTensor(t, backend); + return t; + } + makeVariable(initialValue, trainable = true, name, dtype) { + name = name || this.nextVariableId().toString(); + if (dtype != null && dtype !== initialValue.dtype) { + initialValue = initialValue.cast(dtype); + } + const v = new Variable(initialValue, trainable, name, this.nextTensorId()); + if (this.state.registeredVariables[v.name] != null) { + throw new Error(`Variable with name ${v.name} was already registered`); + } + this.state.registeredVariables[v.name] = v; + this.incRef(v, this.backend); + return v; + } + trackTensor(a, backend) { + this.state.numTensors++; + if (a.dtype === 'string') { + this.state.numStringTensors++; + } + // Bytes for complex numbers are counted by their components. Bytes for + // string tensors are counted when writing values. + let bytes = 0; + if (a.dtype !== 'complex64' && a.dtype !== 'string') { + bytes = a.size * bytesPerElement(a.dtype); + } + this.state.numBytes += bytes; + if (!this.state.tensorInfo.has(a.dataId)) { + this.state.numDataBuffers++; + this.state.tensorInfo.set(a.dataId, { + backend: backend || this.backend, + dtype: a.dtype, + shape: a.shape, + bytes + }); + } + if (!(a instanceof Variable)) { + this.track(a); + } + } + // Track the tensor by dataId and increase the refCount for the dataId in the + // backend. + // TODO(pyu10055): This is currently used by makeVariable method, to increase + // refCount on the backend for the dataId. It can potentially be replaced with + // Identity op indead of calling backend directly. + incRef(a, backend) { + this.trackTensor(a, backend); + this.backend.incRef(a.dataId); + } + removeDataId(dataId, backend) { + if (this.state.tensorInfo.has(dataId) && + this.state.tensorInfo.get(dataId).backend === backend) { + this.state.tensorInfo.delete(dataId); + this.state.numDataBuffers--; + } + } + disposeTensor(a) { + if (!this.state.tensorInfo.has(a.dataId)) { + return; + } + const info = this.state.tensorInfo.get(a.dataId); + this.state.numTensors--; + if (a.dtype === 'string') { + this.state.numStringTensors--; + this.state.numBytes -= info.bytes; + } + // Don't count bytes for complex numbers as they are counted by their + // components. + if (a.dtype !== 'complex64' && a.dtype !== 'string') { + const bytes = a.size * bytesPerElement(a.dtype); + this.state.numBytes -= bytes; + } + // Remove the reference to dataId if backend dispose the data successfully + if (info.backend.disposeData(a.dataId)) { + this.removeDataId(a.dataId, info.backend); + } + // TODO(nsthorat): Construct an error and save the stack trace for + // debugging when in debug mode. Creating a stack trace is too expensive + // to do unconditionally. + } + disposeVariables() { + for (const varName in this.state.registeredVariables) { + const v = this.state.registeredVariables[varName]; + this.disposeVariable(v); + } + } + disposeVariable(v) { + this.disposeTensor(v); + if (this.state.registeredVariables[v.name] != null) { + delete this.state.registeredVariables[v.name]; + } + } + memory() { + const info = this.backend.memory(); + info.numTensors = this.state.numTensors; + info.numDataBuffers = this.state.numDataBuffers; + info.numBytes = this.state.numBytes; + if (this.state.numStringTensors > 0) { + info.unreliable = true; + if (info.reasons == null) { + info.reasons = []; + } + info.reasons.push('Memory usage by string tensors is approximate ' + + '(2 bytes per character)'); + } + return info; + } + async profile(query) { + this.state.profiling = true; + const startBytes = this.state.numBytes; + const startNumTensors = this.state.numTensors; + this.state.activeProfile.kernels = []; + this.state.activeProfile.result = await query(); + this.state.profiling = false; + this.state.activeProfile.peakBytes = Math.max(...this.state.activeProfile.kernels.map(d => d.totalBytesSnapshot)); + this.state.activeProfile.newBytes = this.state.numBytes - startBytes; + this.state.activeProfile.newTensors = + this.state.numTensors - startNumTensors; + for (const kernel of this.state.activeProfile.kernels) { + kernel.kernelTimeMs = await kernel.kernelTimeMs; + kernel.extraInfo = await kernel.extraInfo; + } + return this.state.activeProfile; + } + isTapeOn() { + return this.state.gradientDepth > 0 && this.state.kernelDepth === 0; + } + addTapeNode(kernelName, inputs, outputs, gradientsFunc, saved, attrs) { + const tapeNode = { id: this.state.nextTapeNodeId++, kernelName, inputs, outputs, saved }; + const gradConfig = getGradient(kernelName); + if (gradConfig != null) { + gradientsFunc = gradConfig.gradFunc; + } + if (gradientsFunc != null) { + tapeNode.gradient = (dys) => { + // TODO(smilkov): To optimize back-prop, pass dys that are not used in + // the backprop graph to the user as null instead of zeros + dys = dys.map((dy, i) => { + if (dy == null) { + const output = outputs[i]; + const vals = makeZerosTypedArray(output.size, output.dtype); + return this.makeTensor(vals, output.shape, output.dtype); + } + return dy; + }); + // Grad functions of ops with single outputs expect a dy, while ops + // with multiple outputs expect dys (array of dy). + return gradientsFunc(dys.length > 1 ? dys : dys[0], saved, attrs); + }; + } + this.state.activeTape.push(tapeNode); + } + keep(result) { + result.kept = true; + return result; + } + startTape() { + if (this.state.gradientDepth === 0) { + this.state.activeTape = []; + } + this.state.gradientDepth++; + } + endTape() { + this.state.gradientDepth--; + } + /** + * Start a scope. Use this with endScope() to achieve the same functionality + * as scope() without the need for a function closure. + */ + startScope(name) { + const scopeInfo = { + track: [], + name: 'unnamed scope', + id: this.state.nextScopeId++ + }; + if (name) { + scopeInfo.name = name; + } + this.state.scopeStack.push(scopeInfo); + this.state.activeScope = scopeInfo; + } + /** + * End a scope. Use this with startScope() to achieve the same functionality + * as scope() without the need for a function closure. + */ + endScope(result) { + const tensorsToTrackInParent = getTensorsInContainer(result); + const tensorsToTrackInParentSet = new Set(tensorsToTrackInParent.map(t => t.id)); + // Dispose the arrays tracked in this scope. + for (let i = 0; i < this.state.activeScope.track.length; i++) { + const tensor = this.state.activeScope.track[i]; + if (!tensor.kept && !tensorsToTrackInParentSet.has(tensor.id)) { + tensor.dispose(); + } + } + const oldScope = this.state.scopeStack.pop(); + this.state.activeScope = this.state.scopeStack.length === 0 ? + null : + this.state.scopeStack[this.state.scopeStack.length - 1]; + // Track the current result in the parent scope. + tensorsToTrackInParent.forEach(tensor => { + // Only track the tensor if was allocated in the inner scope and is not + // globally kept. + if (!tensor.kept && tensor.scopeId === oldScope.id) { + this.track(tensor); + } + }); + } + /** + * Returns gradients of `f` with respect to each of the `xs`. The gradients + * returned are of the same length as `xs`, but some might be null if `f` + * was not a function of that `x`. It also takes optional dy to multiply the + * gradient, which defaults to `1`. + */ + gradients(f, xs, dy, allowNoGradients = false) { + assert$1(xs.length > 0, () => 'gradients() received an empty list of xs.'); + if (dy != null && dy.dtype !== 'float32') { + throw new Error(`dy must have 'float32' dtype, but has '${dy.dtype}'`); + } + const y = this.scopedRun(() => this.startTape(), () => this.endTape(), () => this.tidy('forward', f)); + assert$1(y instanceof Tensor, () => 'The result y returned by f() must be a tensor.'); + // Filter out the nodes that don't connect x => y. + const filteredTape = getFilteredNodesXToY(this.state.activeTape, xs, y); + if (!allowNoGradients && filteredTape.length === 0 && xs.length > 0) { + throw new Error('Cannot compute gradient of y=f(x) with respect to x. Make sure ' + + 'that the f you passed encloses all operations that lead from x ' + + 'to y.'); + } + return this.tidy('backward', () => { + const accumulatedGradientMap = {}; + accumulatedGradientMap[y.id] = (dy == null) ? ones$2(y.shape) : dy; + // Backprop gradients through the filtered nodes. + backpropagateGradients(accumulatedGradientMap, filteredTape, + // Pass the tidy function to avoid circular dep with `tape.ts`. + f => this.tidy(f), + // Pass an add function to avoide a circular dep with `tape.ts`. + add$4); + const grads = xs.map(x => accumulatedGradientMap[x.id]); + if (this.state.gradientDepth === 0) { + // This means that we are not computing higher-order gradients + // and can clean up the tape. + this.state.activeTape.forEach(node => { + for (const tensor of node.saved) { + tensor.dispose(); + } + }); + this.state.activeTape = null; + } + return { value: y, grads }; + }); + } + customGrad(f) { + assert$1(isFunction(f), () => 'The f passed in customGrad(f) must be a function.'); + return (...inputs) => { + assert$1(inputs.every(t => t instanceof Tensor), () => 'The args passed in customGrad(f)(x1, x2,...) must all be ' + + 'tensors'); + let res; + const inputMap = {}; + inputs.forEach((input, i) => { + inputMap[i] = input; + }); + const forwardFunc = (_, save) => { + res = f(...[...inputs, save]); + assert$1(res.value instanceof Tensor, () => 'The function f passed in customGrad(f) must return an ' + + 'object where `obj.value` is a tensor'); + assert$1(isFunction(res.gradFunc), () => 'The function f passed in customGrad(f) must return an ' + + 'object where `obj.gradFunc` is a function.'); + return res.value; + }; + const backwardsFunc = (dy, saved) => { + const gradRes = res.gradFunc(dy, saved); + const grads = Array.isArray(gradRes) ? gradRes : [gradRes]; + assert$1(grads.length === inputs.length, () => 'The function f passed in customGrad(f) must return an ' + + 'object where `obj.gradFunc` is a function that returns ' + + 'the same number of tensors as inputs passed to f(...).'); + assert$1(grads.every(t => t instanceof Tensor), () => 'The function f passed in customGrad(f) must return an ' + + 'object where `obj.gradFunc` is a function that returns ' + + 'a list of only tensors.'); + const gradMap = {}; + grads.forEach((grad, i) => { + gradMap[i] = () => grad; + }); + return gradMap; + }; + return this.runKernelFunc({ + forwardFunc, + backwardsFunc, + inputs: inputMap, + }); + }; + } + readSync(dataId) { + // Route the read to the correct backend. + const info = this.state.tensorInfo.get(dataId); + return info.backend.readSync(dataId); + } + read(dataId) { + // Route the read to the correct backend. + const info = this.state.tensorInfo.get(dataId); + return info.backend.read(dataId); + } + readToGPU(dataId, options) { + // Route the read to the correct backend. + const info = this.state.tensorInfo.get(dataId); + return info.backend.readToGPU(dataId, options); + } + async time(query) { + const start = now(); + const timingInfo = await this.backend.time(query); + timingInfo.wallMs = now() - start; + return timingInfo; + } + /** + * Tracks a Tensor in the current scope to be automatically cleaned up + * when the current scope ends, and returns the value. + * + * @param result The Tensor to track in the current scope. + */ + track(result) { + if (this.state.activeScope != null) { + result.scopeId = this.state.activeScope.id; + this.state.activeScope.track.push(result); + } + return result; + } + get registeredVariables() { + return this.state.registeredVariables; + } + /** + * Resets the engine state. Removes all backends but does not remove + * registered backend factories. + */ + reset() { + // Make any pending promise obsolete. + this.pendingBackendInitId++; + this.state.dispose(); + this.ENV.reset(); + this.state = new EngineState(); + for (const backendName in this.registry) { + this.disposeRegisteredKernels(backendName); + this.registry[backendName].dispose(); + delete this.registry[backendName]; + } + this.backendName = null; + this.backendInstance = null; + this.pendingBackendInit = null; + } + } + Engine.nextTensorId = 0; + Engine.nextVariableId = 0; + function ones$2(shape) { + const values = makeOnesTypedArray(sizeFromShape(shape), 'float32'); + return ENGINE.makeTensor(values, shape, 'float32'); + } + function getOrMakeEngine() { + const ns = getGlobalNamespace(); + if (ns._tfengine == null) { + const environment = new Environment(ns); + ns._tfengine = new Engine(environment); + } + setEnvironmentGlobal(ns._tfengine.ENV); + // Tell the current tensor interface that the global engine is responsible + // for tracking. + setTensorTracker(() => ns._tfengine); + return ns._tfengine; + } + const ENGINE = getOrMakeEngine(); + /** + * A implementation of the add op for use within engine and tape. + * + * This allows us to avoid a circular dependency between add.ts and engine. + * It is exported to be available in tape tests. + */ + function add$4(a, b) { + // We duplicate Add here to avoid a circular dependency with add.ts. + const inputs = { a, b }; + return ENGINE.runKernel(Add$1, inputs); + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // tslint:disable-next-line:no-any + function _isNavigatorDefined() { + return typeof navigator !== 'undefined' && navigator != null; + } + let isMobileMockValue; + function mockIsMobile(value) { + isMobileMockValue = value; + } + function isMobile(nav) { + if (isMobileMockValue !== undefined) { + return isMobileMockValue; + } + if (nav || _isNavigatorDefined()) { + if (!nav) { + nav = navigator; + } + if (nav.product === 'ReactNative') { + return true; + } + const a = nav.userAgent || nav.vendor || + // tslint:disable-next-line:no-any + (typeof window !== 'undefined' ? window.opera : ''); + // Use `navigator.userAgentData.mobile` as fallback. + if (!a) { + // tslint:disable-next-line:no-any + const navAny = nav; + return navAny.userAgentData && navAny.userAgentData.mobile; + } + // tslint:disable-next-line:max-line-length + return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i + .test(a) || + // tslint:disable-next-line:max-line-length + /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i + .test(a.substr(0, 4)); + } + return false; + } + function isBrowser() { + return (typeof window !== 'undefined' && window.document != null) || + //@ts-ignore + (typeof WorkerGlobalScope !== 'undefined'); + } + + var device_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + isBrowser: isBrowser, + isMobile: isMobile, + mockIsMobile: mockIsMobile + }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ENV$3 = env(); + /** + * This file contains environment-related flag registrations. + */ + /** Whether to enable debug mode. */ + ENV$3.registerFlag('DEBUG', () => false, debugValue => { + if (debugValue) { + console.warn('Debugging mode is ON. The output of every math call will ' + + 'be downloaded to CPU and checked for NaNs. ' + + 'This significantly impacts performance.'); + } + }); + /** Whether we are in a browser (as versus, say, node.js) environment. */ + ENV$3.registerFlag('IS_BROWSER', () => isBrowser()); + /** Whether we are in a browser (as versus, say, node.js) environment. */ + ENV$3.registerFlag('IS_NODE', () => (typeof process !== 'undefined') && + (typeof process.versions !== 'undefined') && + (typeof process.versions.node !== 'undefined')); + /** Whether this browser is Chrome. */ + ENV$3.registerFlag('IS_CHROME', () => typeof navigator !== 'undefined' && navigator != null && + navigator.userAgent != null && /Chrome/.test(navigator.userAgent) && + /Google Inc/.test(navigator.vendor)); + /** Whether this browser is Safari. */ + ENV$3.registerFlag('IS_SAFARI', () => typeof navigator !== 'undefined' && navigator != null && + navigator.userAgent != null && /Safari/.test(navigator.userAgent) && + /Apple/.test(navigator.vendor)); + /** + * True when the environment is "production" where we disable safety checks + * to gain performance. + */ + ENV$3.registerFlag('PROD', () => false); + /** + * Whether to do sanity checks when inferring a shape from user-provided + * values, used when creating a new tensor. + */ + ENV$3.registerFlag('TENSORLIKE_CHECK_SHAPE_CONSISTENCY', () => ENV$3.getBool('DEBUG')); + /** Whether deprecation warnings are enabled. */ + ENV$3.registerFlag('DEPRECATION_WARNINGS_ENABLED', () => true); + /** True if running unit tests. */ + ENV$3.registerFlag('IS_TEST', () => false); + /** Whether to check computation result for errors. */ + ENV$3.registerFlag('CHECK_COMPUTATION_FOR_ERRORS', () => ENV$3.getBool('DEBUG')); + /** Whether the backend needs to wrap input to imageBitmap. */ + ENV$3.registerFlag('WRAP_TO_IMAGEBITMAP', () => false); + /** Whether to enable canvas2d willReadFrequently for GPU backends */ + ENV$3.registerFlag('CANVAS2D_WILL_READ_FREQUENTLY_FOR_GPU', () => false); + /** Whether to use setTimeoutCustom */ + ENV$3.registerFlag('USE_SETTIMEOUTCUSTOM', () => false); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function inferShape(val, dtype) { + let firstElem = val; + if (isTypedArray(val)) { + return dtype === 'string' ? [] : [val.length]; + } + if (isWebGLData(val)) { + const usedChannels = val.channels || 'RGBA'; + return [val.height, val.width * usedChannels.length]; + } + else if (isWebGPUData(val)) { + return [val.buffer.size / (dtype == null ? 4 : bytesPerElement(dtype))]; + } + if (!Array.isArray(val)) { + return []; // Scalar. + } + const shape = []; + while (Array.isArray(firstElem) || + isTypedArray(firstElem) && dtype !== 'string') { + shape.push(firstElem.length); + firstElem = firstElem[0]; + } + if (Array.isArray(val) && + env().getBool('TENSORLIKE_CHECK_SHAPE_CONSISTENCY')) { + deepAssertShapeConsistency(val, shape, []); + } + return shape; + } + function deepAssertShapeConsistency(val, shape, indices) { + indices = indices || []; + if (!(Array.isArray(val)) && !isTypedArray(val)) { + assert$1(shape.length === 0, () => `Element arr[${indices.join('][')}] is a primitive, ` + + `but should be an array/TypedArray of ${shape[0]} elements`); + return; + } + assert$1(shape.length > 0, () => `Element arr[${indices.join('][')}] should be a primitive, ` + + `but is an array of ${val.length} elements`); + assert$1(val.length === shape[0], () => `Element arr[${indices.join('][')}] should have ${shape[0]} ` + + `elements, but has ${val.length} elements`); + const subShape = shape.slice(1); + for (let i = 0; i < val.length; ++i) { + deepAssertShapeConsistency(val[i], subShape, indices.concat(i)); + } + } + function assertDtype(expectedDtype, actualDType, argName, functionName) { + if (expectedDtype === 'string_or_numeric') { + return; + } + if (expectedDtype == null) { + throw new Error(`Expected dtype cannot be null.`); + } + if (expectedDtype !== 'numeric' && expectedDtype !== actualDType || + expectedDtype === 'numeric' && actualDType === 'string') { + throw new Error(`Argument '${argName}' passed to '${functionName}' must ` + + `be ${expectedDtype} tensor, but got ${actualDType} tensor`); + } + } + function convertToTensor(x, argName, functionName, parseAsDtype = 'numeric') { + if (x instanceof getGlobalTensorClass()) { + assertDtype(parseAsDtype, x.dtype, argName, functionName); + return x; + } + let inferredDtype = inferDtype(x); + // If the user expects a bool/int/float, use that info to update the + // inferredDtype when it is not a string. + if (inferredDtype !== 'string' && + ['bool', 'int32', 'float32'].indexOf(parseAsDtype) >= 0) { + inferredDtype = parseAsDtype; + } + assertDtype(parseAsDtype, inferredDtype, argName, functionName); + if ((x == null) || + (!isTypedArray(x) && !Array.isArray(x) && typeof x !== 'number' && + typeof x !== 'boolean' && typeof x !== 'string')) { + const type = x == null ? 'null' : x.constructor.name; + throw new Error(`Argument '${argName}' passed to '${functionName}' must be a ` + + `Tensor or TensorLike, but got '${type}'`); + } + const inferredShape = inferShape(x, inferredDtype); + if (!isTypedArray(x) && !Array.isArray(x)) { + x = [x]; + } + const skipTypedArray = true; + const values = inferredDtype !== 'string' ? + toTypedArray(x, inferredDtype) : + flatten$2(x, [], skipTypedArray); + return ENGINE.makeTensor(values, inferredShape, inferredDtype); + } + function convertToTensorArray(arg, argName, functionName, parseAsDtype = 'numeric') { + if (!Array.isArray(arg)) { + throw new Error(`Argument ${argName} passed to ${functionName} must be a ` + + '`Tensor[]` or `TensorLike[]`'); + } + const tensors = arg; + return tensors.map((t, i) => convertToTensor(t, `${argName}[${i}]`, functionName, parseAsDtype)); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const OP_SCOPE_SUFFIX = '__op'; + /** + * Used for wrapping functions that perform math operations on + * Tensors. The function will be wrapped in a named scope that cleans all + * memory usage after the function is done. + */ + function op(f) { + const keys = Object.keys(f); + if (keys.length !== 1) { + throw new Error(`Please provide an object with a single key ` + + `(operation name) mapping to a function. Got an object with ` + + `${keys.length} keys.`); + } + let opName = keys[0]; + const fn = f[opName]; + // Strip the underscore from the end of the function name. + if (opName.endsWith('_')) { + opName = opName.substring(0, opName.length - 1); + } + // add an __op suffix to distinguish ops from kernels in tf.profile + opName = opName + OP_SCOPE_SUFFIX; + // tslint:disable-next-line:no-any + const f2 = (...args) => { + ENGINE.startScope(opName); + try { + const result = fn(...args); + if (isPromise(result)) { + console.error('Cannot return a Promise inside of tidy.'); + } + ENGINE.endScope(result); + return result; + } + catch (ex) { + ENGINE.endScope(null); + throw ex; + } + }; + Object.defineProperty(f2, 'name', { value: opName, configurable: true }); + // tslint:disable-next-line:no-any + return f2; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts two real numbers to a complex number. + * + * Given a tensor `real` representing the real part of a complex number, and a + * tensor `imag` representing the imaginary part of a complex number, this + * operation returns complex numbers elementwise of the form [r0, i0, r1, i1], + * where r represents the real part and i represents the imag part. + * + * The input tensors real and imag must have the same shape. + * + * ```js + * const real = tf.tensor1d([2.25, 3.25]); + * const imag = tf.tensor1d([4.75, 5.75]); + * const complex = tf.complex(real, imag); + * + * complex.print(); + * ``` + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function complex_(real, imag) { + const $real = convertToTensor(real, 'real', 'complex'); + const $imag = convertToTensor(imag, 'imag', 'complex'); + assertShapesMatch($real.shape, $imag.shape, `real and imag shapes, ${$real.shape} and ${$imag.shape}, ` + + `must match in call to tf.complex().`); + const inputs = { real: $real, imag: $imag }; + return ENGINE.runKernel(Complex, inputs); + } + const complex$2 = /* @__PURE__ */ op({ complex_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** This is shared code across all tensor creation methods. */ + function makeTensor(values, shape, inferredShape, dtype) { + if (dtype == null) { + dtype = inferDtype(values); + } + else if (dtype === 'complex64') { + throw new Error(`Cannot construct a complex64 tensor directly. ` + + `Please use tf.complex(real, imag).`); + } + if (isWebGPUData(values) || isWebGLData(values)) { + if (dtype !== 'float32' && dtype !== 'int32') { + throw new Error(`Creating tensor from GPU data only supports ` + + `'float32'|'int32' dtype, while the dtype is ${dtype}.`); + } + return ENGINE.backend.createTensorFromGPUData(values, shape || inferredShape, dtype); + } + if (!isTypedArray(values) && !Array.isArray(values) && + typeof values !== 'number' && typeof values !== 'boolean' && + typeof values !== 'string') { + throw new Error('values passed to tensor(values) must be a number/boolean/string or ' + + 'an array of numbers/booleans/strings, or a TypedArray'); + } + // Verify that the shape matches the inferred shape. + if (shape != null) { + assertNonNegativeIntegerDimensions(shape); + const providedSize = sizeFromShape(shape); + const inferredSize = sizeFromShape(inferredShape); + assert$1(providedSize === inferredSize, () => `Based on the provided shape, [${shape}], the tensor should have ` + + `${providedSize} values but has ${inferredSize}`); + for (let i = 0; i < inferredShape.length; ++i) { + const inferred = inferredShape[i]; + const flatDimsDontMatch = i === inferredShape.length - 1 ? + inferred !== sizeFromShape(shape.slice(i)) : + true; + assert$1(inferredShape[i] === shape[i] || !flatDimsDontMatch, () => `Error creating a new Tensor. Inferred shape ` + + `(${inferredShape}) does not match the provided ` + + `shape (${shape}). `); + } + } + if (!isTypedArray(values) && !Array.isArray(values)) { + values = [values]; + } + shape = shape || inferredShape; + values = dtype !== 'string' ? + toTypedArray(values, dtype) : + flatten$2(values, [], true); + return ENGINE.makeTensor(values, shape, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with the provided values, shape and dtype. + * + * ```js + * // Pass an array of values to create a vector. + * tf.tensor([1, 2, 3, 4]).print(); + * ``` + * + * ```js + * // Pass a nested array of values to make a matrix or a higher + * // dimensional tensor. + * tf.tensor([[1, 2], [3, 4]]).print(); + * ``` + * + * ```js + * // Pass a flat array and specify a shape yourself. + * tf.tensor([1, 2, 3, 4], [2, 2]).print(); + * ``` + * + * ```js + * // Pass a `WebGLData` object and specify a shape yourself. + * + * // This makes it possible for TF.js applications to avoid GPU / CPU sync. + * // For example, if your application includes a preprocessing step on the GPU, + * // you could upload the GPU output directly to TF.js, rather than first + * // downloading the values. + * + * // Example for WebGL2: + * if (tf.findBackend('custom-webgl') == null) { + * const customCanvas = document.createElement('canvas'); + * const customBackend = new tf.MathBackendWebGL(customCanvas); + * tf.registerBackend('custom-webgl', () => customBackend); + * } + * const savedBackend = tf.getBackend(); + * await tf.setBackend('custom-webgl'); + * const gl = tf.backend().gpgpu.gl; + * const texture = gl.createTexture(); + * const tex2d = gl.TEXTURE_2D; + * const width = 2; + * const height = 2; + * + * gl.bindTexture(tex2d, texture); + * gl.texParameteri(tex2d, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + * gl.texParameteri(tex2d, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + * gl.texParameteri(tex2d, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + * gl.texParameteri(tex2d, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + * gl.texImage2D( + * tex2d, 0, gl.RGBA32F, // internalFormat + * width, height, 0, + * gl.RGBA, // textureFormat + * gl.FLOAT, // textureType + * new Float32Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) + * ); + * + * // Currently, the `texture` has 4 pixels: + * // Pixel0 is {R:0, G:1, B:2, A:3} + * // Pixel1 is {R:4, G:5, B:6, A:7} + * // Pixel2 is {R:8, G:9, B:10, A:11} + * // Pixel3 is {R:12, G:13, B:14, A:15} + * + * const logicalShape = [height * width * 2]; + * const a = tf.tensor({texture, height, width, channels: 'BR'}, logicalShape); + * a.print(); + * // Tensor value will be [2, 0, 6, 4, 10, 8, 14, 12], since [2, 0] is the + * // values of 'B' and 'R' channels of Pixel0, [6, 4] is the values of 'B' and + * 'R' + * // channels of Pixel1... + * + * // For postprocessing on the GPU, it's possible to retrieve the texture + * // backing any tensor by calling the tensor's `dataToGPU` method like + * // so: + * + * const tex = a.dataToGPU(); + * await tf.setBackend(savedBackend); + * ``` + * + * ```js + * // Pass a `WebGPUData` object and specify a shape yourself. + * + * // This makes it possible for TF.js applications to avoid GPU / CPU sync. + * // For example, if your application includes a preprocessing step on the GPU, + * // you could upload the GPU output directly to TF.js, rather than first + * // downloading the values. Unlike WebGL, this optionally supports zero copy + * // by WebGPUData.zeroCopy. When zeroCopy is false or undefined(default), this + * // passing GPUBuffer can be destroyed after tensor is created. When zeroCopy + * // is true, this GPUBuffer is bound directly by the tensor, so do not destroy + * // this GPUBuffer until all access is done. + * + * // Example for WebGPU: + * function createGPUBufferFromData(device, data, dtype) { + * const bytesPerElement = 4; + * const sizeInBytes = data.length * bytesPerElement; + * + * const gpuWriteBuffer = device.createBuffer({ + * mappedAtCreation: true, + * size: sizeInBytes, + * usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.COPY_SRC + * }); + * const arrayBuffer = gpuWriteBuffer.getMappedRange(); + * if (dtype === 'float32') { + * new Float32Array(arrayBuffer).set(data); + * } else if (dtype === 'int32') { + * new Int32Array(arrayBuffer).set(data); + * } else { + * throw new Error( + * `Creating tensor from GPUBuffer only supports` + + * `'float32'|'int32' dtype, while the dtype is ${dtype}.`); + * } + * gpuWriteBuffer.unmap(); + * + * const gpuReadBuffer = device.createBuffer({ + * mappedAtCreation: false, + * size: sizeInBytes, + * usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.STORAGE | + * GPUBufferUsage.COPY_SRC + * }); + * + * const copyEncoder = device.createCommandEncoder(); + * copyEncoder.copyBufferToBuffer( + * gpuWriteBuffer, 0, gpuReadBuffer, 0, sizeInBytes); + * const copyCommands = copyEncoder.finish(); + * device.queue.submit([copyCommands]); + * gpuWriteBuffer.destroy(); + * return gpuReadBuffer; + * } + * + * const savedBackend = tf.getBackend(); + * await tf.setBackend('webgpu').catch( + * () => {throw new Error( + * 'Failed to use WebGPU backend. Please use Chrome Canary to run.')}); + * const dtype = 'float32'; + * const device = tf.backend().device; + * const aData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + * const bData = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; + * const expected = [2, 4, 6, 8, 6, 8, 10, 12, 10, 12, 14, 16, 14, 16, 18, 20]; + * const aBuffer = createGPUBufferFromData(device, aData, dtype); + * const shape = [aData.length]; + * // To use zeroCopy, use {buffer: aBuffer, zeroCopy: true} instead and destroy + * // aBuffer untill all access is done. + * const a = tf.tensor({buffer: aBuffer}, shape, dtype); + * const b = tf.tensor(bData, shape, dtype); + * const result = tf.add(a, b); + * result.print(); + * a.dispose(); + * b.dispose(); + * result.dispose(); + * aBuffer.destroy(); + * await tf.setBackend(savedBackend); + * ``` + * @param values The values of the tensor. Can be nested array of numbers, + * or a flat array, or a `TypedArray`(At the moment it supports Uint8Array, + * Uint8ClampedArray, Int32Array, Float32Array) data types, or a `WebGLData` + * object, or a `WebGPUData` object. If the values are strings, they will be + * encoded as utf-8 and kept as `Uint8Array[]`. If the values is a `WebGLData` + * object, the dtype could only be 'float32' or 'int32' and the object has to + * have: 1. texture, a `WebGLTexture`, the texture must share the same + * `WebGLRenderingContext` with TFJS's WebGL backend (you could create a custom + * WebGL backend from your texture's canvas) and the internal texture format + * for the input texture must be floating point or normalized integer; 2. + * height, the height of the texture; 3. width, the width of the texture; 4. + * channels, a non-empty subset of 'RGBA', indicating the values of which + * channels will be passed to the tensor, such as 'R' or 'BR' (The order of the + * channels affect the order of tensor values. ). (If the values passed from + * texture is less than the tensor size, zeros will be padded at the rear.). If + * the values is a `WebGPUData` object, the dtype could only be 'float32' or + * 'int32 and the object has to have: buffer, a `GPUBuffer`. The buffer must: + * 1. share the same `GPUDevice` with TFJS's WebGPU backend; 2. buffer.usage + * should at least support GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC; 3. + * buffer.size should not be smaller than the byte size of tensor shape. + * WebGPUData optionally supports zero copy by flag zeroCopy. When zeroCopy is + * false or undefined(default),this passing GPUBuffer can be destroyed after + * tensor is created. When zeroCopy is true, this GPUBuffer is bound directly + * by the tensor, so do not destroy this GPUBuffer until all access is done. + * @param shape The shape of the tensor. Optional. If not provided, + * it is inferred from `values`. + * @param dtype The data type. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function tensor(values, shape, dtype) { + const inferredShape = inferShape(values, dtype); + return makeTensor(values, shape, inferredShape, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /* Type definitions for exporting and importing of models. */ + /** + * A map from Tensor dtype to number of bytes per element of the Tensor. + */ + const DTYPE_VALUE_SIZE_MAP = { + 'float32': 4, + 'float16': 2, + 'int32': 4, + 'uint16': 2, + 'uint8': 1, + 'bool': 1, + 'complex64': 8 + }; + + /** + * Wraps a list of ArrayBuffers into a `slice()`-able object without allocating + * a large ArrayBuffer. + * + * Allocating large ArrayBuffers (~2GB) can be unstable on Chrome. TFJS loads + * its weights as a list of (usually) 4MB ArrayBuffers and then slices the + * weight tensors out of them. For small models, it's safe to concatenate all + * the weight buffers into a single ArrayBuffer and then slice the weight + * tensors out of it, but for large models, a different approach is needed. + */ + class CompositeArrayBuffer { + /** + * Concatenate a number of ArrayBuffers into one. + * + * @param buffers An array of ArrayBuffers to concatenate, or a single + * ArrayBuffer. + * @returns Result of concatenating `buffers` in order. + */ + static join(buffers) { + return new CompositeArrayBuffer(buffers).slice(); + } + constructor(buffers) { + this.shards = []; + this.previousShardIndex = 0; + if (buffers == null) { + return; + } + // Normalize the `buffers` input to be `ArrayBuffer[]`. + if (!(buffers instanceof Array)) { + buffers = [buffers]; + } + buffers = buffers.map((bufferOrTypedArray) => { + if (isTypedArray(bufferOrTypedArray)) { + return bufferOrTypedArray.buffer; + } + return bufferOrTypedArray; + }); + // Skip setting up shards if there are no buffers. + if (buffers.length === 0) { + return; + } + this.bufferUniformSize = buffers[0].byteLength; + let start = 0; + for (let i = 0; i < buffers.length; i++) { + const buffer = buffers[i]; + // Check that all buffers except the last one have the same length. + if (i !== buffers.length - 1 && + buffer.byteLength !== this.bufferUniformSize) { + // Unset the buffer uniform size, since the buffer sizes are not + // uniform. + this.bufferUniformSize = undefined; + } + // Create the shards, including their start and end points. + const end = start + buffer.byteLength; + this.shards.push({ buffer, start, end }); + start = end; + } + // Set the byteLength + if (this.shards.length === 0) { + this.byteLength = 0; + } + this.byteLength = this.shards[this.shards.length - 1].end; + } + slice(start = 0, end = this.byteLength) { + // If there are no shards, then the CompositeArrayBuffer was initialized + // with no data. + if (this.shards.length === 0) { + return new ArrayBuffer(0); + } + // NaN is treated as zero for slicing. This matches ArrayBuffer's behavior. + start = isNaN(Number(start)) ? 0 : start; + end = isNaN(Number(end)) ? 0 : end; + // Fix the bounds to within the array. + start = Math.max(0, start); + end = Math.min(this.byteLength, end); + if (end <= start) { + return new ArrayBuffer(0); + } + const startShardIndex = this.findShardForByte(start); + if (startShardIndex === -1) { + // This should not happen since the start and end indices are always + // within 0 and the composite array's length. + throw new Error(`Could not find start shard for byte ${start}`); + } + const size = end - start; + const outputBuffer = new ArrayBuffer(size); + const outputArray = new Uint8Array(outputBuffer); + let sliced = 0; + for (let i = startShardIndex; i < this.shards.length; i++) { + const shard = this.shards[i]; + const globalStart = start + sliced; + const localStart = globalStart - shard.start; + const outputStart = sliced; + const globalEnd = Math.min(end, shard.end); + const localEnd = globalEnd - shard.start; + const outputSlice = new Uint8Array(shard.buffer, localStart, localEnd - localStart); + outputArray.set(outputSlice, outputStart); + sliced += outputSlice.length; + if (end < shard.end) { + break; + } + } + return outputBuffer; + } + /** + * Get the index of the shard that contains the byte at `byteIndex`. + */ + findShardForByte(byteIndex) { + if (this.shards.length === 0 || byteIndex < 0 || + byteIndex >= this.byteLength) { + return -1; + } + // If the buffers have a uniform size, compute the shard directly. + if (this.bufferUniformSize != null) { + this.previousShardIndex = Math.floor(byteIndex / this.bufferUniformSize); + return this.previousShardIndex; + } + // If the buffers don't have a uniform size, we need to search for the + // shard. That means we need a function to check where the byteIndex lies + // relative to a given shard. + function check(shard) { + if (byteIndex < shard.start) { + return -1; + } + if (byteIndex >= shard.end) { + return 1; + } + return 0; + } + // For efficiency, try the previous shard first. + if (check(this.shards[this.previousShardIndex]) === 0) { + return this.previousShardIndex; + } + // Otherwise, use a generic search function. + // This should almost never end up being used in practice since the weight + // entries should always be in order. + const index = search(this.shards, check); + if (index === -1) { + return -1; + } + this.previousShardIndex = index; + return this.previousShardIndex; + } + } + /** + * Search for an element of a sorted array. + * + * @param sortedArray The sorted array to search + * @param compare A function to compare the current value against the searched + * value. Return 0 on a match, negative if the searched value is less than + * the value passed to the function, and positive if the searched value is + * greater than the value passed to the function. + * @returns The index of the element, or -1 if it's not in the array. + */ + function search(sortedArray, compare) { + // Binary search + let min = 0; + let max = sortedArray.length; + while (min <= max) { + const middle = Math.floor((max - min) / 2) + min; + const side = compare(sortedArray[middle]); + if (side === 0) { + return middle; + } + else if (side < 0) { + max = middle; + } + else { + min = middle + 1; + } + } + return -1; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Enables production mode which disables correctness checks in favor of + * performance. + * + * @doc {heading: 'Environment'} + */ + function enableProdMode() { + env().set('PROD', true); + } + /** + * Enables debug mode which will log information about all executed kernels: + * the elapsed time of the kernel execution, as well as the rank, shape, and + * size of the output tensor. + * + * Debug mode will significantly slow down your application as it will + * download the result of every operation to the CPU. This should not be used in + * production. Debug mode does not affect the timing information of the kernel + * execution as we do not measure download time in the kernel execution time. + * + * See also: `tf.profile`, `tf.memory`. + * + * @doc {heading: 'Environment'} + */ + function enableDebugMode() { + env().set('DEBUG', true); + } + /** Globally disables deprecation warnings */ + function disableDeprecationWarnings() { + env().set('DEPRECATION_WARNINGS_ENABLED', false); + console.warn(`TensorFlow.js deprecation warnings have been disabled.`); + } + /** Warn users about deprecated functionality. */ + function deprecationWarn(msg) { + if (env().getBool('DEPRECATION_WARNINGS_ENABLED')) { + console.warn(msg + ' You can disable deprecation warnings with ' + + 'tf.disableDeprecationWarnings().'); + } + } + setDeprecationWarningFn(deprecationWarn); + /** + * Dispose all variables kept in backend engine. + * + * @doc {heading: 'Environment'} + */ + function disposeVariables() { + ENGINE.disposeVariables(); + } + /** + * It returns the global engine that keeps track of all tensors and backends. + * + * @doc {heading: 'Environment'} + */ + function engine() { + return ENGINE; + } + /** + * Returns memory info at the current time in the program. The result is an + * object with the following properties: + * + * - `numBytes`: Number of bytes allocated (undisposed) at this time. + * - `numTensors`: Number of unique tensors allocated. + * - `numDataBuffers`: Number of unique data buffers allocated + * (undisposed) at this time, which is ≤ the number of tensors + * (e.g. `a.reshape(newShape)` makes a new Tensor that shares the same + * data buffer with `a`). + * - `unreliable`: True if the memory usage is unreliable. See `reasons` when + * `unreliable` is true. + * - `reasons`: `string[]`, reasons why the memory is unreliable, present if + * `unreliable` is true. + * + * WebGL Properties: + * - `numBytesInGPU`: Number of bytes allocated (undisposed) in the GPU only at + * this time. + * + * @doc {heading: 'Performance', subheading: 'Memory'} + */ + function memory() { + return ENGINE.memory(); + } + /** + * Executes the provided function `f()` and returns a promise that resolves + * with information about the function's memory use: + * - `newBytes`: the number of new bytes allocated + * - `newTensors`: the number of new tensors created + * - `peakBytes`: the peak number of bytes allocated + * - `kernels`: an array of objects for each kernel involved that reports + * their input and output shapes, number of bytes used, and number of new + * tensors created. + * - `kernelNames`: an array of unique strings with just the names of the + * kernels in the `kernels` array. + * + * ```js + * const profile = await tf.profile(() => { + * const x = tf.tensor1d([1, 2, 3]); + * let x2 = x.square(); + * x2.dispose(); + * x2 = x.square(); + * x2.dispose(); + * return x; + * }); + * + * console.log(`newBytes: ${profile.newBytes}`); + * console.log(`newTensors: ${profile.newTensors}`); + * console.log(`byte usage over all kernels: ${profile.kernels.map(k => + * k.totalBytesSnapshot)}`); + * ``` + * + * + * @doc {heading: 'Performance', subheading: 'Profile'} + */ + function profile(f) { + return ENGINE.profile(f); + } + /** + * Executes the provided function `fn` and after it is executed, cleans up all + * intermediate tensors allocated by `fn` except those returned by `fn`. + * `fn` must not return a Promise (async functions not allowed). The returned + * result can be a complex object. + * + * Using this method helps avoid memory leaks. In general, wrap calls to + * operations in `tf.tidy` for automatic memory cleanup. + * + * NOTE: Variables do *not* get cleaned up when inside a tidy(). If you want to + * dispose variables, please use `tf.disposeVariables` or call dispose() + * directly on variables. + * + * ```js + * // y = 2 ^ 2 + 1 + * const y = tf.tidy(() => { + * // a, b, and one will be cleaned up when the tidy ends. + * const one = tf.scalar(1); + * const a = tf.scalar(2); + * const b = a.square(); + * + * console.log('numTensors (in tidy): ' + tf.memory().numTensors); + * + * // The value returned inside the tidy function will return + * // through the tidy, in this case to the variable y. + * return b.add(one); + * }); + * + * console.log('numTensors (outside tidy): ' + tf.memory().numTensors); + * y.print(); + * ``` + * + * @param nameOrFn The name of the closure, or the function to execute. + * If a name is provided, the 2nd argument should be the function. + * If debug mode is on, the timing and the memory usage of the function + * will be tracked and displayed on the console using the provided name. + * @param fn The function to execute. + * + * @doc {heading: 'Performance', subheading: 'Memory'} + */ + function tidy(nameOrFn, fn) { + return ENGINE.tidy(nameOrFn, fn); + } + /** + * Disposes any `tf.Tensor`s found within the provided object. + * + * @param container an object that may be a `tf.Tensor` or may directly + * contain `tf.Tensor`s, such as a `Tensor[]` or `{key: Tensor, ...}`. If + * the object is not a `tf.Tensor` or does not contain `Tensors`, nothing + * happens. In general it is safe to pass any object here, except that + * `Promise`s are not supported. + * + * @doc {heading: 'Performance', subheading: 'Memory'} + */ + function dispose(container) { + const tensors = getTensorsInContainer(container); + tensors.forEach(tensor => tensor.dispose()); + } + /** + * Keeps a `tf.Tensor` generated inside a `tf.tidy` from being disposed + * automatically. + * + * ```js + * let b; + * const y = tf.tidy(() => { + * const one = tf.scalar(1); + * const a = tf.scalar(2); + * + * // b will not be cleaned up by the tidy. a and one will be cleaned up + * // when the tidy ends. + * b = tf.keep(a.square()); + * + * console.log('numTensors (in tidy): ' + tf.memory().numTensors); + * + * // The value returned inside the tidy function will return + * // through the tidy, in this case to the variable y. + * return b.add(one); + * }); + * + * console.log('numTensors (outside tidy): ' + tf.memory().numTensors); + * console.log('y:'); + * y.print(); + * console.log('b:'); + * b.print(); + * ``` + * + * @param result The tensor to keep from being disposed. + * + * @doc {heading: 'Performance', subheading: 'Memory'} + */ + function keep(result) { + return ENGINE.keep(result); + } + /** + * Executes `f()` and returns a promise that resolves with timing + * information. + * + * The result is an object with the following properties: + * + * - `wallMs`: Wall execution time. + * - `kernelMs`: Kernel execution time, ignoring data transfer. If using the + * WebGL backend and the query timer extension is not available, this will + * return an error object. + * - On `WebGL` The following additional properties exist: + * - `uploadWaitMs`: CPU blocking time on texture uploads. + * - `downloadWaitMs`: CPU blocking time on texture downloads (readPixels). + * + * ```js + * const x = tf.randomNormal([20, 20]); + * const time = await tf.time(() => x.matMul(x)); + * + * console.log(`kernelMs: ${time.kernelMs}, wallTimeMs: ${time.wallMs}`); + * ``` + * + * @param f The function to execute and time. + * + * @doc {heading: 'Performance', subheading: 'Timing'} + */ + function time(f) { + return ENGINE.time(f); + } + /** + * Sets the backend (cpu, webgl, wasm, etc) responsible for creating tensors and + * executing operations on those tensors. Returns a promise that resolves + * to a boolean if the backend initialization was successful. + * + * Note this disposes the current backend, if any, as well as any tensors + * associated with it. A new backend is initialized, even if it is of the + * same type as the previous one. + * + * @param backendName The name of the backend. Currently supports + * `'webgl'|'cpu'` in the browser, `'tensorflow'` under node.js + * (requires tfjs-node), and `'wasm'` (requires tfjs-backend-wasm). + * + * @doc {heading: 'Backends'} + */ + function setBackend$1(backendName) { + return ENGINE.setBackend(backendName); + } + /** + * Returns a promise that resolves when the currently selected backend (or the + * highest priority one) has initialized. Await this promise when you are using + * a backend that has async initialization. + * + * @doc {heading: 'Backends'} + */ + function ready() { + return ENGINE.ready(); + } + /** + * Returns the current backend name (cpu, webgl, etc). The backend is + * responsible for creating tensors and executing operations on those tensors. + * + * @doc {heading: 'Backends'} + */ + function getBackend$1() { + return ENGINE.backendName; + } + /** + * Removes a backend and the registered factory. + * + * @doc {heading: 'Backends'} + */ + function removeBackend(name) { + ENGINE.removeBackend(name); + } + /** + * Finds the backend registered under the provided name. Returns null if the + * name is not in the registry, or the registration hasn't finished yet. + */ + function findBackend(name) { + return ENGINE.findBackend(name); + } + /** + * Finds the backend factory registered under the provided name. Returns a + * function that produces a new backend when called. Returns null if the name + * is not in the registry. + */ + function findBackendFactory(name) { + return ENGINE.findBackendFactory(name); + } + /** + * Registers a global backend. The registration should happen when importing + * a module file (e.g. when importing `backend_webgl.ts`), and is used for + * modular builds (e.g. custom tfjs bundle with only webgl support). + * + * @param factory The backend factory function. When called, it should + * return a backend instance, or a promise of an instance. + * @param priority The priority of the backend (higher = more important). + * In case multiple backends are registered, the priority is used to find + * the best backend. Defaults to 1. + * @return False if there is already a registered backend under this name, true + * if not. + * + * @doc {heading: 'Backends'} + */ + function registerBackend(name, factory, priority = 1) { + return ENGINE.registerBackend(name, factory, priority); + } + /** + * Gets the current backend. If no backends have been initialized, this will + * attempt to initialize the best backend. Will throw an error if the highest + * priority backend has async initialization, in which case you should call + * 'await tf.ready()' before running other code. + * + * @doc {heading: 'Backends'} + */ + function backend$1() { + return ENGINE.backend; + } + /** + * Sets the global platform. + * + * @param platformName The name of this platform. + * @param platform A platform implementation. + */ + function setPlatform(platformName, platform) { + env().setPlatform(platformName, platform); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** Number of bytes reserved for the length of the string. (32bit integer). */ + const NUM_BYTES_STRING_LENGTH = 4; + /** + * Encode a map from names to weight values as an ArrayBuffer, along with an + * `Array` of `WeightsManifestEntry` as specification of the encoded weights. + * + * This function does not perform sharding. + * + * This function is the reverse of `decodeWeights`. + * + * @param tensors A map ("dict") from names to tensors. + * @param group Group to which the weights belong (optional). + * @returns A `Promise` of + * - A flat `ArrayBuffer` with all the binary values of the `Tensor`s + * concatenated. + * - An `Array` of `WeightManifestEntry`s, carrying information including + * tensor names, `dtype`s and shapes. + * @throws Error: on unsupported tensor `dtype`. + */ + async function encodeWeights(tensors, group) { + // TODO(adarob, cais): Support quantization. + const specs = []; + const dataPromises = []; + const names = Array.isArray(tensors) ? + tensors.map(tensor => tensor.name) : + Object.keys(tensors); + for (let i = 0; i < names.length; ++i) { + const name = names[i]; + const t = Array.isArray(tensors) ? tensors[i].tensor : tensors[name]; + if (t.dtype !== 'float32' && t.dtype !== 'int32' && t.dtype !== 'bool' && + t.dtype !== 'string' && t.dtype !== 'complex64') { + throw new Error(`Unsupported dtype in weight '${name}': ${t.dtype}`); + } + const spec = { name, shape: t.shape, dtype: t.dtype }; + if (t.dtype === 'string') { + const utf8bytes = new Promise(async (resolve) => { + const vals = await t.bytes(); + const totalNumBytes = vals.reduce((p, c) => p + c.length, 0) + + NUM_BYTES_STRING_LENGTH * vals.length; + const bytes = new Uint8Array(totalNumBytes); + let offset = 0; + for (let i = 0; i < vals.length; i++) { + const val = vals[i]; + const bytesOfLength = new Uint8Array(new Uint32Array([val.length]).buffer); + bytes.set(bytesOfLength, offset); + offset += NUM_BYTES_STRING_LENGTH; + bytes.set(val, offset); + offset += val.length; + } + resolve(bytes); + }); + dataPromises.push(utf8bytes); + } + else { + dataPromises.push(t.data()); + } + if (group != null) { + spec.group = group; + } + specs.push(spec); + } + const tensorValues = await Promise.all(dataPromises); + return { data: concatenateTypedArrays(tensorValues), specs }; + } + /** + * Decode flat ArrayBuffer as weights. + * + * This function does not handle sharding. + * + * This function is the reverse of `encodeWeights`. + * + * @param weightData A flat ArrayBuffer or an array of ArrayBuffers carrying the + * binary values of the tensors concatenated in the order specified in + * `specs`. + * @param specs Specifications of the names, dtypes and shapes of the tensors + * whose value are encoded by `buffer`. + * @return A map from tensor name to tensor value, with the names corresponding + * to names in `specs`. + * @throws Error, if any of the tensors has unsupported dtype. + */ + function decodeWeights(weightData, specs) { + // TODO(adarob, cais): Support quantization. + const compositeBuffer = new CompositeArrayBuffer(weightData); + const out = {}; + let offset = 0; + for (const spec of specs) { + const byteLength = getWeightBytelength(spec, (start, end) => { + return compositeBuffer.slice(offset + start, offset + end); + }); + out[spec.name] = decodeWeight(spec, compositeBuffer + .slice(offset, offset + byteLength)); + offset += byteLength; + } + return out; + } + function getWeightBytelength(spec, slice) { + const size = sizeFromShape(spec.shape); + let bytesPerValue; + if ('quantization' in spec) { + const quantization = spec.quantization; + bytesPerValue = DTYPE_VALUE_SIZE_MAP[quantization.dtype]; + } + else if (spec.dtype === 'string') { + // Can not statically determine string length. + let byteLength = 0; + for (let i = 0; i < size; i++) { + byteLength += NUM_BYTES_STRING_LENGTH + new Uint32Array(slice(byteLength, byteLength + NUM_BYTES_STRING_LENGTH))[0]; + } + return byteLength; + } + else { + bytesPerValue = DTYPE_VALUE_SIZE_MAP[spec.dtype]; + } + return size * bytesPerValue; + } + async function getWeightBytelengthAsync(spec, slice) { + const size = sizeFromShape(spec.shape); + let bytesPerValue; + if ('quantization' in spec) { + const quantization = spec.quantization; + bytesPerValue = DTYPE_VALUE_SIZE_MAP[quantization.dtype]; + } + else if (spec.dtype === 'string') { + // Can not statically determine string length. + let byteLength = 0; + for (let i = 0; i < size; i++) { + byteLength += NUM_BYTES_STRING_LENGTH + new Uint32Array(await slice(byteLength, byteLength + NUM_BYTES_STRING_LENGTH))[0]; + } + return byteLength; + } + else { + bytesPerValue = DTYPE_VALUE_SIZE_MAP[spec.dtype]; + } + return size * bytesPerValue; + } + function decodeWeight(spec, byteBuffer) { + const name = spec.name; + const dtype = spec.dtype; + const shape = spec.shape; + const size = sizeFromShape(shape); + let values; + let offset = 0; + if ('quantization' in spec) { + const quantization = spec.quantization; + if (quantization.dtype === 'uint8' || quantization.dtype === 'uint16') { + if (!('min' in quantization && 'scale' in quantization)) { + throw new Error(`Weight ${spec.name} with quantization ${quantization.dtype} ` + + `doesn't have corresponding metadata min and scale.`); + } + } + else if (quantization.dtype === 'float16') { + if (dtype !== 'float32') { + throw new Error(`Weight ${spec.name} is quantized with ${quantization.dtype} ` + + `which only supports weights of type float32 not ${dtype}.`); + } + } + else { + throw new Error(`Weight ${spec.name} has unknown ` + + `quantization dtype ${quantization.dtype}. ` + + `Supported quantization dtypes are: ` + + `'uint8', 'uint16', and 'float16'.`); + } + const quantizationSizeFactor = DTYPE_VALUE_SIZE_MAP[quantization.dtype]; + const quantizedArray = (quantization.dtype === 'uint8') ? + new Uint8Array(byteBuffer) : + new Uint16Array(byteBuffer); + if (dtype === 'float32') { + if (quantization.dtype === 'uint8' || quantization.dtype === 'uint16') { + values = new Float32Array(quantizedArray.length); + for (let i = 0; i < quantizedArray.length; i++) { + const v = quantizedArray[i]; + values[i] = v * quantization.scale + quantization.min; + } + } + else if (quantization.dtype === 'float16') { + // TODO: This is inefficient. Make getFloat16Decoder efficient. + const float16Decode = getFloat16Decoder(); + values = float16Decode(quantizedArray); + } + else { + throw new Error(`Unsupported quantization type ${quantization.dtype} ` + + `for weight type float32.`); + } + } + else if (dtype === 'int32') { + if (quantization.dtype !== 'uint8' && quantization.dtype !== 'uint16') { + throw new Error(`Unsupported quantization type ${quantization.dtype} ` + + `for weight type int32.`); + } + values = new Int32Array(quantizedArray.length); + for (let i = 0; i < quantizedArray.length; i++) { + const v = quantizedArray[i]; + values[i] = Math.round(v * quantization.scale + quantization.min); + } + } + else { + throw new Error(`Unsupported dtype in weight '${name}': ${dtype}`); + } + offset += size * quantizationSizeFactor; + } + else if (dtype === 'string') { + const size = sizeFromShape(spec.shape); + values = []; + for (let i = 0; i < size; i++) { + const byteLength = new Uint32Array(byteBuffer.slice(offset, offset + NUM_BYTES_STRING_LENGTH))[0]; + offset += NUM_BYTES_STRING_LENGTH; + const bytes = new Uint8Array(byteBuffer.slice(offset, offset + byteLength)); + values.push(bytes); + offset += byteLength; + } + } + else { + const dtypeFactor = DTYPE_VALUE_SIZE_MAP[dtype]; + if (dtype === 'float32') { + values = new Float32Array(byteBuffer); + } + else if (dtype === 'int32') { + values = new Int32Array(byteBuffer); + } + else if (dtype === 'bool') { + values = new Uint8Array(byteBuffer); + } + else if (dtype === 'complex64') { + values = new Float32Array(byteBuffer); + const real = new Float32Array(values.length / 2); + const image = new Float32Array(values.length / 2); + for (let i = 0; i < real.length; i++) { + real[i] = values[i * 2]; + image[i] = values[i * 2 + 1]; + } + const realTensor = tensor(real, shape, 'float32'); + const imageTensor = tensor(image, shape, 'float32'); + const complexTensor = complex$2(realTensor, imageTensor); + realTensor.dispose(); + imageTensor.dispose(); + return complexTensor; + } + else { + throw new Error(`Unsupported dtype in weight '${name}': ${dtype}`); + } + offset += size * dtypeFactor; + } + return tensor(values, shape, dtype); + } + async function readToLength(reader, initialData, length) { + let data = new Uint8Array(initialData); + while (data.byteLength < length) { + const { done, value } = await reader.read(); + if (done && value == null) { + const missing = length - data.byteLength; + throw new Error(`Reader is done but ${missing} bytes are still expected`); + } + // TODO: Don't create a new array every loop. + const newData = new Uint8Array(data.length + value.byteLength); + newData.set(data, 0); + newData.set(new Uint8Array(value), data.length); + data = newData; + } + return data.buffer; + } + async function decodeWeightsStream(weightStream, specs) { + const tensors = {}; + const reader = weightStream.getReader(); + let data = new ArrayBuffer(0); + for (const spec of specs) { + const byteLength = await getWeightBytelengthAsync(spec, async (start, end) => { + data = await readToLength(reader, data, end); + return data.slice(start, end); + }); + data = await readToLength(reader, data, byteLength); + // Slice the tensor out + const tensorData = data.slice(0, byteLength); + data = data.slice(byteLength); + const weightTensor = decodeWeight(spec, tensorData); + tensors[spec.name] = weightTensor; + // TODO(mattsoulanille): Better way to call uploadToGPU. + // TODO(mattsoulanille): Make this work for webgl too. + if (getBackend$1() === 'webgpu') { + const b = backend$1(); + if ('uploadToGPU' in b && + sizeFromShape(weightTensor.shape) >= env() + .get('WEBGPU_CPU_HANDOFF_SIZE_THRESHOLD')) { + b.uploadToGPU(weightTensor.dataId); + } + } + } + return tensors; + } + /** + * Concatenate TypedArrays into an ArrayBuffer. + */ + function concatenateTypedArrays(xs) { + // TODO(adarob, cais): Support quantization. + if (xs === null) { + throw new Error(`Invalid input value: ${JSON.stringify(xs)}`); + } + let totalByteLength = 0; + // `normalizedXs` is here for this reason: a `TypedArray`'s `buffer' + // can have a different byte length from that of the `TypedArray` itself, + // for example, when the `TypedArray` is created from an offset in an + // `ArrayBuffer`. `normliazedXs` holds `TypedArray`s whose `buffer`s match + // the `TypedArray` in byte length. If an element of `xs` does not show + // this property, a new `TypedArray` that satisfy this property will be + // constructed and pushed into `normalizedXs`. + const normalizedXs = []; + xs.forEach((x) => { + totalByteLength += x.byteLength; + // tslint:disable:no-any + normalizedXs.push(x.byteLength === x.buffer.byteLength ? x : + new x.constructor(x)); + if (!(x instanceof Float32Array || x instanceof Int32Array || + x instanceof Uint8Array)) { + throw new Error(`Unsupported TypedArray subtype: ${x.constructor.name}`); + } + // tslint:enable:no-any + }); + const y = new Uint8Array(totalByteLength); + let offset = 0; + normalizedXs.forEach((x) => { + y.set(new Uint8Array(x.buffer), offset); + offset += x.byteLength; + }); + return y.buffer; + } + // Use Buffer on Node.js instead of Blob/atob/btoa + const useNodeBuffer = typeof Buffer !== 'undefined' && + (typeof Blob === 'undefined' || typeof atob === 'undefined' || + typeof btoa === 'undefined'); + /** + * Calculate the byte length of a JavaScript string. + * + * Note that a JavaScript string can contain wide characters, therefore the + * length of the string is not necessarily equal to the byte length. + * + * @param str Input string. + * @returns Byte length. + */ + function stringByteLength(str) { + if (useNodeBuffer) { + return Buffer.byteLength(str, 'utf8'); + } + return new Blob([str]).size; + } + /** + * Encode an ArrayBuffer as a base64 encoded string. + * + * @param buffer `ArrayBuffer` to be converted. + * @returns A string that base64-encodes `buffer`. + */ + function arrayBufferToBase64String(buffer) { + if (useNodeBuffer) { + return Buffer.from(buffer).toString('base64'); + } + const buf = new Uint8Array(buffer); + let s = ''; + for (let i = 0, l = buf.length; i < l; i++) { + s += String.fromCharCode(buf[i]); + } + return btoa(s); + } + /** + * Decode a base64 string as an ArrayBuffer. + * + * @param str Base64 string. + * @returns Decoded `ArrayBuffer`. + */ + function base64StringToArrayBuffer(str) { + if (useNodeBuffer) { + const buf = Buffer.from(str, 'base64'); + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + } + const s = atob(str); + const buffer = new Uint8Array(s.length); + for (let i = 0; i < s.length; ++i) { + buffer.set([s.charCodeAt(i)], i); + } + return buffer.buffer; + } + /** + * Concatenate a number of ArrayBuffers into one. + * + * @param buffers An array of ArrayBuffers to concatenate, or a single + * ArrayBuffer. + * @returns Result of concatenating `buffers` in order. + * + * @deprecated Use tf.io.CompositeArrayBuffer.join() instead. + */ + function concatenateArrayBuffers(buffers) { + return CompositeArrayBuffer.join(buffers); + } + /** + * Get the basename of a path. + * + * Behaves in a way analogous to Linux's basename command. + * + * @param path + */ + function basename(path) { + const SEPARATOR = '/'; + path = path.trim(); + while (path.endsWith(SEPARATOR)) { + path = path.slice(0, path.length - 1); + } + const items = path.split(SEPARATOR); + return items[items.length - 1]; + } + /** + * Create `ModelJSON` from `ModelArtifacts`. + * + * @param artifacts Model artifacts, describing the model and its weights. + * @param manifest Weight manifest, describing where the weights of the + * `ModelArtifacts` are stored, and some metadata about them. + * @returns Object representing the `model.json` file describing the model + * artifacts and weights + */ + function getModelJSONForModelArtifacts(artifacts, manifest) { + const result = { + modelTopology: artifacts.modelTopology, + format: artifacts.format, + generatedBy: artifacts.generatedBy, + convertedBy: artifacts.convertedBy, + weightsManifest: manifest + }; + if (artifacts.signature != null) { + result.signature = artifacts.signature; + } + if (artifacts.userDefinedMetadata != null) { + result.userDefinedMetadata = artifacts.userDefinedMetadata; + } + if (artifacts.modelInitializer != null) { + result.modelInitializer = artifacts.modelInitializer; + } + if (artifacts.initializerSignature != null) { + result.initializerSignature = artifacts.initializerSignature; + } + if (artifacts.trainingConfig != null) { + result.trainingConfig = artifacts.trainingConfig; + } + return result; + } + /** + * Create `ModelArtifacts` from a JSON file and weights. + * + * @param modelJSON Object containing the parsed JSON of `model.json` + * @param weightSpecs The list of WeightsManifestEntry for the model. Must be + * passed if the modelJSON has a weightsManifest. + * @param weightData An ArrayBuffer or array of ArrayBuffers of weight data for + * the model corresponding to the weights in weightSpecs. Must be passed if + * the modelJSON has a weightsManifest. + * @returns A Promise of the `ModelArtifacts`, as described by the JSON file. + */ + function getModelArtifactsForJSONSync(modelJSON, weightSpecs, weightData) { + const modelArtifacts = { + modelTopology: modelJSON.modelTopology, + format: modelJSON.format, + generatedBy: modelJSON.generatedBy, + convertedBy: modelJSON.convertedBy + }; + if (modelJSON.trainingConfig != null) { + modelArtifacts.trainingConfig = modelJSON.trainingConfig; + } + if (modelJSON.weightsManifest != null) { + if (!weightSpecs) { + throw new Error('modelJSON has weightsManifest but weightSpecs is null'); + } + if (!weightData) { + throw new Error('modelJSON has weightsManifest but weightData is null'); + } + modelArtifacts.weightSpecs = weightSpecs; + modelArtifacts.weightData = weightData; + } + if (modelJSON.signature != null) { + modelArtifacts.signature = modelJSON.signature; + } + if (modelJSON.userDefinedMetadata != null) { + modelArtifacts.userDefinedMetadata = modelJSON.userDefinedMetadata; + } + if (modelJSON.modelInitializer != null) { + modelArtifacts.modelInitializer = modelJSON.modelInitializer; + } + if (modelJSON.initializerSignature != null) { + modelArtifacts.initializerSignature = modelJSON.initializerSignature; + } + return modelArtifacts; + } + /** + * Create `ModelArtifacts` from a JSON file. + * + * @param modelJSON Object containing the parsed JSON of `model.json` + * @param loadWeights Function that takes the JSON file's weights manifest, + * reads weights from the listed path(s), and returns a Promise of the + * weight manifest entries along with the weights data. + * @returns A Promise of the `ModelArtifacts`, as described by the JSON file. + */ + async function getModelArtifactsForJSON(modelJSON, loadWeights) { + let weightSpecs; + let weightData; + if (modelJSON.weightsManifest != null) { + [weightSpecs, weightData] = await loadWeights(modelJSON.weightsManifest); + } + return getModelArtifactsForJSONSync(modelJSON, weightSpecs, weightData); + } + /** + * Populate ModelArtifactsInfo fields for a model with JSON topology. + * @param modelArtifacts + * @returns A ModelArtifactsInfo object. + */ + function getModelArtifactsInfoForJSON(modelArtifacts) { + if (modelArtifacts.modelTopology instanceof ArrayBuffer) { + throw new Error('Expected JSON model topology, received ArrayBuffer.'); + } + return { + dateSaved: new Date(), + modelTopologyType: 'JSON', + modelTopologyBytes: modelArtifacts.modelTopology == null ? + 0 : + stringByteLength(JSON.stringify(modelArtifacts.modelTopology)), + weightSpecsBytes: modelArtifacts.weightSpecs == null ? + 0 : + stringByteLength(JSON.stringify(modelArtifacts.weightSpecs)), + weightDataBytes: modelArtifacts.weightData == null ? + 0 : + new CompositeArrayBuffer(modelArtifacts.weightData).byteLength, + }; + } + /** + * Concatenate the weights stored in a WeightsManifestConfig into a list of + * WeightsManifestEntry + * + * @param weightsManifest The WeightsManifestConfig to extract weights from. + * @returns A list of WeightsManifestEntry of the weights in the weightsManifest + */ + function getWeightSpecs(weightsManifest) { + const weightSpecs = []; + for (const entry of weightsManifest) { + weightSpecs.push(...entry.weights); + } + return weightSpecs; + } + /** + * Computes mantisa table for casting Float16 to Float32 + * See http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf + * + * @returns Uint32Array, 2048 mantissa lookup values. + */ + function computeFloat16MantisaTable() { + const convertMantissa = (i) => { + let m = i << 13; + let e = 0; + while ((m & 0x00800000) === 0) { + e -= 0x00800000; + m <<= 1; + } + m &= ~0x00800000; + e += 0x38800000; + return m | e; + }; + const mantisaTable = new Uint32Array(2048); + mantisaTable[0] = 0; + for (let i = 1; i < 1024; i++) { + mantisaTable[i] = convertMantissa(i); + } + for (let i = 1024; i < 2048; i++) { + mantisaTable[i] = 0x38000000 + ((i - 1024) << 13); + } + return mantisaTable; + } + /** + * Computes exponent table for casting Float16 to Float32 + * See http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf + * + * @returns Uint32Array, 64 exponent lookup values. + */ + function computeFloat16ExponentTable() { + const exponentTable = new Uint32Array(64); + exponentTable[0] = 0; + exponentTable[31] = 0x47800000; + exponentTable[32] = 0x80000000; + exponentTable[63] = 0xc7800000; + for (let i = 1; i < 31; i++) { + exponentTable[i] = i << 23; + } + for (let i = 33; i < 63; i++) { + exponentTable[i] = 0x80000000 + ((i - 32) << 23); + } + return exponentTable; + } + /** + * Computes offset table for casting Float16 to Float32 + * See http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf + * + * @returns Uint32Array, 6d offset values. + */ + function computeFloat16OffsetTable() { + const offsetTable = new Uint32Array(64); + for (let i = 0; i < 64; i++) { + offsetTable[i] = 1024; + } + offsetTable[0] = offsetTable[32] = 0; + return offsetTable; + } + /** + * Retrieve a Float16 decoder which will decode a ByteArray of Float16 values + * to a Float32Array. + * + * @returns Function (buffer: Uint16Array) => Float32Array which decodes + * the Uint16Array of Float16 bytes to a Float32Array. + */ + function getFloat16Decoder() { + // Algorithm is based off of + // http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf + // Cache lookup tables + const mantisaTable = computeFloat16MantisaTable(); + const exponentTable = computeFloat16ExponentTable(); + const offsetTable = computeFloat16OffsetTable(); + return (quantizedArray) => { + const buffer = new ArrayBuffer(4 * quantizedArray.length); + const bufferUint32View = new Uint32Array(buffer); + for (let index = 0; index < quantizedArray.length; index++) { + const float16Bits = quantizedArray[index]; + const float32Bits = mantisaTable[offsetTable[float16Bits >> 10] + (float16Bits & 0x3ff)] + + exponentTable[float16Bits >> 10]; + bufferUint32View[index] = float32Bits; + } + return new Float32Array(buffer); + }; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class IORouterRegistry { + constructor() { + this.saveRouters = []; + this.loadRouters = []; + } + static getInstance() { + if (IORouterRegistry.instance == null) { + IORouterRegistry.instance = new IORouterRegistry(); + } + return IORouterRegistry.instance; + } + /** + * Register a save-handler router. + * + * @param saveRouter A function that maps a URL-like string onto an instance + * of `IOHandler` with the `save` method defined or `null`. + */ + static registerSaveRouter(saveRouter) { + IORouterRegistry.getInstance().saveRouters.push(saveRouter); + } + /** + * Register a load-handler router. + * + * @param loadRouter A function that maps a URL-like string onto an instance + * of `IOHandler` with the `load` method defined or `null`. + */ + static registerLoadRouter(loadRouter) { + IORouterRegistry.getInstance().loadRouters.push(loadRouter); + } + /** + * Look up IOHandler for saving, given a URL-like string. + * + * @param url + * @returns If only one match is found, an instance of IOHandler with the + * `save` method defined. If no match is found, `null`. + * @throws Error, if more than one match is found. + */ + static getSaveHandlers(url) { + return IORouterRegistry.getHandlers(url, 'save'); + } + /** + * Look up IOHandler for loading, given a URL-like string. + * + * @param url + * @param loadOptions Optional, custom load options. + * @returns All valid handlers for `url`, given the currently registered + * handler routers. + */ + static getLoadHandlers(url, loadOptions) { + return IORouterRegistry.getHandlers(url, 'load', loadOptions); + } + static getHandlers(url, handlerType, loadOptions) { + const validHandlers = []; + const routers = handlerType === 'load' ? + IORouterRegistry.getInstance().loadRouters : + IORouterRegistry.getInstance().saveRouters; + routers.forEach(router => { + const handler = router(url, loadOptions); + if (handler !== null) { + validHandlers.push(handler); + } + }); + return validHandlers; + } + } + const registerSaveRouter = (loudRouter) => IORouterRegistry.registerSaveRouter(loudRouter); + const registerLoadRouter = (loudRouter) => IORouterRegistry.registerLoadRouter(loudRouter); + const getSaveHandlers = (url) => IORouterRegistry.getSaveHandlers(url); + const getLoadHandlers = (url, loadOptions) => IORouterRegistry.getLoadHandlers(url, loadOptions); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const DATABASE_NAME = 'tensorflowjs'; + const DATABASE_VERSION = 1; + // Model data and ModelArtifactsInfo (metadata) are stored in two separate + // stores for efficient access of the list of stored models and their metadata. + // 1. The object store for model data: topology, weights and weight manifests. + const MODEL_STORE_NAME = 'models_store'; + // 2. The object store for ModelArtifactsInfo, including meta-information such + // as the type of topology (JSON vs binary), byte size of the topology, byte + // size of the weights, etc. + const INFO_STORE_NAME = 'model_info_store'; + /** + * Delete the entire database for tensorflow.js, including the models store. + */ + async function deleteDatabase() { + const idbFactory = getIndexedDBFactory(); + return new Promise((resolve, reject) => { + const deleteRequest = idbFactory.deleteDatabase(DATABASE_NAME); + deleteRequest.onsuccess = () => resolve(); + deleteRequest.onerror = error => reject(error); + }); + } + function getIndexedDBFactory() { + if (!env().getBool('IS_BROWSER')) { + // TODO(cais): Add more info about what IOHandler subtypes are available. + // Maybe point to a doc page on the web and/or automatically determine + // the available IOHandlers and print them in the error message. + throw new Error('Failed to obtain IndexedDB factory because the current environment' + + 'is not a web browser.'); + } + // tslint:disable-next-line:no-any + const theWindow = typeof window === 'undefined' ? self : window; + const factory = theWindow.indexedDB || theWindow.mozIndexedDB || + theWindow.webkitIndexedDB || theWindow.msIndexedDB || + theWindow.shimIndexedDB; + if (factory == null) { + throw new Error('The current browser does not appear to support IndexedDB.'); + } + return factory; + } + function setUpDatabase(openRequest) { + const db = openRequest.result; + db.createObjectStore(MODEL_STORE_NAME, { keyPath: 'modelPath' }); + db.createObjectStore(INFO_STORE_NAME, { keyPath: 'modelPath' }); + } + /** + * IOHandler subclass: Browser IndexedDB. + * + * See the doc string of `browserIndexedDB` for more details. + */ + class BrowserIndexedDB { + constructor(modelPath) { + this.indexedDB = getIndexedDBFactory(); + if (modelPath == null || !modelPath) { + throw new Error('For IndexedDB, modelPath must not be null, undefined or empty.'); + } + this.modelPath = modelPath; + } + async save(modelArtifacts) { + // TODO(cais): Support saving GraphDef models. + if (modelArtifacts.modelTopology instanceof ArrayBuffer) { + throw new Error('BrowserLocalStorage.save() does not support saving model topology ' + + 'in binary formats yet.'); + } + return this.databaseAction(this.modelPath, modelArtifacts); + } + async load() { + return this.databaseAction(this.modelPath); + } + /** + * Perform database action to put model artifacts into or read model artifacts + * from IndexedDB object store. + * + * Whether the action is put or get depends on whether `modelArtifacts` is + * specified. If it is specified, the action will be put; otherwise the action + * will be get. + * + * @param modelPath A unique string path for the model. + * @param modelArtifacts If specified, it will be the model artifacts to be + * stored in IndexedDB. + * @returns A `Promise` of `SaveResult`, if the action is put, or a `Promise` + * of `ModelArtifacts`, if the action is get. + */ + databaseAction(modelPath, modelArtifacts) { + return new Promise((resolve, reject) => { + const openRequest = this.indexedDB.open(DATABASE_NAME, DATABASE_VERSION); + openRequest.onupgradeneeded = () => setUpDatabase(openRequest); + openRequest.onsuccess = () => { + const db = openRequest.result; + if (modelArtifacts == null) { + // Read model out from object store. + const modelTx = db.transaction(MODEL_STORE_NAME, 'readonly'); + const modelStore = modelTx.objectStore(MODEL_STORE_NAME); + const getRequest = modelStore.get(this.modelPath); + getRequest.onsuccess = () => { + if (getRequest.result == null) { + db.close(); + return reject(new Error(`Cannot find model with path '${this.modelPath}' ` + + `in IndexedDB.`)); + } + else { + resolve(getRequest.result.modelArtifacts); + } + }; + getRequest.onerror = error => { + db.close(); + return reject(getRequest.error); + }; + modelTx.oncomplete = () => db.close(); + } + else { + // Put model into object store. + // Concatenate all the model weights into a single ArrayBuffer. Large + // models (~1GB) have problems saving if they are not concatenated. + // TODO(mattSoulanille): Save large models to multiple indexeddb + // records. + modelArtifacts.weightData = CompositeArrayBuffer.join(modelArtifacts.weightData); + const modelArtifactsInfo = getModelArtifactsInfoForJSON(modelArtifacts); + // First, put ModelArtifactsInfo into info store. + const infoTx = db.transaction(INFO_STORE_NAME, 'readwrite'); + let infoStore = infoTx.objectStore(INFO_STORE_NAME); + let putInfoRequest; + try { + putInfoRequest = + infoStore.put({ modelPath: this.modelPath, modelArtifactsInfo }); + } + catch (error) { + return reject(error); + } + let modelTx; + putInfoRequest.onsuccess = () => { + // Second, put model data into model store. + modelTx = db.transaction(MODEL_STORE_NAME, 'readwrite'); + const modelStore = modelTx.objectStore(MODEL_STORE_NAME); + let putModelRequest; + try { + putModelRequest = modelStore.put({ + modelPath: this.modelPath, + modelArtifacts, + modelArtifactsInfo + }); + } + catch (error) { + // Sometimes, the serialized value is too large to store. + return reject(error); + } + putModelRequest.onsuccess = () => resolve({ modelArtifactsInfo }); + putModelRequest.onerror = error => { + // If the put-model request fails, roll back the info entry as + // well. + infoStore = infoTx.objectStore(INFO_STORE_NAME); + const deleteInfoRequest = infoStore.delete(this.modelPath); + deleteInfoRequest.onsuccess = () => { + db.close(); + return reject(putModelRequest.error); + }; + deleteInfoRequest.onerror = error => { + db.close(); + return reject(putModelRequest.error); + }; + }; + }; + putInfoRequest.onerror = error => { + db.close(); + return reject(putInfoRequest.error); + }; + infoTx.oncomplete = () => { + if (modelTx == null) { + db.close(); + } + else { + modelTx.oncomplete = () => db.close(); + } + }; + } + }; + openRequest.onerror = error => reject(openRequest.error); + }); + } + } + BrowserIndexedDB.URL_SCHEME = 'indexeddb://'; + const indexedDBRouter = (url) => { + if (!env().getBool('IS_BROWSER')) { + return null; + } + else { + if (!Array.isArray(url) && url.startsWith(BrowserIndexedDB.URL_SCHEME)) { + return browserIndexedDB(url.slice(BrowserIndexedDB.URL_SCHEME.length)); + } + else { + return null; + } + } + }; + IORouterRegistry.registerSaveRouter(indexedDBRouter); + IORouterRegistry.registerLoadRouter(indexedDBRouter); + /** + * Creates a browser IndexedDB IOHandler for saving and loading models. + * + * ```js + * const model = tf.sequential(); + * model.add( + * tf.layers.dense({units: 1, inputShape: [100], activation: 'sigmoid'})); + * + * const saveResult = await model.save('indexeddb://MyModel')); + * console.log(saveResult); + * ``` + * + * @param modelPath A unique identifier for the model to be saved. Must be a + * non-empty string. + * @returns An instance of `BrowserIndexedDB` (subclass of `IOHandler`), + * which can be used with, e.g., `tf.Model.save`. + */ + function browserIndexedDB(modelPath) { + return new BrowserIndexedDB(modelPath); + } + function maybeStripScheme$1(key) { + return key.startsWith(BrowserIndexedDB.URL_SCHEME) ? + key.slice(BrowserIndexedDB.URL_SCHEME.length) : + key; + } + class BrowserIndexedDBManager { + constructor() { + this.indexedDB = getIndexedDBFactory(); + } + async listModels() { + return new Promise((resolve, reject) => { + const openRequest = this.indexedDB.open(DATABASE_NAME, DATABASE_VERSION); + openRequest.onupgradeneeded = () => setUpDatabase(openRequest); + openRequest.onsuccess = () => { + const db = openRequest.result; + const tx = db.transaction(INFO_STORE_NAME, 'readonly'); + const store = tx.objectStore(INFO_STORE_NAME); + // tslint:disable:max-line-length + // Need to cast `store` as `any` here because TypeScript's DOM + // library does not have the `getAll()` method even though the + // method is supported in the latest version of most mainstream + // browsers: + // https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/getAll + // tslint:enable:max-line-length + // tslint:disable-next-line:no-any + const getAllInfoRequest = store.getAll(); + getAllInfoRequest.onsuccess = () => { + const out = {}; + for (const item of getAllInfoRequest.result) { + out[item.modelPath] = item.modelArtifactsInfo; + } + resolve(out); + }; + getAllInfoRequest.onerror = error => { + db.close(); + return reject(getAllInfoRequest.error); + }; + tx.oncomplete = () => db.close(); + }; + openRequest.onerror = error => reject(openRequest.error); + }); + } + async removeModel(path) { + path = maybeStripScheme$1(path); + return new Promise((resolve, reject) => { + const openRequest = this.indexedDB.open(DATABASE_NAME, DATABASE_VERSION); + openRequest.onupgradeneeded = () => setUpDatabase(openRequest); + openRequest.onsuccess = () => { + const db = openRequest.result; + const infoTx = db.transaction(INFO_STORE_NAME, 'readwrite'); + const infoStore = infoTx.objectStore(INFO_STORE_NAME); + const getInfoRequest = infoStore.get(path); + let modelTx; + getInfoRequest.onsuccess = () => { + if (getInfoRequest.result == null) { + db.close(); + return reject(new Error(`Cannot find model with path '${path}' ` + + `in IndexedDB.`)); + } + else { + // First, delete the entry in the info store. + const deleteInfoRequest = infoStore.delete(path); + const deleteModelData = () => { + // Second, delete the entry in the model store. + modelTx = db.transaction(MODEL_STORE_NAME, 'readwrite'); + const modelStore = modelTx.objectStore(MODEL_STORE_NAME); + const deleteModelRequest = modelStore.delete(path); + deleteModelRequest.onsuccess = () => resolve(getInfoRequest.result.modelArtifactsInfo); + deleteModelRequest.onerror = error => reject(getInfoRequest.error); + }; + // Proceed with deleting model data regardless of whether deletion + // of info data succeeds or not. + deleteInfoRequest.onsuccess = deleteModelData; + deleteInfoRequest.onerror = error => { + deleteModelData(); + db.close(); + return reject(getInfoRequest.error); + }; + } + }; + getInfoRequest.onerror = error => { + db.close(); + return reject(getInfoRequest.error); + }; + infoTx.oncomplete = () => { + if (modelTx == null) { + db.close(); + } + else { + modelTx.oncomplete = () => db.close(); + } + }; + }; + openRequest.onerror = error => reject(openRequest.error); + }); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const PATH_SEPARATOR = '/'; + const PATH_PREFIX = 'tensorflowjs_models'; + const INFO_SUFFIX = 'info'; + const MODEL_TOPOLOGY_SUFFIX = 'model_topology'; + const WEIGHT_SPECS_SUFFIX = 'weight_specs'; + const WEIGHT_DATA_SUFFIX = 'weight_data'; + const MODEL_METADATA_SUFFIX = 'model_metadata'; + /** + * Purge all tensorflow.js-saved model artifacts from local storage. + * + * @returns Paths of the models purged. + */ + function purgeLocalStorageArtifacts() { + if (!env().getBool('IS_BROWSER') || typeof window === 'undefined' || + typeof window.localStorage === 'undefined') { + throw new Error('purgeLocalStorageModels() cannot proceed because local storage is ' + + 'unavailable in the current environment.'); + } + const LS = window.localStorage; + const purgedModelPaths = []; + for (let i = 0; i < LS.length; ++i) { + const key = LS.key(i); + const prefix = PATH_PREFIX + PATH_SEPARATOR; + if (key.startsWith(prefix) && key.length > prefix.length) { + LS.removeItem(key); + const modelName = getModelPathFromKey(key); + if (purgedModelPaths.indexOf(modelName) === -1) { + purgedModelPaths.push(modelName); + } + } + } + return purgedModelPaths; + } + function getModelKeys(path) { + return { + info: [PATH_PREFIX, path, INFO_SUFFIX].join(PATH_SEPARATOR), + topology: [PATH_PREFIX, path, MODEL_TOPOLOGY_SUFFIX].join(PATH_SEPARATOR), + weightSpecs: [PATH_PREFIX, path, WEIGHT_SPECS_SUFFIX].join(PATH_SEPARATOR), + weightData: [PATH_PREFIX, path, WEIGHT_DATA_SUFFIX].join(PATH_SEPARATOR), + modelMetadata: [PATH_PREFIX, path, MODEL_METADATA_SUFFIX].join(PATH_SEPARATOR) + }; + } + function removeItems(keys) { + for (const key of Object.values(keys)) { + window.localStorage.removeItem(key); + } + } + /** + * Get model path from a local-storage key. + * + * E.g., 'tensorflowjs_models/my/model/1/info' --> 'my/model/1' + * + * @param key + */ + function getModelPathFromKey(key) { + const items = key.split(PATH_SEPARATOR); + if (items.length < 3) { + throw new Error(`Invalid key format: ${key}`); + } + return items.slice(1, items.length - 1).join(PATH_SEPARATOR); + } + function maybeStripScheme(key) { + return key.startsWith(BrowserLocalStorage.URL_SCHEME) ? + key.slice(BrowserLocalStorage.URL_SCHEME.length) : + key; + } + /** + * IOHandler subclass: Browser Local Storage. + * + * See the doc string to `browserLocalStorage` for more details. + */ + class BrowserLocalStorage { + constructor(modelPath) { + if (!env().getBool('IS_BROWSER') || typeof window === 'undefined' || + typeof window.localStorage === 'undefined') { + // TODO(cais): Add more info about what IOHandler subtypes are + // available. + // Maybe point to a doc page on the web and/or automatically determine + // the available IOHandlers and print them in the error message. + throw new Error('The current environment does not support local storage.'); + } + this.LS = window.localStorage; + if (modelPath == null || !modelPath) { + throw new Error('For local storage, modelPath must not be null, undefined or empty.'); + } + this.modelPath = modelPath; + this.keys = getModelKeys(this.modelPath); + } + /** + * Save model artifacts to browser local storage. + * + * See the documentation to `browserLocalStorage` for details on the saved + * artifacts. + * + * @param modelArtifacts The model artifacts to be stored. + * @returns An instance of SaveResult. + */ + async save(modelArtifacts) { + if (modelArtifacts.modelTopology instanceof ArrayBuffer) { + throw new Error('BrowserLocalStorage.save() does not support saving model topology ' + + 'in binary formats yet.'); + } + else { + const topology = JSON.stringify(modelArtifacts.modelTopology); + const weightSpecs = JSON.stringify(modelArtifacts.weightSpecs); + const modelArtifactsInfo = getModelArtifactsInfoForJSON(modelArtifacts); + // TODO(mattsoulanille): Support saving models over 2GB that exceed + // Chrome's ArrayBuffer size limit. + const weightBuffer = CompositeArrayBuffer.join(modelArtifacts.weightData); + try { + this.LS.setItem(this.keys.info, JSON.stringify(modelArtifactsInfo)); + this.LS.setItem(this.keys.topology, topology); + this.LS.setItem(this.keys.weightSpecs, weightSpecs); + this.LS.setItem(this.keys.weightData, arrayBufferToBase64String(weightBuffer)); + // Note that JSON.stringify doesn't write out keys that have undefined + // values, so for some keys, we set undefined instead of a null-ish + // value. + const metadata = { + format: modelArtifacts.format, + generatedBy: modelArtifacts.generatedBy, + convertedBy: modelArtifacts.convertedBy, + signature: modelArtifacts.signature != null ? + modelArtifacts.signature : + undefined, + userDefinedMetadata: modelArtifacts.userDefinedMetadata != null ? + modelArtifacts.userDefinedMetadata : + undefined, + modelInitializer: modelArtifacts.modelInitializer != null ? + modelArtifacts.modelInitializer : + undefined, + initializerSignature: modelArtifacts.initializerSignature != null ? + modelArtifacts.initializerSignature : + undefined, + trainingConfig: modelArtifacts.trainingConfig != null ? + modelArtifacts.trainingConfig : + undefined + }; + this.LS.setItem(this.keys.modelMetadata, JSON.stringify(metadata)); + return { modelArtifactsInfo }; + } + catch (err) { + // If saving failed, clean up all items saved so far. + removeItems(this.keys); + throw new Error(`Failed to save model '${this.modelPath}' to local storage: ` + + `size quota being exceeded is a possible cause of this failure: ` + + `modelTopologyBytes=${modelArtifactsInfo.modelTopologyBytes}, ` + + `weightSpecsBytes=${modelArtifactsInfo.weightSpecsBytes}, ` + + `weightDataBytes=${modelArtifactsInfo.weightDataBytes}.`); + } + } + } + /** + * Load a model from local storage. + * + * See the documentation to `browserLocalStorage` for details on the saved + * artifacts. + * + * @returns The loaded model (if loading succeeds). + */ + async load() { + const info = JSON.parse(this.LS.getItem(this.keys.info)); + if (info == null) { + throw new Error(`In local storage, there is no model with name '${this.modelPath}'`); + } + if (info.modelTopologyType !== 'JSON') { + throw new Error('BrowserLocalStorage does not support loading non-JSON model ' + + 'topology yet.'); + } + const out = {}; + // Load topology. + const topology = JSON.parse(this.LS.getItem(this.keys.topology)); + if (topology == null) { + throw new Error(`In local storage, the topology of model '${this.modelPath}' ` + + `is missing.`); + } + out.modelTopology = topology; + // Load weight specs. + const weightSpecs = JSON.parse(this.LS.getItem(this.keys.weightSpecs)); + if (weightSpecs == null) { + throw new Error(`In local storage, the weight specs of model '${this.modelPath}' ` + + `are missing.`); + } + out.weightSpecs = weightSpecs; + // Load meta-data fields. + const metadataString = this.LS.getItem(this.keys.modelMetadata); + if (metadataString != null) { + const metadata = JSON.parse(metadataString); + out.format = metadata.format; + out.generatedBy = metadata.generatedBy; + out.convertedBy = metadata.convertedBy; + if (metadata.signature != null) { + out.signature = metadata.signature; + } + if (metadata.userDefinedMetadata != null) { + out.userDefinedMetadata = metadata.userDefinedMetadata; + } + if (metadata.modelInitializer != null) { + out.modelInitializer = metadata.modelInitializer; + } + if (metadata.initializerSignature != null) { + out.initializerSignature = metadata.initializerSignature; + } + if (metadata.trainingConfig != null) { + out.trainingConfig = metadata.trainingConfig; + } + } + // Load weight data. + const weightDataBase64 = this.LS.getItem(this.keys.weightData); + if (weightDataBase64 == null) { + throw new Error(`In local storage, the binary weight values of model ` + + `'${this.modelPath}' are missing.`); + } + out.weightData = base64StringToArrayBuffer(weightDataBase64); + return out; + } + } + BrowserLocalStorage.URL_SCHEME = 'localstorage://'; + const localStorageRouter = (url) => { + if (!env().getBool('IS_BROWSER')) { + return null; + } + else { + if (!Array.isArray(url) && url.startsWith(BrowserLocalStorage.URL_SCHEME)) { + return browserLocalStorage(url.slice(BrowserLocalStorage.URL_SCHEME.length)); + } + else { + return null; + } + } + }; + IORouterRegistry.registerSaveRouter(localStorageRouter); + IORouterRegistry.registerLoadRouter(localStorageRouter); + /** + * Factory function for local storage IOHandler. + * + * This `IOHandler` supports both `save` and `load`. + * + * For each model's saved artifacts, four items are saved to local storage. + * - `${PATH_SEPARATOR}/${modelPath}/info`: Contains meta-info about the + * model, such as date saved, type of the topology, size in bytes, etc. + * - `${PATH_SEPARATOR}/${modelPath}/topology`: Model topology. For Keras- + * style models, this is a stringized JSON. + * - `${PATH_SEPARATOR}/${modelPath}/weight_specs`: Weight specs of the + * model, can be used to decode the saved binary weight values (see + * item below). + * - `${PATH_SEPARATOR}/${modelPath}/weight_data`: Concatenated binary + * weight values, stored as a base64-encoded string. + * + * Saving may throw an `Error` if the total size of the artifacts exceed the + * browser-specific quota. + * + * @param modelPath A unique identifier for the model to be saved. Must be a + * non-empty string. + * @returns An instance of `IOHandler`, which can be used with, e.g., + * `tf.Model.save`. + */ + function browserLocalStorage(modelPath) { + return new BrowserLocalStorage(modelPath); + } + class BrowserLocalStorageManager { + constructor() { + assert$1(env().getBool('IS_BROWSER'), () => 'Current environment is not a web browser'); + assert$1(typeof window === 'undefined' || + typeof window.localStorage !== 'undefined', () => 'Current browser does not appear to support localStorage'); + this.LS = window.localStorage; + } + async listModels() { + const out = {}; + const prefix = PATH_PREFIX + PATH_SEPARATOR; + const suffix = PATH_SEPARATOR + INFO_SUFFIX; + for (let i = 0; i < this.LS.length; ++i) { + const key = this.LS.key(i); + if (key.startsWith(prefix) && key.endsWith(suffix)) { + const modelPath = getModelPathFromKey(key); + out[modelPath] = JSON.parse(this.LS.getItem(key)); + } + } + return out; + } + async removeModel(path) { + path = maybeStripScheme(path); + const keys = getModelKeys(path); + if (this.LS.getItem(keys.info) == null) { + throw new Error(`Cannot find model at path '${path}'`); + } + const info = JSON.parse(this.LS.getItem(keys.info)); + removeItems(keys); + return info; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const URL_SCHEME_SUFFIX = '://'; + class ModelStoreManagerRegistry { + constructor() { + this.managers = {}; + } + static getInstance() { + if (ModelStoreManagerRegistry.instance == null) { + ModelStoreManagerRegistry.instance = new ModelStoreManagerRegistry(); + } + return ModelStoreManagerRegistry.instance; + } + /** + * Register a save-handler router. + * + * @param saveRouter A function that maps a URL-like string onto an instance + * of `IOHandler` with the `save` method defined or `null`. + */ + static registerManager(scheme, manager) { + assert$1(scheme != null, () => 'scheme must not be undefined or null.'); + if (scheme.endsWith(URL_SCHEME_SUFFIX)) { + scheme = scheme.slice(0, scheme.indexOf(URL_SCHEME_SUFFIX)); + } + assert$1(scheme.length > 0, () => 'scheme must not be an empty string.'); + const registry = ModelStoreManagerRegistry.getInstance(); + assert$1(registry.managers[scheme] == null, () => `A model store manager is already registered for scheme '${scheme}'.`); + registry.managers[scheme] = manager; + } + static getManager(scheme) { + const manager = ModelStoreManagerRegistry.getInstance().managers[scheme]; + if (manager == null) { + throw new Error(`Cannot find model manager for scheme '${scheme}'`); + } + return manager; + } + static getSchemes() { + return Object.keys(ModelStoreManagerRegistry.getInstance().managers); + } + } + /** + * Helper method for parsing a URL string into a scheme and a path. + * + * @param url E.g., 'localstorage://my-model' + * @returns A dictionary with two fields: scheme and path. + * Scheme: e.g., 'localstorage' in the example above. + * Path: e.g., 'my-model' in the example above. + */ + function parseURL(url) { + if (url.indexOf(URL_SCHEME_SUFFIX) === -1) { + throw new Error(`The url string provided does not contain a scheme. ` + + `Supported schemes are: ` + + `${ModelStoreManagerRegistry.getSchemes().join(',')}`); + } + return { + scheme: url.split(URL_SCHEME_SUFFIX)[0], + path: url.split(URL_SCHEME_SUFFIX)[1], + }; + } + async function cloneModelInternal(sourceURL, destURL, deleteSource = false) { + assert$1(sourceURL !== destURL, () => `Old path and new path are the same: '${sourceURL}'`); + const loadHandlers = IORouterRegistry.getLoadHandlers(sourceURL); + assert$1(loadHandlers.length > 0, () => `Copying failed because no load handler is found for source URL ${sourceURL}.`); + assert$1(loadHandlers.length < 2, () => `Copying failed because more than one (${loadHandlers.length}) ` + + `load handlers for source URL ${sourceURL}.`); + const loadHandler = loadHandlers[0]; + const saveHandlers = IORouterRegistry.getSaveHandlers(destURL); + assert$1(saveHandlers.length > 0, () => `Copying failed because no save handler is found for destination ` + + `URL ${destURL}.`); + assert$1(saveHandlers.length < 2, () => `Copying failed because more than one (${loadHandlers.length}) ` + + `save handlers for destination URL ${destURL}.`); + const saveHandler = saveHandlers[0]; + const sourceScheme = parseURL(sourceURL).scheme; + const sourcePath = parseURL(sourceURL).path; + const sameMedium = sourceScheme === parseURL(sourceURL).scheme; + const modelArtifacts = await loadHandler.load(); + // If moving within the same storage medium, remove the old model as soon as + // the loading is done. Without doing this, it is possible that the combined + // size of the two models will cause the cloning to fail. + if (deleteSource && sameMedium) { + await ModelStoreManagerRegistry.getManager(sourceScheme) + .removeModel(sourcePath); + } + const saveResult = await saveHandler.save(modelArtifacts); + // If moving between mediums, the deletion is done after the save succeeds. + // This guards against the case in which saving to the destination medium + // fails. + if (deleteSource && !sameMedium) { + await ModelStoreManagerRegistry.getManager(sourceScheme) + .removeModel(sourcePath); + } + return saveResult.modelArtifactsInfo; + } + /** + * List all models stored in registered storage mediums. + * + * For a web browser environment, the registered mediums are Local Storage and + * IndexedDB. + * + * ```js + * // First create and save a model. + * const model = tf.sequential(); + * model.add(tf.layers.dense( + * {units: 1, inputShape: [10], activation: 'sigmoid'})); + * await model.save('localstorage://demo/management/model1'); + * + * // Then list existing models. + * console.log(JSON.stringify(await tf.io.listModels())); + * + * // Delete the model. + * await tf.io.removeModel('localstorage://demo/management/model1'); + * + * // List models again. + * console.log(JSON.stringify(await tf.io.listModels())); + * ``` + * + * @returns A `Promise` of a dictionary mapping URLs of existing models to + * their model artifacts info. URLs include medium-specific schemes, e.g., + * 'indexeddb://my/model/1'. Model artifacts info include type of the + * model's topology, byte sizes of the topology, weights, etc. + * + * @doc { + * heading: 'Models', + * subheading: 'Management', + * namespace: 'io', + * ignoreCI: true + * } + */ + async function listModels() { + const schemes = ModelStoreManagerRegistry.getSchemes(); + const out = {}; + for (const scheme of schemes) { + const schemeOut = await ModelStoreManagerRegistry.getManager(scheme).listModels(); + for (const path in schemeOut) { + const url = scheme + URL_SCHEME_SUFFIX + path; + out[url] = schemeOut[path]; + } + } + return out; + } + /** + * Remove a model specified by URL from a registered storage medium. + * + * ```js + * // First create and save a model. + * const model = tf.sequential(); + * model.add(tf.layers.dense( + * {units: 1, inputShape: [10], activation: 'sigmoid'})); + * await model.save('localstorage://demo/management/model1'); + * + * // Then list existing models. + * console.log(JSON.stringify(await tf.io.listModels())); + * + * // Delete the model. + * await tf.io.removeModel('localstorage://demo/management/model1'); + * + * // List models again. + * console.log(JSON.stringify(await tf.io.listModels())); + * ``` + * + * @param url A URL to a stored model, with a scheme prefix, e.g., + * 'localstorage://my-model-1', 'indexeddb://my/model/2'. + * @returns ModelArtifactsInfo of the deleted model (if and only if deletion + * is successful). + * @throws Error if deletion fails, e.g., if no model exists at `path`. + * + * @doc { + * heading: 'Models', + * subheading: 'Management', + * namespace: 'io', + * ignoreCI: true + * } + */ + async function removeModel(url) { + const schemeAndPath = parseURL(url); + const manager = ModelStoreManagerRegistry.getManager(schemeAndPath.scheme); + return manager.removeModel(schemeAndPath.path); + } + /** + * Copy a model from one URL to another. + * + * This function supports: + * + * 1. Copying within a storage medium, e.g., + * `tf.io.copyModel('localstorage://model-1', 'localstorage://model-2')` + * 2. Copying between two storage mediums, e.g., + * `tf.io.copyModel('localstorage://model-1', 'indexeddb://model-1')` + * + * ```js + * // First create and save a model. + * const model = tf.sequential(); + * model.add(tf.layers.dense( + * {units: 1, inputShape: [10], activation: 'sigmoid'})); + * await model.save('localstorage://demo/management/model1'); + * + * // Then list existing models. + * console.log(JSON.stringify(await tf.io.listModels())); + * + * // Copy the model, from Local Storage to IndexedDB. + * await tf.io.copyModel( + * 'localstorage://demo/management/model1', + * 'indexeddb://demo/management/model1'); + * + * // List models again. + * console.log(JSON.stringify(await tf.io.listModels())); + * + * // Remove both models. + * await tf.io.removeModel('localstorage://demo/management/model1'); + * await tf.io.removeModel('indexeddb://demo/management/model1'); + * ``` + * + * @param sourceURL Source URL of copying. + * @param destURL Destination URL of copying. + * @returns ModelArtifactsInfo of the copied model (if and only if copying + * is successful). + * @throws Error if copying fails, e.g., if no model exists at `sourceURL`, or + * if `oldPath` and `newPath` are identical. + * + * @doc { + * heading: 'Models', + * subheading: 'Management', + * namespace: 'io', + * ignoreCI: true + * } + */ + async function copyModel(sourceURL, destURL) { + const deleteSource = false; + return cloneModelInternal(sourceURL, destURL, deleteSource); + } + /** + * Move a model from one URL to another. + * + * This function supports: + * + * 1. Moving within a storage medium, e.g., + * `tf.io.moveModel('localstorage://model-1', 'localstorage://model-2')` + * 2. Moving between two storage mediums, e.g., + * `tf.io.moveModel('localstorage://model-1', 'indexeddb://model-1')` + * + * ```js + * // First create and save a model. + * const model = tf.sequential(); + * model.add(tf.layers.dense( + * {units: 1, inputShape: [10], activation: 'sigmoid'})); + * await model.save('localstorage://demo/management/model1'); + * + * // Then list existing models. + * console.log(JSON.stringify(await tf.io.listModels())); + * + * // Move the model, from Local Storage to IndexedDB. + * await tf.io.moveModel( + * 'localstorage://demo/management/model1', + * 'indexeddb://demo/management/model1'); + * + * // List models again. + * console.log(JSON.stringify(await tf.io.listModels())); + * + * // Remove the moved model. + * await tf.io.removeModel('indexeddb://demo/management/model1'); + * ``` + * + * @param sourceURL Source URL of moving. + * @param destURL Destination URL of moving. + * @returns ModelArtifactsInfo of the copied model (if and only if copying + * is successful). + * @throws Error if moving fails, e.g., if no model exists at `sourceURL`, or + * if `oldPath` and `newPath` are identical. + * + * @doc { + * heading: 'Models', + * subheading: 'Management', + * namespace: 'io', + * ignoreCI: true + * } + */ + async function moveModel(sourceURL, destURL) { + const deleteSource = true; + return cloneModelInternal(sourceURL, destURL, deleteSource); + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class PlatformBrowser { + constructor() { + // For setTimeoutCustom + this.messageName = 'setTimeoutCustom'; + this.functionRefs = []; + this.handledMessageCount = 0; + this.hasEventListener = false; + } + fetch(path, init) { + return fetch(path, init); + } + now() { + return performance.now(); + } + encode(text, encoding) { + if (encoding !== 'utf-8' && encoding !== 'utf8') { + throw new Error(`Browser's encoder only supports utf-8, but got ${encoding}`); + } + if (this.textEncoder == null) { + this.textEncoder = new TextEncoder(); + } + return this.textEncoder.encode(text); + } + decode(bytes, encoding) { + return new TextDecoder(encoding).decode(bytes); + } + // If the setTimeout nesting level is greater than 5 and timeout is less + // than 4ms, timeout will be clamped to 4ms, which hurts the perf. + // Interleaving window.postMessage and setTimeout will trick the browser and + // avoid the clamp. + setTimeoutCustom(functionRef, delay) { + if (typeof window === 'undefined' || + !env().getBool('USE_SETTIMEOUTCUSTOM')) { + setTimeout(functionRef, delay); + return; + } + this.functionRefs.push(functionRef); + setTimeout(() => { + window.postMessage({ name: this.messageName, index: this.functionRefs.length - 1 }, '*'); + }, delay); + if (!this.hasEventListener) { + this.hasEventListener = true; + window.addEventListener('message', (event) => { + if (event.source === window && event.data.name === this.messageName) { + event.stopPropagation(); + const functionRef = this.functionRefs[event.data.index]; + functionRef(); + this.handledMessageCount++; + if (this.handledMessageCount === this.functionRefs.length) { + this.functionRefs = []; + this.handledMessageCount = 0; + } + } + }, true); + } + } + isTypedArray(a) { + return isTypedArrayBrowser(a); + } + } + if (env().get('IS_BROWSER')) { + env().setPlatform('browser', new PlatformBrowser()); + // Register LocalStorage IOHandler + try { + ModelStoreManagerRegistry.registerManager(BrowserLocalStorage.URL_SCHEME, new BrowserLocalStorageManager()); + } + catch (err) { + } + // Register IndexedDB IOHandler + try { + ModelStoreManagerRegistry.registerManager(BrowserIndexedDB.URL_SCHEME, new BrowserIndexedDBManager()); + } + catch (err) { + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // We are wrapping this within an object so it can be stubbed by Jasmine. + const getNodeFetch = { + // tslint:disable-next-line:no-require-imports + importFetch: () => require('node-fetch') + }; + let systemFetch; + // These getters and setters are for testing so we don't export a mutable + // variable. + function resetSystemFetch() { + systemFetch = null; + } + function setSystemFetch(fetchFn) { + systemFetch = fetchFn; + } + function getSystemFetch() { + return systemFetch; + } + class PlatformNode { + constructor() { + // tslint:disable-next-line:no-require-imports + this.util = require('util'); + // According to the spec, the built-in encoder can do only UTF-8 encoding. + // https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder/TextEncoder + this.textEncoder = new this.util.TextEncoder(); + } + fetch(path, requestInits) { + if (env().global.fetch != null) { + return env().global.fetch(path, requestInits); + } + if (systemFetch == null) { + systemFetch = getNodeFetch.importFetch(); + } + return systemFetch(path, requestInits); + } + now() { + const time = process.hrtime(); + return time[0] * 1000 + time[1] / 1000000; + } + encode(text, encoding) { + if (encoding !== 'utf-8' && encoding !== 'utf8') { + throw new Error(`Node built-in encoder only supports utf-8, but got ${encoding}`); + } + return this.textEncoder.encode(text); + } + decode(bytes, encoding) { + if (bytes.length === 0) { + return ''; + } + return new this.util.TextDecoder(encoding).decode(bytes); + } + isTypedArray(a) { + return this.util.types.isFloat32Array(a) + || this.util.types.isInt32Array(a) + || this.util.types.isUint8Array(a) + || this.util.types.isUint8ClampedArray(a); + } + } + if (env().get('IS_NODE') && !env().get('IS_BROWSER')) { + env().setPlatform('node', new PlatformNode()); + } + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates an empty `tf.TensorBuffer` with the specified `shape` and `dtype`. + * + * The values are stored in CPU as `TypedArray`. Fill the buffer using + * `buffer.set()`, or by modifying directly `buffer.values`. + * + * When done, call `buffer.toTensor()` to get an immutable `tf.Tensor` with + * those values. + * + * ```js + * // Create a buffer and set values at particular indices. + * const buffer = tf.buffer([2, 2]); + * buffer.set(3, 0, 0); + * buffer.set(5, 1, 0); + * + * // Convert the buffer back to a tensor. + * buffer.toTensor().print(); + * ``` + * + * @param shape An array of integers defining the output tensor shape. + * @param dtype The dtype of the buffer. Defaults to 'float32'. + * @param values The values of the buffer as `TypedArray`. Defaults to + * zeros. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function buffer(shape, dtype = 'float32', values) { + dtype = dtype || 'float32'; + assertNonNegativeIntegerDimensions(shape); + return new TensorBuffer(shape, dtype, values); + } + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Casts a `tf.Tensor` to a new dtype. + * + * ```js + * const x = tf.tensor1d([1.5, 2.5, 3]); + * tf.cast(x, 'int32').print(); + * ``` + * @param x The input tensor to be casted. + * @param dtype The dtype to cast the input tensor to. + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function cast_(x, dtype) { + const $x = convertToTensor(x, 'x', 'cast'); + // Sanity checks. + if (!isValidDtype(dtype)) { + throw new Error(`Failed to cast to unknown dtype ${dtype}`); + } + if (dtype === 'string' && $x.dtype !== 'string' || + dtype !== 'string' && $x.dtype === 'string') { + throw new Error('Only strings can be casted to strings'); + } + const inputs = { x: $x }; + const attrs = { dtype }; + return ENGINE.runKernel(Cast, inputs, attrs); + } + const cast$3 = /* @__PURE__ */ op({ cast_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a new tensor with the same values and shape as the specified + * tensor. + * + * ```js + * const x = tf.tensor([1, 2]); + * + * x.clone().print(); + * ``` + * + * @param x The tensor to clone. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function clone_(x) { + const $x = convertToTensor(x, 'x', 'clone', 'string_or_numeric'); + const inputs = { x: $x }; + // Note this op is called tf.identity in python. Hence the kernel name used + // here. + return ENGINE.runKernel(Identity$1, inputs); + } + const clone = /* @__PURE__ */ op({ clone_ }); + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Prints information about the `tf.Tensor` including its data. + * + * ```js + * const verbose = true; + * tf.tensor2d([1, 2, 3, 4], [2, 2]).print(verbose); + * ``` + * @param x The tensor to be printed. + * @param verbose Whether to print verbose information about the ` Tensor`, + * including dtype and size. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function print(x, verbose = false) { + console.log(x.toString(verbose)); + } + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getOrMakeEngine(); + const opHandler = { + buffer, + cast: cast$3, + clone, + print + }; + setOpHandler(opHandler); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Adds two `tf.Tensor`s element-wise, A + B. Supports broadcasting. + * + * + * ```js + * const a = tf.tensor1d([1, 2, 3, 4]); + * const b = tf.tensor1d([10, 20, 30, 40]); + * + * a.add(b).print(); // or tf.add(a, b) + * ``` + * + * ```js + * // Broadcast add a with b. + * const a = tf.scalar(5); + * const b = tf.tensor1d([10, 20, 30, 40]); + * + * a.add(b).print(); // or tf.add(a, b) + * ``` + * @param a The first `tf.Tensor` to add. + * @param b The second `tf.Tensor` to add. Must have the same type as `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function add_(a, b) { + let $a = convertToTensor(a, 'a', 'add'); + let $b = convertToTensor(b, 'b', 'add'); + [$a, $b] = makeTypesMatch($a, $b); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Add$1, inputs); + } + const add$3 = /* @__PURE__ */ op({ add_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Divides two `tf.Tensor`s element-wise, A / B. Supports broadcasting. + * The result is rounded with floor function. + * + * + * ```js + * const a = tf.tensor1d([1, 4, 9, 16]); + * const b = tf.tensor1d([1, 2, 3, 4]); + * + * a.floorDiv(b).print(); // or tf.div(a, b) + * ``` + * + * ```js + * // Broadcast div a with b. + * const a = tf.tensor1d([2, 4, 6, 8]); + * const b = tf.scalar(2); + * + * a.floorDiv(b).print(); // or tf.floorDiv(a, b) + * ``` + * + * @param a The first tensor as the numerator. + * @param b The second tensor as the denominator. Must have the same dtype as + * `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function floorDiv_(a, b) { + let $a = convertToTensor(a, 'a', 'floorDiv'); + let $b = convertToTensor(b, 'b', 'floorDiv'); + [$a, $b] = makeTypesMatch($a, $b); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(FloorDiv, inputs); + } + const floorDiv$2 = /* @__PURE__ */ op({ floorDiv_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Divides two `tf.Tensor`s element-wise, A / B. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([1, 4, 9, 16]); + * const b = tf.tensor1d([1, 2, 3, 4]); + * + * a.div(b).print(); // or tf.div(a, b) + * ``` + * + * ```js + * // Broadcast div a with b. + * const a = tf.tensor1d([2, 4, 6, 8]); + * const b = tf.scalar(2); + * + * a.div(b).print(); // or tf.div(a, b) + * ``` + * + * @param a The first tensor as the numerator. + * @param b The second tensor as the denominator. Must have the same dtype as + * `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function div_(a, b) { + let $a = convertToTensor(a, 'a', 'div'); + let $b = convertToTensor(b, 'b', 'div'); + [$a, $b] = makeTypesMatch($a, $b); + if ($a.dtype === 'int32' && $b.dtype === 'int32') { + return floorDiv$2($a, $b); + } + const inputs = { a: $a, b: $b }; + const attrs = {}; + // tslint:disable-next-line: no-unnecessary-type-assertion + return ENGINE.runKernel(RealDiv, inputs, attrs); + } + const div$1 = /* @__PURE__ */ op({ div_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Multiplies two `tf.Tensor`s element-wise, A * B. Supports broadcasting. + * + * We also expose `tf.mulStrict` which has the same signature as this op and + * asserts that `a` and `b` are the same shape (does not broadcast). + * + * ```js + * const a = tf.tensor1d([1, 2, 3, 4]); + * const b = tf.tensor1d([2, 3, 4, 5]); + * + * a.mul(b).print(); // or tf.mul(a, b) + * ``` + * + * ```js + * // Broadcast mul a with b. + * const a = tf.tensor1d([1, 2, 3, 4]); + * const b = tf.scalar(5); + * + * a.mul(b).print(); // or tf.mul(a, b) + * ``` + * @param a The first tensor to multiply. + * @param b The second tensor to multiply. Must have the same dtype as `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function mul_(a, b) { + let $a = convertToTensor(a, 'a', 'mul'); + let $b = convertToTensor(b, 'b', 'mul'); + [$a, $b] = makeTypesMatch($a, $b); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Multiply$1, inputs); + } + const mul = /* @__PURE__ */ op({ mul_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes absolute value element-wise: `abs(x)` + * + * ```js + * const x = tf.tensor1d([-1, 2, -3, 4]); + * + * x.abs().print(); // or tf.abs(x) + * ``` + * @param x The input `tf.Tensor`. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function abs_(x) { + const $x = convertToTensor(x, 'x', 'abs'); + if ($x.dtype === 'complex64') { + const inputs = { x: $x }; + return ENGINE.runKernel(ComplexAbs, inputs); + } + else { + const inputs = { x: $x }; + return ENGINE.runKernel(Abs, inputs); + } + } + const abs$2 = /* @__PURE__ */ op({ abs_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes acos of the input `tf.Tensor` element-wise: `acos(x)` + * + * ```js + * const x = tf.tensor1d([0, 1, -1, .7]); + * + * x.acos().print(); // or tf.acos(x) + * ``` + * @param x The input tensor. + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function acos_(x) { + const $x = convertToTensor(x, 'x', 'acos'); + const inputs = { x: $x }; + return ENGINE.runKernel(Acos, inputs); + } + const acos$2 = /* @__PURE__ */ op({ acos_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the inverse hyperbolic cos of the input `tf.Tensor` element-wise: + * `acosh(x)` + * + * ```js + * const x = tf.tensor1d([10, 1, 3, 5.7]); + * + * x.acosh().print(); // or tf.acosh(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function acosh_(x) { + const $x = convertToTensor(x, 'x', 'acosh'); + const inputs = { x: $x }; + return ENGINE.runKernel(Acosh, inputs); + } + const acosh$2 = /* @__PURE__ */ op({ acosh_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Adds a list of `tf.Tensor`s element-wise, each with the same shape and dtype. + * + * ```js + * const a = tf.tensor1d([1, 2]); + * const b = tf.tensor1d([3, 4]); + * const c = tf.tensor1d([5, 6]); + * + * tf.addN([a, b, c]).print(); + * ``` + * @param tensors A list of tensors with the same shape and dtype. + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function addN_(tensors) { + assert$1(Array.isArray(tensors), () => 'The argument passed to tf.addN() must be a list of tensors'); + assert$1(tensors.length >= 1, () => `Must pass at least one tensor to tf.addN(), but got ` + + `${tensors.length}`); + const $tensors = tensors.map((t, i) => convertToTensor(t, `tensors${i}`, 'addN')); + const firstTensor = $tensors[0]; + $tensors.forEach(t => { + if (t.dtype !== firstTensor.dtype) { + throw new Error('All tensors passed to tf.addN() must have the same dtype'); + } + }); + $tensors.forEach(t => { + if (!arraysEqual(t.shape, firstTensor.shape)) { + throw new Error('All tensors passed to tf.addN() must have the same shape'); + } + }); + const inputs = $tensors; + return ENGINE.runKernel(AddN, inputs); + } + const addN$2 = /* @__PURE__ */ op({ addN_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the logical and of elements across dimensions of a `tf.Tensor`. + * + * Reduces the input along the dimensions given in `axes`. Unless `keepDims` + * is true, the rank of the `tf.Tensor` is reduced by 1 for each entry in + * `axes`. If `keepDims` is true, the reduced dimensions are retained with + * length 1. If `axes` has no entries, all dimensions are reduced, and a + * `tf.Tensor` with a single element is returned. + * + * ```js + * const x = tf.tensor1d([1, 1, 1], 'bool'); + * + * x.all().print(); // or tf.all(x) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 1, 0, 0], [2, 2], 'bool'); + * + * const axis = 1; + * x.all(axis).print(); // or tf.all(x, axis) + * ``` + * + * @param x The input tensor. Must be of dtype bool. + * @param axis The dimension(s) to reduce. By default it reduces + * all dimensions. + * @param keepDims If true, retains reduced dimensions with size 1. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function all_(x, axis = null, keepDims = false) { + const $x = convertToTensor(x, 'x', 'all', 'bool'); + const inputs = { x: $x }; + const attrs = { axis, keepDims }; + return ENGINE.runKernel(All, inputs, attrs); + } + const all$2 = /* @__PURE__ */ op({ all_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the logical or of elements across dimensions of a `tf.Tensor`. + * + * Reduces the input along the dimensions given in `axes`. Unless `keepDims` + * is true, the rank of the `tf.Tensor` is reduced by 1 for each entry in + * `axes`. If `keepDims` is true, the reduced dimensions are retained with + * length 1. If `axes` has no entries, all dimensions are reduced, and a + * `tf.Tensor` with a single element is returned. + * + * ```js + * const x = tf.tensor1d([1, 1, 1], 'bool'); + * + * x.any().print(); // or tf.any(x) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 1, 0, 0], [2, 2], 'bool'); + * + * const axis = 1; + * x.any(axis).print(); // or tf.any(x, axis) + * ``` + * + * @param x The input tensor. Must be of dtype bool. + * @param axis The dimension(s) to reduce. By default it reduces + * all dimensions. + * @param keepDims If true, retains reduced dimensions with size 1. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function any_(x, axis = null, keepDims = false) { + const $x = convertToTensor(x, 'x', 'any', 'bool'); + const inputs = { x: $x }; + const attrs = { axis, keepDims }; + return ENGINE.runKernel(Any, inputs, attrs); + } + // tslint:disable-next-line:variable-name + const any$2 = /* @__PURE__ */ op({ any_ }); + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the indices of the maximum values along an `axis`. + * + * The result has the same shape as `input` with the dimension along `axis` + * removed. + * + * ```js + * const x = tf.tensor1d([1, 2, 3]); + * + * x.argMax().print(); // or tf.argMax(x) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 4, 3], [2, 2]); + * + * const axis = 1; + * x.argMax(axis).print(); // or tf.argMax(x, axis) + * ``` + * + * @param x The input tensor. + * @param axis The dimension to reduce. Defaults to 0 (outer-most dimension). + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function argMax_(x, axis = 0) { + const $x = convertToTensor(x, 'x', 'argMax'); + const inputs = { x: $x }; + const attrs = { axis }; + return ENGINE.runKernel(ArgMax, inputs, attrs); + } + const argMax$2 = /* @__PURE__ */ op({ argMax_ }); + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the indices of the minimum values along an `axis`. + * + * The result has the same shape as `input` with the dimension along `axis` + * removed. + * + * ```js + * const x = tf.tensor1d([1, 2, 3]); + * + * x.argMin().print(); // or tf.argMin(x) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 4, 3], [2, 2]); + * + * const axis = 1; + * x.argMin(axis).print(); // or tf.argMin(x, axis) + * ``` + * + * @param x The input tensor. + * @param axis The dimension to reduce. Defaults to 0 (outer-most dimension). + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function argMin_(x, axis = 0) { + const $x = convertToTensor(x, 'x', 'argMin'); + const inputs = { x: $x }; + const attrs = { axis }; + return ENGINE.runKernel(ArgMin, inputs, attrs); + } + const argMin$2 = /* @__PURE__ */ op({ argMin_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes asin of the input `tf.Tensor` element-wise: `asin(x)` + * + * ```js + * const x = tf.tensor1d([0, 1, -1, .7]); + * + * x.asin().print(); // or tf.asin(x) + * ``` + * @param x The input tensor. + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function asin_(x) { + const $x = convertToTensor(x, 'x', 'asin'); + const inputs = { x: $x }; + return ENGINE.runKernel(Asin, inputs); + } + const asin$2 = /* @__PURE__ */ op({ asin_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes inverse hyperbolic sin of the input `tf.Tensor` element-wise: + * `asinh(x)` + * + * ```js + * const x = tf.tensor1d([0, 1, -1, .7]); + * + * x.asinh().print(); // or tf.asinh(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function asinh_(x) { + const $x = convertToTensor(x, 'x', 'asinh'); + const inputs = { x: $x }; + return ENGINE.runKernel(Asinh, inputs); + } + const asinh$2 = /* @__PURE__ */ op({ asinh_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes atan of the input `tf.Tensor` element-wise: `atan(x)` + * + * ```js + * const x = tf.tensor1d([0, 1, -1, .7]); + * + * x.atan().print(); // or tf.atan(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function atan_(x) { + const $x = convertToTensor(x, 'x', 'atan'); + const inputs = { x: $x }; + return ENGINE.runKernel(Atan, inputs); + } + const atan$2 = /* @__PURE__ */ op({ atan_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes arctangent of `tf.Tensor`s a / b element-wise: `atan2(a, b)`. + * Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([1.0, 1.0, -1.0, .7]); + * const b = tf.tensor1d([2.0, 13.0, 3.5, .21]); + * + * tf.atan2(a, b).print() + * ``` + * + * @param a The first tensor. + * @param b The second tensor. Must have the same dtype as `a`. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function atan2_(a, b) { + let $a = convertToTensor(a, 'a', 'atan2'); + let $b = convertToTensor(b, 'b', 'atan2'); + [$a, $b] = makeTypesMatch($a, $b); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Atan2, inputs); + } + const atan2$2 = /* @__PURE__ */ op({ atan2_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes inverse hyperbolic tan of the input `tf.Tensor` element-wise: + * `atanh(x)` + * + * ```js + * const x = tf.tensor1d([0, .1, -.1, .7]); + * + * x.atanh().print(); // or tf.atanh(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function atanh_(x) { + const $x = convertToTensor(x, 'x', 'atanh'); + const inputs = { x: $x }; + return ENGINE.runKernel(Atanh, inputs); + } + const atanh$2 = /* @__PURE__ */ op({ atanh_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * + * @param inputShape Input tensor shape is of the following dimensions: + * `[batch, height, width, inChannels]`. + * @param filterShape The filter shape is of the following dimensions: + * `[filterHeight, filterWidth, depth]`. + * @param strides The strides of the sliding window for each dimension of the + * input tensor: `[strideHeight, strideWidth]`. + * If `strides` is a single number, + * then `strideHeight == strideWidth`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1*1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dataFormat The data format of the input and output data. + * Defaults to 'NHWC'. + * @param dilations The dilation rates: `[dilationHeight, dilationWidth]`. + * Defaults to `[1, 1]`. If `dilations` is a single number, then + * `dilationHeight == dilationWidth`. + */ + function computeDilation2DInfo(inputShape, filterShape, strides, pad, dataFormat = 'NHWC', dilations) { + // `computerConv2DInfo` require filterShape to be in the dimension of: + // `[filterHeight, filterWidth, depth, outDepth]`, dilation2d doesn't have + // outDepth, it should have the same depth as the input. + // Input shape: [batch, height, width, inChannels] + const inputChannels = inputShape[3]; + const $filterShape = [...filterShape, inputChannels]; + const $dataFormat = convertConv2DDataFormat(dataFormat); + return computeConv2DInfo(inputShape, $filterShape, strides, dilations, pad, null /* roundingMode */, null /* depthWise */, $dataFormat); + } + function computePool2DInfo(inShape, filterSize, strides, dilations, pad, roundingMode, dataFormat = 'channelsLast') { + const [filterHeight, filterWidth] = parseTupleParam(filterSize); + let filterShape; + if (dataFormat === 'channelsLast') { + filterShape = [filterHeight, filterWidth, inShape[3], inShape[3]]; + } + else if (dataFormat === 'channelsFirst') { + filterShape = [filterHeight, filterWidth, inShape[1], inShape[1]]; + } + else { + throw new Error(`Unknown dataFormat ${dataFormat}`); + } + return computeConv2DInfo(inShape, filterShape, strides, dilations, pad, roundingMode, false, dataFormat); + } + /** + * Computes the information for a forward pass of a pooling3D operation. + */ + function computePool3DInfo(inShape, filterSize, strides, dilations, pad, roundingMode, dataFormat = 'NDHWC') { + const [filterDepth, filterHeight, filterWidth] = parse3TupleParam(filterSize); + let filterShape; + let $dataFormat; + if (dataFormat === 'NDHWC') { + $dataFormat = 'channelsLast'; + filterShape = + [filterDepth, filterHeight, filterWidth, inShape[4], inShape[4]]; + } + else if (dataFormat === 'NCDHW') { + $dataFormat = 'channelsFirst'; + filterShape = + [filterDepth, filterHeight, filterWidth, inShape[1], inShape[1]]; + } + else { + throw new Error(`Unknown dataFormat ${dataFormat}`); + } + return computeConv3DInfo(inShape, filterShape, strides, dilations, pad, false, $dataFormat, roundingMode); + } + /** + * Computes the information for a forward pass of a convolution/pooling + * operation. + */ + function computeConv2DInfo(inShape, filterShape, strides, dilations, pad, roundingMode, depthwise = false, dataFormat = 'channelsLast') { + let [batchSize, inHeight, inWidth, inChannels] = [-1, -1, -1, -1]; + if (dataFormat === 'channelsLast') { + [batchSize, inHeight, inWidth, inChannels] = inShape; + } + else if (dataFormat === 'channelsFirst') { + [batchSize, inChannels, inHeight, inWidth] = inShape; + } + else { + throw new Error(`Unknown dataFormat ${dataFormat}`); + } + const [filterHeight, filterWidth, , filterChannels] = filterShape; + const [strideHeight, strideWidth] = parseTupleParam(strides); + const [dilationHeight, dilationWidth] = parseTupleParam(dilations); + const effectiveFilterHeight = getEffectiveFilterSize(filterHeight, dilationHeight); + const effectiveFilterWidth = getEffectiveFilterSize(filterWidth, dilationWidth); + const { padInfo, outHeight, outWidth } = getPadAndOutInfo(pad, inHeight, inWidth, strideHeight, strideWidth, effectiveFilterHeight, effectiveFilterWidth, roundingMode, dataFormat); + const outChannels = depthwise ? filterChannels * inChannels : filterChannels; + let outShape; + if (dataFormat === 'channelsFirst') { + outShape = [batchSize, outChannels, outHeight, outWidth]; + } + else if (dataFormat === 'channelsLast') { + outShape = [batchSize, outHeight, outWidth, outChannels]; + } + return { + batchSize, + dataFormat, + inHeight, + inWidth, + inChannels, + outHeight, + outWidth, + outChannels, + padInfo, + strideHeight, + strideWidth, + filterHeight, + filterWidth, + effectiveFilterHeight, + effectiveFilterWidth, + dilationHeight, + dilationWidth, + inShape, + outShape, + filterShape + }; + } + /** + * Computes the information for a forward pass of a 3D convolution/pooling + * operation. + */ + function computeConv3DInfo(inShape, filterShape, strides, dilations, pad, depthwise = false, dataFormat = 'channelsLast', roundingMode) { + let [batchSize, inDepth, inHeight, inWidth, inChannels] = [-1, -1, -1, -1, -1]; + if (dataFormat === 'channelsLast') { + [batchSize, inDepth, inHeight, inWidth, inChannels] = inShape; + } + else if (dataFormat === 'channelsFirst') { + [batchSize, inChannels, inDepth, inHeight, inWidth] = inShape; + } + else { + throw new Error(`Unknown dataFormat ${dataFormat}`); + } + const [filterDepth, filterHeight, filterWidth, , filterChannels] = filterShape; + const [strideDepth, strideHeight, strideWidth] = parse3TupleParam(strides); + const [dilationDepth, dilationHeight, dilationWidth] = parse3TupleParam(dilations); + const effectiveFilterDepth = getEffectiveFilterSize(filterDepth, dilationDepth); + const effectiveFilterHeight = getEffectiveFilterSize(filterHeight, dilationHeight); + const effectiveFilterWidth = getEffectiveFilterSize(filterWidth, dilationWidth); + const { padInfo, outDepth, outHeight, outWidth } = get3DPadAndOutInfo(pad, inDepth, inHeight, inWidth, strideDepth, strideHeight, strideWidth, effectiveFilterDepth, effectiveFilterHeight, effectiveFilterWidth, roundingMode); + const outChannels = depthwise ? filterChannels * inChannels : filterChannels; + let outShape; + if (dataFormat === 'channelsFirst') { + outShape = [batchSize, outChannels, outDepth, outHeight, outWidth]; + } + else if (dataFormat === 'channelsLast') { + outShape = [batchSize, outDepth, outHeight, outWidth, outChannels]; + } + return { + batchSize, + dataFormat, + inDepth, + inHeight, + inWidth, + inChannels, + outDepth, + outHeight, + outWidth, + outChannels, + padInfo, + strideDepth, + strideHeight, + strideWidth, + filterDepth, + filterHeight, + filterWidth, + effectiveFilterDepth, + effectiveFilterHeight, + effectiveFilterWidth, + dilationDepth, + dilationHeight, + dilationWidth, + inShape, + outShape, + filterShape + }; + } + function computeOutputShape2D(inShape, fieldSize, stride, zeroPad, roundingMode) { + if (zeroPad == null) { + zeroPad = computeDefaultPad(inShape, fieldSize, stride); + } + const inputRows = inShape[0]; + const inputCols = inShape[1]; + const outputRows = round$3((inputRows - fieldSize + 2 * zeroPad) / stride + 1, roundingMode); + const outputCols = round$3((inputCols - fieldSize + 2 * zeroPad) / stride + 1, roundingMode); + return [outputRows, outputCols]; + } + function computeOutputShape4D(inShape, filterShape, outChannels, strides, zeroPad, roundingMode) { + if (zeroPad == null) { + zeroPad = computeDefaultPad(inShape, filterShape[0], strides[0]); + } + const outShape = [0, 0, 0, outChannels]; + for (let index = 0; index < 3; index++) { + if (inShape[index] + 2 * zeroPad >= filterShape[index]) { + outShape[index] = round$3((inShape[index] - filterShape[index] + 2 * zeroPad) / strides[index] + + 1, roundingMode); + } + } + return outShape; + } + function computeDefaultPad(inputShape, fieldSize, stride, dilation = 1) { + const effectiveFieldSize = getEffectiveFilterSize(fieldSize, dilation); + return Math.floor((inputShape[0] * (stride - 1) - stride + effectiveFieldSize) / 2); + } + function parseTupleParam(param) { + if (typeof param === 'number') { + return [param, param, param]; + } + if (param.length === 2) { + return [param[0], param[1], 1]; + } + return param; + } + function parse3TupleParam(param) { + return typeof param === 'number' ? [param, param, param] : param; + } + /* See https://www.tensorflow.org/api_docs/python/tf/nn/atrous_conv2d + * Atrous convolution is equivalent to standard convolution with upsampled + * filters with effective_filter_height = + * filter_height + (filter_height - 1) * (dilation - 1) + * and effective_filter_width = + * filter_width + (filter_width - 1) * (dilation - 1), + * produced by inserting dilation - 1 zeros along consecutive elements across + * the filters' spatial dimensions. + * When there is a dilation, this converts a filter dimension to the + * effective filter dimension, so it can be used in a standard convolution. + */ + function getEffectiveFilterSize(filterSize, dilation) { + if (dilation <= 1) { + return filterSize; + } + return filterSize + (filterSize - 1) * (dilation - 1); + } + function getPadAndOutInfo(pad, inHeight, inWidth, strideHeight, strideWidth, filterHeight, filterWidth, roundingMode, dataFormat) { + let padInfo; + let outHeight; + let outWidth; + if (typeof pad === 'number') { + const padType = (pad === 0) ? 'VALID' : 'NUMBER'; + padInfo = { top: pad, bottom: pad, left: pad, right: pad, type: padType }; + const outShape = computeOutputShape2D([inHeight, inWidth], filterHeight, strideHeight, pad, roundingMode); + outHeight = outShape[0]; + outWidth = outShape[1]; + } + else if (pad === 'same') { + outHeight = Math.ceil(inHeight / strideHeight); + outWidth = Math.ceil(inWidth / strideWidth); + const padAlongHeight = Math.max(0, (outHeight - 1) * strideHeight + filterHeight - inHeight); + const padAlongWidth = Math.max(0, (outWidth - 1) * strideWidth + filterWidth - inWidth); + const top = Math.floor(padAlongHeight / 2); + const bottom = padAlongHeight - top; + const left = Math.floor(padAlongWidth / 2); + const right = padAlongWidth - left; + padInfo = { top, bottom, left, right, type: 'SAME' }; + } + else if (pad === 'valid') { + padInfo = { top: 0, bottom: 0, left: 0, right: 0, type: 'VALID' }; + outHeight = Math.ceil((inHeight - filterHeight + 1) / strideHeight); + outWidth = Math.ceil((inWidth - filterWidth + 1) / strideWidth); + } + else if (typeof pad === 'object') { + const top = dataFormat === 'channelsLast' ? pad[1][0] : pad[2][0]; + const bottom = dataFormat === 'channelsLast' ? pad[1][1] : pad[2][1]; + const left = dataFormat === 'channelsLast' ? pad[2][0] : pad[3][0]; + const right = dataFormat === 'channelsLast' ? pad[2][1] : pad[3][1]; + const padType = (top === 0 && bottom === 0 && left === 0 && right === 0) ? + 'VALID' : + 'EXPLICIT'; + padInfo = { top, bottom, left, right, type: padType }; + outHeight = round$3((inHeight - filterHeight + top + bottom) / strideHeight + 1, roundingMode); + outWidth = round$3((inWidth - filterWidth + left + right) / strideWidth + 1, roundingMode); + } + else { + throw Error(`Unknown padding parameter: ${pad}`); + } + return { padInfo, outHeight, outWidth }; + } + function get3DPadAndOutInfo(pad, inDepth, inHeight, inWidth, strideDepth, strideHeight, strideWidth, filterDepth, filterHeight, filterWidth, roundingMode) { + let padInfo; + let outDepth; + let outHeight; + let outWidth; + if (pad === 'valid') { + pad = 0; + } + if (typeof pad === 'number') { + const padType = (pad === 0) ? 'VALID' : 'NUMBER'; + padInfo = { + top: pad, + bottom: pad, + left: pad, + right: pad, + front: pad, + back: pad, + type: padType + }; + const outShape = computeOutputShape4D([inDepth, inHeight, inWidth, 1], [filterDepth, filterHeight, filterWidth], 1, [strideDepth, strideHeight, strideWidth], pad, roundingMode); + outDepth = outShape[0]; + outHeight = outShape[1]; + outWidth = outShape[2]; + } + else if (pad === 'same') { + outDepth = Math.ceil(inDepth / strideDepth); + outHeight = Math.ceil(inHeight / strideHeight); + outWidth = Math.ceil(inWidth / strideWidth); + const padAlongDepth = (outDepth - 1) * strideDepth + filterDepth - inDepth; + const padAlongHeight = (outHeight - 1) * strideHeight + filterHeight - inHeight; + const padAlongWidth = (outWidth - 1) * strideWidth + filterWidth - inWidth; + const front = Math.floor(padAlongDepth / 2); + const back = padAlongDepth - front; + const top = Math.floor(padAlongHeight / 2); + const bottom = padAlongHeight - top; + const left = Math.floor(padAlongWidth / 2); + const right = padAlongWidth - left; + padInfo = { top, bottom, left, right, front, back, type: 'SAME' }; + } + else { + throw Error(`Unknown padding parameter: ${pad}`); + } + return { padInfo, outDepth, outHeight, outWidth }; + } + /** + * Rounds a value depending on the rounding mode + * @param value + * @param roundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + */ + function round$3(value, roundingMode) { + if (!roundingMode) { + return Math.trunc(value); + } + switch (roundingMode) { + case 'round': + // used for Caffe Conv + return Math.round(value); + case 'ceil': + // used for Caffe Pool + return Math.ceil(value); + case 'floor': + return Math.floor(value); + default: + throw new Error(`Unknown roundingMode ${roundingMode}`); + } + } + function tupleValuesAreOne(param) { + const [dimA, dimB, dimC] = parseTupleParam(param); + return dimA === 1 && dimB === 1 && dimC === 1; + } + function eitherStridesOrDilationsAreOne(strides, dilations) { + return tupleValuesAreOne(strides) || tupleValuesAreOne(dilations); + } + function stridesOrDilationsArePositive(values) { + return parseTupleParam(values).every(value => value > 0); + } + /** + * Convert Conv2D dataFormat from 'NHWC'|'NCHW' to + * 'channelsLast'|'channelsFirst' + * @param dataFormat in 'NHWC'|'NCHW' mode + * @return dataFormat in 'channelsLast'|'channelsFirst' mode + * @throws unknown dataFormat + */ + function convertConv2DDataFormat(dataFormat) { + if (dataFormat === 'NHWC') { + return 'channelsLast'; + } + else if (dataFormat === 'NCHW') { + return 'channelsFirst'; + } + else { + throw new Error(`Unknown dataFormat ${dataFormat}`); + } + } + /** + * Check validity of pad when using dimRoundingMode. + * @param opDesc A string of op description + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid` output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * @throws unknown padding parameter + */ + function checkPadOnDimRoundingMode(opDesc, pad, dimRoundingMode) { + if (dimRoundingMode != null) { + if (typeof pad === 'string') { + throw Error(`Error in ${opDesc}: pad must be an integer when using ` + + `dimRoundingMode ${dimRoundingMode} but got pad ${pad}.`); + } + else if (typeof pad === 'number') { + assert$1(isInt(pad), () => `Error in ${opDesc}: pad must be an integer when using ` + + `dimRoundingMode ${dimRoundingMode} but got pad ${pad}.`); + } + else if (typeof pad === 'object') { + pad.forEach(p => { + p.forEach(v => { + assert$1(isInt(v), () => `Error in ${opDesc}: pad must be an integer when using ` + + `dimRoundingMode ${dimRoundingMode} but got pad ${v}.`); + }); + }); + } + else { + throw Error(`Error in ${opDesc}: Unknown padding parameter: ${pad}`); + } + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Reshapes a `tf.Tensor` to a given shape. + * + * Given an input tensor, returns a new tensor with the same values as the + * input tensor with shape `shape`. + * + * If one component of shape is the special value -1, the size of that + * dimension is computed so that the total size remains constant. In + * particular, a shape of [-1] flattens into 1-D. At most one component of + * shape can be -1. + * + * If shape is 1-D or higher, then the operation returns a tensor with shape + * shape filled with the values of tensor. In this case, the number of + * elements implied by shape must be the same as the number of elements in + * tensor. + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * x.reshape([2, 2]).print(); + * ``` + * + * @param x The input tensor to be reshaped. + * @param shape An array of integers defining the output tensor shape. + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function reshape_(x, shape) { + const $x = convertToTensor(x, 'x', 'reshape', 'string_or_numeric'); + const inputs = { x: $x }; + const attrs = { shape }; + return ENGINE.runKernel(Reshape$1, inputs, attrs); + } + const reshape$3 = /* @__PURE__ */ op({ reshape_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the 2D average pooling of an image. + * + * @param x The input tensor, of rank 4 or rank 3 of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is assumed. + * @param filterSize The filter size: `[filterHeight, filterWidth]`. If + * `filterSize` is a single number, then `filterHeight == filterWidth`. + * @param strides The strides of the pooling: `[strideHeight, strideWidth]`. If + * `strides` is a single number, then `strideHeight == strideWidth`. + * @param pad The type of padding algorithm: + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function avgPool_(x, filterSize, strides, pad, dimRoundingMode) { + const $x = convertToTensor(x, 'x', 'avgPool', 'float32'); + const dilations = 1; + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in avgPool: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + reshapedTo4D = true; + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + } + assert$1(x4D.rank === 4, () => `Error in avgPool: x must be rank 4 but got rank ${x4D.rank}.`); + checkPadOnDimRoundingMode('avgPool', pad, dimRoundingMode); + const inputs = { x: x4D }; + const attrs = { filterSize, strides, pad, dimRoundingMode }; + // tslint:disable-next-line: no-unnecessary-type-assertion + let res = ENGINE.runKernel(AvgPool, inputs, attrs); + res = cast$3(res, $x.dtype); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const avgPool$2 = /* @__PURE__ */ op({ avgPool_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the 3D average pooling. + * + * ```js + * const x = tf.tensor5d([1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 2, 2, 1]); + * const result = tf.avgPool3d(x, 2, 1, 'valid'); + * result.print(); + * ``` + * + * @param x The input tensor, of rank 5 or rank 4 of shape + * `[batch, depth, height, width, inChannels]`. + * @param filterSize The filter size: + * `[filterDepth, filterHeight, filterWidth]`. + * If `filterSize` is a single number, + * then `filterDepth == filterHeight == filterWidth`. + * @param strides The strides of the pooling: + * `[strideDepth, strideHeight, strideWidth]`. + * If `strides` is a single number, + * then `strideDepth == strideHeight == strideWidth`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1*1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * @param dataFormat An optional string from: "NDHWC", "NCDHW". Defaults to + * "NDHWC". Specify the data format of the input and output data. With the + * default format "NDHWC", the data is stored in the order of: [batch, + * depth, height, width, channels]. Only "NDHWC" is currently supported. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function avgPool3d_(x, filterSize, strides, pad, dimRoundingMode, dataFormat = 'NDHWC') { + const $x = convertToTensor(x, 'x', 'avgPool3d', 'float32'); + let x5D = $x; + let reshapedTo5D = false; + if ($x.rank === 4) { + reshapedTo5D = true; + x5D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2], $x.shape[3]]); + } + assert$1(x5D.rank === 5, () => `Error in avgPool3d: x must be rank 5 but got rank ${x5D.rank}.`); + assert$1(dataFormat === 'NDHWC', () => `Error in avgPool3d: Only NDHWC is currently supported, ` + + `but got dataFormat of ${dataFormat}`); + assert$1((typeof strides === 'number' && strides > 0) || + (Array.isArray(strides) && strides[0] > 0 && strides[1] > 0 && + strides[2] > 0), () => `Error in avgPool3d: Stride must be > 0, but got '${strides}'`); + checkPadOnDimRoundingMode('avgPool3d', pad, dimRoundingMode); + const inputs = { x: x5D }; + const attrs = { filterSize, strides, pad, dimRoundingMode, dataFormat }; + // tslint:disable-next-line: no-unnecessary-type-assertion + let res = ENGINE.runKernel(AvgPool3D, inputs, attrs); + res = cast$3(res, x5D.dtype); + if (reshapedTo5D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3], res.shape[4]]); + } + return res; + } + const avgPool3d$1 = /* @__PURE__ */ op({ avgPool3d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Concatenates a list of `tf.Tensor`s along a given axis. + * + * The tensors ranks and types must match, and their sizes must match in all + * dimensions except `axis`. + * + * Also available are stricter rank-specific methods that assert that + * `tensors` are of the given rank: + * - `tf.concat1d` + * - `tf.concat2d` + * - `tf.concat3d` + * - `tf.concat4d` + * + * Except `tf.concat1d` (which does not have axis param), all methods have + * same signature as this method. + * + * ```js + * const a = tf.tensor1d([1, 2]); + * const b = tf.tensor1d([3, 4]); + * a.concat(b).print(); // or a.concat(b) + * ``` + * + * ```js + * const a = tf.tensor1d([1, 2]); + * const b = tf.tensor1d([3, 4]); + * const c = tf.tensor1d([5, 6]); + * tf.concat([a, b, c]).print(); + * ``` + * + * ```js + * const a = tf.tensor2d([[1, 2], [10, 20]]); + * const b = tf.tensor2d([[3, 4], [30, 40]]); + * const axis = 1; + * tf.concat([a, b], axis).print(); + * ``` + * @param tensors A list of tensors to concatenate. + * @param axis The axis to concatenate along. Defaults to 0 (the first dim). + * + * @doc {heading: 'Tensors', subheading: 'Slicing and Joining'} + */ + function concat_(tensors, axis = 0) { + assert$1(tensors.length >= 1, () => 'Pass at least one tensor to concat'); + const $tensors = convertToTensorArray(tensors, 'tensors', 'concat', 'string_or_numeric'); + if ($tensors[0].dtype === 'complex64') { + $tensors.forEach(tensor => { + if (tensor.dtype !== 'complex64') { + throw new Error(`Cannot concatenate complex64 tensors with a tensor + with dtype ${tensor.dtype}. `); + } + }); + } + if ($tensors.length === 1) { + return clone($tensors[0]); + } + const inputs = $tensors; + const attr = { axis }; + return ENGINE.runKernel(Concat, inputs, attr); + } + const concat$2 = /* @__PURE__ */ op({ concat_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the dot product of two matrices, A * B. These must be matrices. + * + * ```js + * const a = tf.tensor2d([1, 2], [1, 2]); + * const b = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * a.matMul(b).print(); // or tf.matMul(a, b) + * ``` + * @param a First matrix in dot product operation. + * @param b Second matrix in dot product operation. + * @param transposeA If true, `a` is transposed before multiplication. + * @param transposeB If true, `b` is transposed before multiplication. + * + * @doc {heading: 'Operations', subheading: 'Matrices'} + */ + function matMul_(a, b, transposeA = false, transposeB = false) { + let $a = convertToTensor(a, 'a', 'matMul'); + let $b = convertToTensor(b, 'b', 'matMul'); + [$a, $b] = makeTypesMatch($a, $b); + const inputs = { a: $a, b: $b }; + const attrs = { transposeA, transposeB }; + return ENGINE.runKernel(BatchMatMul, inputs, attrs); + } + const matMul$1 = /* @__PURE__ */ op({ matMul_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes sigmoid element-wise, `1 / (1 + exp(-x))` + * + * ```js + * const x = tf.tensor1d([0, -1, 2, -3]); + * + * x.sigmoid().print(); // or tf.sigmoid(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function sigmoid_(x) { + const $x = convertToTensor(x, 'x', 'sigmoid', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Sigmoid$1, inputs); + } + const sigmoid$2 = /* @__PURE__ */ op({ sigmoid_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Extracts a slice from a `tf.Tensor` starting at coordinates `begin` + * and is of size `size`. + * + * Also available are stricter rank-specific methods with the same signature + * as this method that assert that `x` is of the given rank: + * - `tf.slice1d` + * - `tf.slice2d` + * - `tf.slice3d` + * - `tf.slice4d` + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * + * x.slice([1], [2]).print(); + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * x.slice([1, 0], [1, 2]).print(); + * ``` + * @param x The input `tf.Tensor` to slice from. + * @param begin The coordinates to start the slice from. The length can be + * less than the rank of x - the rest of the axes will have implicit 0 as + * start. Can also be a single number, in which case it specifies the + * first axis. + * @param size The size of the slice. The length can be less than the rank of + * x - the rest of the axes will have implicit -1. A value of -1 requests + * the rest of the dimensions in the axis. Can also be a single number, + * in which case it specifies the size of the first axis. + * + * @doc {heading: 'Tensors', subheading: 'Slicing and Joining'} + */ + function slice_(x, begin, size) { + const $x = convertToTensor(x, 'x', 'slice', 'string_or_numeric'); + if ($x.rank === 0) { + throw new Error('Slicing scalar is not possible'); + } + const inputs = { x: $x }; + const attrs = { begin, size }; + return ENGINE.runKernel(Slice, inputs, attrs); + } + const slice$2 = /* @__PURE__ */ op({ slice_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes hyperbolic tangent of the input `tf.Tensor` element-wise: `tanh(x)` + * + * ```js + * const x = tf.tensor1d([0, 1, -1, 70]); + * + * x.tanh().print(); // or tf.tanh(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function tanh_(x) { + const $x = convertToTensor(x, 'x', 'tanh', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Tanh$1, inputs); + } + const tanh$2 = /* @__PURE__ */ op({ tanh_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the next state and output of a BasicLSTMCell. + * + * Returns `[newC, newH]`. + * + * Derived from tf.contrib.rnn.BasicLSTMCell. + * + * @param forgetBias Forget bias for the cell. + * @param lstmKernel The weights for the cell. + * @param lstmBias The bias for the cell. + * @param data The input to the cell. + * @param c Previous cell state. + * @param h Previous cell output. + * + * @doc {heading: 'Operations', subheading: 'RNN'} + */ + function basicLSTMCell_(forgetBias, lstmKernel, lstmBias, data, c, h) { + const $forgetBias = convertToTensor(forgetBias, 'forgetBias', 'basicLSTMCell'); + const $lstmKernel = convertToTensor(lstmKernel, 'lstmKernel', 'basicLSTMCell'); + const $lstmBias = convertToTensor(lstmBias, 'lstmBias', 'basicLSTMCell'); + const $data = convertToTensor(data, 'data', 'basicLSTMCell'); + const $c = convertToTensor(c, 'c', 'basicLSTMCell'); + const $h = convertToTensor(h, 'h', 'basicLSTMCell'); + const combined = concat$2([$data, $h], 1); + const weighted = matMul$1(combined, $lstmKernel); + const res = add$3(weighted, $lstmBias); + // i = input_gate, j = new_input, f = forget_gate, o = output_gate + const batchSize = res.shape[0]; + const sliceCols = res.shape[1] / 4; + const sliceSize = [batchSize, sliceCols]; + const i = slice$2(res, [0, 0], sliceSize); + const j = slice$2(res, [0, sliceCols], sliceSize); + const f = slice$2(res, [0, sliceCols * 2], sliceSize); + const o = slice$2(res, [0, sliceCols * 3], sliceSize); + const newC = add$3(mul(sigmoid$2(i), tanh$2(j)), mul($c, sigmoid$2(add$3($forgetBias, f)))); + const newH = mul(tanh$2(newC), sigmoid$2(o)); + return [newC, newH]; + } + const basicLSTMCell = /* @__PURE__ */ op({ basicLSTMCell_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * This operation reshapes the "batch" dimension 0 into `M + 1` dimensions of + * shape `blockShape + [batch]`, interleaves these blocks back into the grid + * defined by the spatial dimensions `[1, ..., M]`, to obtain a result with + * the same rank as the input. The spatial dimensions of this intermediate + * result are then optionally cropped according to `crops` to produce the + * output. This is the reverse of `tf.spaceToBatchND`. See below for a precise + * description. + * + * ```js + * const x = tf.tensor4d([1, 2, 3, 4], [4, 1, 1, 1]); + * const blockShape = [2, 2]; + * const crops = [[0, 0], [0, 0]]; + * + * x.batchToSpaceND(blockShape, crops).print(); + * ``` + * + * @param x A `tf.Tensor`. N-D with `x.shape` = `[batch] + spatialShape + + * remainingShape`, where spatialShape has `M` dimensions. + * @param blockShape A 1-D array. Must have shape `[M]`, all values must + * be >= 1. + * @param crops A 2-D array. Must have shape `[M, 2]`, all values must be >= 0. + * `crops[i] = [cropStart, cropEnd]` specifies the amount to crop from input + * dimension `i + 1`, which corresponds to spatial dimension `i`. It is required + * that `cropStart[i] + cropEnd[i] <= blockShape[i] * inputShape[i + 1]` + * + * This operation is equivalent to the following steps: + * + * 1. Reshape `x` to `reshaped` of shape: `[blockShape[0], ..., + * blockShape[M-1], batch / prod(blockShape), x.shape[1], ..., + * x.shape[N-1]]` + * + * 2. Permute dimensions of `reshaped` to produce `permuted` of shape `[batch / + * prod(blockShape),x.shape[1], blockShape[0], ..., x.shape[M], + * blockShape[M-1],x.shape[M+1], ..., x.shape[N-1]]` + * + * 3. Reshape `permuted` to produce `reshapedPermuted` of shape `[batch / + * prod(blockShape),x.shape[1] * blockShape[0], ..., x.shape[M] * + * blockShape[M-1],x.shape[M+1], ..., x.shape[N-1]]` + * + * 4. Crop the start and end of dimensions `[1, ..., M]` of `reshapedPermuted` + * according to `crops` to produce the output of shape: `[batch / + * prod(blockShape),x.shape[1] * blockShape[0] - crops[0,0] - crops[0,1], + * ..., x.shape[M] * blockShape[M-1] - crops[M-1,0] - + * crops[M-1,1],x.shape[M+1], ..., x.shape[N-1]]` + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function batchToSpaceND_(x, blockShape, crops) { + const $x = convertToTensor(x, 'x', 'batchToSpaceND'); + const prod = blockShape.reduce((a, b) => a * b); + assert$1($x.rank >= 1 + blockShape.length, () => `input rank is ${$x.rank} but should be > than blockShape.length ${blockShape.length}`); + assert$1(crops.length === blockShape.length, () => `crops.length is ${crops.length} but should be equal to blockShape.length ${blockShape.length}`); + assert$1($x.shape[0] % prod === 0, () => `input tensor batch is ${$x.shape[0]} but is not divisible by the product of ` + + `the elements of blockShape ${blockShape.join(' * ')} === ${prod}`); + const inputs = { x: $x }; + const attrs = { blockShape, crops }; + return ENGINE.runKernel(BatchToSpaceND, inputs, attrs); + } + const batchToSpaceND$2 = /* @__PURE__ */ op({ batchToSpaceND_ }); + + function xAs4D(x) { + let x4D; + if (x.rank === 0 || x.rank === 1) { + x4D = reshape$3(x, [1, 1, 1, x.size]); + } + else if (x.rank === 2) { + x4D = reshape$3(x, [1, 1, x.shape[0], x.shape[1]]); + } + else if (x.rank === 3) { + x4D = reshape$3(x, [1, x.shape[0], x.shape[1], x.shape[2]]); + } + else { + x4D = x; + } + return x4D; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Batch normalization. + * + * As described in + * [http://arxiv.org/abs/1502.03167](http://arxiv.org/abs/1502.03167). + * + * Mean, variance, scale, and offset can be of two shapes: + * - The same shape as the input. + * - In the common case, the depth dimension is the last dimension of x, so + * the values would be a `tf.Tensor1D` of shape [depth]. + * + * Also available are stricter rank-specific methods with the same signature + * as this method that assert that parameters passed are of given rank + * - `tf.batchNorm2d` + * - `tf.batchNorm3d` + * - `tf.batchNorm4d` + * + * @param x The input Tensor. + * @param mean A mean Tensor. + * @param variance A variance Tensor. + * @param offset An offset Tensor. + * @param scale A scale Tensor. + * @param varianceEpsilon A small float number to avoid dividing by 0. + * + * @doc {heading: 'Operations', subheading: 'Normalization'} + */ + function batchNorm_(x, mean, variance, offset, scale, varianceEpsilon) { + if (varianceEpsilon == null) { + varianceEpsilon = 0.001; + } + const $x = convertToTensor(x, 'x', 'batchNorm'); + const $mean = convertToTensor(mean, 'mean', 'batchNorm'); + const $variance = convertToTensor(variance, 'variance', 'batchNorm'); + let $scale; + if (scale != null) { + $scale = convertToTensor(scale, 'scale', 'batchNorm'); + } + let $offset; + if (offset != null) { + $offset = convertToTensor(offset, 'offset', 'batchNorm'); + } + assert$1($mean.rank === $variance.rank, () => 'Batch normalization gradient requires mean and variance to have ' + + 'equal ranks.'); + assert$1($offset == null || $mean.rank === $offset.rank, () => 'Batch normalization gradient requires mean and offset to have ' + + 'equal ranks.'); + assert$1($scale == null || $mean.rank === $scale.rank, () => 'Batch normalization gradient requires mean and scale to have ' + + 'equal ranks.'); + const x4D = xAs4D($x); + const inputs = { + x: x4D, + scale: $scale, + offset: $offset, + mean: $mean, + variance: $variance + }; + const attrs = { varianceEpsilon }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(FusedBatchNorm, inputs, attrs); + return reshape$3(res, $x.shape); + } + const batchNorm$2 = /* @__PURE__ */ op({ batchNorm_ }); + + /** + * Batch normalization, strictly for 2D. For the more relaxed version, see + * `tf.batchNorm`. + * + * @param x The input Tensor. + * @param mean A mean Tensor. + * @param variance A variance Tensor. + * @param offset An offset Tensor. + * @param scale A scale Tensor. + * @param varianceEpsilon A small float number to avoid dividing by 0. + */ + function batchNorm2d_(x, mean, variance, offset, scale, varianceEpsilon) { + const $x = convertToTensor(x, 'x', 'batchNorm'); + const $mean = convertToTensor(mean, 'mean', 'batchNorm'); + const $variance = convertToTensor(variance, 'variance', 'batchNorm'); + let $scale; + if (scale != null) { + $scale = convertToTensor(scale, 'scale', 'batchNorm'); + } + let $offset; + if (offset != null) { + $offset = convertToTensor(offset, 'offset', 'batchNorm'); + } + assert$1($x.rank === 2, () => `Error in batchNorm2D: x must be rank 2 but got rank ` + + `${$x.rank}.`); + assert$1($mean.rank === 2 || $mean.rank === 1, () => `Error in batchNorm2D: mean must be rank 2 or rank 1 but ` + + `got rank ${$mean.rank}.`); + assert$1($variance.rank === 2 || $variance.rank === 1, () => `Error in batchNorm2D: variance must be rank 2 or rank 1 ` + + `but got rank ${$variance.rank}.`); + if ($scale != null) { + assert$1($scale.rank === 2 || $scale.rank === 1, () => `Error in batchNorm2D: scale must be rank 2 or rank 1 ` + + `but got rank ${$scale.rank}.`); + } + if ($offset != null) { + assert$1($offset.rank === 2 || $offset.rank === 1, () => `Error in batchNorm2D: offset must be rank 2 or rank 1 ` + + `but got rank ${$offset.rank}.`); + } + return batchNorm$2($x, $mean, $variance, $offset, $scale, varianceEpsilon); + } + const batchNorm2d = /* @__PURE__ */ op({ batchNorm2d_ }); + + /** + * Batch normalization, strictly for 3D. For the more relaxed version, see + * `tf.batchNorm`. + * + * @param x The input Tensor. + * @param mean A mean Tensor. + * @param variance A variance Tensor. + * @param offset An offset Tensor. + * @param scale A scale Tensor. + * @param varianceEpsilon A small float number to avoid dividing by 0. + */ + function batchNorm3d_(x, mean, variance, offset, scale, varianceEpsilon) { + const $x = convertToTensor(x, 'x', 'batchNorm'); + const $mean = convertToTensor(mean, 'mean', 'batchNorm'); + const $variance = convertToTensor(variance, 'variance', 'batchNorm'); + let $scale; + if (scale != null) { + $scale = convertToTensor(scale, 'scale', 'batchNorm'); + } + let $offset; + if (offset != null) { + $offset = convertToTensor(offset, 'offset', 'batchNorm'); + } + assert$1($x.rank === 3, () => `Error in batchNorm3D: x must be rank 3 but got rank ` + + `${$x.rank}.`); + assert$1($mean.rank === 3 || $mean.rank === 1, () => `Error in batchNorm3D: mean must be rank 3 or rank 1 but ` + + `got rank ${$mean.rank}.`); + assert$1($variance.rank === 3 || $variance.rank === 1, () => `Error in batchNorm3D: variance must be rank 3 or rank 1 ` + + `but got rank ${$variance.rank}.`); + if ($scale != null) { + assert$1($scale.rank === 3 || $scale.rank === 1, () => `Error in batchNorm3D: scale must be rank 3 or rank 1 ` + + `but got rank ${$scale.rank}.`); + } + if ($offset != null) { + assert$1($offset.rank === 3 || $offset.rank === 1, () => `Error in batchNorm3D: offset must be rank 3 or rank 1 ` + + `but got rank ${$offset.rank}.`); + } + return batchNorm$2($x, $mean, $variance, $offset, $scale, varianceEpsilon); + } + const batchNorm3d = /* @__PURE__ */ op({ batchNorm3d_ }); + + /** + * Batch normalization, strictly for 4D. For the more relaxed version, see + * `tf.batchNorm`. + * + * @param x The input Tensor. + * @param mean A mean Tensor. + * @param variance A variance Tensor. + * @param offset An offset Tensor. + * @param scale A scale Tensor. + * @param varianceEpsilon A small float number to avoid dividing by 0. + */ + function batchNorm4d_(x, mean, variance, offset, scale, varianceEpsilon) { + const $x = convertToTensor(x, 'x', 'batchNorm'); + const $mean = convertToTensor(mean, 'mean', 'batchNorm'); + const $variance = convertToTensor(variance, 'variance', 'batchNorm'); + let $scale; + if (scale != null) { + $scale = convertToTensor(scale, 'scale', 'batchNorm'); + } + let $offset; + if (offset != null) { + $offset = convertToTensor(offset, 'offset', 'batchNorm'); + } + assert$1($x.rank === 4, () => `Error in batchNorm4D: x must be rank 4 but got rank ` + + `${$x.rank}.`); + assert$1($mean.rank === 4 || $mean.rank === 1, () => `Error in batchNorm4D: mean must be rank 4 or rank 1 but ` + + `got rank ${$mean.rank}.`); + assert$1($variance.rank === 4 || $variance.rank === 1, () => `Error in batchNorm4D: variance must be rank 4 or rank 1 ` + + `but got rank ${$variance.rank}.`); + if ($scale != null) { + assert$1($scale.rank === 4 || $scale.rank === 1, () => `Error in batchNorm4D: scale must be rank 4 or rank 1 ` + + `but got rank ${$scale.rank}.`); + } + if ($offset != null) { + assert$1($offset.rank === 4 || $offset.rank === 1, () => `Error in batchNorm4D: offset must be rank 4 or rank 1 ` + + `but got rank ${$offset.rank}.`); + } + return batchNorm$2($x, $mean, $variance, $offset, $scale, varianceEpsilon); + } + const batchNorm4d = /* @__PURE__ */ op({ batchNorm4d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Outputs a vector with length `size` and the same dtype as `weights`. + * + * If `weights` are empty, then index `i` stores the number of times the value + * `i` is counted in `x`. If `weights` are non-empty, then index `i` stores the + * sum of the value in `weights` at each index where the corresponding value in + * `x` is `i`. + * + * Values in `x` outside of the range [0, size) are ignored. + * + * @param x The input int tensor, rank 1. + * @param weights The weights tensor, must have the same shape as x, or a + * length-0 Tensor, in which case it acts as all weights equal to 1. + * @param size Non-negative integer. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function bincount_(x, weights, size) { + const $x = convertToTensor(x, 'x', 'bincount'); + const $weights = convertToTensor(weights, 'weights', 'bincount'); + assert$1($x.dtype === 'int32', () => `Error in bincount: input ` + + `dtype must be int32, but got ${$x.dtype}`); + assert$1(size >= 0, () => `size must be non-negative, but got ${size}.`); + assert$1($weights.size === $x.size || $weights.size === 0, () => `Error in bincount: weights must have the same size as input or` + + `0-length, but got input shape: ${$x.shape}, weights shape: ` + + `${$weights.shape}.`); + const inputs = { x: $x, weights: $weights }; + const attrs = { size }; + return ENGINE.runKernel(Bincount, inputs, attrs); + } + const bincount$2 = /* @__PURE__ */ op({ bincount_ }); + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Bitwise `AND` operation for input tensors. + * + * Given two input tensors, returns a new tensor + * with the `AND` calculated values. + * + * The method supports int32 values + * + * + * ```js + * const x = tf.tensor1d([0, 5, 3, 14], 'int32'); + * const y = tf.tensor1d([5, 0, 7, 11], 'int32'); + * tf.bitwiseAnd(x, y).print(); + * ``` + * + * @param x The input tensor to be calculated. + * @param y The input tensor to be calculated. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function bitwiseAnd_(x, y) { + const $x = convertToTensor(x, 'x', 'bitwiseAnd'); + const $y = convertToTensor(y, 'y', 'bitwiseAnd'); + if (!arraysEqual($x.shape, $y.shape)) { + throw new Error(`BitwiseAnd: Tensors must have the same shape. x: ${$x.shape}, y: ${$y.shape}`); + } + if ($x.dtype !== 'int32' || $y.dtype !== 'int32') { + throw new Error(`BitwiseAnd: Only supports 'int32' values in tensor, found type of x: ${$x.dtype} and type of y: ${$y.dtype}`); + } + const inputs = { a: $x, b: $y }; + return ENGINE.runKernel(BitwiseAnd, inputs); + } + const bitwiseAnd$2 = /* @__PURE__ */ op({ bitwiseAnd_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Return the shape of s0 op s1 with broadcast. + * + * compute r0, the broadcasted shape as a tensor. + * s0, s1 and r0 are all integer vectors. + * + * This function returns the shape of the result of an operation between + * two tensors of size s0 and s1 performed with broadcast. + * + * @param s0 A tensor representing a shape + * @param s1 A tensor representing a shape + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function broadcastArgs_(s0, s1) { + const shape1Input = convertToTensor(s0, 's0', 'broadcastArgs', 'int32'); + const shape2Input = convertToTensor(s1, 's1', 'broadcastArgs', 'int32'); + if (shape1Input.rank !== 1) { + throw new Error('broadcastArgs(): first input must be a vector (rank=1). ' + + `Has rank ${shape1Input.rank}`); + } + if (shape2Input.rank !== 1) { + throw new Error('broadcastArgs(): second input must be a vector (rank=1). ' + + `Has rank ${shape2Input.rank}`); + } + const inputs = { s0: shape1Input, s1: shape2Input }; + return ENGINE.runKernel(BroadcastArgs, inputs); + } + const broadcastArgs$2 = /* @__PURE__ */ op({ broadcastArgs_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Broadcast an array to a compatible shape NumPy-style. + * + * The tensor's shape is compared to the broadcast shape from end to beginning. + * Ones are prepended to the tensor's shape until it has the same length as + * the broadcast shape. If input.shape[i]==shape[i], the (i+1)-th axis is + * already broadcast-compatible. If input.shape[i]==1 and shape[i]==N, then + * the input tensor is tiled N times along that axis (using tf.tile). + * + * @param input The tensor that is to be broadcasted. + * @param shape The input is to be broadcast to this shape. + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function broadcastTo_(x, shape) { + let input = convertToTensor(x, 'broadcastTo', 'x'); + const xShape = input.shape; + assertNonNegativeIntegerDimensions(shape); + if (shape.length < input.rank) { + throw new Error(`broadcastTo(): shape.length=${shape.length} < input.rank=${input.rank}.`); + } + if (shape.length > input.rank) { + const newShape = input.shape.slice(); + while (newShape.length < shape.length) { + newShape.unshift(1); + } + input = reshape$3(input, newShape); + } + const inputShape = input.shape; + const reps = Array.from(shape); + for (let i = shape.length - 1; i >= 0; i--) { + if (inputShape[i] === shape[i]) { + reps[i] = 1; + } + else if (input.shape[i] !== 1) { + throw new Error(`broadcastTo(): [${xShape}] cannot be broadcast to [${shape}].`); + } + } + const axes = reps.map((n, i) => n > 1 ? i : -1).filter(i => i >= 0); + if (axes.length === 0) { + return clone(input); + } + // TODO call broadcastTo kernel directly once backends implement broadcstTo + const inputs = { x: input }; + const attrs = { reps }; + return ENGINE.runKernel(Tile, inputs, attrs); + } + const broadcastTo = /* @__PURE__ */ op({ broadcastTo_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes ceiling of input `tf.Tensor` element-wise: `ceil(x)` + * + * ```js + * const x = tf.tensor1d([.6, 1.1, -3.3]); + * + * x.ceil().print(); // or tf.ceil(x) + * ``` + * @param x The input Tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function ceil_(x) { + const $x = convertToTensor(x, 'x', 'ceil', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Ceil, inputs); + } + const ceil$2 = /* @__PURE__ */ op({ ceil_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` filled with a scalar value. + * + * ```js + * tf.fill([2, 2], 4).print(); + * ``` + * + * @param shape An array of integers defining the output tensor shape. + * @param value The scalar value to fill the tensor with. + * @param dtype The type of an element in the resulting tensor. Defaults to + * 'float32' if the given param value is a number, otherwise 'string'. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function fill$2(shape, value, dtype) { + assertNonNegativeIntegerDimensions(shape); + dtype = dtype || inferDtype(value); + const attrs = { shape, value, dtype }; + return ENGINE.runKernel(Fill, {}, attrs); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Clips values element-wise. `max(min(x, clipValueMax), clipValueMin)` + * + * ```js + * const x = tf.tensor1d([-1, 2, -3, 4]); + * + * x.clipByValue(-2, 3).print(); // or tf.clipByValue(x, -2, 3) + * ``` + * @param x The input tensor. + * @param clipValueMin Lower bound of range to be clipped to. + * @param clipValueMax Upper bound of range to be clipped to. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function clipByValue_(x, clipValueMin, clipValueMax) { + const $x = convertToTensor(x, 'x', 'clipByValue'); + assert$1((clipValueMin <= clipValueMax), () => `Error in clip: min (${clipValueMin}) must be ` + + `less than or equal to max (${clipValueMax}).`); + if (clipValueMin === clipValueMax) { + return fill$2($x.shape, clipValueMin, $x.dtype); + } + const inputs = { x: $x }; + const attrs = { clipValueMin, clipValueMax }; + return ENGINE.runKernel(ClipByValue, inputs, attrs); + } + const clipByValue$2 = /* @__PURE__ */ op({ clipByValue_ }); + + /** + * Concatenates a list of`tf.Tensor1D`s along an axis. See `concat` for details. + * + * For example, if: + * A: shape(3) = |r1, g1, b1| + * B: shape(2) = |r2, g2| + * C = tf.concat1d([A, B]) == |r1, g1, b1, r2, g2| + * + * @param tensors A list of`tf.Tensor`s to concatenate. + * @return The concatenated array. + */ + function concat1d_(tensors) { + return concat$2(tensors, 0 /* axis */); + } + const concat1d = /* @__PURE__ */ op({ concat1d_ }); + + /** + * Concatenates a list of`tf.Tensor2D`s along an axis. See `concat` for details. + * + * For example, if: + * A: shape(2, 3) = | r1, g1, b1 | + * | r2, g2, b2 | + * + * B: shape(2, 3) = | r3, g3, b3 | + * | r4, g4, b4 | + * + * C = tf.concat2d([A, B], axis) + * + * if axis = 0: + * C: shape(4, 3) = | r1, g1, b1 | + * | r2, g2, b2 | + * | r3, g3, b3 | + * | r4, g4, b4 | + * + * if axis = 1: + * C = shape(2, 6) = | r1, g1, b1, r3, g3, b3 | + * | r2, g2, b2, r4, g4, b4 | + * + * + * @param tensors A list of `tf.Tensor`s to concatenate. + * @param axis The axis to concatenate along. + * @return The concatenated array. + */ + function concat2d_(tensors, axis) { + return concat$2(tensors, axis); + } + const concat2d = /* @__PURE__ */ op({ concat2d_ }); + + /** + * Concatenates a list of `tf.Tensor3D`s along an axis. + * See `concat` for details. + * + * For example, if: + * A: shape(2, 1, 3) = | r1, g1, b1 | + * | r2, g2, b2 | + * + * B: shape(2, 1, 3) = | r3, g3, b3 | + * | r4, g4, b4 | + * + * C = tf.concat3d([A, B], axis) + * + * if axis = 0: + * C: shape(4, 1, 3) = | r1, g1, b1 | + * | r2, g2, b2 | + * | r3, g3, b3 | + * | r4, g4, b4 | + * + * if axis = 1: + * C: shape(2, 2, 3) = | r1, g1, b1, r3, g3, b3 | + * | r2, g2, b2, r4, g4, b4 | + * + * if axis = 2: + * C = shape(2, 1, 6) = | r1, g1, b1, r3, g3, b3 | + * | r2, g2, b2, r4, g4, b4 | + * + * @param tensors A list of`tf.Tensor`s to concatenate. + * @param axis The axis to concate along. + * @return The concatenated array. + */ + function concat3d_(tensors, axis) { + return concat$2(tensors, axis); + } + const concat3d = /* @__PURE__ */ op({ concat3d_ }); + + /** + * Concatenates a list of `tf.Tensor4D`s along an axis. + * See `concat` for details. + * + * @param tensors A list of `tf.Tensor`s to concatenate. + * @param axis The axis to concate along. + * @return The concatenated array. + */ + function concat4d_(tensors, axis) { + return concat$2(tensors, axis); + } + const concat4d = /* @__PURE__ */ op({ concat4d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes a 2D convolution over the input x. + * + * @param x The input tensor, of rank 4 or rank 3, of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is + * assumed. + * @param filter The filter, rank 4, of shape + * `[filterHeight, filterWidth, inDepth, outDepth]`. + * @param strides The strides of the convolution: `[strideHeight, + * strideWidth]`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dataFormat: An optional string from: "NHWC", "NCHW". Defaults to + * "NHWC". Specify the data format of the input and output data. With the + * default format "NHWC", the data is stored in the order of: [batch, + * height, width, channels]. + * @param dilations The dilation rates: `[dilationHeight, dilationWidth]` + * in which we sample input values across the height and width dimensions + * in atrous convolution. Defaults to `[1, 1]`. If `dilations` is a single + * number, then `dilationHeight == dilationWidth`. If it is greater than + * 1, then all values of `strides` must be 1. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function conv2d_(x, filter, strides, pad, dataFormat = 'NHWC', dilations = [1, 1], dimRoundingMode) { + const $x = convertToTensor(x, 'x', 'conv2d', 'float32'); + const $filter = convertToTensor(filter, 'filter', 'conv2d', 'float32'); + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + reshapedTo4D = true; + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + } + assert$1(x4D.rank === 4, () => `Error in conv2d: input must be rank 4, but got rank ${x4D.rank}.`); + assert$1($filter.rank === 4, () => `Error in conv2d: filter must be rank 4, but got rank ` + + `${$filter.rank}.`); + checkPadOnDimRoundingMode('conv2d', pad, dimRoundingMode); + const inDepth = dataFormat === 'NHWC' ? x4D.shape[3] : x4D.shape[1]; + assert$1(inDepth === $filter.shape[2], () => `Error in conv2d: depth of input (${inDepth}) must match ` + + `input depth for filter ${$filter.shape[2]}.`); + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in conv2D: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + assert$1(stridesOrDilationsArePositive(dilations), () => 'Error in conv2D: Dilated rates should be larger than 0.'); + assert$1(stridesOrDilationsArePositive(strides), () => 'Error in conv2D: Strides should be larger than 0.'); + const inputs = { x: x4D, filter: $filter }; + const attrs = { strides, pad, dataFormat, dilations, dimRoundingMode }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(Conv2D$1, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const conv2d$4 = /* @__PURE__ */ op({ conv2d_ }); + + /** + * Computes a 1D convolution over the input x. + * + * @param x The input tensor, of rank 3 or rank 2, of shape + * `[batch, width, inChannels]`. If rank 2, batch of 1 is assumed. + * @param filter The filter, rank 3, of shape + * `[filterWidth, inDepth, outDepth]`. + * @param stride The number of entries by which the filter is moved right at + * each step. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dataFormat An optional string from "NWC", "NCW". Defaults to "NWC", + * the data is stored in the order of [batch, in_width, in_channels]. Only + * "NWC" is currently supported. + * @param dilation The dilation rate in which we sample input values in + * atrous convolution. Defaults to `1`. If it is greater than 1, then + * stride must be `1`. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function conv1d_(x, filter, stride, pad, dataFormat = 'NWC', dilation = 1, dimRoundingMode) { + const $x = convertToTensor(x, 'x', 'conv1d'); + const $filter = convertToTensor(filter, 'filter', 'conv1d'); + let x3D = $x; + let reshapedTo3D = false; + if ($x.rank === 2) { + reshapedTo3D = true; + x3D = reshape$3($x, [1, $x.shape[0], $x.shape[1]]); + } + assert$1(x3D.rank === 3, () => `Error in conv1d: input must be rank 3, but got rank ${x3D.rank}.`); + assert$1($filter.rank === 3, () => `Error in conv1d: filter must be rank 3, but got rank ` + + `${$filter.rank}.`); + checkPadOnDimRoundingMode('conv1d', pad, dimRoundingMode); + assert$1(x3D.shape[2] === $filter.shape[1], () => `Error in conv1d: depth of input (${x3D.shape[2]}) must match ` + + `input depth for filter ${$filter.shape[1]}.`); + assert$1(eitherStridesOrDilationsAreOne(stride, dilation), () => 'Error in conv1D: Either stride or dilation must be 1. ' + + `Got stride ${stride} and dilation '${dilation}'`); + assert$1(stridesOrDilationsArePositive(dilation), () => 'Error in conv1D: Dilated rates should be larger than 0.'); + assert$1(stridesOrDilationsArePositive(stride), () => 'Error in conv1D: Stride should be larger than 0.'); + assert$1(dataFormat === 'NWC', () => `Error in conv1d: got dataFormat of ${dataFormat} but only NWC is currently supported.`); + const filter4D = reshape$3($filter, [1, $filter.shape[0], $filter.shape[1], $filter.shape[2]]); + const input4D = reshape$3(x3D, [x3D.shape[0], 1, x3D.shape[1], x3D.shape[2]]); + const strides = [1, stride]; + const dilations = [1, dilation]; + const conv2dDataFormat = 'NHWC'; + const res = conv2d$4(input4D, filter4D, strides, pad, conv2dDataFormat, dilations, dimRoundingMode); + if (reshapedTo3D) { + return reshape$3(res, [res.shape[2], res.shape[3]]); + } + return reshape$3(res, [res.shape[0], res.shape[2], res.shape[3]]); + } + const conv1d$2 = /* @__PURE__ */ op({ conv1d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the derivative of the input of a 2D convolution. + * + * @param xShape The shape of the input: [batch, height, width, inDepth]. + * If length of 3, batch of 1 is assumed. + * @param dy The derivative of the output, of rank 4 or rank 3 of shape + * `[batch, outHeight, outWidth, outDepth]`. If rank 3, batch of 1 is + * assumed. + * @param filter The filter, rank 4, of shape + * `[filterHeight, filterWidth, inDepth, outDepth]`. + * @param strides The strides of the convolution: `[strideHeight, + * strideWidth]`. + * @param pad The type of padding algorithm used: + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * @param dataFormat: An optional string from: "NHWC", "NCHW". Defaults to + * "NHWC". Specify the data format of the input and output data. With the + * default format "NHWC", the data is stored in the order of: [batch, + * height, width, channels]. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + */ + function conv2DBackpropInput_(xShape, dy, filter, strides, pad, dataFormat = 'NHWC', dimRoundingMode) { + assert$1(xShape.length === dy.rank, () => `Length of inShape ` + + `(${xShape.length}) and rank of dy (${dy.rank}) must match`); + let xShape4D = xShape; + let dy4D = dy; + let reshapedTo4D = false; + if (dy.rank === 3) { + reshapedTo4D = true; + dy4D = reshape$3(dy, [1, dy.shape[0], dy.shape[1], dy.shape[2]]); + xShape4D = [1, xShape[0], xShape[1], xShape[2]]; + } + assert$1(xShape4D.length === 4, () => `Error in conv2dDerInput: inShape must be length 4, but got length ` + + `${xShape4D.length}.`); + assert$1(dy4D.rank === 4, () => `Error in conv2dDerInput: dy must be rank 4, but got ` + + `rank ${dy4D.rank}`); + assert$1(filter.rank === 4, () => `Error in conv2dDerInput: filter must be rank 4, but got ` + + `rank ${filter.rank}`); + const inDepth = dataFormat === 'NHWC' ? xShape4D[3] : xShape4D[1]; + const outDepth = dataFormat === 'NHWC' ? dy4D.shape[3] : dy4D.shape[1]; + assert$1(inDepth === filter.shape[2], () => `Error in conv2dDerInput: depth of input (${inDepth}) must ` + + `match input depth for filter ${filter.shape[2]}.`); + assert$1(outDepth === filter.shape[3], () => `Error in conv2dDerInput: depth of output (${outDepth}) must ` + + `match output depth for filter ${filter.shape[3]}.`); + checkPadOnDimRoundingMode('conv2dDerInput', pad, dimRoundingMode); + const inputs = { dy: dy4D, filter }; + const attrs = { strides, pad, dataFormat, dimRoundingMode, inputShape: xShape4D }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(Conv2DBackpropInput, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const conv2DBackpropInput$2 = /* @__PURE__ */ op({ conv2DBackpropInput_ }); + + /** + * Computes the transposed 2D convolution of an image, also known as a + * deconvolution. + * + * @param x The input image, of rank 4 or rank 3, of shape + * `[batch, height, width, inDepth]`. If rank 3, batch of 1 is assumed. + * @param filter The filter, rank 4, of shape + * `[filterHeight, filterWidth, outDepth, inDepth]`. + * `inDepth` must match `inDepth` in `x`. + * @param outputShape Output shape, of rank 4 or rank 3: + * `[batch, height, width, outDepth]`. If rank 3, batch of 1 is assumed. + * @param strides The strides of the original convolution: + * `[strideHeight, strideWidth]`. + * @param pad The type of padding algorithm used in the non-transpose version + * of the op. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function conv2dTranspose_(x, filter, outputShape, strides, pad, dimRoundingMode) { + const $x = convertToTensor(x, 'x', 'conv2dTranspose'); + const $filter = convertToTensor(filter, 'filter', 'conv2dTranspose'); + return conv2DBackpropInput$2(outputShape, $x, $filter, strides, pad, 'NHWC', dimRoundingMode); + } + const conv2dTranspose$1 = /* @__PURE__ */ op({ conv2dTranspose_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes a 3D convolution over the input x. + * + * @param x The input tensor, of rank 5 or rank 4, of shape + * `[batch, depth, height, width, channels]`. If rank 4, + * batch of 1 is assumed. + * @param filter The filter, rank 5, of shape + * `[filterDepth, filterHeight, filterWidth, inChannels, outChannels]`. + * inChannels must match between input and filter. + * @param strides The strides of the convolution: `[strideDepth, strideHeight, + * strideWidth]`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dataFormat: An optional string from: "NDHWC", "NCDHW". Defaults to + * "NDHWC". Specify the data format of the input and output data. With the + * default format "NDHWC", the data is stored in the order of: [batch, + * depth, height, width, channels]. Only "NDHWC" is currently supported. + * @param dilations The dilation rates: `[dilationDepth, dilationHeight, + * dilationWidth]` in which we sample input values across the height + * and width dimensions in atrous convolution. Defaults to `[1, 1, 1]`. + * If `dilations` is a single number, then + * `dilationDepth == dilationHeight == dilationWidth`. If it is greater + * than 1, then all values of `strides` must be 1. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function conv3d_(x, filter, strides, pad, dataFormat = 'NDHWC', dilations = [1, 1, 1]) { + const $x = convertToTensor(x, 'x', 'conv3d'); + const $filter = convertToTensor(filter, 'filter', 'conv3d'); + let x5D = $x; + let reshapedTo5D = false; + if ($x.rank === 4) { + reshapedTo5D = true; + x5D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2], $x.shape[3]]); + } + assert$1(x5D.rank === 5, () => `Error in conv3d: input must be rank 5, but got rank ${x5D.rank}.`); + assert$1($filter.rank === 5, () => `Error in conv3d: filter must be rank 5, but got rank ` + + `${$filter.rank}.`); + assert$1(x5D.shape[4] === $filter.shape[3], () => `Error in conv3d: depth of input (${x5D.shape[4]}) must match ` + + `input depth for filter ${$filter.shape[3]}.`); + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in conv3D: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + assert$1(dataFormat === 'NDHWC', () => `Error in conv3d: got dataFormat of ${dataFormat} but only NDHWC is currently supported.`); + assert$1(stridesOrDilationsArePositive(dilations), () => 'Error in conv3D: Dilated rates should be larger than 0.'); + assert$1(stridesOrDilationsArePositive(strides), () => 'Error in conv3D: Strides should be larger than 0.'); + const inputs = { x: x5D, filter: $filter }; + const attrs = { strides, pad, dataFormat, dilations }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(Conv3D$1, inputs, attrs); + if (reshapedTo5D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3], res.shape[4]]); + } + return res; + } + const conv3d$2 = /* @__PURE__ */ op({ conv3d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the derivative of the input of a 3D convolution. + * + * @param xShape The shape of the input: [batch, depth, height, width, + * in_channels]. If length of 4, batch of 1 is assumed. + * @param dy The derivative of the output, of rank 5 or rank 4 of shape + * `[batch, outDepth, outHeight, outWidth, in_channels]`. + * If rank 4, batch of 1 is assumed. + * @param filter The filter, rank 5, of shape + * `[filterDepth, filterHeight, filterWidth, inDepth, outDepth]`. + * @param strides The strides of the convolution: `[strideDepth, strideHeight, + * strideWidth]`. + * @param pad The type of padding algorithm used: + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + */ + function conv3DBackpropInput_(xShape, dy, filter, strides, pad) { + assert$1(xShape.length === dy.rank, () => `Length of inShape ` + + `(${xShape.length}) and rank of dy (${dy.rank}) must match`); + let xShape5D = xShape; + let dy5D = dy; + let reshapedTo5D = false; + if (dy.rank === 4) { + reshapedTo5D = true; + dy5D = reshape$3(dy, [1, dy.shape[0], dy.shape[1], dy.shape[2], dy.shape[3]]); + xShape5D = [1, xShape[0], xShape[1], xShape[2], xShape[3]]; + } + const inDepth = xShape5D[4]; + const outDepth = dy5D.shape[4]; + assert$1(xShape5D.length === 5, () => `Error in conv3dDerInput: inShape must be length 5, but got length ` + + `${xShape5D.length}.`); + assert$1(dy5D.rank === 5, () => `Error in conv3dDerInput: dy must be rank 5, but got ` + + `rank ${dy5D.rank}`); + assert$1(filter.rank === 5, () => `Error in conv3dDerInput: filter must be rank 5, but got ` + + `rank ${filter.rank}`); + assert$1(inDepth === filter.shape[3], () => `Error in conv3dDerInput: depth of input (${inDepth}) must ` + + `match input depth for filter ${filter.shape[3]}.`); + assert$1(outDepth === filter.shape[4], () => `Error in conv3dDerInput: depth of output (${outDepth}) must ` + + `match output depth for filter ${filter.shape[4]}.`); + const inputs = { dy: dy5D, filter }; + const attrs = { pad, strides, inputShape: xShape5D }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(Conv3DBackpropInputV2, inputs, attrs); + if (reshapedTo5D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3], res.shape[4]]); + } + return res; + } + const conv3DBackpropInput$1 = /* @__PURE__ */ op({ conv3DBackpropInput_ }); + + /** + * Computes the transposed 3D convolution of a volume, also known as a + * deconvolution. + * + * @param x The input image, of rank 5 or rank 4, of shape + * `[batch, depth, height, width, inDepth]`. If rank 4, batch of 1 is assumed. + * @param filter The filter, rank 4, of shape + * `[depth, filterHeight, filterWidth, outDepth, inDepth]`. + * `inDepth` must match `inDepth` in `x`. + * @param outputShape Output shape, of rank 5 or rank 4: + * `[batch, depth, height, width, outDepth]`. If rank 3, batch of 1 is + * assumed. + * @param strides The strides of the original convolution: + * `[strideDepth, strideHeight, strideWidth]`. + * @param pad The type of padding algorithm used in the non-transpose version + * of the op. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function conv3dTranspose_(x, filter, outputShape, strides, pad) { + const $x = convertToTensor(x, 'x', 'conv3dTranspose'); + const $filter = convertToTensor(filter, 'filter', 'conv3dTranspose'); + return conv3DBackpropInput$1(outputShape, $x, $filter, strides, pad); + } + const conv3dTranspose$1 = /* @__PURE__ */ op({ conv3dTranspose_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes cos of the input `tf.Tensor` element-wise: `cos(x)` + * + * ```js + * const x = tf.tensor1d([0, Math.PI / 2, Math.PI * 3 / 4]); + * + * x.cos().print(); // or tf.cos(x) + * ``` + * @param x The input tensor. Must be float32 type. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function cos_(x) { + const $x = convertToTensor(x, 'x', 'cos', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Cos, inputs); + } + const cos$2 = /* @__PURE__ */ op({ cos_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes hyperbolic cos of the input `tf.Tensor` element-wise: `cosh(x)` + * + * ```js + * const x = tf.tensor1d([0, 1, -1, .7]); + * + * x.cosh().print(); // or tf.cosh(x) + * ``` + * @param x The input tensor. Must be float32 type. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function cosh_(x) { + const $x = convertToTensor(x, 'x', 'cosh', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Cosh, inputs); + } + const cosh$2 = /* @__PURE__ */ op({ cosh_ }); + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the cumulative product of a `tf.Tensor` along `axis`. + * + * ```js + * const x = tf.tensor([1, 2, 3, 4]); + * x.cumprod().print(); + * ``` + * ```js + * const x = tf.tensor([[1, 2], [3, 4]]); + * x.cumprod().print(); + * ``` + * + * @param x The input tensor to cumulatively multiply. + * @param axis The axis along which to multiply. Optional. Defaults to 0. + * @param exclusive Whether to perform exclusive cumulative product. Optional. + * Defaults to false. If set to true then the product of each tensor entry + * does not include its own value, but only the values previous to it + * along the specified axis. + * @param reverse Whether to multiply in the opposite direction. Optional. + * Defaults to false. + * + * @doc {heading: 'Operations', subheading: 'Scan'} + */ + function cumprod_(x, axis = 0, exclusive = false, reverse = false) { + const $x = convertToTensor(x, 'x', 'cumprod'); + const inputs = { x: $x }; + const attrs = { axis, exclusive, reverse }; + return ENGINE.runKernel(Cumprod, inputs, attrs); + } + const cumprod$2 = /* @__PURE__ */ op({ cumprod_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the cumulative sum of a `tf.Tensor` along `axis`. + * + * ```js + * const x = tf.tensor([1, 2, 3, 4]); + * x.cumsum().print(); + * ``` + * ```js + * const x = tf.tensor([[1, 2], [3, 4]]); + * x.cumsum().print(); + * ``` + * + * @param x The input tensor to be summed. + * @param axis The axis along which to sum. Optional. Defaults to 0. + * @param exclusive Whether to perform exclusive cumulative sum. Optional. + * Defaults to false. If set to true then the sum of each tensor entry + * does not include its own value, but only the values previous to it + * along the specified axis. + * @param reverse Whether to sum in the opposite direction. Optional. + * Defaults to false. + * + * @doc {heading: 'Operations', subheading: 'Scan'} + */ + function cumsum_(x, axis = 0, exclusive = false, reverse = false) { + const $x = convertToTensor(x, 'x', 'cumsum'); + const inputs = { x: $x }; + const attrs = { axis, exclusive, reverse }; + return ENGINE.runKernel(Cumsum, inputs, attrs); + } + const cumsum$2 = /* @__PURE__ */ op({ cumsum_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Outputs a vector with length `size` and the same dtype as `weights`. + * + * If `weights` are empty, then index `i` stores the number of times the value + * `i` is counted in `x`. If `weights` are non-empty, then index `i` stores the + * sum of the value in `weights` at each index where the corresponding value in + * `x` is `i`. + * + * Values in `x` outside of the range [0, size) are ignored. + * + * @param x The input int tensor, rank 1 or rank 2. + * @param weights The weights tensor, must have the same shape as x, or a + * length-0 Tensor, in which case it acts as all weights equal to 1. + * @param size Non-negative integer. + * @param binaryOutput Optional. Whether the kernel should count the appearance + * or number of occurrences. Defaults to False. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function denseBincount_(x, weights, size, binaryOutput = false) { + const $x = convertToTensor(x, 'x', 'denseBincount'); + const $weights = convertToTensor(weights, 'weights', 'denseBincount'); + assert$1($x.dtype === 'int32', () => `Error in denseBincount: input ` + + `dtype must be int32, but got ${$x.dtype}`); + assert$1($x.rank <= 2, () => `Error in denseBincount: input must be at most rank 2, but got ` + + `rank ${$x.rank}.`); + assert$1(size >= 0, () => `size must be non-negative, but got ${size}.`); + assert$1($weights.size === $x.size || $weights.size === 0, () => `Error in denseBincount: weights must have the same shape as x or ` + + `0-length, but got x shape: ${$x.shape}, weights shape: ` + + `${$weights.shape}.`); + const inputs = { x: $x, weights: $weights }; + const attrs = { size, binaryOutput }; + return ENGINE.runKernel(DenseBincount, inputs, attrs); + } + const denseBincount$2 = /* @__PURE__ */ op({ denseBincount_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Rearranges data from depth into blocks of spatial data. More specifically, + * this op outputs a copy of the input tensor where values from the `depth` + * dimension are moved in spatial blocks to the `height` and `width` dimensions. + * The attr `blockSize` indicates the input block size and how the data is + * moved. + * + * - Chunks of data of size `blockSize * blockSize` from depth are rearranged + * into non-overlapping blocks of size `blockSize x blockSize` + * + * - The width the output tensor is `inputWidth * blockSize`, whereas the + * height is `inputHeight * blockSize` + * + * - The Y, X coordinates within each block of the output image are determined + * by the high order component of the input channel index + * + * - The depth of the input tensor must be divisible by `blockSize * + * blockSize` + * + * The `dataFormat` attr specifies the layout of the input and output tensors + * with the following options: "NHWC": [ `batch, height, width, channels` ] + * "NCHW": [ `batch, channels, height, width` ] + * + * ```js + * const x = tf.tensor4d([1, 2, 3, 4], [1, 1, 1, 4]); + * const blockSize = 2; + * const dataFormat = "NHWC"; + * + * tf.depthToSpace(x, blockSize, dataFormat).print(); + * ``` + * + * @param x The input tensor of rank 4 + * @param blockSIze An `int` that is `>= 2`. The size of the spatial block + * @param dataFormat An optional string from: "NHWC", "NCHW". Defaults to "NHWC" + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function depthToSpace_(x, blockSize, dataFormat = 'NHWC') { + const $x = convertToTensor(x, 'x', 'depthToSpace', 'float32'); + const inputHeight = (dataFormat === 'NHWC') ? $x.shape[1] : $x.shape[2]; + const inputWidth = (dataFormat === 'NHWC') ? $x.shape[2] : $x.shape[3]; + const inputDepth = (dataFormat === 'NHWC') ? $x.shape[3] : $x.shape[1]; + assert$1(blockSize > 1, () => `blockSize should be > 1 for depthToSpace, but was: ${blockSize}`); + assert$1(inputHeight * blockSize >= 0, () => `Negative dimension size caused by overflow when multiplying + ${inputHeight} and ${blockSize} for depthToSpace with input shape + ${$x.shape}`); + assert$1(inputWidth * blockSize >= 0, () => `Negative dimension size caused by overflow when multiplying + ${inputWidth} and ${blockSize} for depthToSpace with input shape + ${$x.shape}`); + assert$1((inputDepth % (blockSize * blockSize) === 0), () => `Dimension size must be evenly divisible by ${blockSize * blockSize} but is ${inputDepth} for depthToSpace with input shape ${$x.shape}`); + const inputs = { x: $x }; + const attrs = { blockSize, dataFormat }; + return ENGINE.runKernel(DepthToSpace, inputs, attrs); + } + const depthToSpace$2 = /* @__PURE__ */ op({ depthToSpace_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Depthwise 2D convolution. + * + * Given a 4D `input` array and a `filter` array of shape + * `[filterHeight, filterWidth, inChannels, channelMultiplier]` containing + * `inChannels` convolutional filters of depth 1, this op applies a + * different filter to each input channel (expanding from 1 channel to + * `channelMultiplier` channels for each), then concatenates the results + * together. The output has `inChannels * channelMultiplier` channels. + * + * See + * [https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d]( + * https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d) + * for more details. + * + * @param x The input tensor, of rank 4 or rank 3, of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is + * assumed. + * @param filter The filter tensor, rank 4, of shape + * `[filterHeight, filterWidth, inChannels, channelMultiplier]`. + * @param strides The strides of the convolution: `[strideHeight, + * strideWidth]`. If strides is a single number, then `strideHeight == + * strideWidth`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dilations The dilation rates: `[dilationHeight, dilationWidth]` + * in which we sample input values across the height and width dimensions + * in atrous convolution. Defaults to `[1, 1]`. If `rate` is a single + * number, then `dilationHeight == dilationWidth`. If it is greater than + * 1, then all values of `strides` must be 1. + * @param dataFormat: An optional string from: "NHWC", "NCHW". Defaults to + * "NHWC". Specify the data format of the input and output data. With the + * default format "NHWC", the data is stored in the order of: [batch, + * height, width, channels]. Only "NHWC" is currently supported. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function depthwiseConv2d_(x, filter, strides, pad, dataFormat = 'NHWC', dilations = [1, 1], dimRoundingMode) { + const $x = convertToTensor(x, 'x', 'depthwiseConv2d', 'float32'); + const $filter = convertToTensor(filter, 'filter', 'depthwiseConv2d', 'float32'); + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + reshapedTo4D = true; + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + } + assert$1(x4D.rank === 4, () => `Error in depthwiseConv2d: input must be rank 4, but got ` + + `rank ${x4D.rank}.`); + assert$1($filter.rank === 4, () => `Error in depthwiseConv2d: filter must be rank 4, but got rank ` + + `${$filter.rank}.`); + const inChannels = dataFormat === 'NHWC' ? x4D.shape[3] : x4D.shape[1]; + assert$1(inChannels === $filter.shape[2], () => `Error in depthwiseConv2d: number of input channels ` + + `(${inChannels}) must match the inChannels dimension in ` + + `filter ${$filter.shape[2]}.`); + checkPadOnDimRoundingMode('depthwiseConv2d', pad, dimRoundingMode); + const inputs = { x: x4D, filter: $filter }; + const attrs = { strides, pad, dataFormat, dilations, dimRoundingMode }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(DepthwiseConv2dNative, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const depthwiseConv2d$3 = /* @__PURE__ */ op({ depthwiseConv2d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns a diagonal tensor with given diagonal values. + * + * Given a diagonal, this operation returns a tensor with the diagonal and + * everything else padded with zeros. + * + * Assume the input has dimensions `[D1,..., Dk]`, then the output is a tensor + * of rank 2k with dimensions `[D1,..., Dk, D1,..., Dk]` + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * + * tf.diag(x).print() + * ``` + * ```js + * const x = tf.tensor2d([1, 2, 3, 4, 5, 6, 7, 8], [4, 2]) + * + * tf.diag(x).print() + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function diag_(x) { + const $x = convertToTensor(x, 'x', 'diag'); + const inputs = { x: $x }; + return ENGINE.runKernel(Diag, inputs); + } + const diag$2 = /* @__PURE__ */ op({ diag_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the grayscale dilation over the input `x`. + * + * @param x The input tensor, rank 3 or rank 4 of shape + * `[batch, height, width, depth]`. If rank 3, batch of 1 is assumed. + * @param filter The filter tensor, rank 3, of shape + * `[filterHeight, filterWidth, depth]`. + * @param strides The strides of the sliding window for each dimension of the + * input tensor: `[strideHeight, strideWidth]`. + * If `strides` is a single number, + * then `strideHeight == strideWidth`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1*1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dataFormat Specify the data format of the input and output data. + * Defaults to 'NHWC'. Only 'NHWC' is currently supported. With the + * default format "NHWC", the data is stored in the order of: [batch, + * height, width, channels]. + * @param dilations The dilation rates: `[dilationHeight, dilationWidth]` + * in which we sample input values across the height and width dimensions + * for atrous morphological dilation. Defaults to `[1, 1]`. If `dilations` + * is a single number, then `dilationHeight == dilationWidth`. If it is + * greater than 1, then all values of `strides` must be 1. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function dilation2d_(x, filter, strides, pad, dilations = [1, 1], dataFormat = 'NHWC') { + const $x = convertToTensor(x, 'x', 'dilation2d'); + const $filter = convertToTensor(filter, 'filter', 'dilation2d'); + assert$1($x.rank === 3 || $x.rank === 4, () => `Error in dilation2d: input must be rank 3 or 4, but got rank ` + + `${$x.rank}.`); + assert$1($filter.rank === 3, () => `Error in dilation2d: filter must be rank 3, but got rank ` + + `${$filter.rank}.`); + assert$1(dataFormat === 'NHWC', () => `Error in dilation2d: Only NHWC is currently supported, ` + + `but got dataFormat of ${dataFormat}`); + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + reshapedTo4D = true; + } + assert$1(x4D.shape[3] === $filter.shape[2], () => `Error in dilation2d: input and filter must have the same depth: ${x4D.shape[3]} vs ${$filter.shape[2]}`); + const inputs = { x: x4D, filter: $filter }; + const attrs = { strides, pad, dilations }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(Dilation2D, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const dilation2d = /* @__PURE__ */ op({ dilation2d_ }); + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the dimensions in the input shape that are broadcasted to + * produce the provided output shape. + * + * The returned dimensions are 0-indexed and sorted. An example: + * inShape = [4, 1, 3] + * outShape = [5, 4, 3, 3] + * result = [1]. Dimension 1 (2nd dimension of input) gets broadcasted 1 => 3. + */ + function getBroadcastDims$1(inShape, outShape) { + const inRank = inShape.length; + const dims = []; + for (let i = 0; i < inRank; i++) { + const dim = inRank - 1 - i; + const a = inShape[dim] || 1; + const b = outShape[outShape.length - 1 - i] || 1; + if (b > 1 && a === 1) { + dims.unshift(dim); + } + } + return dims; + } + /** + * Returns the axes in the output space that should be reduced to produce + * the input space. + */ + function getReductionAxes(inShape, outShape) { + const result = []; + for (let i = 0; i < outShape.length; i++) { + const inDim = inShape[inShape.length - i - 1]; + const outAxis = outShape.length - i - 1; + const outDim = outShape[outAxis]; + if (inDim == null || (inDim === 1 && outDim > 1)) { + result.unshift(outAxis); + } + } + return result; + } + function assertAndGetBroadcastShape(shapeA, shapeB) { + const l = Math.max(shapeA.length, shapeB.length); + const result = new Array(l); + for (let i = 0; i < l; i++) { + let a = shapeA[shapeA.length - i - 1]; + if (a == null) { + a = 1; + } + let b = shapeB[shapeB.length - i - 1]; + if (b == null) { + b = 1; + } + if (a === 1) { + result[l - i - 1] = b; + } + else if (b === 1) { + result[l - i - 1] = a; + } + else if (a !== b) { + const errMsg = `Operands could not be broadcast together with shapes ` + + `${shapeA} and ${shapeB}.`; + throw Error(errMsg); + } + else { + result[l - i - 1] = a; + } + } + return result; + } + + var broadcast_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + assertAndGetBroadcastShape: assertAndGetBroadcastShape, + getBroadcastDims: getBroadcastDims$1, + getReductionAxes: getReductionAxes + }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of (a == b) element-wise. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([1, 2, 3]); + * const b = tf.tensor1d([2, 2, 2]); + * + * a.equal(b).print(); + * ``` + * + * @param a The first input tensor. + * @param b The second input tensor. Must have the same dtype as `a`. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function equal_(a, b) { + let $a = convertToTensor(a, 'a', 'equal', 'string_or_numeric'); + let $b = convertToTensor(b, 'b', 'equal', 'string_or_numeric'); + [$a, $b] = makeTypesMatch($a, $b); + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Equal, inputs); + } + const equal$2 = /* @__PURE__ */ op({ equal_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the elements, either `a` or `b` depending on the `condition`. + * + * If the condition is true, select from `a`, otherwise select from `b`. + * + * ```js + * const cond = tf.tensor1d([false, false, true], 'bool'); + * const a = tf.tensor1d([1 , 2, 3]); + * const b = tf.tensor1d([-1, -2, -3]); + * + * a.where(cond, b).print(); + * ``` + * + * @param condition The input condition. Must be of dtype bool. + * @param a If `condition` is rank 1, `a` may have a higher rank but + * its first dimension must match the size of `condition`. + * @param b A tensor with the same dtype as `a` and with shape that is + * compatible with `a`. + * @return A tensor with same dtype as `a` and `b`, and shape that is + * broadcastable from `a` and `b`. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function where_(condition, a, b) { + const $a = convertToTensor(a, 'a', 'where'); + const $b = convertToTensor(b, 'b', 'where'); + const $condition = convertToTensor(condition, 'condition', 'where', 'bool'); + // TODO: move this logic to forward function when the broadcastTo op is + // implemented in WASM. + // Find the broadcastable shape for $condition, $a, and $b. + const broadcastShape = assertAndGetBroadcastShape(assertAndGetBroadcastShape($condition.shape, $a.shape), $b.shape); + const $broadcastedCondition = broadcastTo($condition, broadcastShape); + const $broadcastedA = broadcastTo($a, broadcastShape); + const $broadcastedB = broadcastTo($b, broadcastShape); + const inputs = { + condition: $broadcastedCondition, + t: $broadcastedA, + e: $broadcastedB + }; + return ENGINE.runKernel(Select, inputs); + } + const where = /* @__PURE__ */ op({ where_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with all elements set to 0 with the same shape as the + * given tensor. + * + * ```js + * const x = tf.tensor([1, 2]); + * tf.zerosLike(x).print(); + * ``` + * + * @param x The tensor of required shape. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function zerosLike_(x) { + const $x = convertToTensor(x, 'x', 'zerosLike'); + const inputs = { x: $x }; + return ENGINE.runKernel(ZerosLike, inputs); + } + const zerosLike$3 = /* @__PURE__ */ op({ zerosLike_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Divides two `tf.Tensor`s element-wise, A / B. Supports broadcasting. Return 0 + * if denominator is 0. + * + * + * ```js + * const a = tf.tensor1d([1, 4, 9, 16]); + * const b = tf.tensor1d([1, 2, 3, 4]); + * const c = tf.tensor1d([0, 0, 0, 0]); + * + * a.divNoNan(b).print(); // or tf.divNoNan(a, b) + * a.divNoNan(c).print(); // or tf.divNoNan(a, c) + * ``` + * + * ```js + * // Broadcast div a with b. + * const a = tf.tensor1d([2, 4, 6, 8]); + * const b = tf.scalar(2); + * const c = tf.scalar(0); + * + * a.divNoNan(b).print(); // or tf.divNoNan(a, b) + * a.divNoNan(c).print(); // or tf.divNoNan(a, c) + * ``` + * + * @param a The first tensor as the numerator. + * @param b The second tensor as the denominator. Must have the same dtype as + * `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function divNoNan_(a, b) { + // TODO: Make this into its own kernel. + let $a = convertToTensor(a, 'a', 'div'); + let $b = convertToTensor(b, 'b', 'div'); + [$a, $b] = makeTypesMatch($a, $b); + const divResult = div$1($a, $b); + const zeros = zerosLike$3(divResult); + const bEqualsZero = equal$2($b, zeros); + return where(bEqualsZero, zeros, divResult); + } + const divNoNan = /* @__PURE__ */ op({ divNoNan_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the dot product of two matrices and/or vectors, `t1` and `t2`. + * + * ```js + * const a = tf.tensor1d([1, 2]); + * const b = tf.tensor2d([[1, 2], [3, 4]]); + * const c = tf.tensor2d([[1, 2, 3], [4, 5, 6]]); + * + * a.dot(b).print(); // or tf.dot(a, b) + * b.dot(a).print(); + * b.dot(c).print(); + * ``` + * @param t1 The first tensor in the dot operation. + * @param t2 The second tensor in the dot operation. + * + * @doc {heading: 'Operations', subheading: 'Matrices'} + */ + function dot_(t1, t2) { + const $t1 = convertToTensor(t1, 't1', 'dot'); + const $t2 = convertToTensor(t2, 't2', 'dot'); + assert$1(($t1.rank === 1 || $t1.rank === 2) && ($t2.rank === 1 || $t2.rank === 2), () => `Error in dot: inputs must all be rank 1 or 2, but got ranks ` + + `${$t1.rank} and ${$t2.rank}.`); + const t1Inner = ($t1.rank === 1 ? $t1.size : $t1.shape[1]); + const t2Inner = ($t2.rank === 1 ? $t2.size : $t2.shape[0]); + assert$1(t1Inner === t2Inner, () => `Error in dot: inner dimensions of inputs must match, but got ` + + `${t1Inner} and ${t2Inner}.`); + if ($t1.rank === 1 && $t2.rank === 1) { + const t12D = reshape$3($t1, [1, -1]); + const t22D = reshape$3($t2, [-1, 1]); + const t1t2 = matMul$1(t12D, t22D); + return reshape$3(t1t2, []); + } + else if ($t1.rank === 1 && $t2.rank === 2) { + const t12D = reshape$3($t1, [1, -1]); + const t22D = reshape$3($t2, [$t2.shape[0], $t2.shape[1]]); + const t1t2 = matMul$1(t12D, t22D); + return reshape$3(t1t2, [t1t2.size]); + } + else if ($t1.rank === 2 && $t2.rank === 1) { + const t22D = reshape$3($t2, [-1, 1]); + const t1t2 = matMul$1($t1, t22D); + return reshape$3(t1t2, [t1t2.size]); + } + else { + const t22D = reshape$3($t2, [$t2.shape[0], $t2.shape[1]]); + const t1t2 = matMul$1($t1, t22D); + return t1t2; + } + } + const dot$2 = /* @__PURE__ */ op({ dot_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Tensor contraction over specified indices and outer product. + * + * `einsum` allows defining Tensors by defining their element-wise computation. + * This computation is based on + * [Einstein summation](https://en.wikipedia.org/wiki/Einstein_notation). + * + * Some special cases include: + * + * Matrix multiplication: + * ```js + * const x = tf.tensor2d([[1, 2, 3], [4, 5, 6]]); + * const y = tf.tensor2d([[0, 1], [2, 3], [4, 5]]); + * x.print(); + * y.print(); + * tf.einsum('ij,jk->ik', x, y).print(); + * ``` + * + * Dot product: + * ```js + * const x = tf.tensor1d([1, 2, 3]); + * const y = tf.tensor1d([0, 1, 2]); + * x.print(); + * y.print(); + * tf.einsum('i,i->', x, y).print(); + * ``` + * + * Batch dot product: + * ```js + * const x = tf.tensor2d([[1, 2, 3], [4, 5, 6]]); + * const y = tf.tensor2d([[0, 1, 2], [3, 4, 5]]); + * x.print(); + * y.print(); + * tf.einsum('bi,bi->b', x, y).print(); + * ``` + * + * Outer prouduct: + * ```js + * const x = tf.tensor1d([1, 3, 5]); + * const y = tf.tensor1d([2, 4, 6]); + * x.print(); + * y.print(); + * tf.einsum('i,j->ij', x, y).print(); + * ``` + * + * Matrix transpose: + * ```js + * const x = tf.tensor2d([[1, 2], [3, 4]]); + * x.print(); + * tf.einsum('ij->ji', x).print(); + * ``` + * + * Batch matrix transpose: + * ```js + * const x = tf.tensor3d([[[1, 2], [3, 4]], [[-1, -2], [-3, -4]]]); + * x.print(); + * tf.einsum('bij->bji', x).print(); + * ``` + * + * Limitations: + * + * This implementation of einsum has the following limitations: + * + * - Does not support >2 input tensors. + * - Does not support duplicate axes for any given input tensor. E.g., equation + * 'ii->' is not supported. + * - The `...` notation is not supported. + * + * @param equation a string describing the contraction, in the same format as + * [numpy.einsum](https://numpy.org/doc/stable/reference/generated/numpy.einsum.html). + * @param tensors the input(s) to contract (each one a Tensor), whose shapes + * should be consistent with equation. + * @returns The output tensor. + * + * @doc {heading: 'Tensors', subheading: 'Matrices'} + */ + function einsum_(equation, ...tensors) { + const $tensors = tensors.map((t, i) => convertToTensor(t, `tensors${i}`, 'einsum')); + const attrs = { equation }; + return ENGINE.runKernel(Einsum, $tensors, attrs); + } + const einsum$2 = /* @__PURE__ */ op({ einsum_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes exponential linear element-wise: `x > 0 ? x : (e ^ x) - 1`. + * + * ```js + * const x = tf.tensor1d([-1, 1, -3, 2]); + * + * x.elu().print(); // or tf.elu(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function elu_(x) { + const $x = convertToTensor(x, 'x', 'elu', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Elu$1, inputs); + } + const elu$4 = /* @__PURE__ */ op({ elu_ }); + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Checks the input tensor mathes the given shape. + * + * Given an input tensor, returns a new tensor with the same values as the + * input tensor with shape `shape`. + * + * The method supports the null value in tensor. It will still check the shapes, + * and null is a placeholder. + * + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * const y = tf.tensor1d([1, null, 3, 4]); + * const z = tf.tensor2d([1, 2, 3, 4], [2,2]); + * tf.ensureShape(x, [4]).print(); + * tf.ensureShape(y, [4]).print(); + * tf.ensureShape(z, [null, 2]).print(); + * ``` + * + * @param x The input tensor to be ensured. + * @param shape A TensorShape representing the shape of this tensor, an array + * or null. + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function ensureShape_(x, shape) { + const $x = convertToTensor(x, 'x', 'ensureShape', 'string_or_numeric'); + if (!arraysEqualWithNull($x.shape, shape)) { + throw new Error(`EnsureShape: Shape of tensor ${$x.shape} is not compatible with expected shape ${shape}`); + } + return x; + } + const ensureShape = /* @__PURE__ */ op({ ensureShape_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes Gauss error function of the input `tf.Tensor` element-wise: + * `erf(x)` + * + * ```js + * const x = tf.tensor1d([0, .1, -.1, .7]); + * + * x.erf().print(); // or tf.erf(x); + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function erf_(x) { + let $x = convertToTensor(x, 'x', 'erf'); + assert$1($x.dtype === 'int32' || $x.dtype === 'float32', () => 'Input dtype must be `int32` or `float32`.'); + if ($x.dtype === 'int32') { + $x = cast$3($x, 'float32'); + } + const inputs = { x: $x }; + return ENGINE.runKernel(Erf, inputs); + } + const erf$2 = /* @__PURE__ */ op({ erf_ }); + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns true if the axis specifies the inner most dimensions of the + * array. + */ + function axesAreInnerMostDims(axes, rank) { + for (let i = 0; i < axes.length; ++i) { + if (axes[axes.length - i - 1] !== rank - 1 - i) { + return false; + } + } + return true; + } + function combineLocations(outputLoc, reduceLoc, axes) { + const rank = outputLoc.length + reduceLoc.length; + const loc = []; + let outIdx = 0; + let reduceIdx = 0; + for (let dim = 0; dim < rank; dim++) { + if (axes.indexOf(dim) === -1) { + loc.push(outputLoc[outIdx++]); + } + else { + loc.push(reduceLoc[reduceIdx++]); + } + } + return loc; + } + function computeOutAndReduceShapes(aShape, axes) { + const outShape = []; + const rank = aShape.length; + for (let dim = 0; dim < rank; dim++) { + if (axes.indexOf(dim) === -1) { + outShape.push(aShape[dim]); + } + } + const reduceShape = axes.map(dim => aShape[dim]); + return [outShape, reduceShape]; + } + function expandShapeToKeepDim(shape, axes) { + const reduceSubShape = axes.map(x => 1); + return combineLocations(shape, reduceSubShape, axes); + } + function assertAxesAreInnerMostDims(msg, axes, rank) { + assert$1(axesAreInnerMostDims(axes, rank), () => `${msg} supports only inner-most axes for now. ` + + `Got axes ${axes} and rank-${rank} input.`); + } + /** + * Returns the axes permutation to be used with `tf.transpose`, if such + * permutation is necessary. Otherwise it returns null. This method is used by + * operations that operate only on inner-most axes. + */ + function getAxesPermutation(axes, rank) { + if (axesAreInnerMostDims(axes, rank)) { + return null; + } + const result = []; + for (let i = 0; i < rank; ++i) { + if (axes.indexOf(i) === -1) { + result.push(i); + } + } + axes.forEach(axis => result.push(axis)); + return result; + } + /** Returns the axes permutation that undoes the original permutation. */ + function getUndoAxesPermutation(axes) { + return axes.map((axis, i) => [i, axis]) + .sort((a, b) => a[1] - b[1]) + .map(x => x[0]); + } + function getInnerMostAxes(numAxes, rank) { + const res = []; + for (let i = rank - numAxes; i < rank; ++i) { + res.push(i); + } + return res; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the maximum of elements across dimensions of a `tf.Tensor`. + * + * Reduces the input along the dimensions given in `axes`. Unless `keepDims` + * is true, the rank of the `tf.Tensor` is reduced by 1 for each entry in + * `axes`. If `keepDims` is true, the reduced dimensions are retained with + * length 1. If `axes` has no entries, all dimensions are reduced, and a + * `tf.Tensor` with a single element is returned. + * + * ```js + * const x = tf.tensor1d([1, 2, 3]); + * + * x.max().print(); // or tf.max(x) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * const axis = 1; + * x.max(axis).print(); // or tf.max(x, axis) + * ``` + * + * @param x The input tensor. + * @param axis The dimension(s) to reduce. By default it reduces + * all dimensions. + * @param keepDims If true, retains reduced dimensions with size 1. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function max_(x, axis = null, keepDims = false) { + const $x = convertToTensor(x, 'x', 'max'); + const inputs = { x: $x }; + const attrs = { reductionIndices: axis, keepDims }; + return ENGINE.runKernel(Max, inputs, attrs); + } + const max$3 = /* @__PURE__ */ op({ max_ }); + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the minimum value from the input. + * + * Reduces the input along the dimensions given in `axes`. Unless `keepDims` + * is true, the rank of the array is reduced by 1 for each entry in `axes`. + * If `keepDims` is true, the reduced dimensions are retained with length 1. + * If `axes` has no entries, all dimensions are reduced, and an array with a + * single element is returned. + * + * ```js + * const x = tf.tensor1d([1, 2, 3]); + * + * x.min().print(); // or tf.min(x) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * const axis = 1; + * x.min(axis).print(); // or tf.min(x, axis) + * ``` + * + * @param x The input Tensor. + * @param axis The dimension(s) to reduce. By default it reduces + * all dimensions. + * @param keepDims If true, retains reduced dimensions with size 1. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function min_(x, axis = null, keepDims = false) { + const $x = convertToTensor(x, 'x', 'min'); + const inputs = { x: $x }; + const attrs = { axis, keepDims }; + // tslint:disable-next-line: no-unnecessary-type-assertion + return ENGINE.runKernel(Min, inputs, attrs); + } + const min$3 = /* @__PURE__ */ op({ min_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the power of one `tf.Tensor` to another. Supports broadcasting. + * + * Given a `tf.Tensor` x and a `tf.Tensor` y, this operation computes x^y for + * corresponding elements in x and y. The result's dtype will be the upcasted + * type of the `base` and `exp` dtypes. + * + * ```js + * const a = tf.tensor([[2, 3], [4, 5]]) + * const b = tf.tensor([[1, 2], [3, 0]]).toInt(); + * + * a.pow(b).print(); // or tf.pow(a, b) + * ``` + * + * ```js + * const a = tf.tensor([[1, 2], [3, 4]]) + * const b = tf.tensor(2).toInt(); + * + * a.pow(b).print(); // or tf.pow(a, b) + * ``` + * We also expose `powStrict` which has the same signature as this op and + * asserts that `base` and `exp` are the same shape (does not broadcast). + * + * @param base The base `tf.Tensor` to pow element-wise. + * @param exp The exponent `tf.Tensor` to pow element-wise. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function pow_(base, exp) { + let $base = convertToTensor(base, 'base', 'pow'); + let $exp = convertToTensor(exp, 'exp', 'pow'); + [$base, $exp] = makeTypesMatch($base, $exp); + const inputs = { a: $base, b: $exp }; + return ENGINE.runKernel(Pow, inputs); + } + const pow$3 = /* @__PURE__ */ op({ pow_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates rank-0 `tf.Tensor` (scalar) with the provided value and dtype. + * + * The same functionality can be achieved with `tf.tensor`, but in general + * we recommend using `tf.scalar` as it makes the code more readable. + * + * ```js + * tf.scalar(3.14).print(); + * ``` + * + * @param value The value of the scalar. + * @param dtype The data type. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function scalar(value, dtype) { + if (((isTypedArray(value) && dtype !== 'string') || Array.isArray(value)) && + dtype !== 'complex64') { + throw new Error('Error creating a new Scalar: value must be a primitive ' + + '(number|boolean|string)'); + } + if (dtype === 'string' && isTypedArray(value) && + !(value instanceof Uint8Array)) { + throw new Error('When making a scalar from encoded string, ' + + 'the value must be `Uint8Array`.'); + } + const shape = []; + const inferredShape = []; + return makeTensor(value, shape, inferredShape, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes square root of the input `tf.Tensor` element-wise: `y = sqrt(x)` + * + * ```js + * const x = tf.tensor1d([1, 2, 4, -1]); + * + * x.sqrt().print(); // or tf.sqrt(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function sqrt_(x) { + const $x = convertToTensor(x, 'x', 'sqrt', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Sqrt, inputs); + } + const sqrt$2 = /* @__PURE__ */ op({ sqrt_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes square of `x` element-wise: `x ^ 2` + * + * ```js + * const x = tf.tensor1d([1, 2, Math.sqrt(2), -1]); + * + * x.square().print(); // or tf.square(x) + * ``` + * @param x The input Tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function square_(x) { + const $x = convertToTensor(x, 'x', 'square'); + const attrs = {}; + return ENGINE.runKernel('Square', { x: $x }, attrs); + } + const square$2 = /* @__PURE__ */ op({ square_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the sum of elements across dimensions of a `tf.Tensor`. + * + * Reduces the input along the dimensions given in `axes`. Unless `keepDims` + * is true, the rank of the `tf.Tensor` is reduced by 1 for each entry in + * `axes`. If `keepDims` is true, the reduced dimensions are retained with + * length 1. If axes has no entries, all dimensions are reduced, and a + * `tf.Tensor` with a single element is returned. + * + * ```js + * const x = tf.tensor1d([1, 2, 3]); + * + * x.sum().print(); // or tf.sum(x) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * const axis = 1; + * x.sum(axis).print(); // or tf.sum(x, axis) + * ``` + * + * @param x The input tensor to compute the sum over. If the dtype is `bool` + * it will be converted to `int32` and the output dtype will be `int32`. + * @param axis The dimension(s) to reduce. By default it reduces + * all dimensions. + * @param keepDims If true, retains reduced dimensions with size 1. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function sum_(x, axis = null, keepDims = false) { + let $x = convertToTensor(x, 'x', 'sum'); + if ($x.dtype === 'bool') { + $x = cast$3($x, 'int32'); + } + const inputs = { x: $x }; + const attrs = { axis, keepDims }; + return ENGINE.runKernel(Sum, inputs, attrs); + } + const sum$3 = /* @__PURE__ */ op({ sum_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the norm of scalar, vectors, and matrices. + * This function can compute several different vector norms (the 1-norm, the + * Euclidean or 2-norm, the inf-norm, and in general the p-norm for p > 0) + * and matrix norms (Frobenius, 1-norm, and inf-norm). + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * + * x.norm().print(); // or tf.norm(x) + * ``` + * + * @param x The input array. + * @param ord Optional. Order of the norm. Supported norm types are + * following: + * + * | ord | norm for matrices | norm for vectors + * |------------|---------------------------|--------------------- + * |'euclidean' |Frobenius norm |2-norm + * |'fro' |Frobenius norm | + * |Infinity |max(sum(abs(x), axis=1)) |max(abs(x)) + * |-Infinity |min(sum(abs(x), axis=1)) |min(abs(x)) + * |1 |max(sum(abs(x), axis=0)) |sum(abs(x)) + * |2 | |sum(abs(x)^2)^(1/2) + * + * @param axis Optional. If axis is null (the default), the input is + * considered a vector and a single vector norm is computed over the entire + * set of values in the Tensor, i.e. norm(x, ord) is equivalent + * to norm(x.reshape([-1]), ord). If axis is an integer, the input + * is considered a batch of vectors, and axis determines the axis in x + * over which to compute vector norms. If axis is a 2-tuple of integer it is + * considered a batch of matrices and axis determines the axes in NDArray + * over which to compute a matrix norm. + * @param keepDims Optional. If true, the norm has the same dimensionality + * as the input. + * + * @doc {heading: 'Operations', subheading: 'Matrices'} + */ + function norm_(x, ord = 'euclidean', axis = null, keepDims = false) { + x = convertToTensor(x, 'x', 'norm'); + const norm = normImpl(x, ord, axis); + let keepDimsShape = norm.shape; + if (keepDims) { + const axes = parseAxisParam(axis, x.shape); + keepDimsShape = expandShapeToKeepDim(norm.shape, axes); + } + return reshape$3(norm, keepDimsShape); + } + function normImpl(x, p, axis = null) { + if (x.rank === 0) { + return abs$2(x); + } + // consider vector when no axis is specified + if (x.rank !== 1 && axis === null) { + return normImpl(reshape$3(x, [-1]), p, axis); + } + // vector + if (x.rank === 1 || typeof axis === 'number' || + Array.isArray(axis) && axis.length === 1) { + if (p === 1) { + return sum$3(abs$2(x), axis); + } + if (p === Infinity) { + return max$3(abs$2(x), axis); + } + if (p === -Infinity) { + return min$3(abs$2(x), axis); + } + if (p === 'euclidean' || p === 2) { + // norm(x, 2) = sum(abs(xi) ^ 2) ^ 1/2 + return sqrt$2(sum$3(pow$3(abs$2(x), scalar(2, 'int32')), axis)); + } + throw new Error(`Error in norm: invalid ord value: ${p}`); + } + // matrix (assumption axis[0] < axis[1]) + if (Array.isArray(axis) && axis.length === 2) { + if (p === 1) { + return max$3(sum$3(abs$2(x), axis[0]), axis[1] - 1); + } + if (p === Infinity) { + return max$3(sum$3(abs$2(x), axis[1]), axis[0]); + } + if (p === -Infinity) { + return min$3(sum$3(abs$2(x), axis[1]), axis[0]); + } + if (p === 'fro' || p === 'euclidean') { + // norm(x) = sqrt(sum(pow(x, 2))) + return sqrt$2(sum$3(square$2(x), axis)); + } + throw new Error(`Error in norm: invalid ord value: ${p}`); + } + throw new Error(`Error in norm: invalid axis: ${axis}`); + } + const norm = /* @__PURE__ */ op({ norm_ }); + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the Euclidean norm of scalar, vectors, and matrices. + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * + * x.euclideanNorm().print(); // or tf.euclideanNorm(x) + * ``` + * + * @param x The input array. + * @param axis Optional. If axis is null (the default), the input is + * considered a vector and a single vector norm is computed over the entire + * set of values in the Tensor, i.e. euclideanNorm(x) is equivalent + * to euclideanNorm(x.reshape([-1])). If axis is an integer, the input + * is considered a batch of vectors, and axis determines the axis in x + * over which to compute vector norms. If axis is a 2-tuple of integer it is + * considered a batch of matrices and axis determines the axes in NDArray + * over which to compute a matrix norm. + * @param keepDims Optional. If true, the norm has the same dimensionality + * as the input. + * + * @doc {heading: 'Operations', subheading: 'Matrices'} + */ + function euclideanNorm_(x, axis = null, keepDims = false) { + return norm(x, 'euclidean', axis, keepDims); + } + const euclideanNorm = /* @__PURE__ */ op({ euclideanNorm_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes exponential of the input `tf.Tensor` element-wise. `e ^ x` + * + * ```js + * const x = tf.tensor1d([1, 2, -3]); + * + * x.exp().print(); // or tf.exp(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function exp_(x) { + const $x = convertToTensor(x, 'x', 'exp'); + const inputs = { x: $x }; + return ENGINE.runKernel(Exp, inputs); + } + const exp$2 = /* @__PURE__ */ op({ exp_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns a `tf.Tensor` that has expanded rank, by inserting a dimension + * into the tensor's shape. + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * const axis = 1; + * x.expandDims(axis).print(); + * ``` + * + * @param x The input tensor whose dimensions are to be expanded. + * @param axis The dimension index at which to insert shape of `1`. Defaults + * to 0 (the first dimension). + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function expandDims_(x, axis = 0) { + const $x = convertToTensor(x, 'x', 'expandDims', 'string_or_numeric'); + assert$1(axis <= $x.rank, () => 'Axis must be <= rank of the tensor'); + const inputs = { input: $x }; + const attrs = { dim: axis }; + return ENGINE.runKernel(ExpandDims, inputs, attrs); + } + const expandDims$3 = /* @__PURE__ */ op({ expandDims_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes exponential of the input `tf.Tensor` minus one element-wise. + * `e ^ x - 1` + * + * ```js + * const x = tf.tensor1d([1, 2, -3]); + * + * x.expm1().print(); // or tf.expm1(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function expm1_(x) { + const $x = convertToTensor(x, 'x', 'expm1'); + const inputs = { x: $x }; + return ENGINE.runKernel(Expm1, inputs); + } + const expm1$2 = /* @__PURE__ */ op({ expm1_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Construct a tensor by repeating it the number of times given by reps. + * + * This operation creates a new tensor by replicating `input` `reps` + * times. The output tensor's `i`th dimension has `input.shape[i] * + * reps[i]` elements, and the values of `input` are replicated + * `reps[i]` times along the `i`th dimension. For example, tiling + * `[a, b, c, d]` by `[2]` produces `[a, b, c, d, a, b, c, d]`. + * + * ```js + * const a = tf.tensor1d([1, 2]); + * + * a.tile([2]).print(); // or tf.tile(a, [2]) + * ``` + * + * ```js + * const a = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * a.tile([1, 2]).print(); // or tf.tile(a, [1,2]) + * ``` + * @param x The tensor to tile. + * @param reps Determines the number of replications per dimension. + * + * @doc {heading: 'Tensors', subheading: 'Slicing and Joining'} + */ + function tile_(x, reps) { + const $x = convertToTensor(x, 'x', 'tile', 'string_or_numeric'); + assert$1($x.rank === reps.length, () => `Error in transpose: rank of input ${$x.rank} ` + + `must match length of reps ${reps}.`); + const inputs = { x: $x }; + const attrs = { reps }; + return ENGINE.runKernel(Tile, inputs, attrs); + } + const tile$3 = /* @__PURE__ */ op({ tile_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Create an identity matrix. + * + * @param numRows Number of rows. + * @param numColumns Number of columns. Defaults to `numRows`. + * @param batchShape If provided, will add the batch shape to the beginning + * of the shape of the returned `tf.Tensor` by repeating the identity + * matrix. + * @param dtype Data type. + * @returns Identity matrix of the specified size and data type, possibly + * with batch repetition if `batchShape` is specified. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function eye_(numRows, numColumns, batchShape, dtype = 'float32') { + if (numColumns == null) { + numColumns = numRows; + } + const buff = buffer([numRows, numColumns], dtype); + const n = numRows <= numColumns ? numRows : numColumns; + for (let i = 0; i < n; ++i) { + buff.set(1, i, i); + } + const out = reshape$3(buff.toTensor(), [numRows, numColumns]); + if (batchShape == null) { + return out; + } + else { + if (batchShape.length === 1) { + return tile$3(expandDims$3(out, 0), [batchShape[0], 1, 1]); + } + else if (batchShape.length === 2) { + // tslint:disable-next-line:no-unnecessary-type-assertion + return tile$3(expandDims$3(expandDims$3(out, 0), 0), [batchShape[0], batchShape[1], 1, 1]); + } + else if (batchShape.length === 3) { + // tslint:disable-next-line:no-unnecessary-type-assertion + return tile$3(expandDims$3(expandDims$3(expandDims$3(out, 0), 0), 0), [ + batchShape[0], batchShape[1], batchShape[2], 1, 1 + ]); + } + else { + throw new Error(`eye() currently supports only 1D and 2D ` + + // tslint:disable-next-line:no-any + `batchShapes, but received ${batchShape.length}D.`); + } + } + } + const eye = /* @__PURE__ */ op({ eye_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes floor of input `tf.Tensor` element-wise: `floor(x)`. + * + * ```js + * const x = tf.tensor1d([.6, 1.1, -3.3]); + * + * x.floor().print(); // or tf.floor(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function floor_(x) { + const $x = convertToTensor(x, 'x', 'floor', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Floor, inputs); + } + const floor$2 = /* @__PURE__ */ op({ floor_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Gather slices from tensor `x`'s axis `axis` according to `indices`. + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * const indices = tf.tensor1d([1, 3, 3], 'int32'); + * + * x.gather(indices).print(); + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * const indices = tf.tensor1d([1, 1, 0], 'int32'); + * + * x.gather(indices).print(); + * ``` + * @param x The input tensor whose slices are to be gathered. + * @param indices The indices of the values to extract. + * @param axis The axis over which to select values. Defaults to 0. + * @param batchDims Optional. The number of batch dimensions. It must be less + * than or equal to rank(indices). Defaults to 0. + * The output tensor will have shape of + * `x.shape[:axis] + indices.shape[batchDims:] + x.shape[axis + 1:]` + * + * @doc {heading: 'Tensors', subheading: 'Slicing and Joining'} + */ + function gather_(x, indices, axis = 0, batchDims = 0) { + const $x = convertToTensor(x, 'x', 'gather'); + const $indices = convertToTensor(indices, 'indices', 'gather', 'int32'); + const inputs = { x: $x, indices: $indices }; + const attrs = { axis, batchDims }; + return ENGINE.runKernel(GatherV2, inputs, attrs); + } + const gather$1 = /* @__PURE__ */ op({ gather_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of (a > b) element-wise. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([1, 2, 3]); + * const b = tf.tensor1d([2, 2, 2]); + * + * a.greater(b).print(); + * ``` + * + * @param a The first input tensor. + * @param b The second input tensor. Must have the same dtype as `a`. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function greater_(a, b) { + let $a = convertToTensor(a, 'a', 'greater', 'string_or_numeric'); + let $b = convertToTensor(b, 'b', 'greater', 'string_or_numeric'); + [$a, $b] = makeTypesMatch($a, $b); + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Greater, inputs); + } + const greater$3 = /* @__PURE__ */ op({ greater_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of (a >= b) element-wise. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([1, 2, 3]); + * const b = tf.tensor1d([2, 2, 2]); + * + * a.greaterEqual(b).print(); + * ``` + * + * @param a The first input tensor. + * @param b The second input tensor. Must have the same dtype as `a`. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function greaterEqual_(a, b) { + let $a = convertToTensor(a, 'a', 'greaterEqual', 'string_or_numeric'); + let $b = convertToTensor(b, 'b', 'greaterEqual', 'string_or_numeric'); + [$a, $b] = makeTypesMatch($a, $b); + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(GreaterEqual, inputs); + } + const greaterEqual$2 = /* @__PURE__ */ op({ greaterEqual_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the imaginary part of a complex (or real) tensor. + * + * Given a tensor input, this operation returns a tensor of type float that is + * the imaginary part of each element in input considered as a complex number. + * If input is real, a tensor of all zeros is returned. + * + * ```js + * const x = tf.complex([-2.25, 3.25], [4.75, 5.75]); + * tf.imag(x).print(); + * ``` + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function imag_(input) { + const $input = convertToTensor(input, 'input', 'imag'); + const inputs = { input: $input }; + return ENGINE.runKernel(Imag, inputs); + } + const imag$2 = /* @__PURE__ */ op({ imag_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns which elements of x are finite. + * + * ```js + * const x = tf.tensor1d([NaN, Infinity, -Infinity, 0, 1]); + * + * x.isFinite().print(); // or tf.isNaN(x) + * ``` + * @param x The input Tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function isFinite_(x) { + const $x = convertToTensor(x, 'x', 'isFinite'); + const inputs = { x: $x }; + return ENGINE.runKernel(IsFinite, inputs); + } + const isFinite$3 = /* @__PURE__ */ op({ isFinite_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns which elements of x are Infinity or -Infinity. + * + * ```js + * const x = tf.tensor1d([NaN, Infinity, -Infinity, 0, 1]); + * + * x.isInf().print(); // or tf.isNaN(x) + * ``` + * @param x The input Tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function isInf_(x) { + const $x = convertToTensor(x, 'x', 'isInf'); + const inputs = { x: $x }; + return ENGINE.runKernel(IsInf, inputs); + } + const isInf$2 = /* @__PURE__ */ op({ isInf_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns which elements of x are NaN. + * + * ```js + * const x = tf.tensor1d([NaN, Infinity, -Infinity, 0, 1]); + * + * x.isNaN().print(); // or tf.isNaN(x) + * ``` + * @param x The input Tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function isNaN_(x) { + const $x = convertToTensor(x, 'x', 'isNaN'); + const inputs = { x: $x }; + return ENGINE.runKernel(IsNan, inputs); + } + const isNaN$3 = /* @__PURE__ */ op({ isNaN_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes leaky rectified linear element-wise. + * + * See + * [http://web.stanford.edu/~awni/papers/relu_hybrid_icml2013_final.pdf]( + * http://web.stanford.edu/~awni/papers/relu_hybrid_icml2013_final.pdf) + * + * ```js + * const x = tf.tensor1d([-1, 2, -3, 4]); + * + * x.leakyRelu(0.1).print(); // or tf.leakyRelu(x, 0.1) + * ``` + * @param x The input tensor. + * @param alpha The scaling factor for negative values, defaults to 0.2. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function leakyRelu_(x, alpha = 0.2) { + const $x = convertToTensor(x, 'x', 'leakyRelu'); + const inputs = { x: $x }; + const attrs = { alpha }; + return ENGINE.runKernel(LeakyRelu, inputs, attrs); + } + const leakyRelu$2 = /* @__PURE__ */ op({ leakyRelu_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of (a < b) element-wise. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([1, 2, 3]); + * const b = tf.tensor1d([2, 2, 2]); + * + * a.less(b).print(); + * ``` + * @param a The first input tensor. + * @param b The second input tensor. Must have the same dtype as `a`. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function less_(a, b) { + let $a = convertToTensor(a, 'a', 'less', 'string_or_numeric'); + let $b = convertToTensor(b, 'b', 'less', 'string_or_numeric'); + [$a, $b] = makeTypesMatch($a, $b); + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Less, inputs); + } + const less$3 = /* @__PURE__ */ op({ less_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of (a <= b) element-wise. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([1, 2, 3]); + * const b = tf.tensor1d([2, 2, 2]); + * + * a.lessEqual(b).print(); + * ``` + * + * @param a The first input tensor. + * @param b The second input tensor. Must have the same dtype as `a`. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function lessEqual_(a, b) { + let $a = convertToTensor(a, 'a', 'lessEqual', 'string_or_numeric'); + let $b = convertToTensor(b, 'b', 'lessEqual', 'string_or_numeric'); + [$a, $b] = makeTypesMatch($a, $b); + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(LessEqual, inputs); + } + const lessEqual$2 = /* @__PURE__ */ op({ lessEqual_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Return an evenly spaced sequence of numbers over the given interval. + * + * ```js + * tf.linspace(0, 9, 10).print(); + * ``` + * @param start The start value of the sequence. + * @param stop The end value of the sequence. + * @param num The number of values to generate. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function linspace(start, stop, num) { + if (num <= 0) { + throw new Error('The number of values should be positive.'); + } + const attrs = { start, stop, num }; + return ENGINE.runKernel(LinSpace, {}, attrs); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Normalizes the activation of a local neighborhood across or within + * channels. + * + * @param x The input tensor. The 4-D input tensor is treated as a 3-D array + * of 1D vectors (along the last dimension), and each vector is + * normalized independently. + * @param depthRadius The number of adjacent channels in the 1D normalization + * window. + * @param bias A constant bias term for the basis. + * @param alpha A scale factor, usually positive. + * @param beta An exponent. + * + * @doc {heading: 'Operations', subheading: 'Normalization'} + */ + function localResponseNormalization_(x, depthRadius = 5, bias = 1, alpha = 1, beta = 0.5) { + const $x = convertToTensor(x, 'x', 'localResponseNormalization'); + assert$1($x.rank === 4 || $x.rank === 3, () => `Error in localResponseNormalization: x must be rank 3 or 4 but got + rank ${$x.rank}.`); + assert$1(isInt(depthRadius), () => `Error in localResponseNormalization: depthRadius must be an ` + + `integer but got depthRadius ${depthRadius}.`); + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + reshapedTo4D = true; + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + } + const inputs = { x: x4D }; + const attrs = { depthRadius, bias, alpha, beta }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(LRN, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + else { + return res; + } + } + const localResponseNormalization = /* @__PURE__ */ op({ localResponseNormalization_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes natural logarithm of the input `tf.Tensor` element-wise: `ln(x)` + * + * ```js + * const x = tf.tensor1d([1, 2, Math.E]); + * + * x.log().print(); // or tf.log(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function log_(x) { + const $x = convertToTensor(x, 'x', 'log', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Log, inputs); + } + const log$2 = /* @__PURE__ */ op({ log_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes natural logarithm of the input `tf.Tensor` plus one + * element-wise: `ln(1 + x)` + * + * ```js + * const x = tf.tensor1d([1, 2, Math.E - 1]); + * + * x.log1p().print(); // or tf.log1p(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function log1p_(x) { + const $x = convertToTensor(x, 'x', 'log1p'); + const inputs = { x: $x }; + return ENGINE.runKernel(Log1p, inputs); + } + const log1p$2 = /* @__PURE__ */ op({ log1p_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Provided `f(x)`, returns another function `g(x, dy?)`, which gives the + * gradient of `f(x)` with respect to `x`. + * + * If `dy` is provided, the gradient of `f(x).mul(dy).sum()` with respect to + * `x` is computed instead. `f(x)` must take a single tensor `x` and return a + * single tensor `y`. If `f()` takes multiple inputs, use `tf.grads` instead. + * + * ```js + * // f(x) = x ^ 2 + * const f = x => x.square(); + * // f'(x) = 2x + * const g = tf.grad(f); + * + * const x = tf.tensor1d([2, 3]); + * g(x).print(); + * ``` + * + * ```js + * // f(x) = x ^ 3 + * const f = x => x.pow(tf.scalar(3, 'int32')); + * // f'(x) = 3x ^ 2 + * const g = tf.grad(f); + * // f''(x) = 6x + * const gg = tf.grad(g); + * + * const x = tf.tensor1d([2, 3]); + * gg(x).print(); + * ``` + * + * @param f The function f(x), to compute gradient for. + * + * @doc {heading: 'Training', subheading: 'Gradients'} + */ + function grad(f) { + assert$1(isFunction(f), () => 'The f passed in grad(f) must be a function'); + return (x, dy) => { + // x can be of any dtype, thus null as the last argument. + const $x = convertToTensor(x, 'x', 'tf.grad', 'string_or_numeric'); + const $dy = (dy != null) ? convertToTensor(dy, 'dy', 'tf.grad') : null; + return ENGINE.tidy(() => { + const { value, grads } = ENGINE.gradients(() => f($x), [$x], $dy); + if ($dy != null) { + assertShapesMatch(value.shape, $dy.shape, 'The shape of dy passed in grad(f)(x, dy) must match the shape ' + + 'returned by f(x)'); + } + checkGrads(grads); + return grads[0]; + }); + }; + } + /** + * Provided `f(x1, x2,...)`, returns another function `g([x1, x2,...], dy?)`, + * which gives an array of gradients of `f()` with respect to each input + * [`x1`,`x2`,...]. + * + * If `dy` is passed when calling `g()`, the gradient of + * `f(x1,...).mul(dy).sum()` with respect to each input is computed instead. + * The provided `f` must take one or more tensors and return a single tensor + * `y`. If `f()` takes a single input, we recommend using `tf.grad` instead. + * + * ```js + * // f(a, b) = a * b + * const f = (a, b) => a.mul(b); + * // df / da = b, df / db = a + * const g = tf.grads(f); + * + * const a = tf.tensor1d([2, 3]); + * const b = tf.tensor1d([-2, -3]); + * const [da, db] = g([a, b]); + * console.log('da'); + * da.print(); + * console.log('db'); + * db.print(); + * ``` + * + * @param f The function `f(x1, x2,...)` to compute gradients for. + * + * @doc {heading: 'Training', subheading: 'Gradients'} + */ + function grads(f) { + assert$1(isFunction(f), () => 'The f passed in grads(f) must be a function'); + return (args, dy) => { + assert$1(Array.isArray(args), () => 'The args passed in grads(f)(args) must be an array ' + + 'of `Tensor`s or `TensorLike`s'); + // args can be of any dtype, thus null as the last argument. + const $args = convertToTensorArray(args, 'args', 'tf.grads', 'string_or_numeric'); + const $dy = (dy != null) ? convertToTensor(dy, 'dy', 'tf.grads') : null; + return ENGINE.tidy(() => { + const { value, grads } = ENGINE.gradients(() => f(...$args), $args, $dy); + if ($dy != null) { + assertShapesMatch(value.shape, $dy.shape, 'The shape of dy passed in grads(f)([x1,...], dy) must ' + + 'match the shape returned by f([x1,...])'); + } + checkGrads(grads); + return grads; + }); + }; + } + /** + * Like `tf.grad`, but also returns the value of `f()`. Useful when `f()` + * returns a metric you want to show. + * + * The result is a rich object with the following properties: + * - grad: The gradient of `f(x)` w.r.t. `x` (result of `tf.grad`). + * - value: The value returned by `f(x)`. + * + * ```js + * // f(x) = x ^ 2 + * const f = x => x.square(); + * // f'(x) = 2x + * const g = tf.valueAndGrad(f); + * + * const x = tf.tensor1d([2, 3]); + * const {value, grad} = g(x); + * + * console.log('value'); + * value.print(); + * console.log('grad'); + * grad.print(); + * ``` + * + * @doc {heading: 'Training', subheading: 'Gradients'} + */ + function valueAndGrad(f) { + assert$1(isFunction(f), () => 'The f passed in valueAndGrad(f) must be a function'); + return (x, dy) => { + assert$1(x instanceof Tensor, () => 'The x passed in valueAndGrad(f)(x) must be a tensor'); + assert$1(dy == null || dy instanceof Tensor, () => 'The dy passed in valueAndGrad(f)(x, dy) must be a tensor'); + const { grads, value } = ENGINE.gradients(() => f(x), [x], dy); + checkGrads(grads); + return { grad: grads[0], value }; + }; + } + /** + * Like `tf.grads`, but returns also the value of `f()`. Useful when `f()` + * returns a metric you want to show. + * + * The result is a rich object with the following properties: + * - grads: The gradients of `f()` w.r.t. each input (result of `tf.grads`). + * - value: The value returned by `f(x)`. + * + * ```js + * // f(a, b) = a * b + * const f = (a, b) => a.mul(b); + * // df/da = b, df/db = a + * const g = tf.valueAndGrads(f); + * + * const a = tf.tensor1d([2, 3]); + * const b = tf.tensor1d([-2, -3]); + * const {value, grads} = g([a, b]); + * + * const [da, db] = grads; + * + * console.log('value'); + * value.print(); + * + * console.log('da'); + * da.print(); + * console.log('db'); + * db.print(); + * ``` + * + * @doc {heading: 'Training', subheading: 'Gradients'} + */ + function valueAndGrads(f) { + assert$1(isFunction(f), () => 'The f passed in valueAndGrads(f) must be a function'); + return (args, dy) => { + assert$1(Array.isArray(args) && args.every(arg => arg instanceof Tensor), () => 'The args passed in valueAndGrads(f)(args) must be array of ' + + 'tensors'); + assert$1(dy == null || dy instanceof Tensor, () => 'The dy passed in valueAndGrads(f)(args, dy) must be a tensor'); + const res = ENGINE.gradients(() => f(...args), args, dy); + if (dy != null) { + assertShapesMatch(res.value.shape, dy.shape, 'The shape of dy passed in valueAndGrads(f)([x1,...], dy) must ' + + 'match the shape returned by f([x1,...])'); + } + checkGrads(res.grads); + return res; + }; + } + /** + * Computes and returns the gradient of f(x) with respect to the list of + * trainable variables provided by `varList`. If no list is provided, it + * defaults to all trainable variables. + * + * ```js + * const a = tf.variable(tf.tensor1d([3, 4])); + * const b = tf.variable(tf.tensor1d([5, 6])); + * const x = tf.tensor1d([1, 2]); + * + * // f(a, b) = a * x ^ 2 + b * x + * const f = () => a.mul(x.square()).add(b.mul(x)).sum(); + * // df/da = x ^ 2, df/db = x + * const {value, grads} = tf.variableGrads(f); + * + * Object.keys(grads).forEach(varName => grads[varName].print()); + * ``` + * + * @param f The function to execute. f() should return a scalar. + * @param varList The list of variables to compute the gradients with respect + * to. Defaults to all trainable variables. + * @returns An object with the following keys and values: + * - `value`: The value of the function `f`. + * - `grads`: A map from the names of the variables to the gradients. + * If the `varList` argument is provided explicitly and contains a subset of + * non-trainable variables, this map in the return value will contain keys + * that map the names of the non-trainable variables to `null`. + * + * @doc {heading: 'Training', subheading: 'Gradients'} + */ + function variableGrads(f, varList) { + assert$1(isFunction(f), () => 'The f passed in variableGrads(f) must be a function'); + assert$1(varList == null || + Array.isArray(varList) && varList.every(v => v instanceof Variable), () => 'The varList passed in variableGrads(f, varList) must be an array ' + + 'of variables'); + const specifiedVarList = varList != null; + if (!specifiedVarList) { + // Get all of the trainable variables. + varList = []; + for (const varName in ENGINE.registeredVariables) { + varList.push(ENGINE.registeredVariables[varName]); + } + } + const specifiedNonTrainable = specifiedVarList ? varList.filter(variable => !variable.trainable) : null; + // Prune non-trainable variables. + const originalVarCount = varList.length; + varList = varList.filter(variable => variable.trainable); + assert$1(varList.length > 0, () => `variableGrads() expects at least one of the input variables to ` + + `be trainable, but none of the ${originalVarCount} variables is ` + + `trainable.`); + const allowNoGradients = true; + const { value, grads } = ENGINE.gradients(f, varList, null, allowNoGradients); + assert$1(grads.some(g => g != null), () => 'Cannot find a connection between any variable and the result of ' + + 'the loss function y=f(x). Please make sure the operations that ' + + 'use variables are inside the function f passed to minimize().'); + assert$1(value.rank === 0, () => `The f passed in variableGrads(f) must return a scalar, but it ` + + `returned a rank-${value.rank} tensor`); + const namedGrads = {}; + varList.forEach((v, i) => { + if (grads[i] != null) { + namedGrads[v.name] = grads[i]; + } + }); + if (specifiedNonTrainable != null) { + // If varList is explicitly provided and contains non-trainable values, + // add them to the returned gradients with `null` values. + specifiedNonTrainable.forEach(v => namedGrads[v.name] = null); + } + return { value, grads: namedGrads }; + } + /** + * Overrides the gradient computation of a function `f`. + * + * Takes a function + * `f(...inputs, save) => {value: Tensor, gradFunc: (dy, saved) => Tensor[]}` + * and returns another function `g(...inputs)` which takes the same inputs as + * `f`. When called, `g` returns `f().value`. In backward mode, custom gradients + * with respect to each input of `f` are computed using `f().gradFunc`. + * + * The `save` function passed to `f` should be used for saving tensors needed + * in the gradient. And the `saved` passed to the `gradFunc` is a + * `NamedTensorMap`, which contains those saved tensors. + * + * ```js + * const customOp = tf.customGrad((x, save) => { + * // Save x to make sure it's available later for the gradient. + * save([x]); + * // Override gradient of our custom x ^ 2 op to be dy * abs(x); + * return { + * value: x.square(), + * // Note `saved.x` which points to the `x` we saved earlier. + * gradFunc: (dy, saved) => [dy.mul(saved[0].abs())] + * }; + * }); + * + * const x = tf.tensor1d([-1, -2, 3]); + * const dx = tf.grad(x => customOp(x)); + * + * console.log(`f(x):`); + * customOp(x).print(); + * console.log(`f'(x):`); + * dx(x).print(); + * ``` + * + * @param f The function to evaluate in forward mode, which should return + * `{value: Tensor, gradFunc: (dy, saved) => Tensor[]}`, where `gradFunc` + * returns the custom gradients of `f` with respect to its inputs. + * + * @doc {heading: 'Training', subheading: 'Gradients'} + */ + function customGrad(f) { + return ENGINE.customGrad(f); + } + function checkGrads(grads) { + const numNullGradients = grads.filter(g => g == null).length; + if (numNullGradients > 0) { + throw new Error(`Cannot compute gradient of y=f(x) with respect to x. Make sure that + the f you passed encloses all operations that lead from x to y.`); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes `-1 * x` element-wise. + * + * ```js + * const x = tf.tensor2d([1, 2, -2, 0], [2, 2]); + * + * x.neg().print(); // or tf.neg(x) + * ``` + * + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function neg_(x) { + const $x = convertToTensor(x, 'x', 'neg'); + const inputs = { x: $x }; + return ENGINE.runKernel(Neg, inputs); + } + const neg$2 = /* @__PURE__ */ op({ neg_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes softplus of the input `tf.Tensor` element-wise: `log(exp(x) + 1)` + * + * ```js + * const x = tf.tensor1d([0, 1, -1, .7]); + * + * x.softplus().print(); // or tf.softplus(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function softplus_(x) { + const $x = convertToTensor(x, 'x', 'softplus'); + const inputs = { x: $x }; + return ENGINE.runKernel(Softplus$1, inputs); + } + const softplus$2 = /* @__PURE__ */ op({ softplus_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes log sigmoid of the input `tf.Tensor` element-wise: + * `logSigmoid(x)`. For numerical stability, we use `-tf.softplus(-x)`. + * + * ```js + * const x = tf.tensor1d([0, 1, -1, .7]); + * + * x.logSigmoid().print(); // or tf.logSigmoid(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function logSigmoid_(x) { + const $x = convertToTensor(x, 'x', 'logSigmoid'); + // Use a custom gradient to maintain previous implementation. + // There is no LogSigmoid kernel in TF so we can't use engine.runKernel + // directly + const customOp = customGrad((x) => { + // TODO(yassogba) we can remove the chained softplus call here only + // after backends have modualrized softplus at which point we can call + // engine runKernel(..., Sotfplus, ...) directly. + const value = neg$2(softplus$2(neg$2(x))); + const gradFunc = (dy) => { + const derX = mul(dy, sigmoid$2(neg$2(x))); + return derX; + }; + return { value, gradFunc }; + }); + return customOp($x); + } + const logSigmoid = /* @__PURE__ */ op({ logSigmoid_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Subtracts two `tf.Tensor`s element-wise, A - B. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([10, 20, 30, 40]); + * const b = tf.tensor1d([1, 2, 3, 4]); + * + * a.sub(b).print(); // or tf.sub(a, b) + * ``` + * + * ```js + * // Broadcast subtract a with b. + * const a = tf.tensor1d([10, 20, 30, 40]); + * const b = tf.scalar(5); + * + * a.sub(b).print(); // or tf.sub(a, b) + * ``` + * @param a The first `tf.Tensor` to subtract from. + * @param b The second `tf.Tensor` to be subtracted. Must have the same dtype as + * `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function sub_(a, b) { + let $a = convertToTensor(a, 'a', 'sub'); + let $b = convertToTensor(b, 'b', 'sub'); + [$a, $b] = makeTypesMatch($a, $b); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Sub, inputs); + } + const sub$2 = /* @__PURE__ */ op({ sub_ }); + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the log softmax. + * + * ```js + * const a = tf.tensor1d([1, 2, 3]); + * + * a.logSoftmax().print(); // or tf.logSoftmax(a) + * ``` + * + * ```js + * const a = tf.tensor2d([2, 4, 6, 1, 2, 3], [2, 3]); + * + * a.logSoftmax().print(); // or tf.logSoftmax(a) + * ``` + * + * @param logits The logits array. + * @param axis The dimension softmax would be performed on. Defaults to `-1` + * which indicates the last dimension. + * + * @doc {heading: 'Operations', subheading: 'Normalization'} + */ + function logSoftmax_(logits, axis = -1) { + const $logits = convertToTensor(logits, 'logits', 'logSoftmax'); + if (axis === -1) { + axis = $logits.rank - 1; + } + if (axis !== $logits.rank - 1) { + throw Error('Log Softmax along a non-last dimension is not yet supported. ' + + `Logits was rank ${$logits.rank} and axis was ${axis}`); + } + // const forward: ForwardFunc = (backend, save) => { + // const keepDims = true; + // const xMax = max(logits, axis, true); + // const shifted = sub(logits, xMax); + // const value = + // sub(cast(shifted, 'float32'), log(sum(exp(shifted), axis, + // keepDims))); + // save([value]); + // return value; + // }; + // Use a custom gradient for numerical stability. + const customOp = customGrad((logits, save) => { + const keepDims = true; + const xMax = max$3(logits, axis, true); + const shifted = sub$2(logits, xMax); + const value = sub$2(cast$3(shifted, 'float32'), log$2(sum$3(exp$2(shifted), axis, keepDims))); + save([value]); + const gradFunc = (dy, saved) => { + const [value] = saved; + const keepDims = true; + const softmax = exp$2(value); + return sub$2(dy, mul(sum$3(dy, axis, keepDims), softmax)); + }; + return { value, gradFunc }; + }); + return customOp($logits); + // TODO Use Engine.runKernel when CPU/WebGL/WASM backends implement this. + // const inputs: LogSoftmaxInputs = {logits: $logits}; + // const attrs: LogSoftmaxAttrs = {axis}; + // return ENGINE.runKernel( + // LogSoftmax, inputs as unknown as NamedTensorMap, + // attrs as unknown as NamedAttrMap); + } + const logSoftmax = /* @__PURE__ */ op({ logSoftmax_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the log(sum(exp(elements across the reduction dimensions))). + * + * Reduces the input along the dimensions given in `axis`. Unless `keepDims` + * is true, the rank of the array is reduced by 1 for each entry in `axis`. + * If `keepDims` is true, the reduced dimensions are retained with length 1. + * If `axis` has no entries, all dimensions are reduced, and an array with a + * single element is returned. + * + * ```js + * const x = tf.tensor1d([1, 2, 3]); + * + * x.logSumExp().print(); // or tf.logSumExp(x) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * const axis = 1; + * x.logSumExp(axis).print(); // or tf.logSumExp(a, axis) + * ``` + * @param x The input tensor. + * @param axis The dimension(s) to reduce. If null (the default), + * reduces all dimensions. + * @param keepDims If true, retains reduced dimensions with length + * of 1. Defaults to false. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function logSumExp_(x, axis = null, keepDims = false) { + const $x = convertToTensor(x, 'x', 'logSumExp'); + const axes = parseAxisParam(axis, $x.shape); + const xMax = max$3($x, axes, true /* keepDims */); + const a = sub$2($x, xMax); + const b = exp$2(a); + const c = sum$3(b, axes); + const d = log$2(c); + const res = add$3(reshape$3(xMax, d.shape), d); + if (keepDims) { + const newShape = expandShapeToKeepDim(res.shape, axes); + return reshape$3(res, newShape); + } + return res; + } + const logSumExp = /* @__PURE__ */ op({ logSumExp_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of `a AND b` element-wise. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([false, false, true, true], 'bool'); + * const b = tf.tensor1d([false, true, false, true], 'bool'); + * + * a.logicalAnd(b).print(); + * ``` + * + * @param a The first input tensor. Must be of dtype bool. + * @param b The second input tensor. Must be of dtype bool. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function logicalAnd_(a, b) { + const $a = convertToTensor(a, 'a', 'logicalAnd', 'bool'); + const $b = convertToTensor(b, 'b', 'logicalAnd', 'bool'); + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(LogicalAnd, inputs); + } + const logicalAnd$2 = /* @__PURE__ */ op({ logicalAnd_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of `NOT x` element-wise. + * + * ```js + * const a = tf.tensor1d([false, true], 'bool'); + * + * a.logicalNot().print(); + * ``` + * + * @param x The input tensor. Must be of dtype 'bool'. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function logicalNot_(x) { + const $x = convertToTensor(x, 'x', 'logicalNot', 'bool'); + const inputs = { x: $x }; + return ENGINE.runKernel(LogicalNot, inputs); + } + const logicalNot$2 = /* @__PURE__ */ op({ logicalNot_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of `a OR b` element-wise. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([false, false, true, true], 'bool'); + * const b = tf.tensor1d([false, true, false, true], 'bool'); + * + * a.logicalOr(b).print(); + * ``` + * @param a The first input tensor. Must be of dtype bool. + * @param b The second input tensor. Must be of dtype bool. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function logicalOr_(a, b) { + const $a = convertToTensor(a, 'a', 'logicalOr', 'bool'); + const $b = convertToTensor(b, 'b', 'logicalOr', 'bool'); + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(LogicalOr, inputs); + } + const logicalOr$2 = /* @__PURE__ */ op({ logicalOr_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of `a XOR b` element-wise. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([false, false, true, true], 'bool'); + * const b = tf.tensor1d([false, true, false, true], 'bool'); + * + * a.logicalXor(b).print(); + * ``` + * + * @param a The first input tensor. Must be of dtype bool. + * @param b The second input tensor. Must be of dtype bool. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function logicalXor_(a, b) { + const $a = convertToTensor(a, 'a', 'logicalXor', 'bool'); + const $b = convertToTensor(b, 'b', 'logicalXor', 'bool'); + assertAndGetBroadcastShape($a.shape, $b.shape); + // x ^ y = (x | y) & ~(x & y) + return logicalAnd$2(logicalOr$2(a, b), logicalNot$2(logicalAnd$2(a, b))); + } + const logicalXor = /* @__PURE__ */ op({ logicalXor_ }); + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const INT32_MAX$1 = 2147483648; + /** + * Searches for where a value would go in a sorted sequence. + * + * This is not a method for checking containment (like javascript in). + * + * The typical use case for this operation is "binning", "bucketing", or + * "discretizing". The values are assigned to bucket-indices based on the edges + * listed in 'sortedSequence'. This operation returns the bucket-index for each + * value. + * + * The side argument controls which index is returned if a value lands exactly + * on an edge. + * + * The axis is not settable for this operation. It always operates on the + * innermost dimension (axis=-1). The operation will accept any number of outer + * dimensions. + * + * Note: This operation assumes that 'sortedSequence' is sorted along the + * innermost axis, maybe using 'sort(..., axis=-1)'. If the sequence is not + * sorted no error is raised and the content of the returned tensor is not well + * defined. + * + * ```js + * const edges = tf.tensor1d([-1, 3.3, 9.1, 10.0]); + * let values = tf.tensor1d([0.0, 4.1, 12.0]); + * const result1 = tf.searchSorted(edges, values, 'left'); + * result1.print(); // [1, 2, 4] + * + * const seq = tf.tensor1d([0, 3, 9, 10, 10]); + * values = tf.tensor1d([0, 4, 10]); + * const result2 = tf.searchSorted(seq, values, 'left'); + * result2.print(); // [0, 2, 3] + * const result3 = tf.searchSorted(seq, values, 'right'); + * result3.print(); // [1, 2, 5] + * + * const sortedSequence = tf.tensor2d([[0., 3., 8., 9., 10.], + * [1., 2., 3., 4., 5.]]); + * values = tf.tensor2d([[9.8, 2.1, 4.3], + * [0.1, 6.6, 4.5, ]]); + * const result4 = tf.searchSorted(sortedSequence, values, 'left'); + * result4.print(); // [[4, 1, 2], [0, 5, 4]] + * ``` + * @param sortedSequence: N-D. Sorted sequence. + * @param values: N-D. Search values. + * @param side: 'left'|'right'. Defaults to 'left'. 'left' corresponds to lower + * bound and 'right' to upper bound. + * @return An N-D int32 tensor the size of values containing the result of + * applying either lower bound or upper bound (depending on side) to each + * value. The result is not a global index to the entire Tensor, but the + * index in the last dimension. + * @doc {heading: 'Operations', subheading: 'Evaluation'} + */ + function searchSorted_(sortedSequence, values, side = 'left') { + const $sortedSequence = convertToTensor(sortedSequence, 'sortedSequence', 'searchSorted'); + const $values = convertToTensor(values, 'values', 'searchSorted'); + const sequenceSize = $sortedSequence.shape[$sortedSequence.shape.length - 1]; + const valuesSize = $values.shape[$values.shape.length - 1]; + const $sortedSequence2D = reshape$3($sortedSequence, [-1, sequenceSize]); + const $values2D = reshape$3($values, [-1, valuesSize]); + if ($sortedSequence2D.rank < 2) { + throw new Error(`Sorted input argument must be at least 2-dimensional`); + } + if ($sortedSequence2D.shape[0] !== $values2D.shape[0]) { + throw new Error(`Leading dimension of 'sortedSequence' and 'values' must match.`); + } + if (sizeFromShape($values2D.shape) >= INT32_MAX$1) { + throw new Error(`values tensor size must less than ${INT32_MAX$1}`); + } + if ($sortedSequence2D.shape[1] >= INT32_MAX$1) { + throw new Error(`trailing dim_size must less than ${INT32_MAX$1} for int32 output type, was ${$sortedSequence2D.shape[1]}`); + } + const inputs = { + sortedSequence: $sortedSequence2D, + values: $values2D, + }; + const attrs = { side }; + return ENGINE.runKernel(SearchSorted, inputs, attrs); + } + const searchSorted$2 = /* @__PURE__ */ op({ searchSorted_ }); + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Searches for where a value would go in a sorted sequence. + * + * This is not a method for checking containment (like javascript in). + * + * The typical use case for this operation is "binning", "bucketing", or + * "discretizing". The values are assigned to bucket-indices based on the edges + * listed in 'sortedSequence'. This operation returns the bucket-index for each + * value. + * + * The index returned corresponds to the first edge greater than or equal to the + * value. + * + * The axis is not settable for this operation. It always operates on the + * innermost dimension (axis=-1). The operation will accept any number of outer + * dimensions. + * + * Note: This operation assumes that 'lowerBound' is sorted along the + * innermost axis, maybe using 'sort(..., axis=-1)'. If the sequence is not + * sorted no error is raised and the content of the returned tensor is not well + * defined. + * + * ```js + * const edges = tf.tensor1d([-1, 3.3, 9.1, 10.0]); + * let values = tf.tensor1d([0.0, 4.1, 12.0]); + * const result1 = tf.lowerBound(edges, values); + * result1.print(); // [1, 2, 4] + * + * const seq = tf.tensor1d([0, 3, 9, 10, 10]); + * values = tf.tensor1d([0, 4, 10]); + * const result2 = tf.lowerBound(seq, values); + * result2.print(); // [0, 2, 3] + * + * const sortedSequence = tf.tensor2d([[0., 3., 8., 9., 10.], + * [1., 2., 3., 4., 5.]]); + * values = tf.tensor2d([[9.8, 2.1, 4.3], + * [0.1, 6.6, 4.5, ]]); + * const result3 = tf.lowerBound(sortedSequence, values); + * result3.print(); // [[4, 1, 2], [0, 5, 4]] + * ``` + * @param sortedSequence: N-D. Sorted sequence. + * @param values: N-D. Search values. + * @return An N-D int32 tensor the size of values containing the result of + * applying lower bound to each value. The result is not a global index to + * the entire Tensor, but the index in the last dimension. + * @doc {heading: 'Operations', subheading: 'Evaluation'} + */ + function lowerBound$1(sortedSequence, values) { + return searchSorted$2(sortedSequence, values, 'left'); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the 2D max pooling of an image. + * + * @param x The input tensor, of rank 4 or rank 3 of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is assumed. + * @param filterSize The filter size: `[filterHeight, filterWidth]`. If + * `filterSize` is a single number, then `filterHeight == filterWidth`. + * @param strides The strides of the pooling: `[strideHeight, strideWidth]`. If + * `strides` is a single number, then `strideHeight == strideWidth`. + * @param dilations The dilation rates: `[dilationHeight, dilationWidth]` + * in which we sample input values across the height and width dimensions + * in dilated pooling. Defaults to `[1, 1]`. If `dilations` is a single + * number, then `dilationHeight == dilationWidth`. If it is greater than + * 1, then all values of `strides` must be 1. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + */ + function maxPool_(x, filterSize, strides, pad, dimRoundingMode) { + const $x = convertToTensor(x, 'x', 'maxPool'); + const dilations = 1; + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + reshapedTo4D = true; + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + } + assert$1(x4D.rank === 4, () => `Error in maxPool: input must be rank 4 but got rank ${x4D.rank}.`); + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in maxPool: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + checkPadOnDimRoundingMode('maxPool', pad, dimRoundingMode); + const inputs = { x: x4D }; + const attrs = { filterSize, strides, pad, dimRoundingMode }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(MaxPool, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const maxPool$2 = /* @__PURE__ */ op({ maxPool_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the 3D max pooling. + * + * ```js + * const x = tf.tensor5d([1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 2, 2, 1]); + * const result = tf.maxPool3d(x, 2, 1, 'valid'); + * result.print(); + * ``` + * + * @param x The input tensor, of rank 5 or rank 4 of shape + * `[batch, depth, height, width, inChannels]`. + * @param filterSize The filter size: + * `[filterDepth, filterHeight, filterWidth]`. + * If `filterSize` is a single number, + * then `filterDepth == filterHeight == filterWidth`. + * @param strides The strides of the pooling: + * `[strideDepth, strideHeight, strideWidth]`. + * If `strides` is a single number, + * then `strideDepth == strideHeight == strideWidth`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1*1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * @param dataFormat An optional string from: "NDHWC", "NCDHW". Defaults to + * "NDHWC". Specify the data format of the input and output data. With the + * default format "NDHWC", the data is stored in the order of: [batch, + * depth, height, width, channels]. Only "NDHWC" is currently supported. + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function maxPool3d_(x, filterSize = [1, 1, 1], strides, pad, dimRoundingMode, dataFormat = 'NDHWC') { + const $x = convertToTensor(x, 'x', 'maxPool3d'); + let x5D = $x; + let reshapedTo5D = false; + if ($x.rank === 4) { + reshapedTo5D = true; + x5D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2], $x.shape[3]]); + } + assert$1(x5D.rank === 5, () => `Error in maxPool3d: x must be rank 5 but got rank ${x5D.rank}.`); + assert$1(dataFormat === 'NDHWC', () => `Error in maxPool3d: Only NDHWC is currently supported, ` + + `but got dataFormat of ${dataFormat}`); + checkPadOnDimRoundingMode('maxPool3d', pad, dimRoundingMode); + const inputs = { x: x5D }; + const attrs = { filterSize, strides, pad, dimRoundingMode, dataFormat }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(MaxPool3D, inputs, attrs); + if (reshapedTo5D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3], res.shape[4]]); + } + return res; + } + const maxPool3d$1 = /* @__PURE__ */ op({ maxPool3d_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the 2D max pooling of an image with Argmax index. + * The indices in argmax are flattened, so that a maximum value at position `[b, + * y, x, c]` becomes flattened index: `(y * width + x) * channels + c` if + * include_batch_in_index is False; `((b * height + y) * width + x) * channels + * +c` if include_batch_in_index is True. + * + * The indices returned are always in `[0, height) x [0, width)` before + * flattening. + * + * @param x The input tensor, of rank 4 or rank 3 of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is assumed. + * @param filterSize The filter size: `[filterHeight, filterWidth]`. If + * `filterSize` is a single number, then `filterHeight == filterWidth`. + * @param strides The strides of the pooling: `[strideHeight, strideWidth]`. If + * `strides` is a single number, then `strideHeight == strideWidth`. + * @param dataFormat An optional string from: "NDHWC", "NCDHW". Defaults to + * "NDHWC". Specify the data format of the input and output data. With the + * default format "NDHWC", the data is stored in the order of: [batch, + * depth, height, width, channels]. Only "NDHWC" is currently supported. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param includeBatchIndex Defaults to False. Whether to include batch + * dimension in flattened index of argmax. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function maxPoolWithArgmax_(x, filterSize, strides, pad, includeBatchInIndex = false) { + const $x = convertToTensor(x, 'x', 'maxPoolWithArgmax'); + const inputs = { x: $x }; + const attrs = { filterSize, strides, pad, includeBatchInIndex }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const result = ENGINE.runKernel(MaxPoolWithArgmax, inputs, attrs); + return { result: result[0], indexes: result[1] }; + } + const maxPoolWithArgmax = /* @__PURE__ */ op({ maxPoolWithArgmax_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the max of a and b (`a > b ? a : b`) element-wise. + * Supports broadcasting. + * + * We also expose `tf.maximumStrict` which has the same signature as this op and + * asserts that `a` and `b` are the same shape (does not broadcast). + * + * ```js + * const a = tf.tensor1d([1, 4, 3, 16]); + * const b = tf.tensor1d([1, 2, 9, 4]); + * + * a.maximum(b).print(); // or tf.maximum(a, b) + * ``` + * + * ```js + * // Broadcast maximum a with b. + * const a = tf.tensor1d([2, 4, 6, 8]); + * const b = tf.scalar(5); + * + * a.maximum(b).print(); // or tf.maximum(a, b) + * ``` + * + * @param a The first tensor. + * @param b The second tensor. Must have the same type as `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function maximum_(a, b) { + let $a = convertToTensor(a, 'a', 'maximum'); + let $b = convertToTensor(b, 'b', 'maximum'); + [$a, $b] = makeTypesMatch($a, $b); + if ($a.dtype === 'bool') { + $a = cast$3($a, 'int32'); + $b = cast$3($b, 'int32'); + } + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Maximum$1, inputs); + } + const maximum$4 = /* @__PURE__ */ op({ maximum_ }); + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the mean of elements across dimensions of a `tf.Tensor`. + * + * Reduces `x` along the dimensions given in `axis`. Unless `keepDims` is + * true, the rank of the `tf.Tensor` is reduced by 1 for each entry in `axis`. + * If `keepDims` is true, the reduced dimensions are retained with length 1. + * If `axis` has no entries, all dimensions are reduced, and a `tf.Tensor` with + * a single element is returned. + * + * ```js + * const x = tf.tensor1d([1, 2, 3]); + * + * x.mean().print(); // or tf.mean(a) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * const axis = 1; + * x.mean(axis).print(); // or tf.mean(x, axis) + * ``` + * + * @param x The input tensor. + * @param axis The dimension(s) to reduce. By default it reduces + * all dimensions. + * @param keepDims If true, retains reduced dimensions with size 1. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function mean_(x, axis = null, keepDims = false) { + const $x = convertToTensor(x, 'x', 'mean'); + const inputs = { x: $x }; + const attrs = { axis, keepDims }; + return ENGINE.runKernel(Mean, inputs, attrs); + } + const mean$3 = /* @__PURE__ */ op({ mean_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with all elements set to 0. + * + * ```js + * tf.zeros([2, 2]).print(); + * ``` + * + * @param shape An array of integers defining the output tensor shape. + * @param dtype The type of an element in the resulting tensor. Can + * be 'float32', 'int32' or 'bool'. Defaults to 'float'. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function zeros$2(shape, dtype = 'float32') { + assertNonNegativeIntegerDimensions(shape); + if (dtype === 'complex64') { + const real = zeros$2(shape, 'float32'); + const imag = zeros$2(shape, 'float32'); + return complex$2(real, imag); + } + const values = makeZerosTypedArray(sizeFromShape(shape), dtype); + return ENGINE.makeTensor(values, shape, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with all elements set to 1. + * + * ```js + * tf.ones([2, 2]).print(); + * ``` + * + * @param shape An array of integers defining the output tensor shape. + * @param dtype The type of an element in the resulting tensor. Defaults to + * 'float'. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function ones$1(shape, dtype = 'float32') { + assertNonNegativeIntegerDimensions(shape); + if (dtype === 'complex64') { + const real = ones$1(shape, 'float32'); + const imag = zeros$2(shape, 'float32'); + return complex$2(real, imag); + } + const values = makeOnesTypedArray(sizeFromShape(shape), dtype); + return ENGINE.makeTensor(values, shape, dtype); + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Broadcasts parameters for evaluation on an N-D grid. + * + * Given N one-dimensional coordinate arrays `*args`, returns a list `outputs` + * of N-D coordinate arrays for evaluating expressions on an N-D grid. + * + * Notes: + * `meshgrid` supports cartesian ('xy') and matrix ('ij') indexing conventions. + * When the `indexing` argument is set to 'xy' (the default), the broadcasting + * instructions for the first two dimensions are swapped. + * Examples: + * Calling `const [X, Y] = meshgrid(x, y)` with the tensors + * + * ```javascript + * const x = [1, 2, 3]; + * const y = [4, 5, 6]; + * const [X, Y] = tf.meshgrid(x, y); + * // X = [[1, 2, 3], + * // [1, 2, 3], + * // [1, 2, 3]] + * // Y = [[4, 4, 4], + * // [5, 5, 5], + * // [6, 6, 6]] + * ``` + * + * @param x Tensor with rank geq 1. + * @param y Tensor with rank geq 1. + * @param indexing + * + * @doc {heading: 'Operations', subheading: 'Slicing and Joining'} + */ + function meshgrid(x, y, { indexing = 'xy' } = {}) { + if (indexing !== 'xy' && indexing !== 'ij') { + throw new TypeError(`${indexing} is not a valid third argument to meshgrid`); + } + if (x === undefined) { + return []; + } + let $x = convertToTensor(x, 'x', 'meshgrid', x instanceof Tensor ? x.dtype : 'float32'); + if (y === undefined) { + return [$x]; + } + let $y = convertToTensor(y, 'y', 'meshgrid', y instanceof Tensor ? y.dtype : 'float32'); + const w = sizeFromShape($x.shape); + const h = sizeFromShape($y.shape); + if (indexing === 'xy') { + $x = reshape$3($x, [1, -1]); + $y = reshape$3($y, [-1, 1]); + return [ + matMul$1(ones$1([h, 1], $x.dtype), $x), + matMul$1($y, ones$1([1, w], $y.dtype)), + ]; + } + $x = reshape$3($x, [-1, 1]); + $y = reshape$3($y, [1, -1]); + return [ + matMul$1($x, ones$1([1, h], $x.dtype)), + matMul$1(ones$1([w, 1], $y.dtype), $y), + ]; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the min of a and b (`a < b ? a : b`) element-wise. + * Supports broadcasting. + * + * We also expose `minimumStrict` which has the same signature as this op and + * asserts that `a` and `b` are the same shape (does not broadcast). + * + * ```js + * const a = tf.tensor1d([1, 4, 3, 16]); + * const b = tf.tensor1d([1, 2, 9, 4]); + * + * a.minimum(b).print(); // or tf.minimum(a, b) + * ``` + * + * ```js + * // Broadcast minimum a with b. + * const a = tf.tensor1d([2, 4, 6, 8]); + * const b = tf.scalar(5); + * + * a.minimum(b).print(); // or tf.minimum(a, b) + * ``` + * + * @param a The first tensor. + * @param b The second tensor. Must have the same type as `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function minimum_(a, b) { + let $a = convertToTensor(a, 'a', 'minimum'); + let $b = convertToTensor(b, 'b', 'minimum'); + [$a, $b] = makeTypesMatch($a, $b); + if ($a.dtype === 'bool') { + $a = cast$3($a, 'int32'); + $b = cast$3($b, 'int32'); + } + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Minimum$1, inputs); + } + const minimum$4 = /* @__PURE__ */ op({ minimum_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Pads a `tf.Tensor` using mirror padding. + * + * This operation implements the `REFLECT` and `SYMMETRIC` modes of pad. + * + * ```js + * const x = tf.range(0, 9).reshape([1, 1, 3, 3]); + * x.mirrorPad([[0, 0], [0, 0], [2, 2], [2, 2]], 'reflect').print(); + * ``` + * @param x The tensor to pad. + * @param paddings An array of length `R` (the rank of the tensor), where + * each element is a length-2 tuple of ints `[padBefore, padAfter]`, + * specifying how much to pad along each dimension of the tensor. + * In "reflect" mode, the padded regions do not include the borders, + * while in "symmetric" mode the padded regions do include the borders. + * For example, if the input is `[1, 2, 3]` and paddings is `[0, 2]`, + * then the output is `[1, 2, 3, 2, 1]` in "reflect" mode, and + * `[1, 2, 3, 3, 2]` in "symmetric" mode. + * If `mode` is "reflect" then both `paddings[D, 0]` and `paddings[D, 1]` + * must be no greater than `x.shape[D] - 1`. If mode is "symmetric" + * then both `paddings[D, 0]` and `paddings[D, 1]` must be no greater than + * `x.shape[D]` + * @param mode String to specify padding mode. Can be `'reflect' | 'symmetric'` + */ + /** @doc {heading: 'Tensors', subheading: 'Transformations'} */ + function mirrorPad_(x, paddings, mode) { + assert$1(mode === 'reflect' || mode === 'symmetric', () => `Invalid mode. Mode must be either reflect or symmetric. ` + + `Got ${mode}.`); + const $x = convertToTensor(x, 'x', 'mirrorPad'); + if ($x.rank === 0) { + throw new Error('mirrorPad(scalar) is not defined. ' + + 'Pass non-scalar to mirrorPad'); + } + assert$1(paddings.length === $x.rank, () => `Padding doesn't match input. Must be ${$x.rank}. ` + + `Got ${paddings.length}.`); + const shapeOffset = mode === 'reflect' ? 1 : 0; + for (let i = 0; i < $x.rank; i++) { + assert$1(paddings[i].length === 2, () => `Invalid number of paddings. Must be length of 2 each.`); + assert$1(paddings[i][0] >= 0 && paddings[i][0] <= $x.shape[i] - shapeOffset && + paddings[i][1] >= 0 && paddings[i][1] <= $x.shape[i] - shapeOffset, () => `Padding in dimension ${i} cannot be greater than or equal ` + + `to ${$x.shape[i] - shapeOffset} or less than 0 for input of ` + + `shape ${$x.shape}`); + } + const attrs = { paddings, mode }; + const inputs = { x: $x }; + return ENGINE.runKernel(MirrorPad, inputs, attrs); + } + const mirrorPad$1 = /* @__PURE__ */ op({ mirrorPad_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the mod of a and b element-wise. + * `floor(x / y) * y + mod(x, y) = x` + * Supports broadcasting. + * + * We also expose `tf.modStrict` which has the same signature as this op and + * asserts that `a` and `b` are the same shape (does not broadcast). + * + * ```js + * const a = tf.tensor1d([1, 4, 3, 16]); + * const b = tf.tensor1d([1, 2, 9, 4]); + * + * a.mod(b).print(); // or tf.mod(a, b) + * ``` + * + * ```js + * // Broadcast a mod b. + * const a = tf.tensor1d([2, 4, 6, 8]); + * const b = tf.scalar(5); + * + * a.mod(b).print(); // or tf.mod(a, b) + * ``` + * + * @param a The first tensor. + * @param b The second tensor. Must have the same type as `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function mod_(a, b) { + let $a = convertToTensor(a, 'a', 'mod'); + let $b = convertToTensor(b, 'b', 'mod'); + [$a, $b] = makeTypesMatch($a, $b); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(Mod, inputs); + } + const mod$2 = /* @__PURE__ */ op({ mod_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Calculates the mean and variance of `x`. The mean and variance are + * calculated by aggregating the contents of `x` across `axes`. If `x` is + * 1-D and `axes = [0]` this is just the mean and variance of a vector. + * + * @param x The input tensor. + * @param axis The dimension(s) along with to compute mean and + * variance. By default it reduces all dimensions. + * @param keepDims If true, the moments have the same dimensionality as the + * input. + * @return An object with two keys: `mean` and `variance`. + * + * @doc {heading: 'Operations', subheading: 'Normalization'} + */ + function moments_(x, axis = null, keepDims = false) { + x = convertToTensor(x, 'x', 'moments'); + const axes = parseAxisParam(axis, x.shape); + const xMean = mean$3(x, axes, keepDims); + let keepDimsShape = xMean.shape; + if (!keepDims) { + keepDimsShape = expandShapeToKeepDim(xMean.shape, axes); + } + const devSquared = square$2(sub$2(cast$3(x, 'float32'), reshape$3(xMean, keepDimsShape))); + const variance = mean$3(devSquared, axes, keepDims); + return { mean: xMean, variance }; + } + const moments = /* @__PURE__ */ op({ moments_ }); + + /** + * Computes the next states and outputs of a stack of LSTMCells. + * + * Each cell output is used as input to the next cell. + * + * Returns `[cellState, cellOutput]`. + * + * Derived from tf.contrib.rn.MultiRNNCell. + * + * @param lstmCells Array of LSTMCell functions. + * @param data The input to the cell. + * @param c Array of previous cell states. + * @param h Array of previous cell outputs. + * + * @doc {heading: 'Operations', subheading: 'RNN'} + */ + function multiRNNCell_(lstmCells, data, c, h) { + const $data = convertToTensor(data, 'data', 'multiRNNCell'); + const $c = convertToTensorArray(c, 'c', 'multiRNNCell'); + const $h = convertToTensorArray(h, 'h', 'multiRNNCell'); + let input = $data; + const newStates = []; + for (let i = 0; i < lstmCells.length; i++) { + const output = lstmCells[i](input, $c[i], $h[i]); + newStates.push(output[0]); + newStates.push(output[1]); + input = output[1]; + } + const newC = []; + const newH = []; + for (let i = 0; i < newStates.length; i += 2) { + newC.push(newStates[i]); + newH.push(newStates[i + 1]); + } + return [newC, newH]; + } + const multiRNNCell = /* @__PURE__ */ op({ multiRNNCell_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with values drawn from a multinomial distribution. + * + * ```js + * const probs = tf.tensor([.75, .25]); + * tf.multinomial(probs, 3).print(); + * ``` + * + * @param logits 1D array with unnormalized log-probabilities, or + * 2D array of shape `[batchSize, numOutcomes]`. See the `normalized` + * parameter. + * @param numSamples Number of samples to draw for each row slice. + * @param seed The seed number. + * @param normalized Whether the provided `logits` are normalized true + * probabilities (sum to 1). Defaults to false. + * @return 1D array of shape `[numSamples]`, or 2D array of shape + * `[batchSize, numSamples]`, depending on the rank of the input. + * + * @doc {heading: 'Tensors', subheading: 'Random'} + */ + function multinomial_(logits, numSamples, seed, normalized = false) { + const $logits = convertToTensor(logits, 'logits', 'multinomial'); + const numOutcomes = $logits.size; + const origRank = $logits.rank; + if (numOutcomes < 2) { + throw new Error(`Error in multinomial: you need at least 2 outcomes, but got ` + + `${numOutcomes}.`); + } + if (origRank > 2) { + throw new Error(`Rank of probabilities must be 1 or 2, but is ${origRank}`); + } + // TODO(lina128): Investigate correct seed behavior. The code seems not allow + // setting see to 0. + seed = seed || Math.random(); + // The kernel only accepts (and returns) rank 2 tensors. + const logits2D = origRank === 1 ? reshape$3($logits, [1, -1]) : $logits; + const inputs = { logits: logits2D }; + const attrs = { numSamples, seed, normalized }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(Multinomial, inputs, attrs); + // tslint:disable-next-line:no-unnecessary-type-assertion + return origRank === 1 ? reshape$3(res, [res.size]) : res; + } + const multinomial$2 = /* @__PURE__ */ op({ multinomial_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the truth value of (a != b) element-wise. Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([1, 2, 3]); + * const b = tf.tensor1d([0, 2, 3]); + * + * a.notEqual(b).print(); + * ``` + * @param a The first input tensor. + * @param b The second input tensor. Must have the same dtype as `a`. + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + function notEqual_(a, b) { + let $a = convertToTensor(a, 'a', 'notEqual', 'string_or_numeric'); + let $b = convertToTensor(b, 'b', 'notEqual', 'string_or_numeric'); + [$a, $b] = makeTypesMatch($a, $b); + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + return ENGINE.runKernel(NotEqual, inputs); + } + const notEqual$2 = /* @__PURE__ */ op({ notEqual_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a one-hot `tf.Tensor`. The locations represented by `indices` take + * value `onValue` (defaults to 1), while all other locations take value + * `offValue` (defaults to 0). If `indices` is rank `R`, the output has rank + * `R+1` with the last axis of size `depth`. + * `indices` used to encode prediction class must start from 0. For example, + * if you have 3 classes of data, class 1 should be encoded as 0, class 2 + * should be 1, and class 3 should be 2. + * + * ```js + * tf.oneHot(tf.tensor1d([0, 1], 'int32'), 3).print(); + * ``` + * + * @param indices `tf.Tensor` of indices with dtype `int32`. Indices must + * start from 0. + * @param depth The depth of the one hot dimension. + * @param onValue A number used to fill in the output when the index matches + * the location. + * @param offValue A number used to fill in the output when the index does + * not match the location. + * @param dtype The dtype of the output tensor, default to 'int32'. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function oneHot_(indices, depth, onValue = 1, offValue = 0, dtype = 'int32') { + if (depth < 2) { + throw new Error(`Error in oneHot: depth must be >=2, but it is ${depth}`); + } + const $indices = convertToTensor(indices, 'indices', 'oneHot', 'int32'); + const inputs = { indices: $indices }; + const attrs = { dtype, depth, onValue, offValue }; + return ENGINE.runKernel(OneHot, inputs, attrs); + } + const oneHot$3 = /* @__PURE__ */ op({ oneHot_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with all elements set to 1 with the same shape as the + * given tensor. + * + * ```js + * const x = tf.tensor([1, 2]); + * tf.onesLike(x).print(); + * ``` + * @param x A tensor. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function onesLike_(x) { + const $x = convertToTensor(x, 'x', 'onesLike'); + const inputs = { x: $x }; + return ENGINE.runKernel(OnesLike, inputs); + } + const onesLike$3 = /* @__PURE__ */ op({ onesLike_ }); + + /** + * Computes the outer product of two vectors, `v1` and `v2`. + * + * ```js + * const a = tf.tensor1d([1, 2, 3]); + * const b = tf.tensor1d([3, 4, 5]); + * + * tf.outerProduct(a, b).print(); + * ``` + * @param v1 The first vector in the outer product operation. + * @param v2 The second vector in the outer product operation. + * + * @doc {heading: 'Operations', subheading: 'Matrices'} + */ + function outerProduct_(v1, v2) { + const $v1 = convertToTensor(v1, 'v1', 'outerProduct'); + const $v2 = convertToTensor(v2, 'v2', 'outerProduct'); + assert$1($v1.rank === 1 && $v2.rank === 1, () => `Error in outerProduct: inputs must be rank 1, but got ranks ` + + `${$v1.rank} and ${$v2.rank}.`); + const v12D = reshape$3($v1, [-1, 1]); + const v22D = reshape$3($v2, [1, -1]); + return matMul$1(v12D, v22D); + } + const outerProduct = /* @__PURE__ */ op({ outerProduct_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Pads a `tf.Tensor` with a given value and paddings. + * + * This operation implements `CONSTANT` mode. For `REFLECT` and `SYMMETRIC`, + * refer to `tf.mirrorPad`. + * + * Also available are stricter rank-specific methods with the same signature + * as this method that assert that `paddings` is of given length. + * - `tf.pad1d` + * - `tf.pad2d` + * - `tf.pad3d` + * - `tf.pad4d` + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * x.pad([[1, 2]]).print(); + * ``` + * @param x The tensor to pad. + * @param paddings An array of length `R` (the rank of the tensor), where + * each element is a length-2 tuple of ints `[padBefore, padAfter]`, + * specifying how much to pad along each dimension of the tensor. + * @param constantValue The pad value to use. Defaults to 0. + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function pad_(x, paddings, constantValue = 0) { + const $x = convertToTensor(x, 'x', 'pad'); + if ($x.rank === 0) { + throw new Error('pad(scalar) is not defined. Pass non-scalar to pad'); + } + const attrs = { paddings, constantValue }; + const inputs = { x: $x }; + return ENGINE.runKernel(PadV2, inputs, attrs); + } + const pad = /* @__PURE__ */ op({ pad_ }); + + /** + * Pads a `tf.Tensor1D` with a given value and paddings. See `pad` for details. + */ + function pad1d_(x, paddings, constantValue = 0) { + assert$1(paddings.length === 2, () => 'Invalid number of paddings. Must be length of 2.'); + return pad(x, [paddings], constantValue); + } + const pad1d = /* @__PURE__ */ op({ pad1d_ }); + + /** + * Pads a `tf.Tensor2D` with a given value and paddings. See `pad` for details. + */ + function pad2d_(x, paddings, constantValue = 0) { + assert$1(paddings.length === 2 && paddings[0].length === 2 && + paddings[1].length === 2, () => 'Invalid number of paddings. Must be length of 2 each.'); + return pad(x, paddings, constantValue); + } + const pad2d = /* @__PURE__ */ op({ pad2d_ }); + + /** + * Pads a `tf.Tensor3D` with a given value and paddings. See `pad` for details. + */ + function pad3d_(x, paddings, constantValue = 0) { + assert$1(paddings.length === 3 && paddings[0].length === 2 && + paddings[1].length === 2 && paddings[2].length === 2, () => 'Invalid number of paddings. Must be length of 2 each.'); + return pad(x, paddings, constantValue); + } + const pad3d = /* @__PURE__ */ op({ pad3d_ }); + + /** + * Pads a `tf.Tensor4D` with a given value and paddings. See `pad` for details. + */ + function pad4d_(x, paddings, constantValue = 0) { + assert$1(paddings.length === 4 && paddings[0].length === 2 && + paddings[1].length === 2 && paddings[2].length === 2 && + paddings[3].length === 2, () => 'Invalid number of paddings. Must be length of 2 each.'); + return pad(x, paddings, constantValue); + } + const pad4d = /* @__PURE__ */ op({ pad4d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * This operation divides "spatial" dimensions `[1, ..., M]` of the input into + * a grid of blocks of shape `blockShape`, and interleaves these blocks with + * the "batch" dimension (0) such that in the output, the spatial + * dimensions `[1, ..., M]` correspond to the position within the grid, + * and the batch dimension combines both the position within a spatial block + * and the original batch position. Prior to division into blocks, + * the spatial dimensions of the input are optionally zero padded + * according to `paddings`. See below for a precise description. + * + * ```js + * const x = tf.tensor4d([1, 2, 3, 4], [1, 2, 2, 1]); + * const blockShape = [2, 2]; + * const paddings = [[0, 0], [0, 0]]; + * + * x.spaceToBatchND(blockShape, paddings).print(); + * ``` + * + * @param x A `tf.Tensor`. N-D with `x.shape` = `[batch] + spatialShape + + * remainingShape`, where spatialShape has `M` dimensions. + * @param blockShape A 1-D array. Must have shape `[M]`, all values must + * be >= 1. + * @param paddings A 2-D array. Must have shape `[M, 2]`, all values must be >= + * 0. `paddings[i] = [padStart, padEnd]` specifies the amount to zero-pad + * from input dimension `i + 1`, which corresponds to spatial dimension `i`. It + * is required that + * `(inputShape[i + 1] + padStart + padEnd) % blockShape[i] === 0` + * + * This operation is equivalent to the following steps: + * + * 1. Zero-pad the start and end of dimensions `[1, ..., M]` of the input + * according to `paddings` to produce `padded` of shape paddedShape. + * + * 2. Reshape `padded` to `reshapedPadded` of shape: + * `[batch] + [paddedShape[1] / blockShape[0], blockShape[0], ..., + * paddedShape[M] / blockShape[M-1], blockShape[M-1]] + remainingShape` + * + * 3. Permute dimensions of `reshapedPadded` to produce `permutedReshapedPadded` + * of shape: `blockShape + [batch] + [paddedShape[1] / blockShape[0], ..., + * paddedShape[M] / blockShape[M-1]] + remainingShape` + * + * 4. Reshape `permutedReshapedPadded` to flatten `blockShape` into the + * batch dimension, producing an output tensor of shape: + * `[batch * prod(blockShape)] + [paddedShape[1] / blockShape[0], ..., + * paddedShape[M] / blockShape[M-1]] + remainingShape` + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function spaceToBatchND_(x, blockShape, paddings) { + const $x = convertToTensor(x, 'x', 'spaceToBatchND'); + assert$1($x.rank >= 1 + blockShape.length, () => `input rank ${$x.rank} should be > than [blockShape] ${blockShape.length}`); + assert$1(paddings.length === blockShape.length, () => `paddings.shape[0] ${paddings.length} must be equal to [blockShape] ${blockShape.length}`); + assert$1($x.shape.reduce((a, b, i) => { + if (i > 0 && i <= blockShape.length) { + return a && + ((b + paddings[i - 1][0] + paddings[i - 1][1]) % + blockShape[i - 1] === + 0); + } + return a; + }, true), () => `input spatial dimensions ${$x.shape.slice(1)} with paddings ${paddings.toString()} must be divisible by blockShapes ${blockShape.toString()}`); + const inputs = { x: $x }; + const attrs = { blockShape, paddings }; + return ENGINE.runKernel(SpaceToBatchND, inputs, attrs); + } + const spaceToBatchND$2 = /* @__PURE__ */ op({ spaceToBatchND_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Performs an N-D pooling operation + * + * @param input The input tensor, of rank 4 or rank 3 of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is assumed. + * @param windowShape The filter size: `[filterHeight, filterWidth]`. If + * `filterSize` is a single number, then `filterHeight == filterWidth`. + * @param poolingType The type of pooling, either 'max' or 'avg'. + * @param pad The type of padding algorithm: + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_guides/python/nn#Convolution]( + * https://www.tensorflow.org/api_guides/python/nn#Convolution) + * @param dilations The dilation rates: `[dilationHeight, dilationWidth]` + * in which we sample input values across the height and width dimensions + * in dilated pooling. Defaults to `[1, 1]`. If `dilationRate` is a single + * number, then `dilationHeight == dilationWidth`. If it is greater than + * 1, then all values of `strides` must be 1. + * @param strides The strides of the pooling: `[strideHeight, strideWidth]`. If + * `strides` is a single number, then `strideHeight == strideWidth`. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function pool_(input, windowShape, poolingType, pad, dilations, strides, dimRoundingMode) { + if (dilations == null) { + dilations = [1, 1]; + } + if (strides == null) { + strides = 1; + } + if (pad === 0) { + pad = 'valid'; + } + const $x = convertToTensor(input, 'x', 'maxPool'); + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + reshapedTo4D = true; + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + } + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in pool: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + const convInfo = computePool2DInfo(x4D.shape, windowShape, strides, dilations, pad); + const dilation = [convInfo.dilationHeight, convInfo.dilationWidth]; + // The following implementation does batchToSpace(pool(spaceToBatch(x))) + // whenever dilation > 1 since the TF kernels do not support dilation > 1. + // tslint:disable-next-line:max-line-length + // https://github.com/tensorflow/tensorflow/blob/50f6bb67dc98c9b74630b6047aae7a4f8a40fd02/tensorflow/python/ops/nn_ops.py#L1037 + let basePadding; + if (pad === 'same') { + basePadding = withSpaceToBatchBasePaddings([convInfo.filterHeight, convInfo.filterWidth], dilation); + } + else { + basePadding = [[0, 0], [0, 0]]; + } + const isDilationOne = dilation[0] === 1 && dilation[1] === 1; + const [adjustedPadding, adjustedCrops] = requiredSpaceToBatchPaddings([convInfo.inHeight, convInfo.inWidth], dilation, basePadding); + const convertedPad = isDilationOne ? pad : 'valid'; + const convertedX = isDilationOne ? x4D : spaceToBatchND$2(x4D, dilation, adjustedPadding); + const forwardOp = poolingType === 'avg' ? + () => avgPool$2(convertedX, windowShape, strides, convertedPad, dimRoundingMode) : + () => maxPool$2(convertedX, windowShape, strides, convertedPad, dimRoundingMode); + const y = forwardOp(); + const res = isDilationOne ? y : batchToSpaceND$2(y, dilation, adjustedCrops); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + // Helper function to compute crops and paddings for pool with dilation > 1. + // tslint:disable-next-line:max-line-length + // https://github.com/tensorflow/tensorflow/blob/50f6bb67dc98c9b74630b6047aae7a4f8a40fd02/tensorflow/python/ops/array_ops.py#L2184 + function requiredSpaceToBatchPaddings(inputShape, blockShape, basePadding) { + const padStart = basePadding.map(b => b[0]); + const origPadEnd = basePadding.map(b => b[1]); + const fullInputShape = inputShape.concat(padStart, origPadEnd); + const padEndExtra = blockShape.map((b, i) => (b - fullInputShape[i] % b) % b); + const padEnd = origPadEnd.map((s, i) => s + padEndExtra[i]); + const paddings = blockShape.map((_, i) => [padStart[i], padEnd[i]]); + const crops = blockShape.map((_, i) => [0, padEndExtra[i]]); + return [paddings, crops]; + } + // Helper function to compute base paddings for pool with dilation > 1. + // tslint:disable-next-line:max-line-length + // https://github.com/tensorflow/tensorflow/blob/50f6bb67dc98c9b74630b6047aae7a4f8a40fd02/tensorflow/python/ops/nn_ops.py#L524 + function withSpaceToBatchBasePaddings(filterShape, dilation) { + // Spatial dimensions of the filters and the upsampled filters in which we + // introduce (rate - 1) zeros between consecutive filter values. + const dilatedFilterShape = filterShape.map((s, i) => { + return s + (s - 1) * (dilation[i] - 1); + }); + const padExtraShape = dilatedFilterShape.map(s => s - 1); + // When padding is odd, we pad more at end, following the same + // convention as conv2d. + const padExtraStart = padExtraShape.map(s => Math.floor(s / 2)); + const padExtraEnd = padExtraShape.map((s, i) => s - padExtraStart[i]); + return padExtraShape.map((_, i) => { + return [padExtraStart[i], padExtraEnd[i]]; + }); + } + const pool$1 = /* @__PURE__ */ op({ pool_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes leaky rectified linear element-wise with parametric alphas. + * + * `x < 0 ? alpha * x : f(x) = x` + * + * ```js + * const x = tf.tensor1d([-1, 2, -3, 4]); + * const alpha = tf.scalar(0.1); + * + * x.prelu(alpha).print(); // or tf.prelu(x, alpha) + * ``` + * @param x The input tensor. + * @param alpha Scaling factor for negative values. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function prelu_(x, alpha) { + const $x = convertToTensor(x, 'x', 'prelu'); + const $alpha = convertToTensor(alpha, 'alpha', 'prelu'); + const inputs = { x: $x, alpha: $alpha }; + return ENGINE.runKernel(Prelu, inputs); + } + const prelu$3 = /* @__PURE__ */ op({ prelu_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the product of elements across dimensions of a `tf.Tensor`. + * + * Reduces the input along the dimensions given in `axes`. Unless `keepDims` + * is true, the rank of the `tf.Tensor` is reduced by 1 for each entry in + * `axes`. If `keepDims` is true, the reduced dimensions are retained with + * length 1. If `axes` has no entries, all dimensions are reduced, and a + * `tf.Tensor` with a single element is returned. + * + * ```js + * const x = tf.tensor1d([1, 2, 3]); + * + * x.prod().print(); // or tf.prod(x) + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * const axis = 1; + * x.prod(axis).print(); // or tf.prod(x, axis) + * ``` + * + * @param x The input tensor to compute the product over. If the dtype is `bool` + * it will be converted to `int32` and the output dtype will be `int32`. + * @param axis The dimension(s) to reduce. By default it reduces + * all dimensions. + * @param keepDims If true, retains reduced dimensions with size 1. + * + * @doc {heading: 'Operations', subheading: 'Reduction'} + */ + function prod_(x, axis = null, keepDims = false) { + let $x = convertToTensor(x, 'x', 'prod'); + if ($x.dtype === 'bool') { + // bool is not an allowed type for the underlying kernel. + $x = cast$3($x, 'int32'); + } + const inputs = { x: $x }; + const attrs = { axis, keepDims }; + return ENGINE.runKernel(Prod, inputs, attrs); + } + const prod$2 = /* @__PURE__ */ op({ prod_ }); + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function raggedGather_(paramsNestedSplits, paramsDenseValues, indices, outputRaggedRank) { + const $paramsNestedSplits = paramsNestedSplits.map((t, i) => convertToTensor(t, `tensors${i}`, 'raggedGather', 'int32')); + const $paramsDenseValues = convertToTensor(paramsDenseValues, 'paramsDenseValues', 'raggedGather'); + const $indices = convertToTensor(indices, 'indices', 'raggedGather', 'int32'); + const inputs = { + paramsNestedSplits: $paramsNestedSplits, + paramsDenseValues: $paramsDenseValues, + indices: $indices, + }; + const attrs = { outputRaggedRank }; + const result = ENGINE.runKernel(RaggedGather, inputs, attrs); + return { + outputNestedSplits: result.slice(0, result.length - 1), + outputDenseValues: result[result.length - 1], + }; + } + const raggedGather$2 = /* @__PURE__ */ op({ raggedGather_ }); + + /** + * @license + * Copyright 2022 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns a RaggedTensor result composed from rtDenseValues and rtNestedSplits, + * such that result[i] = [starts[i], starts[i] + deltas[i], ..., limits[i]]). + * + * @param starts: A Tensor. Must be one of the following types: + * 'float32', 'int32'. The starts of each range. + * @param limits: A Tensor. Must have the same type as starts. The limits of + * each range. + * @param deltas: A Tensor. Must have the same type as starts. The deltas of + * each range. + * @return A map with the following properties: + * - rtNestedSplits: A Tensor of type 'int32'. + * - rtDenseValues: A Tensor. Has the same type as starts. + */ + function raggedRange_(starts, limits, deltas) { + const $starts = convertToTensor(starts, 'starts', 'raggedRange'); + const $limits = convertToTensor(limits, 'limits', 'raggedRange', $starts.dtype); + const $deltas = convertToTensor(deltas, 'deltas', 'raggedRange', $starts.dtype); + const inputs = { + starts: $starts, + limits: $limits, + deltas: $deltas, + }; + const result = ENGINE.runKernel(RaggedRange, inputs); + return { + rtNestedSplits: result[0], + rtDenseValues: result[1], + }; + } + const raggedRange$2 = /* @__PURE__ */ op({ raggedRange_ }); + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Create a dense tensor from a ragged tensor, possibly altering its shape. + * + * The raggedTensorToTensor op creates a dense tensor from am array of row + * partition tensors, a value vector, and default values. If the shape is + * unspecified, the minimal shape required to contain all the elements in the + * ragged tensor (the natural shape) will be used. If some dimensions are left + * unspecified, then the size of the natural shape is used in that dimension. + * + * The defaultValue will be broadcast to the output shape. After that, the + * values from the ragged tensor overwrite the default values. Note that the + * defaultValue must have less dimensions than the value. + * + * The row partition tensors are in the order of the dimensions. At present, the + * types can be: "ROW_SPLITS": the row_splits tensor from the ragged tensor. + * "VALUE_ROWIDS": the value_rowids tensor from the ragged tensor. + * "FIRST_DIM_SIZE": if value_rowids is used for the first dimension, then it + * is preceded by "FIRST_DIM_SIZE". + * ``` + * @param shape: A Tensor. Must be one of the following types: 'int32'. The + * desired shape of the output tensor. If left unspecified (empty), the + * minimal shape required to contain all the elements in the ragged tensor + * (the natural shape) will be used. If some dimensions are left + * unspecified, then the size of the natural shape is used in that + * dimension. + * + * Note that dense dimensions cannot be modified by the shape argument. + * Trying to change the size of a dense dimension will cause the op to fail. + * Examples: natural shape: [4, 5, 6] shape: -1 output shape: [4, 5, 6] + * + * natural shape: [4, 5, 6] shape: [3, -1, 2] output shape: [3, 5, 2] + * + * natural shape: [4, 5, 6] shape: [3, 7, 2] output shape: [3, 7, 2] + * @param values: A Tensor. A 1D tensor representing the values of the ragged + * tensor. + * @param defaultValue: A Tensor. Must have the same type as values. The + * defaultValue when the shape is larger than the ragged tensor. The + * defaultValue is broadcast until it is the shape of the output tensor, + * and then overwritten by values in the ragged tensor. The default value + * must be compatible with this broadcast operation, and must have fewer + * dimensions than the value tensor. + * @param rowPartitionTensors: A list of at least 1 Tensor objects with the same + * type in: 'int32'. + * @param rowPartitionTypes: A list of strings. The types of the row partition + * tensors. At present, these can be: + * "ROW_SPLITS": the row_splits tensor from the ragged tensor. + * "VALUE_ROWIDS": the value_rowids tensor from the ragged tensor. + * "FIRST_DIM_SIZE": if value_rowids is used for the first dimension, then + * it is preceded by "FIRST_DIM_SIZE". The tensors are in the order of + * the dimensions. + * @return A Tensor. Has the same type as values. + * @doc {heading: 'Operations', subheading: 'Ragged'} + */ + function raggedTensorToTensor_(shape, values, defaultValue, rowPartitionTensors, rowPartitionTypes) { + const $shape = convertToTensor(shape, 'shape', 'raggedTensorToTensor', 'int32'); + const $values = convertToTensor(values, 'values', 'raggedTensorToTensor'); + const $defaultValue = convertToTensor(defaultValue, 'defaultValue', 'raggedTensorToTensor', $values.dtype); + const $rowPartitionTensors = rowPartitionTensors.map((t, i) => convertToTensor(t, `tensors${i}`, 'raggedTensorToTensor', 'int32')); + const inputs = { + shape: $shape, + values: $values, + defaultValue: $defaultValue, + rowPartitionTensors: $rowPartitionTensors + }; + const attrs = { rowPartitionTypes }; + return ENGINE.runKernel(RaggedTensorToTensor, inputs, attrs); + } + const raggedTensorToTensor$2 = /* @__PURE__ */ op({ raggedTensorToTensor_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with values sampled from a random number generator + * function defined by the user. + * + * @param shape An array of integers defining the output tensor shape. + * @param randFunction A random number generator function which is called + * for each element in the output tensor. + * @param dtype The data type of the output tensor. Defaults to 'float32'. + * + * @doc {heading: 'Tensors', subheading: 'Random'} + */ + function rand_(shape, randFunction, dtype) { + assertNonNegativeIntegerDimensions(shape); + const size = sizeFromShape(shape); + let values = null; + if (dtype == null || dtype === 'float32') { + values = new Float32Array(size); + } + else if (dtype === 'int32') { + values = new Int32Array(size); + } + else if (dtype === 'bool') { + values = new Uint8Array(size); + } + else { + throw new Error(`Unknown data type ${dtype}`); + } + for (let i = 0; i < size; i++) { + values[i] = randFunction(); + } + return ENGINE.makeTensor(values, shape, dtype); + } + const rand = /* @__PURE__ */ op({ rand_ }); + + var alea$3 = {exports: {}}; + + var alea$1 = alea$3.exports; + + (function (module) { + // A port of an algorithm by Johannes Baagøe , 2010 + // http://baagoe.com/en/RandomMusings/javascript/ + // https://github.com/nquinlan/better-random-numbers-for-javascript-mirror + // Original work is under MIT license - + + // Copyright (C) 2010 by Johannes Baagøe + // + // 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. + + + + (function(global, module, define) { + + function Alea(seed) { + var me = this, mash = Mash(); + + me.next = function() { + var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32 + me.s0 = me.s1; + me.s1 = me.s2; + return me.s2 = t - (me.c = t | 0); + }; + + // Apply the seeding algorithm from Baagoe. + me.c = 1; + me.s0 = mash(' '); + me.s1 = mash(' '); + me.s2 = mash(' '); + me.s0 -= mash(seed); + if (me.s0 < 0) { me.s0 += 1; } + me.s1 -= mash(seed); + if (me.s1 < 0) { me.s1 += 1; } + me.s2 -= mash(seed); + if (me.s2 < 0) { me.s2 += 1; } + mash = null; + } + + function copy(f, t) { + t.c = f.c; + t.s0 = f.s0; + t.s1 = f.s1; + t.s2 = f.s2; + return t; + } + + function impl(seed, opts) { + var xg = new Alea(seed), + state = opts && opts.state, + prng = xg.next; + prng.int32 = function() { return (xg.next() * 0x100000000) | 0; }; + prng.double = function() { + return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 + }; + prng.quick = prng; + if (state) { + if (typeof(state) == 'object') copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + function Mash() { + var n = 0xefc8249d; + + var mash = function(data) { + data = String(data); + for (var i = 0; i < data.length; i++) { + n += data.charCodeAt(i); + var h = 0.02519603282416938 * n; + n = h >>> 0; + h -= n; + h *= n; + n = h >>> 0; + h -= n; + n += h * 0x100000000; // 2^32 + } + return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 + }; + + return mash; + } + + + if (module && module.exports) { + module.exports = impl; + } else if (define && define.amd) { + define(function() { return impl; }); + } else { + this.alea = impl; + } + + })( + commonjsGlobal, + ('object') == 'object' && module, // present in node.js + (typeof undefined) == 'function' && undefined // present with an AMD loader + ); + } (alea$3)); + + var aleaExports = alea$3.exports; + var alea$2 = /*@__PURE__*/getDefaultExportFromCjs(aleaExports); + + var xor128$3 = {exports: {}}; + + var xor128$1 = xor128$3.exports; + + (function (module) { + // A Javascript implementaion of the "xor128" prng algorithm by + // George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper + + (function(global, module, define) { + + function XorGen(seed) { + var me = this, strseed = ''; + + me.x = 0; + me.y = 0; + me.z = 0; + me.w = 0; + + // Set up generator function. + me.next = function() { + var t = me.x ^ (me.x << 11); + me.x = me.y; + me.y = me.z; + me.z = me.w; + return me.w ^= (me.w >>> 19) ^ t ^ (t >>> 8); + }; + + if (seed === (seed | 0)) { + // Integer seed. + me.x = seed; + } else { + // String seed. + strseed += seed; + } + + // Mix in string seed, then discard an initial batch of 64 values. + for (var k = 0; k < strseed.length + 64; k++) { + me.x ^= strseed.charCodeAt(k) | 0; + me.next(); + } + } + + function copy(f, t) { + t.x = f.x; + t.y = f.y; + t.z = f.z; + t.w = f.w; + return t; + } + + function impl(seed, opts) { + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (typeof(state) == 'object') copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else if (define && define.amd) { + define(function() { return impl; }); + } else { + this.xor128 = impl; + } + + })( + commonjsGlobal, + ('object') == 'object' && module, // present in node.js + (typeof undefined) == 'function' && undefined // present with an AMD loader + ); + } (xor128$3)); + + var xor128Exports = xor128$3.exports; + var xor128$2 = /*@__PURE__*/getDefaultExportFromCjs(xor128Exports); + + var xorwow$3 = {exports: {}}; + + var xorwow$1 = xorwow$3.exports; + + (function (module) { + // A Javascript implementaion of the "xorwow" prng algorithm by + // George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper + + (function(global, module, define) { + + function XorGen(seed) { + var me = this, strseed = ''; + + // Set up generator function. + me.next = function() { + var t = (me.x ^ (me.x >>> 2)); + me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v; + return (me.d = (me.d + 362437 | 0)) + + (me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0; + }; + + me.x = 0; + me.y = 0; + me.z = 0; + me.w = 0; + me.v = 0; + + if (seed === (seed | 0)) { + // Integer seed. + me.x = seed; + } else { + // String seed. + strseed += seed; + } + + // Mix in string seed, then discard an initial batch of 64 values. + for (var k = 0; k < strseed.length + 64; k++) { + me.x ^= strseed.charCodeAt(k) | 0; + if (k == strseed.length) { + me.d = me.x << 10 ^ me.x >>> 4; + } + me.next(); + } + } + + function copy(f, t) { + t.x = f.x; + t.y = f.y; + t.z = f.z; + t.w = f.w; + t.v = f.v; + t.d = f.d; + return t; + } + + function impl(seed, opts) { + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (typeof(state) == 'object') copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else if (define && define.amd) { + define(function() { return impl; }); + } else { + this.xorwow = impl; + } + + })( + commonjsGlobal, + ('object') == 'object' && module, // present in node.js + (typeof undefined) == 'function' && undefined // present with an AMD loader + ); + } (xorwow$3)); + + var xorwowExports = xorwow$3.exports; + var xorwow$2 = /*@__PURE__*/getDefaultExportFromCjs(xorwowExports); + + var xorshift7$3 = {exports: {}}; + + var xorshift7$1 = xorshift7$3.exports; + + (function (module) { + // A Javascript implementaion of the "xorshift7" algorithm by + // François Panneton and Pierre L'ecuyer: + // "On the Xorgshift Random Number Generators" + // http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf + + (function(global, module, define) { + + function XorGen(seed) { + var me = this; + + // Set up generator function. + me.next = function() { + // Update xor generator. + var X = me.x, i = me.i, t, v, w; + t = X[i]; t ^= (t >>> 7); v = t ^ (t << 24); + t = X[(i + 1) & 7]; v ^= t ^ (t >>> 10); + t = X[(i + 3) & 7]; v ^= t ^ (t >>> 3); + t = X[(i + 4) & 7]; v ^= t ^ (t << 7); + t = X[(i + 7) & 7]; t = t ^ (t << 13); v ^= t ^ (t << 9); + X[i] = v; + me.i = (i + 1) & 7; + return v; + }; + + function init(me, seed) { + var j, w, X = []; + + if (seed === (seed | 0)) { + // Seed state array using a 32-bit integer. + w = X[0] = seed; + } else { + // Seed state using a string. + seed = '' + seed; + for (j = 0; j < seed.length; ++j) { + X[j & 7] = (X[j & 7] << 15) ^ + (seed.charCodeAt(j) + X[(j + 1) & 7] << 13); + } + } + // Enforce an array length of 8, not all zeroes. + while (X.length < 8) X.push(0); + for (j = 0; j < 8 && X[j] === 0; ++j); + if (j == 8) w = X[7] = -1; else w = X[j]; + + me.x = X; + me.i = 0; + + // Discard an initial 256 values. + for (j = 256; j > 0; --j) { + me.next(); + } + } + + init(me, seed); + } + + function copy(f, t) { + t.x = f.x.slice(); + t.i = f.i; + return t; + } + + function impl(seed, opts) { + if (seed == null) seed = +(new Date); + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (state.x) copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else if (define && define.amd) { + define(function() { return impl; }); + } else { + this.xorshift7 = impl; + } + + })( + commonjsGlobal, + ('object') == 'object' && module, // present in node.js + (typeof undefined) == 'function' && undefined // present with an AMD loader + ); + } (xorshift7$3)); + + var xorshift7Exports = xorshift7$3.exports; + var xorshift7$2 = /*@__PURE__*/getDefaultExportFromCjs(xorshift7Exports); + + var xor4096$3 = {exports: {}}; + + var xor4096$1 = xor4096$3.exports; + + (function (module) { + // A Javascript implementaion of Richard Brent's Xorgens xor4096 algorithm. + // + // This fast non-cryptographic random number generator is designed for + // use in Monte-Carlo algorithms. It combines a long-period xorshift + // generator with a Weyl generator, and it passes all common batteries + // of stasticial tests for randomness while consuming only a few nanoseconds + // for each prng generated. For background on the generator, see Brent's + // paper: "Some long-period random number generators using shifts and xors." + // http://arxiv.org/pdf/1004.3115v1.pdf + // + // Usage: + // + // var xor4096 = require('xor4096'); + // random = xor4096(1); // Seed with int32 or string. + // assert.equal(random(), 0.1520436450538547); // (0, 1) range, 53 bits. + // assert.equal(random.int32(), 1806534897); // signed int32, 32 bits. + // + // For nonzero numeric keys, this impelementation provides a sequence + // identical to that by Brent's xorgens 3 implementaion in C. This + // implementation also provides for initalizing the generator with + // string seeds, or for saving and restoring the state of the generator. + // + // On Chrome, this prng benchmarks about 2.1 times slower than + // Javascript's built-in Math.random(). + + (function(global, module, define) { + + function XorGen(seed) { + var me = this; + + // Set up generator function. + me.next = function() { + var w = me.w, + X = me.X, i = me.i, t, v; + // Update Weyl generator. + me.w = w = (w + 0x61c88647) | 0; + // Update xor generator. + v = X[(i + 34) & 127]; + t = X[i = ((i + 1) & 127)]; + v ^= v << 13; + t ^= t << 17; + v ^= v >>> 15; + t ^= t >>> 12; + // Update Xor generator array state. + v = X[i] = v ^ t; + me.i = i; + // Result is the combination. + return (v + (w ^ (w >>> 16))) | 0; + }; + + function init(me, seed) { + var t, v, i, j, w, X = [], limit = 128; + if (seed === (seed | 0)) { + // Numeric seeds initialize v, which is used to generates X. + v = seed; + seed = null; + } else { + // String seeds are mixed into v and X one character at a time. + seed = seed + '\0'; + v = 0; + limit = Math.max(limit, seed.length); + } + // Initialize circular array and weyl value. + for (i = 0, j = -32; j < limit; ++j) { + // Put the unicode characters into the array, and shuffle them. + if (seed) v ^= seed.charCodeAt((j + 32) % seed.length); + // After 32 shuffles, take v as the starting w value. + if (j === 0) w = v; + v ^= v << 10; + v ^= v >>> 15; + v ^= v << 4; + v ^= v >>> 13; + if (j >= 0) { + w = (w + 0x61c88647) | 0; // Weyl. + t = (X[j & 127] ^= (v + w)); // Combine xor and weyl to init array. + i = (0 == t) ? i + 1 : 0; // Count zeroes. + } + } + // We have detected all zeroes; make the key nonzero. + if (i >= 128) { + X[(seed && seed.length || 0) & 127] = -1; + } + // Run the generator 512 times to further mix the state before using it. + // Factoring this as a function slows the main generator, so it is just + // unrolled here. The weyl generator is not advanced while warming up. + i = 127; + for (j = 4 * 128; j > 0; --j) { + v = X[(i + 34) & 127]; + t = X[i = ((i + 1) & 127)]; + v ^= v << 13; + t ^= t << 17; + v ^= v >>> 15; + t ^= t >>> 12; + X[i] = v ^ t; + } + // Storing state as object members is faster than using closure variables. + me.w = w; + me.X = X; + me.i = i; + } + + init(me, seed); + } + + function copy(f, t) { + t.i = f.i; + t.w = f.w; + t.X = f.X.slice(); + return t; + }; + + function impl(seed, opts) { + if (seed == null) seed = +(new Date); + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (state.X) copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else if (define && define.amd) { + define(function() { return impl; }); + } else { + this.xor4096 = impl; + } + + })( + commonjsGlobal, // window object or global + ('object') == 'object' && module, // present in node.js + (typeof undefined) == 'function' && undefined // present with an AMD loader + ); + } (xor4096$3)); + + var xor4096Exports = xor4096$3.exports; + var xor4096$2 = /*@__PURE__*/getDefaultExportFromCjs(xor4096Exports); + + var tychei$3 = {exports: {}}; + + var tychei$1 = tychei$3.exports; + + (function (module) { + // A Javascript implementaion of the "Tyche-i" prng algorithm by + // Samuel Neves and Filipe Araujo. + // See https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf + + (function(global, module, define) { + + function XorGen(seed) { + var me = this, strseed = ''; + + // Set up generator function. + me.next = function() { + var b = me.b, c = me.c, d = me.d, a = me.a; + b = (b << 25) ^ (b >>> 7) ^ c; + c = (c - d) | 0; + d = (d << 24) ^ (d >>> 8) ^ a; + a = (a - b) | 0; + me.b = b = (b << 20) ^ (b >>> 12) ^ c; + me.c = c = (c - d) | 0; + me.d = (d << 16) ^ (c >>> 16) ^ a; + return me.a = (a - b) | 0; + }; + + /* The following is non-inverted tyche, which has better internal + * bit diffusion, but which is about 25% slower than tyche-i in JS. + me.next = function() { + var a = me.a, b = me.b, c = me.c, d = me.d; + a = (me.a + me.b | 0) >>> 0; + d = me.d ^ a; d = d << 16 ^ d >>> 16; + c = me.c + d | 0; + b = me.b ^ c; b = b << 12 ^ d >>> 20; + me.a = a = a + b | 0; + d = d ^ a; me.d = d = d << 8 ^ d >>> 24; + me.c = c = c + d | 0; + b = b ^ c; + return me.b = (b << 7 ^ b >>> 25); + } + */ + + me.a = 0; + me.b = 0; + me.c = 2654435769 | 0; + me.d = 1367130551; + + if (seed === Math.floor(seed)) { + // Integer seed. + me.a = (seed / 0x100000000) | 0; + me.b = seed | 0; + } else { + // String seed. + strseed += seed; + } + + // Mix in string seed, then discard an initial batch of 64 values. + for (var k = 0; k < strseed.length + 20; k++) { + me.b ^= strseed.charCodeAt(k) | 0; + me.next(); + } + } + + function copy(f, t) { + t.a = f.a; + t.b = f.b; + t.c = f.c; + t.d = f.d; + return t; + }; + + function impl(seed, opts) { + var xg = new XorGen(seed), + state = opts && opts.state, + prng = function() { return (xg.next() >>> 0) / 0x100000000; }; + prng.double = function() { + do { + var top = xg.next() >>> 11, + bot = (xg.next() >>> 0) / 0x100000000, + result = (top + bot) / (1 << 21); + } while (result === 0); + return result; + }; + prng.int32 = xg.next; + prng.quick = prng; + if (state) { + if (typeof(state) == 'object') copy(state, xg); + prng.state = function() { return copy(xg, {}); }; + } + return prng; + } + + if (module && module.exports) { + module.exports = impl; + } else if (define && define.amd) { + define(function() { return impl; }); + } else { + this.tychei = impl; + } + + })( + commonjsGlobal, + ('object') == 'object' && module, // present in node.js + (typeof undefined) == 'function' && undefined // present with an AMD loader + ); + } (tychei$3)); + + var tycheiExports = tychei$3.exports; + var tychei$2 = /*@__PURE__*/getDefaultExportFromCjs(tycheiExports); + + var seedrandom$3 = {exports: {}}; + + /* + Copyright 2019 David Bau. + + 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. + + */ + var seedrandom$1 = seedrandom$3.exports; + + (function (module) { + (function (global, pool, math) { + // + // The following constants are related to IEEE 754 limits. + // + + var width = 256, // each RC4 output is 0 <= x < 256 + chunks = 6, // at least six RC4 outputs for each double + digits = 52, // there are 52 significant digits in a double + rngname = 'random', // rngname: name for Math.random and Math.seedrandom + startdenom = math.pow(width, chunks), + significance = math.pow(2, digits), + overflow = significance * 2, + mask = width - 1, + nodecrypto; // node.js crypto module, initialized at the bottom. + + // + // seedrandom() + // This is the seedrandom function described above. + // + function seedrandom(seed, options, callback) { + var key = []; + options = (options == true) ? { entropy: true } : (options || {}); + + // Flatten the seed string or build one from local entropy if needed. + var shortseed = mixkey(flatten( + options.entropy ? [seed, tostring(pool)] : + (seed == null) ? autoseed() : seed, 3), key); + + // Use the seed to initialize an ARC4 generator. + var arc4 = new ARC4(key); + + // This function returns a random double in [0, 1) that contains + // randomness in every bit of the mantissa of the IEEE 754 value. + var prng = function() { + var n = arc4.g(chunks), // Start with a numerator n < 2 ^ 48 + d = startdenom, // and denominator d = 2 ^ 48. + x = 0; // and no 'extra last byte'. + while (n < significance) { // Fill up all significant digits by + n = (n + x) * width; // shifting numerator and + d *= width; // denominator and generating a + x = arc4.g(1); // new least-significant-byte. + } + while (n >= overflow) { // To avoid rounding up, before adding + n /= 2; // last byte, shift everything + d /= 2; // right using integer math until + x >>>= 1; // we have exactly the desired bits. + } + return (n + x) / d; // Form the number within [0, 1). + }; + + prng.int32 = function() { return arc4.g(4) | 0; }; + prng.quick = function() { return arc4.g(4) / 0x100000000; }; + prng.double = prng; + + // Mix the randomness into accumulated entropy. + mixkey(tostring(arc4.S), pool); + + // Calling convention: what to return as a function of prng, seed, is_math. + return (options.pass || callback || + function(prng, seed, is_math_call, state) { + if (state) { + // Load the arc4 state from the given state if it has an S array. + if (state.S) { copy(state, arc4); } + // Only provide the .state method if requested via options.state. + prng.state = function() { return copy(arc4, {}); }; + } + + // If called as a method of Math (Math.seedrandom()), mutate + // Math.random because that is how seedrandom.js has worked since v1.0. + if (is_math_call) { math[rngname] = prng; return seed; } + + // Otherwise, it is a newer calling convention, so return the + // prng directly. + else return prng; + })( + prng, + shortseed, + 'global' in options ? options.global : (this == math), + options.state); + } + + // + // ARC4 + // + // An ARC4 implementation. The constructor takes a key in the form of + // an array of at most (width) integers that should be 0 <= x < (width). + // + // The g(count) method returns a pseudorandom integer that concatenates + // the next (count) outputs from ARC4. Its return value is a number x + // that is in the range 0 <= x < (width ^ count). + // + function ARC4(key) { + var t, keylen = key.length, + me = this, i = 0, j = me.i = me.j = 0, s = me.S = []; + + // The empty key [] is treated as [0]. + if (!keylen) { key = [keylen++]; } + + // Set up S using the standard key scheduling algorithm. + while (i < width) { + s[i] = i++; + } + for (i = 0; i < width; i++) { + s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))]; + s[j] = t; + } + + // The "g" method returns the next (count) outputs as one number. + (me.g = function(count) { + // Using instance members instead of closure state nearly doubles speed. + var t, r = 0, + i = me.i, j = me.j, s = me.S; + while (count--) { + t = s[i = mask & (i + 1)]; + r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))]; + } + me.i = i; me.j = j; + return r; + // For robust unpredictability, the function call below automatically + // discards an initial batch of values. This is called RC4-drop[256]. + // See http://google.com/search?q=rsa+fluhrer+response&btnI + })(width); + } + + // + // copy() + // Copies internal state of ARC4 to or from a plain object. + // + function copy(f, t) { + t.i = f.i; + t.j = f.j; + t.S = f.S.slice(); + return t; + }; + + // + // flatten() + // Converts an object tree to nested arrays of strings. + // + function flatten(obj, depth) { + var result = [], typ = (typeof obj), prop; + if (depth && typ == 'object') { + for (prop in obj) { + try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {} + } + } + return (result.length ? result : typ == 'string' ? obj : obj + '\0'); + } + + // + // mixkey() + // Mixes a string seed into a key that is an array of integers, and + // returns a shortened string seed that is equivalent to the result key. + // + function mixkey(seed, key) { + var stringseed = seed + '', smear, j = 0; + while (j < stringseed.length) { + key[mask & j] = + mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++)); + } + return tostring(key); + } + + // + // autoseed() + // Returns an object for autoseeding, using window.crypto and Node crypto + // module if available. + // + function autoseed() { + try { + var out; + if (nodecrypto && (out = nodecrypto.randomBytes)) { + // The use of 'out' to remember randomBytes makes tight minified code. + out = out(width); + } else { + out = new Uint8Array(width); + (global.crypto || global.msCrypto).getRandomValues(out); + } + return tostring(out); + } catch (e) { + var browser = global.navigator, + plugins = browser && browser.plugins; + return [+new Date, global, plugins, global.screen, tostring(pool)]; + } + } + + // + // tostring() + // Converts an array of charcodes to a string + // + function tostring(a) { + return String.fromCharCode.apply(0, a); + } + + // + // When seedrandom.js is loaded, we immediately mix a few bits + // from the built-in RNG into the entropy pool. Because we do + // not want to interfere with deterministic PRNG state later, + // seedrandom will not call math.random on its own again after + // initialization. + // + mixkey(math.random(), pool); + + // + // Nodejs and AMD support: export the implementation as a module using + // either convention. + // + if (('object') == 'object' && module.exports) { + module.exports = seedrandom; + // When in node.js, try using crypto package for autoseeding. + try { + nodecrypto = require('crypto'); + } catch (ex) {} + } else if ((typeof undefined) == 'function' && undefined.amd) { + undefined(function() { return seedrandom; }); + } else { + // When included as a plain script, set up Math.seedrandom global. + math['seed' + rngname] = seedrandom; + } + + + // End anonymous scope, and pass initial values. + })( + // global: `self` in browsers (including strict mode and web workers), + // otherwise `this` in Node and other environments + (typeof self !== 'undefined') ? self : commonjsGlobal, + [], // pool: entropy pool starts empty + Math // math: package containing random, pow, and seedrandom + ); + } (seedrandom$3)); + + var seedrandomExports = seedrandom$3.exports; + var seedrandom$2 = /*@__PURE__*/getDefaultExportFromCjs(seedrandomExports); + + // A library of seedable RNGs implemented in Javascript. + // + // Usage: + // + // var seedrandom = require('seedrandom'); + // var random = seedrandom(1); // or any seed. + // var x = random(); // 0 <= x < 1. Every bit is random. + // var x = random.quick(); // 0 <= x < 1. 32 bits of randomness. + + // alea, a 53-bit multiply-with-carry generator by Johannes Baagøe. + // Period: ~2^116 + // Reported to pass all BigCrush tests. + var alea = aleaExports; + + // xor128, a pure xor-shift generator by George Marsaglia. + // Period: 2^128-1. + // Reported to fail: MatrixRank and LinearComp. + var xor128 = xor128Exports; + + // xorwow, George Marsaglia's 160-bit xor-shift combined plus weyl. + // Period: 2^192-2^32 + // Reported to fail: CollisionOver, SimpPoker, and LinearComp. + var xorwow = xorwowExports; + + // xorshift7, by François Panneton and Pierre L'ecuyer, takes + // a different approach: it adds robustness by allowing more shifts + // than Marsaglia's original three. It is a 7-shift generator + // with 256 bits, that passes BigCrush with no systmatic failures. + // Period 2^256-1. + // No systematic BigCrush failures reported. + var xorshift7 = xorshift7Exports; + + // xor4096, by Richard Brent, is a 4096-bit xor-shift with a + // very long period that also adds a Weyl generator. It also passes + // BigCrush with no systematic failures. Its long period may + // be useful if you have many generators and need to avoid + // collisions. + // Period: 2^4128-2^32. + // No systematic BigCrush failures reported. + var xor4096 = xor4096Exports; + + // Tyche-i, by Samuel Neves and Filipe Araujo, is a bit-shifting random + // number generator derived from ChaCha, a modern stream cipher. + // https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf + // Period: ~2^127 + // No systematic BigCrush failures reported. + var tychei = tycheiExports; + + // The original ARC4-based prng included in this library. + // Period: ~2^1600 + var sr = seedrandomExports; + + sr.alea = alea; + sr.xor128 = xor128; + sr.xorwow = xorwow; + sr.xorshift7 = xorshift7; + sr.xor4096 = xor4096; + sr.tychei = tychei; + + var seedrandom = sr; + + var index$1 = /*@__PURE__*/getDefaultExportFromCjs(seedrandom); + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const TEST_EPSILON_FLOAT32 = 1e-3; + const TEST_EPSILON_FLOAT16 = 1e-1; + function expectArraysClose(actual, expected, epsilon) { + if (epsilon == null) { + epsilon = testEpsilon(); + } + return expectArraysPredicate(actual, expected, (a, b) => areClose(a, b, epsilon)); + } + function testEpsilon() { + return ENGINE.backend.floatPrecision() === 32 ? TEST_EPSILON_FLOAT32 : + TEST_EPSILON_FLOAT16; + } + function expectArraysPredicate(actual, expected, predicate) { + let checkClassType = true; + if (isTypedArray(actual) || isTypedArray(expected)) { + checkClassType = false; + } + if (isTypedArray(actual) && isTypedArray(expected)) { + checkClassType = true; + } + if (checkClassType) { + const aType = actual.constructor.name; + const bType = expected.constructor.name; + if (aType !== bType) { + throw new Error(`Arrays are of different type. Actual: ${aType}. ` + + `Expected: ${bType}`); + } + } + if (Array.isArray(actual) && Array.isArray(expected)) { + const actualShape = inferShape(actual); + const expectedShape = inferShape(expected); + if (!arraysEqual(actualShape, expectedShape)) { + throw new Error(`Arrays have different shapes. ` + + `Actual: [${actualShape}]. Expected: [${expectedShape}]`); + } + } + const actualFlat = isTypedArray(actual) ? actual : flatten$2(actual); + const expectedFlat = isTypedArray(expected) ? + expected : + flatten$2(expected); + if (actualFlat.length !== expectedFlat.length) { + throw new Error(`Arrays have different lengths actual: ${actualFlat.length} vs ` + + `expected: ${expectedFlat.length}.\n` + + `Actual: ${actualFlat}.\n` + + `Expected: ${expectedFlat}.`); + } + for (let i = 0; i < expectedFlat.length; ++i) { + const a = actualFlat[i]; + const e = expectedFlat[i]; + if (!predicate(a, e)) { + throw new Error(`Arrays differ: actual[${i}] = ${a}, expected[${i}] = ${e}.\n` + + `Actual: ${actualFlat}.\n` + + `Expected: ${expectedFlat}.`); + } + } + if (typeof expect !== 'undefined') { + expect().nothing(); + } + } + function expectPromiseToFail(fn, done) { + fn().then(() => done.fail(), () => done()); + if (typeof expect !== 'undefined') { + expect().nothing(); + } + } + function expectArraysEqual(actual, expected) { + const exp = typeof expected === 'string' || typeof expected === 'number' || + typeof expected === 'boolean' ? + [expected] : + expected; + if (isString(actual) || isString(actual[0]) || + isString(expected) || isString(expected[0])) { + // tslint:disable-next-line: triple-equals + return expectArraysPredicate(actual, exp, (a, b) => a == b); + } + return expectArraysPredicate(actual, expected, (a, b) => areClose(a, b, 0)); + } + function expectNumbersClose(a, e, epsilon) { + if (epsilon == null) { + epsilon = testEpsilon(); + } + if (!areClose(a, e, epsilon)) { + throw new Error(`Numbers differ: actual === ${a}, expected === ${e}`); + } + if (typeof expect !== 'undefined') { + expect().nothing(); + } + } + function areClose(a, e, epsilon) { + if (!isFinite(a) && !isFinite(e)) { + return true; + } + if (isNaN(a) || isNaN(e) || Math.abs(a - e) > epsilon) { + return false; + } + return true; + } + function expectValuesInRange(actual, low, high) { + for (let i = 0; i < actual.length; i++) { + if (actual[i] < low || actual[i] > high) { + throw new Error(`Value out of range:${actual[i]} low: ${low}, high: ${high}`); + } + } + } + function expectArrayBuffersEqual(actual, expected) { + // Safari does not like comparing ArrayBuffers directly. Wrapping in + // a Float32Array solves this issue. + const actualArray = new Float32Array(actual); + const expectedArray = new Float32Array(expected); + if (actualArray.length !== expectedArray.length) { + throw new Error('Expected ArrayBuffer to be of length ' + + `${expectedArray.length}, but it was ${actualArray.length}`); + } + for (let i = 0; i < expectedArray.length; i++) { + if (actualArray[i] !== expectedArray[i]) { + throw new Error(`Expected ArrayBuffer value at ${i} to be ` + + `${expectedArray[i]} but got ${actualArray[i]} instead`); + } + } + } + /** Encodes strings into utf-8 bytes. */ + function encodeStrings(a) { + for (let i = 0; i < a.length; i++) { + const val = a[i]; + if (Array.isArray(val)) { + encodeStrings(val); + } + else { + a[i] = encodeString(val); + } + } + return a; + } + /** Creates an HTMLVideoElement with autoplay-friendly default settings. */ + function createVideoElement(source) { + const video = document.createElement('video'); + if ('playsInline' in video) { + // tslint:disable-next-line:no-any + video.playsInline = true; + } + video.muted = true; + video.loop = true; + video.style.position = 'fixed'; + video.style.left = '0px'; + video.style.top = '0px'; + video.preload = 'auto'; + video.appendChild(source); + return new Promise(resolve => { + video.addEventListener('loadeddata', _ => resolve(video)); + video.load(); + }); + } + async function play(video) { + await video.play(); + if ('requestVideoFrameCallback' in video) { + await new Promise(resolve => { + // tslint:disable-next-line:no-any + video.requestVideoFrameCallback(resolve); + }); + } + } + + var test_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + TEST_EPSILON_FLOAT16: TEST_EPSILON_FLOAT16, + createVideoElement: createVideoElement, + encodeStrings: encodeStrings, + expectArrayBuffersEqual: expectArrayBuffersEqual, + expectArraysClose: expectArraysClose, + expectArraysEqual: expectArraysEqual, + expectNumbersClose: expectNumbersClose, + expectPromiseToFail: expectPromiseToFail, + expectValuesInRange: expectValuesInRange, + play: play, + testEpsilon: testEpsilon + }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // https://en.wikipedia.org/wiki/Marsaglia_polar_method + class MPRandGauss { + constructor(mean, stdDeviation, dtype, truncated, seed) { + this.mean = mean; + this.stdDev = stdDeviation; + this.dtype = dtype; + this.nextVal = NaN; + this.truncated = truncated; + if (this.truncated) { + this.upper = this.mean + this.stdDev * 2; + this.lower = this.mean - this.stdDev * 2; + } + const seedValue = seed ? seed : Math.random(); + this.random = seedrandom.alea(seedValue.toString()); + } + /** Returns next sample from a Gaussian distribution. */ + nextValue() { + if (!isNaN(this.nextVal)) { + const value = this.nextVal; + this.nextVal = NaN; + return value; + } + let resultX, resultY; + let isValid = false; + while (!isValid) { + let v1, v2, s; + do { + v1 = 2 * this.random() - 1; + v2 = 2 * this.random() - 1; + s = v1 * v1 + v2 * v2; + } while (s >= 1 || s === 0); + const mul = Math.sqrt(-2.0 * Math.log(s) / s); + resultX = this.mean + this.stdDev * v1 * mul; + resultY = this.mean + this.stdDev * v2 * mul; + if (!this.truncated || this.isValidTruncated(resultX)) { + isValid = true; + } + } + if (!this.truncated || this.isValidTruncated(resultY)) { + this.nextVal = this.convertValue(resultY); + } + return this.convertValue(resultX); + } + /** Handles proper rounding for non-floating-point numbers. */ + convertValue(value) { + if (this.dtype == null || this.dtype === 'float32') { + return value; + } + return Math.round(value); + } + /** Returns true if less than 2-standard-deviations from the mean. */ + isValidTruncated(value) { + return value <= this.upper && value >= this.lower; + } + } + // Marsaglia, George, and Wai Wan Tsang. 2000. "A Simple Method for Generating + // Gamma Variables." + class RandGamma { + constructor(alpha, beta, dtype, seed) { + this.alpha = alpha; + this.beta = 1 / beta; // convert rate to scale parameter + this.dtype = dtype; + const seedValue = seed ? seed : Math.random(); + this.randu = seedrandom.alea(seedValue.toString()); + this.randn = new MPRandGauss(0, 1, dtype, false, this.randu()); + if (alpha < 1) { + this.d = alpha + (2 / 3); + } + else { + this.d = alpha - (1 / 3); + } + this.c = 1 / Math.sqrt(9 * this.d); + } + /** Returns next sample from a gamma distribution. */ + nextValue() { + let x2, v0, v1, x, u, v; + while (true) { + do { + x = this.randn.nextValue(); + v = 1 + (this.c * x); + } while (v <= 0); + v *= v * v; + x2 = x * x; + v0 = 1 - (0.331 * x2 * x2); + v1 = (0.5 * x2) + (this.d * (1 - v + Math.log(v))); + u = this.randu(); + if (u < v0 || Math.log(u) < v1) { + break; + } + } + v = (1 / this.beta) * this.d * v; + if (this.alpha < 1) { + v *= Math.pow(this.randu(), 1 / this.alpha); + } + return this.convertValue(v); + } + /** Handles proper rounding for non-floating-point numbers. */ + convertValue(value) { + if (this.dtype === 'float32') { + return value; + } + return Math.round(value); + } + } + class UniformRandom { + constructor(min = 0, max = 1, dtype, seed) { + /** Handles proper rounding for non floating point numbers. */ + this.canReturnFloat = () => (this.dtype == null || this.dtype === 'float32'); + this.min = min; + this.range = max - min; + this.dtype = dtype; + if (seed == null) { + seed = Math.random(); + } + if (typeof seed === 'number') { + seed = seed.toString(); + } + if (!this.canReturnFloat() && this.range <= 1) { + throw new Error(`The difference between ${min} - ${max} <= 1 and dtype is not float`); + } + this.random = seedrandom.alea(seed); + } + convertValue(value) { + if (this.canReturnFloat()) { + return value; + } + return Math.round(value); + } + nextValue() { + return this.convertValue(this.min + this.range * this.random()); + } + } + function jarqueBeraNormalityTest(values) { + // https://en.wikipedia.org/wiki/Jarque%E2%80%93Bera_test + const n = values.length; + const s = skewness(values); + const k = kurtosis(values); + const jb = n / 6 * (Math.pow(s, 2) + 0.25 * Math.pow(k - 3, 2)); + // JB test requires 2-degress of freedom from Chi-Square @ 0.95: + // http://www.itl.nist.gov/div898/handbook/eda/section3/eda3674.htm + const CHI_SQUARE_2DEG = 5.991; + if (jb > CHI_SQUARE_2DEG) { + throw new Error(`Invalid p-value for JB: ${jb}`); + } + } + function expectArrayInMeanStdRange(actual, expectedMean, expectedStdDev, epsilon) { + if (epsilon == null) { + epsilon = testEpsilon(); + } + const actualMean = mean$2(actual); + expectNumbersClose(actualMean, expectedMean, epsilon); + expectNumbersClose(standardDeviation(actual, actualMean), expectedStdDev, epsilon); + } + function mean$2(values) { + let sum = 0; + for (let i = 0; i < values.length; i++) { + sum += values[i]; + } + return sum / values.length; + } + function standardDeviation(values, mean) { + let squareDiffSum = 0; + for (let i = 0; i < values.length; i++) { + const diff = values[i] - mean; + squareDiffSum += diff * diff; + } + return Math.sqrt(squareDiffSum / values.length); + } + function kurtosis(values) { + // https://en.wikipedia.org/wiki/Kurtosis + const valuesMean = mean$2(values); + const n = values.length; + let sum2 = 0; + let sum4 = 0; + for (let i = 0; i < n; i++) { + const v = values[i] - valuesMean; + sum2 += Math.pow(v, 2); + sum4 += Math.pow(v, 4); + } + return (1 / n) * sum4 / Math.pow((1 / n) * sum2, 2); + } + function skewness(values) { + // https://en.wikipedia.org/wiki/Skewness + const valuesMean = mean$2(values); + const n = values.length; + let sum2 = 0; + let sum3 = 0; + for (let i = 0; i < n; i++) { + const v = values[i] - valuesMean; + sum2 += Math.pow(v, 2); + sum3 += Math.pow(v, 3); + } + return (1 / n) * sum3 / Math.pow((1 / (n - 1)) * sum2, 3 / 2); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with values sampled from a gamma distribution. + * + * ```js + * tf.randomGamma([2, 2], 1).print(); + * ``` + * + * @param shape An array of integers defining the output tensor shape. + * @param alpha The shape parameter of the gamma distribution. + * @param beta The inverse scale parameter of the gamma distribution. Defaults + * to 1. + * @param dtype The data type of the output. Defaults to float32. + * @param seed The seed for the random number generator. + * + * @doc {heading: 'Tensors', subheading: 'Random'} + */ + function randomGamma_(shape, alpha, beta = 1, dtype = 'float32', seed) { + assertNonNegativeIntegerDimensions(shape); + if (beta == null) { + beta = 1; + } + if (dtype == null) { + dtype = 'float32'; + } + if (dtype !== 'float32' && dtype !== 'int32') { + throw new Error(`Unsupported data type ${dtype}`); + } + const rgamma = new RandGamma(alpha, beta, dtype, seed); + const res = buffer(shape, dtype); + for (let i = 0; i < res.values.length; i++) { + res.values[i] = rgamma.nextValue(); + } + return res.toTensor(); + } + const randomGamma = /* @__PURE__ */ op({ randomGamma_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with values sampled from a normal distribution. + * + * ```js + * tf.randomNormal([2, 2]).print(); + * ``` + * + * @param shape An array of integers defining the output tensor shape. + * @param mean The mean of the normal distribution. + * @param stdDev The standard deviation of the normal distribution. + * @param dtype The data type of the output. + * @param seed The seed for the random number generator. + * + * @doc {heading: 'Tensors', subheading: 'Random'} + */ + function randomNormal_(shape, mean = 0, stdDev = 1, dtype, seed) { + assertNonNegativeIntegerDimensions(shape); + if (dtype != null && dtype === 'bool') { + throw new Error(`Unsupported data type ${dtype}`); + } + const randGauss = new MPRandGauss(mean, stdDev, dtype, false /* truncated */, seed); + const res = buffer(shape, dtype); + for (let i = 0; i < res.values.length; i++) { + res.values[i] = randGauss.nextValue(); + } + return res.toTensor(); + } + const randomNormal$2 = /* @__PURE__ */ op({ randomNormal_ }); + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with values sampled from a normal distribution. + * + * The generated values will have mean 0 and standard deviation 1. + * + * ```js + * tf.randomStandardNormal([2, 2]).print(); + * ``` + * + * @param shape An array of integers defining the output tensor shape. + * @param dtype The data type of the output. + * @param seed The seed for the random number generator. + * + * @doc {heading: 'Tensors', subheading: 'Random'} + */ + function randomStandardNormal_(shape, dtype, seed) { + if (dtype != null && dtype === 'bool') { + throw new Error(`Unsupported data type ${dtype}`); + } + return randomNormal$2(shape, 0, 1, dtype, seed); + } + const randomStandardNormal = /* @__PURE__ */ op({ randomStandardNormal_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with values sampled from a uniform distribution. + * + * The generated values follow a uniform distribution in the range [minval, + * maxval). The lower bound minval is included in the range, while the upper + * bound maxval is excluded. + * + * ```js + * tf.randomUniform([2, 2]).print(); + * ``` + * + * @param shape An array of integers defining the output tensor shape. + * @param minval The lower bound on the range of random values to generate. + * Defaults to 0. + * @param maxval The upper bound on the range of random values to generate. + * Defaults to 1. + * @param dtype The data type of the output tensor. Defaults to 'float32'. + * @param seed An optional int. Defaults to 0. If seed is set to be non-zero, + * the random number generator is seeded by the given seed. Otherwise, it is + * seeded by a random seed. + * + * @doc {heading: 'Tensors', subheading: 'Random'} + */ + function randomUniform_(shape, minval = 0, maxval = 1, dtype = 'float32', seed) { + assertNonNegativeIntegerDimensions(shape); + const res = buffer(shape, dtype); + const random = new UniformRandom(minval, maxval, null, seed); + for (let i = 0; i < res.values.length; i++) { + res.values[i] = random.nextValue(); + } + return res.toTensor(); + } + const randomUniform$1 = /* @__PURE__ */ op({ randomUniform_ }); + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with integers sampled from a uniform distribution. + * + * The generated values are uniform integers in the range [minval, maxval). The + * lower bound minval is included in the range, while the upper bound maxval is + * excluded. + * + * ```js + * tf.randomUniformInt([2, 2], 0, 10).print(); + * ``` + * + * @param shape An array of integers defining the output tensor shape. + * @param minval Inclusive lower bound on the generated integers. + * @param maxval Exclusive upper bound on the generated integers. + * @param seed An optional int. Defaults to 0. If seed is set to be non-zero, + * the random number generator is seeded by the given seed. Otherwise, it is + * seeded by a random seed. + * + * @doc {heading: 'Tensors', subheading: 'Random'} + */ + function randomUniformInt_(shape, minval, maxval, seed) { + // TODO(mattsoulanille): Handle optional seed2 input. + return randomUniform$1(shape, minval, maxval, 'int32', seed); + } + const randomUniformInt = /* @__PURE__ */ op({ randomUniformInt_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a new `tf.Tensor1D` filled with the numbers in the range provided. + * + * The tensor is a half-open interval meaning it includes start, but + * excludes stop. Decrementing ranges and negative step values are also + * supported. + * + * + * ```js + * tf.range(0, 9, 2).print(); + * ``` + * + * @param start An integer start value + * @param stop An integer stop value + * @param step An integer increment (will default to 1 or -1) + * @param dtype The data type of the output tensor. Defaults to 'float32'. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function range$3(start, stop, step = 1, dtype = 'float32') { + if (step === 0) { + throw new Error('Cannot have a step of zero'); + } + const attrs = { start, stop, step, dtype }; + return ENGINE.runKernel(Range, {} /* inputs */, attrs); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the real part of a complex (or real) tensor. + * + * Given a tensor input, this operation returns a tensor of type float that is + * the real part of each element in input considered as a complex number. + * + * If the input is real, it simply makes a clone. + * + * ```js + * const x = tf.complex([-2.25, 3.25], [4.75, 5.75]); + * tf.real(x).print(); + * ``` + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function real_(input) { + const $input = convertToTensor(input, 'input', 'real'); + const inputs = { input: $input }; + return ENGINE.runKernel(Real, inputs); + } + const real$2 = /* @__PURE__ */ op({ real_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes reciprocal of x element-wise: `1 / x` + * + * ```js + * const x = tf.tensor1d([0, 1, 2]); + * + * x.reciprocal().print(); // or tf.reciprocal(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function reciprocal_(x) { + const $x = convertToTensor(x, 'x', 'reciprocal'); + const inputs = { x: $x }; + return ENGINE.runKernel(Reciprocal, inputs); + } + const reciprocal$2 = /* @__PURE__ */ op({ reciprocal_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes rectified linear element-wise: `max(x, 0)`. + * + * ```js + * const x = tf.tensor1d([-1, 2, -3, 4]); + * + * x.relu().print(); // or tf.relu(x) + * ``` + * @param x The input tensor. If the dtype is `bool`, the output dtype will be + * `int32`. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function relu_(x) { + const $x = convertToTensor(x, 'x', 'relu'); + const inputs = { x: $x }; + return ENGINE.runKernel(Relu$1, inputs); + } + const relu$2 = /* @__PURE__ */ op({ relu_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes rectified linear 6 element-wise: `min(max(x, 0), 6)`. + * + * ```js + * const x = tf.tensor1d([-1, 2, -3, 8]); + * + * x.relu6().print(); // or tf.relu6(x) + * ``` + * @param x The input tensor. If the dtype is `bool`, the output dtype will be + * `int32`. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function relu6_(x) { + const $x = convertToTensor(x, 'x', 'relu6'); + const inputs = { x: $x }; + return ENGINE.runKernel(Relu6$1, inputs); + } + const relu6$2 = /* @__PURE__ */ op({ relu6_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Reverses a `tf.Tensor` along a specified axis. + * + * Also available are stricter rank-specific methods that assert that `x` is + * of the given rank: + * - `tf.reverse1d` + * - `tf.reverse2d` + * - `tf.reverse3d` + * - `tf.reverse4d` + * + * Except `tf.reverse1d` (which does not have axis param), all methods have + * same signature as this method. + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * + * x.reverse().print(); + * ``` + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * const axis = 1; + * x.reverse(axis).print(); + * ``` + * @param x The input tensor to be reversed. + * @param axis The set of dimensions to reverse. Must be in the + * range [-rank(x), rank(x)). Defaults to all axes. + * + * @doc {heading: 'Tensors', subheading: 'Slicing and Joining'} + */ + function reverse_(x, axis) { + const $x = convertToTensor(x, 'x', 'reverse'); + const inputs = { x: $x }; + const attrs = { dims: axis }; + return ENGINE.runKernel(Reverse, inputs, attrs); + } + const reverse$2 = /* @__PURE__ */ op({ reverse_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Reverses a `tf.Tensor1D`. + * + * @param x The input tensor. + */ + function reverse1d_(x) { + const $x = convertToTensor(x, 'x', 'reverse'); + assert$1($x.rank === 1, () => `Error in reverse1D: x must be rank 1 but got rank ${$x.rank}.`); + return reverse$2($x, 0); + } + const reverse1d = /* @__PURE__ */ op({ reverse1d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Reverses a `tf.Tensor2D` along a specified axis. + * + * @param x The input tensor. + * @param axis The set of dimensions to reverse. Must be in the + * range [-rank(x), rank(x)). Defaults to all axes. + */ + function reverse2d_(x, axis) { + const $x = convertToTensor(x, 'x', 'reverse'); + assert$1($x.rank === 2, () => `Error in reverse2D: x must be rank 2 but got rank ${$x.rank}.`); + return reverse$2($x, axis); + } + const reverse2d = /* @__PURE__ */ op({ reverse2d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Reverses a `tf.Tensor3D` along a specified axis. + * + * @param x The input tensor. + * @param axis The set of dimensions to reverse. Must be in the + * range [-rank(x), rank(x)). Defaults to all axes. + */ + function reverse3d_(x, axis) { + const $x = convertToTensor(x, 'x', 'reverse'); + assert$1($x.rank === 3, () => `Error in reverse3D: x must be rank 3 but got rank ${$x.rank}.`); + return reverse$2($x, axis); + } + const reverse3d = /* @__PURE__ */ op({ reverse3d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Reverses a `tf.Tensor4D` along a specified axis. + * + * @param x The input tensor. + * @param axis The set of dimensions to reverse. Must be in the + * range [-rank(x), rank(x)). Defaults to all axes. + */ + function reverse4d_(x, axis) { + const $x = convertToTensor(x, 'x', 'reverse'); + assert$1($x.rank === 4, () => `Error in reverse4D: x must be rank 4 but got rank ${$x.rank}.`); + return reverse$2($x, axis); + } + const reverse4d = /* @__PURE__ */ op({ reverse4d_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes round of input `tf.Tensor` element-wise: `round(x)`. + * It implements banker's rounding. + * + * ```js + * const x = tf.tensor1d([.6, 1.1, -3.3]); + * + * x.round().print(); // or tf.round(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function round_(x) { + const $x = convertToTensor(x, 'x', 'round'); + const inputs = { x: $x }; + return ENGINE.runKernel(Round, inputs); + } + const round$2 = /* @__PURE__ */ op({ round_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes reciprocal of square root of the input `tf.Tensor` element-wise: + * `y = 1 / sqrt(x)` + * + * ```js + * const x = tf.tensor1d([1, 2, 4, -1]); + * + * x.rsqrt().print(); // or tf.rsqrt(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function rsqrt_(x) { + const $x = convertToTensor(x, 'x', 'rsqrt', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Rsqrt, inputs); + } + const rsqrt$2 = /* @__PURE__ */ op({ rsqrt_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes scaled exponential linear element-wise. + * + * `x < 0 ? scale * alpha * (exp(x) - 1) : scale * x` + * + * ```js + * const x = tf.tensor1d([-1, 2, -3, 4]); + * + * x.selu().print(); // or tf.selu(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function selu_(x) { + const $x = convertToTensor(x, 'x', 'selu'); + const inputs = { x: $x }; + return ENGINE.runKernel(Selu$1, inputs); + } + const selu$2 = /* @__PURE__ */ op({ selu_ }); + + /** + * 2-D convolution with separable filters. + * + * Performs a depthwise convolution that acts separately on channels followed + * by a pointwise convolution that mixes channels. Note that this is + * separability between dimensions [1, 2] and 3, not spatial separability + * between dimensions 1 and 2. + * + * See + * [https://www.tensorflow.org/api_docs/python/tf/nn/separable_conv2d]( + * https://www.tensorflow.org/api_docs/python/tf/nn/separable_conv2d) + * for more details. + * + * @param x The input tensor, of rank 4 or rank 3, of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is + * assumed. + * @param depthwiseFilter The depthwise filter tensor, rank 4, of shape + * `[filterHeight, filterWidth, inChannels, channelMultiplier]`. This is + * the filter used in the first step. + * @param pointwiseFilter The pointwise filter tensor, rank 4, of shape + * `[1, 1, inChannels * channelMultiplier, outChannels]`. This is + * the filter used in the second step. + * @param strides The strides of the convolution: `[strideHeight, + * strideWidth]`. If strides is a single number, then `strideHeight == + * strideWidth`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dilations The dilation rates: `[dilationHeight, dilationWidth]` + * in which we sample input values across the height and width dimensions + * in atrous convolution. Defaults to `[1, 1]`. If `rate` is a single + * number, then `dilationHeight == dilationWidth`. If it is greater than + * 1, then all values of `strides` must be 1. + * @param dataFormat: An optional string from: "NHWC", "NCHW". Defaults to + * "NHWC". Specify the data format of the input and output data. With the + * default format "NHWC", the data is stored in the order of: [batch, + * height, width, channels]. Only "NHWC" is currently supported. + * + * @doc {heading: 'Operations', subheading: 'Convolution'} + */ + function separableConv2d_(x, depthwiseFilter, pointwiseFilter, strides, pad, dilation = [1, 1], dataFormat = 'NHWC') { + const $x = convertToTensor(x, 'x', 'separableConv2d'); + const $depthwiseFilter = convertToTensor(depthwiseFilter, 'depthwiseFilter', 'separableConv2d'); + const $pointwiseFilter = convertToTensor(pointwiseFilter, 'pointwiseFilter', 'separableConv2d'); + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + reshapedTo4D = true; + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + } + if (dataFormat === 'NCHW') { + throw new Error('separableConv2d currently does not support dataFormat NCHW; only ' + + 'NHWC is supported'); + } + assert$1(x4D.rank === 4, () => `Error in separableConv2d: input must be rank 4, but got ` + + `rank ${x4D.rank}.`); + assert$1($depthwiseFilter.rank === 4, () => `Error in separableConv2d: depthwise filter must be rank 4, but ` + + `got rank ${$depthwiseFilter.rank}.`); + assert$1($pointwiseFilter.rank === 4, () => `Error in separableConv2d: pointwise filter must be rank 4, but ` + + `got rank ${$depthwiseFilter.rank}.`); + assert$1($pointwiseFilter.shape[0] === 1, () => `Error in separableConv2d: the first dimension of pointwise filter ` + + ` must be 1, but got ${$pointwiseFilter.shape[0]}.`); + assert$1($pointwiseFilter.shape[1] === 1, () => `Error in separableConv2d: the second dimension of pointwise ` + + `filter must be 1, but got ${$pointwiseFilter.shape[1]}.`); + const inChannels = $depthwiseFilter.shape[2]; + const channelMultiplier = $depthwiseFilter.shape[3]; + assert$1($pointwiseFilter.shape[2] === inChannels * channelMultiplier, () => `Error in separableConv2d: the third dimension of pointwise filter ` + + `must be ${inChannels * channelMultiplier}, ` + + `but got ${$pointwiseFilter.shape[2]}.`); + const depthwise = depthwiseConv2d$3(x4D, $depthwiseFilter, strides, pad, dataFormat, dilation); + const pointwiseStride = 1; + const res = conv2d$4(depthwise, $pointwiseFilter, pointwiseStride, 'valid', dataFormat); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const separableConv2d$1 = /* @__PURE__ */ op({ separableConv2d_ }); + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the difference between two lists of numbers. + * + * Given a Tensor `x` and a Tensor `y`, this operation returns a Tensor `out` + * that represents all values that are in `x` but not in `y`. The returned + * Tensor `out` is sorted in the same order that the numbers appear in `x` + * (duplicates are preserved). This operation also returns a Tensor indices that + * represents the position of each out element in `x`. In other words: + * + * `out[i] = x[idx[i]] for i in [0, 1, ..., out.length - 1]` + * + * ```js + * const x = [1, 2, 3, 4, 5, 6]; + * const y = [1, 3, 5]; + * + * const [out, indices] = await tf.setdiff1dAsync(x, y); + * out.print(); // [2, 4, 6] + * indices.print(); // [1, 3, 5] + * ``` + * + * @param x 1-D Tensor. Values to keep. + * @param y 1-D Tensor. Must have the same type as x. Values to exclude in the + * output. + * @returns Promise of Tensor tuple [out, indices]. + * out: Tensor with the same type as x. + * indices: A Tensor of type int32. + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + async function setdiff1dAsync_(x, y) { + const $x = convertToTensor(x, 'x', 'setdiff1d'); + const $y = convertToTensor(y, 'y', 'setdiff1d'); + assert$1($x.dtype === $y.dtype, () => `x and y should have the same dtype, but got x (${$x.dtype}) and y (${$y.dtype}).`); + assert$1($x.rank === 1, () => `x should be 1D tensor, but got x (${$x.shape}).`); + assert$1($y.rank === 1, () => `y should be 1D tensor, but got y (${$y.shape}).`); + const xVals = await $x.data(); + const yVals = await $y.data(); + const ySet = new Set(yVals); + let outputSize = 0; + for (let i = 0; i < xVals.length; i++) { + if (!ySet.has(xVals[i])) { + outputSize++; + } + } + const buffer = new TensorBuffer([outputSize], $x.dtype); + const indices = new TensorBuffer([outputSize], 'int32'); + for (let i = 0, p = 0; i < xVals.length; i++) { + if (!ySet.has(xVals[i])) { + buffer.values[p] = xVals[i]; + indices.values[p] = i; + p++; + } + } + return [buffer.toTensor(), indices.toTensor()]; + } + const setdiff1dAsync = setdiff1dAsync_; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns an element-wise indication of the sign of a number. + * + * ```js + * const x = tf.tensor1d([.6, 1.1, -3.3, NaN, 0]); + * + * x.sign().print(); // or tf.sign(x) + * ``` + * @param x The input Tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function sign_(x) { + const $x = convertToTensor(x, 'x', 'sign'); + const inputs = { x: $x }; + return ENGINE.runKernel(Sign, inputs); + } + const sign$3 = /* @__PURE__ */ op({ sign_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes sin of the input Tensor element-wise: `sin(x)` + * + * ```js + * const x = tf.tensor1d([0, Math.PI / 2, Math.PI * 3 / 4]); + * + * x.sin().print(); // or tf.sin(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function sin_(x) { + const $x = convertToTensor(x, 'x', 'sin', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Sin, inputs); + } + const sin$2 = /* @__PURE__ */ op({ sin_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes hyperbolic sin of the input `tf.Tensor` element-wise: `sinh(x)` + * + * ```js + * const x = tf.tensor1d([0, 1, -1, .7]); + * + * x.sinh().print(); // or tf.sinh(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function sinh_(x) { + const $x = convertToTensor(x, 'x', 'sinh'); + const inputs = { x: $x }; + return ENGINE.runKernel(Sinh, inputs); + } + const sinh$2 = /* @__PURE__ */ op({ sinh_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Extracts a 1D slice from 1D array starting at coordinates `begin` and is + * of length `size`. See `slice` for details. + */ + function slice1d_(x, begin, size) { + const $x = convertToTensor(x, 'x', 'slice1d'); + assert$1($x.rank === 1, () => `slice1d expects a rank-1 tensor, but got a rank-${$x.rank} tensor`); + return slice$2($x, [begin], [size]); + } + const slice1d = /* @__PURE__ */ op({ slice1d_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Extracts a 2D slice from a 2D array starting at coordinates `begin` and + * is of size `size`. See `slice` for details. + */ + function slice2d_(x, begin, size) { + const $x = convertToTensor(x, 'x', 'slice2d'); + assert$1($x.rank === 2, () => `slice2d expects a rank-2 tensor, but got a rank-${$x.rank} tensor`); + return slice$2($x, begin, size); + } + const slice2d = /* @__PURE__ */ op({ slice2d_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Extracts a 3D slice from a 3D array starting at coordinates `begin` and + * is of size `size`. See `slice` for details. + */ + function slice3d_(x, begin, size) { + const $x = convertToTensor(x, 'x', 'slice3d'); + assert$1($x.rank === 3, () => `slice3d expects a rank-3 tensor, but got a rank-${$x.rank} tensor`); + return slice$2($x, begin, size); + } + const slice3d = /* @__PURE__ */ op({ slice3d_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Extracts a 4D slice from a 4D array starting at coordinates `begin` and + * is of size `size`. See `slice` for details. + */ + function slice4d_(x, begin, size) { + const $x = convertToTensor(x, 'x', 'slice4d'); + assert$1($x.rank === 4, () => `slice4d expects a rank-4 tensor, but got a rank-${$x.rank} tensor`); + return slice$2($x, begin, size); + } + const slice4d = /* @__PURE__ */ op({ slice4d_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the softmax normalized vector given the logits. + * + * ```js + * const a = tf.tensor1d([1, 2, 3]); + * + * a.softmax().print(); // or tf.softmax(a) + * ``` + * + * ```js + * const a = tf.tensor2d([2, 4, 6, 1, 2, 3], [2, 3]); + * + * a.softmax().print(); // or tf.softmax(a) + * ``` + * + * @param logits The logits array. + * @param dim The dimension softmax would be performed on. Defaults to `-1` + * which indicates the last dimension. + * + * @doc {heading: 'Operations', subheading: 'Normalization'} + */ + function softmax_(logits, dim = -1) { + const $logits = convertToTensor(logits, 'logits', 'softmax', 'float32'); + if (dim === -1) { + dim = $logits.rank - 1; + } + if (dim !== $logits.rank - 1) { + throw Error('Softmax along a non-last dimension is not yet supported. ' + + `Logits was rank ${$logits.rank} and dim was ${dim}`); + } + const inputs = { logits: $logits }; + const attrs = { dim }; + return ENGINE.runKernel(Softmax$2, inputs, attrs); + } + const softmax$3 = /* @__PURE__ */ op({ softmax_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Fast Fourier transform. + * + * Computes the 1-dimensional discrete Fourier transform over the inner-most + * dimension of input. + * + * ```js + * const real = tf.tensor1d([1, 2, 3]); + * const imag = tf.tensor1d([1, 2, 3]); + * const x = tf.complex(real, imag); + * + * x.fft().print(); // tf.spectral.fft(x).print(); + * ``` + * @param input The complex input to compute an fft over. + * + * @doc {heading: 'Operations', subheading: 'Spectral', namespace: 'spectral'} + */ + function fft_(input) { + assert$1(input.dtype === 'complex64', () => `The dtype for tf.spectral.fft() must be complex64 ` + + `but got ${input.dtype}.`); + const inputs = { input }; + return ENGINE.runKernel(FFT, inputs); + } + const fft$2 = /* @__PURE__ */ op({ fft_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Inverse fast Fourier transform. + * + * Computes the inverse 1-dimensional discrete Fourier transform over the + * inner-most dimension of input. + * + * ```js + * const real = tf.tensor1d([1, 2, 3]); + * const imag = tf.tensor1d([1, 2, 3]); + * const x = tf.complex(real, imag); + * + * x.ifft().print(); // tf.spectral.ifft(x).print(); + * ``` + * @param input The complex input to compute an ifft over. + * + * @doc {heading: 'Operations', subheading: 'Spectral', namespace: 'spectral'} + */ + function ifft_(input) { + assert$1(input.dtype === 'complex64', () => `The dtype for tf.spectral.ifft() must be complex64 ` + + `but got ${input.dtype}.`); + const inputs = { input }; + return ENGINE.runKernel(IFFT, inputs); + } + const ifft$2 = /* @__PURE__ */ op({ ifft_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Inversed real value input fast Fourier transform. + * + * Computes the 1-dimensional inversed discrete Fourier transform over the + * inner-most dimension of the real input. + * + * ```js + * const real = tf.tensor1d([1, 2, 3]); + * const imag = tf.tensor1d([0, 0, 0]); + * const x = tf.complex(real, imag); + * + * x.irfft().print(); + * ``` + * @param input The real value input to compute an irfft over. + * + * @doc {heading: 'Operations', subheading: 'Spectral', namespace: 'spectral'} + */ + function irfft_(input) { + const innerDimensionSize = input.shape[input.shape.length - 1]; + const batch = input.size / innerDimensionSize; + let ret; + if (innerDimensionSize <= 2) { + const complexInput = reshape$3(input, [batch, innerDimensionSize]); + ret = ifft$2(complexInput); + } + else { + // The length of unique components of the DFT of a real-valued signal + // is 2 * (input_len - 1) + const outputShape = [batch, 2 * (innerDimensionSize - 1)]; + const realInput = reshape$3(real$2(input), [batch, innerDimensionSize]); + const imagInput = reshape$3(imag$2(input), [batch, innerDimensionSize]); + const realConjugate = reverse$2(slice$2(realInput, [0, 1], [batch, innerDimensionSize - 2]), 1); + const imagConjugate = mul(reverse$2(slice$2(imagInput, [0, 1], [batch, innerDimensionSize - 2]), 1), scalar(-1)); + const r = concat$2([realInput, realConjugate], 1); + const i = concat$2([imagInput, imagConjugate], 1); + const complexInput = reshape$3(complex$2(r, i), [outputShape[0], outputShape[1]]); + ret = ifft$2(complexInput); + } + ret = real$2(ret); + // reshape the result if the input is 3D tensor. + if (input.rank === 3 && input.shape[0] !== 0) { + const temp = ret; + const batch = input.shape[0]; + ret = reshape$3(ret, [batch, ret.shape[0] / batch, ret.shape[1]]); + temp.dispose(); + } + return ret; + } + const irfft = /* @__PURE__ */ op({ irfft_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Splits a `tf.Tensor` into sub tensors. + * + * If `numOrSizeSplits` is a number, splits `x` along dimension `axis` + * into `numOrSizeSplits` smaller tensors. + * Requires that `numOrSizeSplits` evenly divides `x.shape[axis]`. + * + * If `numOrSizeSplits` is a number array, splits `x` into + * `numOrSizeSplits.length` pieces. The shape of the `i`-th piece has the + * same size as `x` except along dimension `axis` where the size is + * `numOrSizeSplits[i]`. + * + * ```js + * const x = tf.tensor2d([1, 2, 3, 4, 5, 6, 7, 8], [2, 4]); + * const [a, b] = tf.split(x, 2, 1); + * a.print(); + * b.print(); + * + * const [c, d, e] = tf.split(x, [1, 2, 1], 1); + * c.print(); + * d.print(); + * e.print(); + * ``` + * + * @param x The input tensor to split. + * @param numOrSizeSplits Either an integer indicating the number of + * splits along the axis or an array of integers containing the sizes of + * each output tensor along the axis. If a number then it must evenly divide + * `x.shape[axis]`; otherwise the sum of sizes must match `x.shape[axis]`. + * Can contain one -1 indicating that dimension is to be inferred. + * @param axis The dimension along which to split. Defaults to 0 (the first + * dim). + * + * @doc {heading: 'Tensors', subheading: 'Slicing and Joining'} + */ + function split_(x, numOrSizeSplits, axis = 0) { + const $x = convertToTensor(x, 'x', 'split'); + const inputs = { x: $x }; + const attr = { numOrSizeSplits, axis }; + return ENGINE.runKernel(SplitV, inputs, attr); + } + const split$3 = /* @__PURE__ */ op({ split_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Real value input fast Fourier transform. + * + * Computes the 1-dimensional discrete Fourier transform over the + * inner-most dimension of the real input. + * + * ```js + * const real = tf.tensor1d([1, 2, 3]); + * + * real.rfft().print(); + * ``` + * @param input The real value input to compute an rfft over. + * + * @doc {heading: 'Operations', subheading: 'Spectral', namespace: 'spectral'} + */ + function rfft_(input, fftLength) { + assert$1(input.dtype === 'float32', () => `The dtype for rfft() must be real value but got ${input.dtype}`); + let innerDimensionSize = input.shape[input.shape.length - 1]; + const batch = input.size / innerDimensionSize; + let adjustedInput; + if (fftLength != null && fftLength < innerDimensionSize) { + // Need to crop + const begin = input.shape.map(v => 0); + const size = input.shape.map(v => v); + size[input.shape.length - 1] = fftLength; + adjustedInput = slice$2(input, begin, size); + innerDimensionSize = fftLength; + } + else if (fftLength != null && fftLength > innerDimensionSize) { + // Need to pad with zeros + const zerosShape = input.shape.map(v => v); + zerosShape[input.shape.length - 1] = fftLength - innerDimensionSize; + adjustedInput = concat$2([input, zeros$2(zerosShape)], input.shape.length - 1); + innerDimensionSize = fftLength; + } + else { + adjustedInput = input; + } + // Complement the input with zero imaginary numbers. + const zerosInput = zerosLike$3(adjustedInput); + const complexInput = reshape$3(complex$2(adjustedInput, zerosInput), [batch, innerDimensionSize]); + const ret = fft$2(complexInput); + // Exclude complex conjugations. These conjugations are put symmetrically. + const half = Math.floor(innerDimensionSize / 2) + 1; + const realValues = real$2(ret); + const imagValues = imag$2(ret); + const realComplexConjugate = split$3(realValues, [half, innerDimensionSize - half], realValues.shape.length - 1); + const imagComplexConjugate = split$3(imagValues, [half, innerDimensionSize - half], imagValues.shape.length - 1); + const outputShape = adjustedInput.shape.slice(); + outputShape[adjustedInput.shape.length - 1] = half; + return reshape$3(complex$2(realComplexConjugate[0], imagComplexConjugate[0]), outputShape); + } + const rfft = /* @__PURE__ */ op({ rfft_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns (a - b) * (a - b) element-wise. + * Supports broadcasting. + * + * ```js + * const a = tf.tensor1d([1, 4, 3, 16]); + * const b = tf.tensor1d([1, 2, 9, 4]); + * + * a.squaredDifference(b).print(); // or tf.squaredDifference(a, b) + * ``` + * + * ```js + * // Broadcast squared difference a with b. + * const a = tf.tensor1d([2, 4, 6, 8]); + * const b = tf.scalar(5); + * + * a.squaredDifference(b).print(); // or tf.squaredDifference(a, b) + * ``` + * + * @param a The first tensor. + * @param b The second tensor. Must have the same type as `a`. + * + * @doc {heading: 'Operations', subheading: 'Arithmetic'} + */ + function squaredDifference_(a, b) { + let $a = convertToTensor(a, 'a', 'squaredDifference'); + let $b = convertToTensor(b, 'b', 'squaredDifference'); + [$a, $b] = makeTypesMatch($a, $b); + assertAndGetBroadcastShape($a.shape, $b.shape); + const inputs = { a: $a, b: $b }; + const attrs = {}; + return ENGINE.runKernel(SquaredDifference, inputs, attrs); + } + const squaredDifference$2 = /* @__PURE__ */ op({ squaredDifference_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Removes dimensions of size 1 from the shape of a `tf.Tensor`. + * + * ```js + * const x = tf.tensor([1, 2, 3, 4], [1, 1, 4]); + * x.squeeze().print(); + * ``` + * + * @param x The input tensor to be squeezed. + * @param axis An optional list of numbers. If specified, only + * squeezes the dimensions listed. The dimension index starts at 0. It + * is an error to squeeze a dimension that is not 1. + * + * @doc {heading: 'Tensors', subheading: 'Transformations'} + */ + function squeeze_(x, axis) { + const $x = convertToTensor(x, 'x', 'squeeze', 'string_or_numeric'); + return reshape$3($x, squeezeShape($x.shape, axis).newShape); + } + const squeeze = /* @__PURE__ */ op({ squeeze_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Stacks a list of rank-`R` `tf.Tensor`s into one rank-`(R+1)` `tf.Tensor`. + * + * ```js + * const a = tf.tensor1d([1, 2]); + * const b = tf.tensor1d([3, 4]); + * const c = tf.tensor1d([5, 6]); + * tf.stack([a, b, c]).print(); + * ``` + * + * @param tensors A list of tensor objects with the same shape and dtype. + * @param axis The axis to stack along. Defaults to 0 (the first dim). + * + * @doc {heading: 'Tensors', subheading: 'Slicing and Joining'} + */ + function stack_(tensors, axis = 0) { + const $tensors = convertToTensorArray(tensors, 'tensors', 'stack', 'string_or_numeric'); + assert$1($tensors.length >= 1, () => 'Pass at least one tensor to tf.stack'); + if ($tensors.length > 0) { + assert$1(axis <= $tensors[0].rank, () => 'Axis must be <= rank of the tensor'); + } + const inputs = $tensors; + const attrs = { axis }; + return ENGINE.runKernel(Pack, inputs, attrs); + } + const stack = /* @__PURE__ */ op({ stack_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes step of the input `tf.Tensor` element-wise: `x > 0 ? 1 : alpha` + * + * ```js + * const x = tf.tensor1d([0, 2, -1, -3]); + * + * x.step(.5).print(); // or tf.step(x, .5) + * ``` + * @param x The input tensor. + * @param alpha The gradient when input is negative. Defaults to 0. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function step_(x, alpha = 0.0) { + const $x = convertToTensor(x, 'x', 'step'); + const inputs = { x: $x }; + const attrs = { alpha }; + return ENGINE.runKernel(Step, inputs, attrs); + } + const step$2 = /* @__PURE__ */ op({ step_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Extracts a strided slice of a tensor. + * + * Roughly speaking, this op extracts a slice of size (end-begin)/stride from + * the given input tensor (x). Starting at the location specified by begin the + * slice continues by adding stride to the index until all dimensions are not + * less than end. Note that a stride can be negative, which causes a reverse + * slice. + * + * ```js + * const t = tf.tensor3d([1, 1, 1 ,2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6], + * [3, 2, 3]); + * t.stridedSlice([1, 0, 0], [2, 1, 3], [1, 1, 1]).print() // [[[3, 3, 3]]] + * t.stridedSlice([1, 0, 0], [2, 2, 3], [1, 1, 1]).print() // [[[3, 3, 3], + * // [4, 4, 4]]] + * t.stridedSlice([1, -1, 0], [2, -3, 3], [1, -1, 1]).print() // [[[4, 4, 4], + * // [3, 3, 3]]] + * ``` + * + * @param x The tensor to stride slice. + * @param begin The coordinates to start the slice from. + * @param end: The coordinates to end the slice at. + * @param strides: The size of the slice. + * @param beginMask: If the ith bit of beginMask is set, begin[i] is ignored + * and the fullest possible range in that dimension is used instead. + * @param endMask: If the ith bit of endMask is set, end[i] is ignored + * and the fullest possible range in that dimension is used instead. + * @param shrinkAxisMask: a bitmask where bit i implies that + * the ith specification should shrink the dimensionality. begin and end must + * imply a slice of size 1 in the dimension. + * + * @doc {heading: 'Operations', subheading: 'Slicing and Joining'} + */ + function stridedSlice_(x, begin, end, strides, beginMask = 0, endMask = 0, ellipsisMask = 0, newAxisMask = 0, shrinkAxisMask = 0) { + const $x = convertToTensor(x, 'x', 'stridedSlice', 'string_or_numeric'); + const inputs = { x: $x }; + const attrs = { + begin, + end, + strides, + beginMask, + endMask, + ellipsisMask, + newAxisMask, + shrinkAxisMask + }; + return ENGINE.runKernel(StridedSlice, inputs, attrs); + } + const stridedSlice$2 = /* @__PURE__ */ op({ stridedSlice_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes tan of the input `tf.Tensor` element-wise, `tan(x)` + * + * ```js + * const x = tf.tensor1d([0, Math.PI / 2, Math.PI * 3 / 4]); + * + * x.tan().print(); // or tf.tan(x) + * ``` + * @param x The input tensor. + * + * @doc {heading: 'Operations', subheading: 'Basic math'} + */ + function tan_(x) { + const $x = convertToTensor(x, 'x', 'tan', 'float32'); + const inputs = { x: $x }; + return ENGINE.runKernel(Tan, inputs); + } + const tan$2 = /* @__PURE__ */ op({ tan_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates rank-1 `tf.Tensor` with the provided values, shape and dtype. + * + * The same functionality can be achieved with `tf.tensor`, but in general + * we recommend using `tf.tensor1d` as it makes the code more readable. + * + * ```js + * tf.tensor1d([1, 2, 3]).print(); + * ``` + * + * @param values The values of the tensor. Can be array of numbers, + * or a `TypedArray`. + * @param dtype The data type. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function tensor1d(values, dtype) { + assertNonNull(values); + const inferredShape = inferShape(values, dtype); + if (inferredShape.length !== 1) { + throw new Error('tensor1d() requires values to be a flat/TypedArray'); + } + const shape = null; + return makeTensor(values, shape, inferredShape, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates rank-2 `tf.Tensor` with the provided values, shape and dtype. + * + * The same functionality can be achieved with `tf.tensor`, but in general + * we recommend using `tf.tensor2d` as it makes the code more readable. + * + * ```js + * // Pass a nested array. + * tf.tensor2d([[1, 2], [3, 4]]).print(); + * ``` + * ```js + * // Pass a flat array and specify a shape. + * tf.tensor2d([1, 2, 3, 4], [2, 2]).print(); + * ``` + * + * @param values The values of the tensor. Can be nested array of numbers, + * or a flat array, or a `TypedArray`. + * @param shape The shape of the tensor. If not provided, it is inferred from + * `values`. + * @param dtype The data type. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function tensor2d(values, shape, dtype) { + assertNonNull(values); + if (shape != null && shape.length !== 2) { + throw new Error('tensor2d() requires shape to have two numbers'); + } + const inferredShape = inferShape(values, dtype); + if (inferredShape.length !== 2 && inferredShape.length !== 1) { + throw new Error('tensor2d() requires values to be number[][] or flat/TypedArray'); + } + if (inferredShape.length === 1 && shape == null) { + throw new Error('tensor2d() requires shape to be provided when `values` ' + + 'are a flat/TypedArray'); + } + return makeTensor(values, shape, inferredShape, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates rank-3 `tf.Tensor` with the provided values, shape and dtype. + * + * The same functionality can be achieved with `tf.tensor`, but in general + * we recommend using `tf.tensor3d` as it makes the code more readable. + * + * ```js + * // Pass a nested array. + * tf.tensor3d([[[1], [2]], [[3], [4]]]).print(); + * ``` + * ```js + * // Pass a flat array and specify a shape. + * tf.tensor3d([1, 2, 3, 4], [2, 2, 1]).print(); + * ``` + * + * @param values The values of the tensor. Can be nested array of numbers, + * or a flat array, or a `TypedArray`. + * @param shape The shape of the tensor. If not provided, it is inferred from + * `values`. + * @param dtype The data type. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function tensor3d(values, shape, dtype) { + assertNonNull(values); + if (shape != null && shape.length !== 3) { + throw new Error('tensor3d() requires shape to have three numbers'); + } + const inferredShape = inferShape(values, dtype); + if (inferredShape.length !== 3 && inferredShape.length !== 1) { + throw new Error('tensor3d() requires values to be number[][][] or flat/TypedArray'); + } + if (inferredShape.length === 1 && shape == null) { + throw new Error('tensor3d() requires shape to be provided when `values` ' + + 'are a flat array'); + } + return makeTensor(values, shape, inferredShape, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates rank-4 `tf.Tensor` with the provided values, shape and dtype. + * + * The same functionality can be achieved with `tf.tensor`, but in general + * we recommend using `tf.tensor4d` as it makes the code more readable. + * + * ```js + * // Pass a nested array. + * tf.tensor4d([[[[1], [2]], [[3], [4]]]]).print(); + * ``` + * ```js + * // Pass a flat array and specify a shape. + * tf.tensor4d([1, 2, 3, 4], [1, 2, 2, 1]).print(); + * ``` + * + * @param values The values of the tensor. Can be nested array of numbers, + * or a flat array, or a `TypedArray`. + * @param shape The shape of the tensor. Optional. If not provided, + * it is inferred from `values`. + * @param dtype The data type. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function tensor4d(values, shape, dtype) { + assertNonNull(values); + if (shape != null && shape.length !== 4) { + throw new Error('tensor4d() requires shape to have four numbers'); + } + const inferredShape = inferShape(values, dtype); + if (inferredShape.length !== 4 && inferredShape.length !== 1) { + throw new Error('tensor4d() requires values to be number[][][][] or flat/TypedArray'); + } + if (inferredShape.length === 1 && shape == null) { + throw new Error('tensor4d() requires shape to be provided when `values` ' + + 'are a flat array'); + } + return makeTensor(values, shape, inferredShape, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates rank-5 `tf.Tensor` with the provided values, shape and dtype. + * + * The same functionality can be achieved with `tf.tensor`, but in general + * we recommend using `tf.tensor5d` as it makes the code more readable. + * + * ```js + * // Pass a nested array. + * tf.tensor5d([[[[[1],[2]],[[3],[4]]],[[[5],[6]],[[7],[8]]]]]).print(); + * ``` + * ```js + * // Pass a flat array and specify a shape. + * tf.tensor5d([1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 2, 2, 1]).print(); + * ``` + * + * @param values The values of the tensor. Can be nested array of numbers, + * or a flat array, or a `TypedArray`. + * @param shape The shape of the tensor. Optional. If not provided, + * it is inferred from `values`. + * @param dtype The data type. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function tensor5d(values, shape, dtype) { + assertNonNull(values); + if (shape != null && shape.length !== 5) { + throw new Error('tensor5d() requires shape to have five numbers'); + } + const inferredShape = inferShape(values, dtype); + if (inferredShape.length !== 5 && inferredShape.length !== 1) { + throw new Error('tensor5d() requires values to be ' + + 'number[][][][][] or flat/TypedArray'); + } + if (inferredShape.length === 1 && shape == null) { + throw new Error('tensor5d() requires shape to be provided when `values` ' + + 'are a flat array'); + } + return makeTensor(values, shape, inferredShape, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates rank-6 `tf.Tensor` with the provided values, shape and dtype. + * + * The same functionality can be achieved with `tf.tensor`, but in general + * we recommend using `tf.tensor6d` as it makes the code more readable. + * + * ```js + * // Pass a nested array. + * tf.tensor6d([[[[[[1],[2]],[[3],[4]]],[[[5],[6]],[[7],[8]]]]]]).print(); + * ``` + * ```js + * // Pass a flat array and specify a shape. + * tf.tensor6d([1, 2, 3, 4, 5, 6, 7, 8], [1, 1, 2, 2, 2, 1]).print(); + * ``` + * + * @param values The values of the tensor. Can be nested array of numbers, + * or a flat array, or a `TypedArray`. + * @param shape The shape of the tensor. Optional. If not provided, + * it is inferred from `values`. + * @param dtype The data type. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function tensor6d(values, shape, dtype) { + assertNonNull(values); + if (shape != null && shape.length !== 6) { + throw new Error('tensor6d() requires shape to have six numbers'); + } + const inferredShape = inferShape(values, dtype); + if (inferredShape.length !== 6 && inferredShape.length !== 1) { + throw new Error('tensor6d() requires values to be number[][][][][][] or ' + + 'flat/TypedArray'); + } + if (inferredShape.length === 1 && shape == null) { + throw new Error('tensor6d() requires shape to be provided when `values` ' + + 'are a flat array'); + } + shape = shape || + inferredShape; + return makeTensor(values, shape, inferredShape, dtype); + } + + /** + * Check whether updates.shape = indices.shape[:batchDim] + + * shape[sliceDim:] + * + * @param x The input tensor. + */ + function validateUpdateShape(shape, indices, updates) { + const sliceDim = (indices.rank > 1) ? indices.shape[indices.rank - 1] : 1; + const batchDim = (indices.rank > 1) ? indices.rank - 1 : 1; + const shapeError = 'Must have updates.shape = indices.shape[:batchDim] + ' + + `shape[sliceDim:], got updates.shape: ${updates.shape}` + + `, indices.shape: ${indices.shape}, shape: ${shape}` + + `, sliceDim: ${sliceDim}, and batchDim: ${batchDim}.`; + if (updates.rank < batchDim) { + throw new Error(shapeError + ` update.rank < ${batchDim}. `); + } + if (shape.length < sliceDim + (updates.rank - batchDim)) { + throw new Error(shapeError + + ` Output shape length < ${sliceDim + (updates.rank - batchDim)}`); + } + if (updates.rank !== batchDim + shape.length - sliceDim) { + throw new Error(shapeError + ` update.rank != ${batchDim + shape.length - sliceDim}`); + } + for (let d = 0; d < batchDim; ++d) { + if (updates.shape[d] !== indices.shape[d]) { + throw new Error(shapeError + + ` updates.shape[${d}] (${updates.shape[d]}) != indices.shape[${d}] (${indices.shape[d]}).`); + } + } + for (let d = 0; d < updates.rank - batchDim; ++d) { + if (updates.shape[d + batchDim] !== shape[d + sliceDim]) { + throw new Error(shapeError + + ` updates.shape[${d + batchDim}] (${updates.shape[d + batchDim]}) != shape[${d + batchDim}] (${shape[d + batchDim]})`); + } + } + } + /** + * Validate scatter nd inputs. + * + * @param update The tensor contains the update values. + * @param indices The tensor contains the indices for the update values. + * @param shape The shape of the output tensor. + */ + function validateInput$1(updates, indices, shape) { + if (indices.rank < 1) { + throw new Error('tf.scatterND() expects the indices to be rank 1 or higher,' + + ` but the rank was ${indices.rank}.`); + } + if (updates.rank < 1) { + throw new Error('tf.scatterND() expects the updates to be rank 1 or higher,' + + ` but the rank was ${updates.rank}.`); + } + if (indices.dtype !== 'int32') { + throw new Error(`The dtype of 'indices' should be int32, but got dtype: ${indices.dtype}`); + } + if (shape.length < 1) { + throw new Error(`Output rank must be greater or equal to 1, but got shape: ${shape}`); + } + if (shape.length === 0) { + if (indices.size === 0) { + throw new Error(`Indices specified for empty output. indices shape: ${indices.shape}`); + } + if (updates.size === 0) { + throw new Error(`Updates specified for empty output. updates shape: ${updates.shape}`); + } + } + validateUpdateShape(shape, indices, updates); + } + /** + * Calculate the shape information for the output. + * + * @param update The tensor contains the update values. + * @param indices The tensor contains the indices for the update values. + * @param shape The shape of the output tensor. + * + * @returns ScatterShapeInfo + */ + function calculateShapes(updates, indices, shape) { + // Calculate the number of dimensions in indices + const indicesRank = indices.shape.length; + const sliceRank = (indicesRank > 1) ? indices.shape[indicesRank - 1] : 1; + // Calculate the number of elements that make up each slice of our updated + // tensor. This allows us to work with flattened tensors and copy over whole + // slices at a time. + const totalNd = shape.length; + let sliceSize = 1; + for (let i = sliceRank; i < totalNd; ++i) { + sliceSize *= shape[i]; + } + const safeSliceDim = (sliceRank < 1) ? 1 : sliceRank; + const numUpdates = sizeFromShape(indices.shape) / safeSliceDim; + const strides = [...computeStrides(shape.slice(0, sliceRank)), 1]; + const outputSize = sizeFromShape(shape); + return { sliceRank, numUpdates, sliceSize, strides, outputSize }; + } + + var scatter_nd_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + calculateShapes: calculateShapes, + validateInput: validateInput$1, + validateUpdateShape: validateUpdateShape + }); + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a new tensor by applying sparse updates to individual + * values or slices to the passed in tensor according to + * indices. This operator is the similar to scatterNd op, except that the + * udpates are scattered on an existing tensor (as opposed to a zero-tensor). + * + * If indices contains duplicates, then we pick the last update for the index. + * + * If an out of bound index is found on CPU, an error is returned. + * + * Warning: There are some GPU specific semantics for this operation. + * - If an out of bound index is found, the index is ignored. + * - The order in which updates are applied is nondeterministic, so the output + * will be nondeterministic if indices contains duplicates. + * ```js + * const shape = [8]; + * const tensor = tf.ones(shape); + * const indices = tf.tensor2d([4, 3, 1, 7], [4, 1], 'int32'); + * const updates = tf.tensor1d([9, 10, 11, 12]); + * + * tf.tensorScatterUpdate(tensor, indices, updates).print(); + * //[1, 11, 1, 10, 9, 1, 1, 12] + * ``` + * + * @param tensor A Tensor. Tensor to copy/update. + * @param indices The tensor contains the indices into the output tensor, must + * have at least 2 axes: (num_updates, index_depth). + * @param updates The tensor contains the value for the indices. + * + * @doc {heading: 'Operations', subheading: 'Slicing and Joining'} + */ + function tensorScatterUpdate_(tensor, indices, updates) { + const $tensor = convertToTensor(tensor, 'tensor', 'tensorScatterupdate'); + const $indices = convertToTensor(indices, 'indices', 'tensorScatterupdate', 'int32'); + const $updates = convertToTensor(updates, 'updates', 'tensorScatterupdate'); + validateInput$1($updates, $indices, $tensor.shape); + if ($tensor.dtype !== $updates.dtype) { + throw new Error(`tensor and updates must have the same dtype, instead they are ${$tensor.dtype} and ${$updates.dtype}.`); + } + const inputs = { + tensor: $tensor, + indices: $indices, + updates: $updates + }; + const attrs = {}; + // tslint:disable-next-line: no-unnecessary-type-assertion + return ENGINE.runKernel(TensorScatterUpdate, inputs, attrs); + } + const tensorScatterUpdate$2 = op({ tensorScatterUpdate_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Finds the values and indices of the `k` largest entries along the last + * dimension. + * + * If the input is a vector (rank=1), finds the k largest entries in the vector + * and outputs their values and indices as vectors. Thus values[j] is the j-th + * largest entry in input, and its index is indices[j]. + * For higher rank inputs, computes the top k entries along the last dimension. + * + * If two elements are equal, the lower-index element appears first. + * + * ```js + * const a = tf.tensor2d([[1, 5], [4, 3]]); + * const {values, indices} = tf.topk(a); + * values.print(); + * indices.print(); + * ``` + * @param x 1-D or higher `tf.Tensor` with last dimension being at least `k`. + * @param k Number of top elements to look for along the last dimension. + * @param sorted If true, the resulting `k` elements will be sorted by the + * values in descending order. + * + * @doc {heading: 'Operations', subheading: 'Evaluation'} + */ + function topk_(x, k = 1, sorted = true) { + const $x = convertToTensor(x, 'x', 'topk'); + if ($x.rank === 0) { + throw new Error('topk() expects the input to be of rank 1 or higher'); + } + const lastDim = $x.shape[$x.shape.length - 1]; + if (k < 0) { + throw new Error(`'k' passed to topk() must be >= 0 but got ${k}`); + } + if (k > lastDim) { + throw new Error(`'k' passed to topk() must be <= the last dimension (${lastDim}) ` + + `but got ${k}`); + } + const inputs = { x: $x }; + const attrs = { k, sorted }; + const [values, indices] = ENGINE.runKernel(TopK, inputs, attrs); + return { values, indices }; + } + const topk = /* @__PURE__ */ op({ topk_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a `tf.Tensor` with values sampled from a truncated normal + * distribution. + * + * ```js + * tf.truncatedNormal([2, 2]).print(); + * ``` + * + * The generated values follow a normal distribution with specified mean and + * standard deviation, except that values whose magnitude is more than 2 + * standard deviations from the mean are dropped and re-picked. + * + * @param shape An array of integers defining the output tensor shape. + * @param mean The mean of the normal distribution. + * @param stdDev The standard deviation of the normal distribution. + * @param dtype The data type of the output tensor. + * @param seed The seed for the random number generator. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function truncatedNormal_(shape, mean = 0, stdDev = 1, dtype, seed) { + assertNonNegativeIntegerDimensions(shape); + if (dtype != null && dtype === 'bool') { + throw new Error(`Unsupported data type $ { dtype }`); + } + const randGauss = new MPRandGauss(mean, stdDev, dtype, true /* truncated */, seed); + const res = buffer(shape, dtype); + for (let i = 0; i < res.values.length; i++) { + res.values[i] = randGauss.nextValue(); + } + return res.toTensor(); + } + const truncatedNormal$1 = /* @__PURE__ */ op({ truncatedNormal_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Finds unique elements along an axis of a tensor. + * + * It returns a tensor `values` containing all of the unique elements along the + * `axis` of the given tensor `x` in the same order that they occur along the + * `axis` in `x`; `x` does not need to be sorted. It also returns a tensor + * `indices` the same size as the number of the elements in `x` along the `axis` + * dimension. It contains the index in the unique output `values`. + * + * ```js + * // A 1-D tensor + * const a = tf.tensor1d([1, 1, 2, 4, 4, 4, 7, 8, 8]); + * const {values, indices} = tf.unique(a); + * values.print(); // [1, 2, 4, 7, 8,] + * indices.print(); // [0, 0, 1, 2, 2, 2, 3, 4, 4] + * ``` + * + * ```js + * // A 2-D tensor with axis=0 + * // + * // 'a' is: [[1, 0, 0], + * // [1, 0, 0], + * // [2, 0, 0]] + * const a = tf.tensor2d([[1, 0, 0], [1, 0, 0], [2, 0, 0]]); + * const {values, indices} = tf.unique(a, 0) + * values.print(); // [[1, 0, 0], + * // [2, 0, 0]] + * indices.print(); // [0, 0, 1] + * ``` + * + * ```js + * // A 2-D tensor with axis=1 + * // + * // 'a' is: [[1, 0, 0], + * // [1, 0, 0], + * // [2, 0, 0]] + * const a = tf.tensor2d([[1, 0, 0], [1, 0, 0], [2, 0, 0]]); + * const {values, indices} = tf.unique(a, 1) + * values.print(); // [[1, 0], + * // [1, 0], + * // [2, 0]] + * indices.print(); // [0, 1, 1] + * ``` + * @param x A tensor (int32, string, bool). + * @param axis The axis of the tensor to find the unique elements. + * @returns [uniqueElements, indices] (see above for details) + * + * @doc {heading: 'Operations', subheading: 'Evaluation'} + */ + function unique_(x, axis = 0) { + const $x = convertToTensor(x, 'x', 'unique', 'string_or_numeric'); + assert$1($x.rank > 0, () => 'The input tensor must be at least 1D'); + const inputs = { x: $x }; + const attrs = { axis }; + const [values, indices] = ENGINE.runKernel(Unique, inputs, attrs); + return { values, indices }; + } + const unique$3 = /* @__PURE__ */ op({ unique_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the sum along segments of a `tf.Tensor`. + * + * ```js + * const x = tf.tensor1d([1, 2, 3, 4]); + * const segmentIds = tf.tensor1d([1, 2, 0, 1], 'int32'); + * const numSegments = 3; + * + * x.unsortedSegmentSum(segmentIds, numSegments).print() + * //or tf.unsortedSegmentSum(x, segmentIds, numSegments) + * ``` + * @param x The `tf.Tensor` that will be summed along its segments. + * @param segmentIds A `tf.Tensor1D` whose rank is equal to the rank of `x`'s + * dimension along the `axis`. Maps each element of `x` to a segment. + * @param numSegments The number of distinct `segmentIds`. + * + * @doc {heading: 'Operations', subheading: 'Segment'} + */ + function unsortedSegmentSum_(x, segmentIds, numSegments) { + const $x = convertToTensor(x, 'x', 'unsortedSegmentSum'); + const $segmentIds = convertToTensor(segmentIds, 'segmentIds', 'unsortedSegmentSum', 'int32'); + assert$1(isInt(numSegments), () => 'numSegments must be of dtype int'); + const inputs = { x: $x, segmentIds: $segmentIds }; + const attrs = { numSegments }; + return ENGINE.runKernel(UnsortedSegmentSum, inputs, attrs); + } + const unsortedSegmentSum$2 = /* @__PURE__ */ op({ unsortedSegmentSum_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Unstacks a `tf.Tensor` of rank-`R` into a list of rank-`(R-1)` `tf.Tensor`s. + * + * ```js + * const a = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * + * tf.unstack(a).forEach(tensor => tensor.print()); + * ``` + * + * @param x A tensor object. + * @param axis The axis to unstack along. Defaults to 0 (the first dim). + * + * @doc {heading: 'Tensors', subheading: 'Slicing and Joining'} + */ + function unstack_(x, axis = 0) { + const $x = convertToTensor(x, 'x', 'unstack', 'string_or_numeric'); + assert$1(axis >= -$x.shape.length && axis < $x.shape.length, () => `Axis = ${axis} is not in [-${$x.shape.length}, ${$x.shape.length})`); + const inputs = { value: $x }; + const attrs = { axis }; + return ENGINE.runKernel(Unpack, inputs, attrs); + } + const unstack = /* @__PURE__ */ op({ unstack_ }); + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Searches for where a value would go in a sorted sequence. + * + * This is not a method for checking containment (like javascript in). + * + * The typical use case for this operation is "binning", "bucketing", or + * "discretizing". The values are assigned to bucket-indices based on the edges + * listed in 'sortedSequence'. This operation returns the bucket-index for each + * value. + * + * The index returned corresponds to the first edge greater than the value. + * + * The axis is not settable for this operation. It always operates on the + * innermost dimension (axis=-1). The operation will accept any number of outer + * dimensions. + * + * Note: This operation assumes that 'upperBound' is sorted along the + * innermost axis, maybe using 'sort(..., axis=-1)'. If the sequence is not + * sorted no error is raised and the content of the returned tensor is not well + * defined. + * + * ```js + * const seq = tf.tensor1d([0, 3, 9, 10, 10]); + * const values = tf.tensor1d([0, 4, 10]); + * const result = tf.upperBound(seq, values); + * result.print(); // [1, 2, 5] + * ``` + * @param sortedSequence: N-D. Sorted sequence. + * @param values: N-D. Search values. + * @return An N-D int32 tensor the size of values containing the result of + * applying upper bound to each value. The result is not a global index to + * the entire Tensor, but the index in the last dimension. + * @doc {heading: 'Operations', subheading: 'Evaluation'} + */ + function upperBound$1(sortedSequence, values) { + return searchSorted$2(sortedSequence, values, 'right'); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a new variable with the provided initial value. + * ```js + * const x = tf.variable(tf.tensor([1, 2, 3])); + * x.assign(tf.tensor([4, 5, 6])); + * + * x.print(); + * ``` + * + * @param initialValue Initial value for the tensor. + * @param trainable If true, optimizers are allowed to update it. + * @param name Name of the variable. Defaults to a unique id. + * @param dtype If set, initialValue will be converted to the given type. + * + * @doc {heading: 'Tensors', subheading: 'Creation'} + */ + function variable$1(initialValue, trainable = true, name, dtype) { + return ENGINE.makeVariable(initialValue, trainable, name, dtype); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function whereImpl$2(condShape, condVals) { + const indices = []; + for (let i = 0; i < condVals.length; i++) { + if (condVals[i]) { + indices.push(i); + } + } + const inBuffer = buffer(condShape, 'int32'); + const out = buffer([indices.length, condShape.length], 'int32'); + for (let i = 0; i < indices.length; i++) { + const loc = inBuffer.indexToLoc(indices[i]); + const offset = i * condShape.length; + out.values.set(loc, offset); + } + return out.toTensor(); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns the coordinates of true elements of condition. + * + * The coordinates are returned in a 2-D tensor where the first dimension (rows) + * represents the number of true elements, and the second dimension (columns) + * represents the coordinates of the true elements. Keep in mind, the shape of + * the output tensor can vary depending on how many true values there are in + * input. Indices are output in row-major order. The resulting tensor has the + * shape `[numTrueElems, condition.rank]`. + * + * This is analogous to calling the python `tf.where(cond)` without an x or y. + * + * ```js + * const cond = tf.tensor1d([false, false, true], 'bool'); + * const result = await tf.whereAsync(cond); + * result.print(); + * ``` + * + * @doc {heading: 'Operations', subheading: 'Logical'} + */ + async function whereAsync_(condition) { + const $condition = convertToTensor(condition, 'condition', 'whereAsync', 'bool'); + const vals = await $condition.data(); + const res = whereImpl$2($condition.shape, vals); + if (condition !== $condition) { + $condition.dispose(); + } + return res; + } + const whereAsync = whereAsync_; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Apply boolean mask to tensor. + * + * ```js + * const tensor = tf.tensor2d([1, 2, 3, 4, 5, 6], [3, 2]); + * const mask = tf.tensor1d([1, 0, 1], 'bool'); + * const result = await tf.booleanMaskAsync(tensor, mask); + * result.print(); + * ``` + * + * @param tensor N-D tensor. + * @param mask K-D boolean tensor, K <= N and K must be known statically. + * @param axis A 0-D int Tensor representing the axis in tensor to mask from. + * By default, axis is 0 which will mask from the first dimension. + * Otherwise K + axis <= N. + * + * @doc {heading: 'Tensors', subheading: 'Slicing and Joining'} + */ + async function booleanMaskAsync_(tensor, mask, axis) { + const $tensor = convertToTensor(tensor, 'tensor', 'boolMask'); + const $mask = convertToTensor(mask, 'mask', 'boolMask', 'bool'); + const axisFrom = axis == null ? 0 : axis; + const maskDim = $mask.rank; + const tensorShape = $tensor.shape; + assert$1(maskDim > 0, () => 'mask cannot be scalar'); + assertShapesMatch(tensorShape.slice(axisFrom, axisFrom + maskDim), $mask.shape, `mask's shape must match the first K dimensions of tensor's shape,`); + let leadingSize = 1; + for (let i = axisFrom; i < axisFrom + maskDim; i++) { + leadingSize *= tensorShape[i]; + } + const targetTensorShape = tensorShape.slice(0, axisFrom) + .concat([leadingSize], tensorShape.slice(axisFrom + maskDim)); + const reshapedTensor = reshape$3($tensor, targetTensorShape); + const reshapedMask = reshape$3($mask, [-1]); + const positivePositions = await whereAsync(reshapedMask); + const indices = squeeze(positivePositions, [1]); + const res = gather$1(reshapedTensor, indices, axisFrom); + // Ensure no memory leak. + if (tensor !== $tensor) { + $tensor.dispose(); + } + if (mask !== $mask) { + $mask.dispose(); + } + indices.dispose(); + reshapedTensor.dispose(); + reshapedMask.dispose(); + positivePositions.dispose(); + return res; + } + const booleanMaskAsync = booleanMaskAsync_; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Transposes the `tf.Tensor`. Permutes the dimensions according to `perm`. + * + * The returned `tf.Tensor`'s dimension `i` will correspond to the input + * dimension `perm[i]`. If `perm` is not given, it is set to `[n-1...0]`, + * where `n` is the rank of the input `tf.Tensor`. Hence by default, this + * operation performs a regular matrix transpose on 2-D input `tf.Tensor`s. + * + * ```js + * const a = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3]); + * + * a.transpose().print(); // or tf.transpose(a) + * ``` + * + * @param x The tensor to transpose. + * @param perm The permutation of the dimensions of a. + * @param conjugate Will conjugate complex input if true. + * + * @doc {heading: 'Operations', subheading: 'Matrices'} + */ + function transpose_(x, perm, conjugate) { + const $x = convertToTensor(x, 'x', 'transpose'); + if (perm == null) { + perm = $x.shape.map((s, i) => i).reverse(); + } + assert$1($x.rank === perm.length, () => `Error in transpose: rank of input ${$x.rank} ` + + `must match length of perm ${perm}.`); + perm.forEach(axis => { + assert$1(axis >= 0 && axis < $x.rank, () => `All entries in 'perm' must be between 0 and ${$x.rank - 1}` + + ` but got ${perm}`); + }); + if ($x.rank <= 1) { + return $x.clone(); + } + const inputs = { x: $x }; + const attrs = { perm }; + if ($x.dtype === 'complex64') { + return tidy(() => { + let $real = real$2($x); + let $imag = imag$2($x); + $real = ENGINE.runKernel(Transpose, { x: $real }, attrs); + $imag = ENGINE.runKernel(Transpose, { x: $imag }, attrs); + if (conjugate) { + $imag = neg$2($imag); + } + return complex$2($real, $imag); + }); + } + return ENGINE.runKernel(Transpose, inputs, attrs); + } + const transpose$2 = /* @__PURE__ */ op({ transpose_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Compute the moving average of a variable. + * + * Without zeroDebias, the moving average operation is defined by: + * `v += delta` + * where + * `delta = (1 - decay) * (x - v)` + * + * With zeroDebias (default), the `delta` term is scaled to debias the + * effect of the (assumed) zero-initialization of `v`. + * `delta /= (1 - decay ^ step)` + * + * For more details on the zero-debiasing algorithm, see: + * https://arxiv.org/abs/1412.6980 + * + * Note that this function is completely stateless and does not keep track of + * step count. The step count needs to be maintained by the caller and passed + * in as `step`. + * + * @param v The current moving average value. + * @param x New input value, must have the same shape and dtype as `v`. + * @param decay The decay factor. Typical values are 0.95 and 0.99. + * @param step Step count. + * @param zeroDebias: Whether zeroDebias is to be performed (default: `true`). + * @returns The new moving average value. + * + * @doc {heading: 'Operations', subheading: 'Moving Average'} + */ + function movingAverage_(v, x, decay, step, zeroDebias = true) { + const $v = convertToTensor(v, 'v', 'movingAverage'); + const $x = convertToTensor(x, 'x', 'movingAverage'); + const $decay = convertToTensor(decay, 'decay', 'movingAverage'); + assertTypesMatch($v, $x); + assert$1(arraysEqual($v.shape, $x.shape), () => 'Shape mismatch in v and x'); + const one = scalar(1); + const oneMinusDecay = sub$2(one, $decay); + let update = mul(sub$2($x, $v), oneMinusDecay); + if (zeroDebias) { + assert$1(step != null, () => 'When using zeroDebias: true, step is required.'); + const $step = convertToTensor(step, 'step', 'movingAverage'); + update = div$1(update, sub$2(one, pow$3($decay, $step))); + } + return add$3($v, update); + } + const movingAverage = /* @__PURE__ */ op({ movingAverage_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates a new tensor by applying sparse updates to individual + * values or slices within a zero tensor of the given shape tensor according to + * indices. This operator is the inverse of the `tf.gatherND` operator which + * extracts values or slices from a given tensor. + * + * ```js + * const indices = tf.tensor2d([4, 3, 1, 7], [4, 1], 'int32'); + * const updates = tf.tensor1d([9, 10, 11, 12]); + * const shape = [8]; + * tf.scatterND(indices, updates, shape).print() //[0, 11, 0, 10, 9, 0, 0, 12] + * ``` + * + * @param indices The tensor contains the indices into the output tensor. + * @param updates The tensor contains the value for the indices. + * @param shape: The shape of the output tensor. + * + * @doc {heading: 'Operations', subheading: 'Slicing and Joining'} + */ + function scatterND_(indices, updates, shape) { + assertNonNegativeIntegerDimensions(shape); + const $indices = convertToTensor(indices, 'indices', 'scatterND', 'int32'); + const $updates = convertToTensor(updates, 'updates', 'scatterND'); + validateInput$1($updates, $indices, shape); + const inputs = { indices: $indices, updates: $updates }; + const attrs = { shape }; + // tslint:disable-next-line: no-unnecessary-type-assertion + return ENGINE.runKernel(ScatterNd, inputs, attrs); + } + const scatterND = /* @__PURE__ */ op({ scatterND_ }); + + /** + * Validate sparseToDense inputs. + * + * @param sparseIndices A 0-D, 1-D, or 2-D Tensor of type int32. + * sparseIndices[i] contains the complete index where sparseValues[i] will be + * placed. + * @param sparseValues A 0-D or 1-D Tensor. Values + * corresponding to each row of sparseIndices, or a scalar value to be used for + * all sparse indices. + * @param outputShape number[]. Shape of the dense output tensor. + * @param validateIndices boolean. indice validation is not supported, error + * will be thrown if it is set. + */ + function validateInput(sparseIndices, sparseValues, outputShape, defaultValues) { + if (sparseIndices.dtype !== 'int32') { + throw new Error('tf.sparseToDense() expects the indices to be int32 type,' + + ` but the dtype was ${sparseIndices.dtype}.`); + } + if (sparseIndices.rank > 2) { + throw new Error('sparseIndices should be a scalar, vector, or matrix,' + + ` but got shape ${sparseIndices.shape}.`); + } + const numElems = sparseIndices.rank > 0 ? sparseIndices.shape[0] : 1; + const numDims = sparseIndices.rank > 1 ? sparseIndices.shape[1] : 1; + if (outputShape.length !== numDims) { + throw new Error('outputShape has incorrect number of elements:,' + + ` ${outputShape.length}, should be: ${numDims}.`); + } + const numValues = sparseValues.size; + if (!(sparseValues.rank === 0 || + sparseValues.rank === 1 && numValues === numElems)) { + throw new Error('sparseValues has incorrect shape ' + + `${sparseValues.shape}, should be [] or [${numElems}]`); + } + if (sparseValues.dtype !== defaultValues.dtype) { + throw new Error('sparseValues.dtype must match defaultValues.dtype'); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts a sparse representation into a dense tensor. + * + * Builds an array dense with shape outputShape such that: + * + * // If sparseIndices is scalar + * dense[i] = (i == sparseIndices ? sparseValues : defaultValue) + * + * // If sparseIndices is a vector, then for each i + * dense[sparseIndices[i]] = sparseValues[i] + * + * // If sparseIndices is an n by d matrix, then for each i in [0, n) + * dense[sparseIndices[i][0], ..., sparseIndices[i][d-1]] = sparseValues[i] + * All other values in dense are set to defaultValue. If sparseValues is a + * scalar, all sparse indices are set to this single value. + * + * If indices are repeated the final value is summed over all values for those + * indices. + * + * ```js + * const indices = tf.tensor1d([4, 5, 6, 1, 2, 3], 'int32'); + * const values = tf.tensor1d([10, 11, 12, 13, 14, 15], 'float32'); + * const shape = [8]; + * tf.sparseToDense(indices, values, shape).print(); + * ``` + * + * @param sparseIndices A 0-D, 1-D, or 2-D Tensor of type int32. + * sparseIndices[i] contains the complete index where sparseValues[i] will be + * placed. + * @param sparseValues A 0-D or 1-D Tensor. Values + * corresponding to each row of sparseIndices, or a scalar value to be used for + * all sparse indices. + * @param outputShape Shape of the dense output tensor. The type is inferred. + * @param defaultValue Scalar. Value to set for indices not specified in + * sparseIndices. Defaults to zero. + * + * @doc {heading: 'Operations', subheading: 'Normalization'} + */ + function sparseToDense_(sparseIndices, sparseValues, outputShape, defaultValue = 0) { + assertNonNegativeIntegerDimensions(outputShape); + const $sparseIndices = convertToTensor(sparseIndices, 'sparseIndices', 'sparseToDense', 'int32'); + const $sparseValues = convertToTensor(sparseValues, 'sparseValues', 'sparseToDense', 'string_or_numeric'); + const $defaultValue = convertToTensor(defaultValue, 'defaultValue', 'sparseToDense', $sparseValues.dtype); + validateInput($sparseIndices, $sparseValues, outputShape, $defaultValue); + const inputs = { + sparseIndices: $sparseIndices, + sparseValues: $sparseValues, + defaultValue: $defaultValue + }; + const attrs = { outputShape }; + return ENGINE.runKernel(SparseToDense, inputs, attrs); + } + const sparseToDense$2 = /* @__PURE__ */ op({ sparseToDense_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Gather slices from input tensor into a Tensor with shape specified by + * `indices`. + * + * `indices` is a K-dimensional integer tensor, best thought of as a + * (K-1)-dimensional tensor of indices into input, where each element defines a + * slice of input: + * output[\\(i_0, ..., i_{K-2}\\)] = input[indices[\\(i_0, ..., i_{K-2}\\)]] + * + * Whereas in `tf.gather`, `indices` defines slices into the first dimension of + * input, in `tf.gatherND`, `indices` defines slices into the first N dimensions + * of input, where N = indices.shape[-1]. + * + * The last dimension of indices can be at most the rank of input: + * indices.shape[-1] <= input.rank + * + * The last dimension of `indices` corresponds to elements + * (if indices.shape[-1] == input.rank) or slices + * (if indices.shape[-1] < input.rank) along dimension indices.shape[-1] of + * input. + * The output tensor has shape + * indices.shape[:-1] + input.shape[indices.shape[-1]:] + * + * Note that on CPU, if an out of bound index is found, an error is returned. On + * GPU, if an out of bound index is found, a 0 is stored in the corresponding + * output value. + * + * ```js + * const indices = tf.tensor2d([0, 1, 1, 0], [2,2], 'int32'); + * const input = tf.tensor2d([9, 10, 11, 12], [2, 2]); + * tf.gatherND(input, indices).print() // [10, 11] + * ``` + * + * @param x The tensor from which to gather values. + * @param indices Index tensor, must be of type int32. + * + * @doc {heading: 'Operations', subheading: 'Slicing and Joining'} + */ + function gatherND_(x, indices) { + const $indices = convertToTensor(indices, 'indices', 'gatherND', 'int32'); + const $x = convertToTensor(x, 'x', 'gatherND', 'string_or_numeric'); + const inputs = { params: $x, indices: $indices }; + return ENGINE.runKernel(GatherNd, inputs); + } + const gatherND = /* @__PURE__ */ op({ gatherND_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Normalize noise shape based on provided tensor and noise shape. + * + * @param x Tensor. + * @param noiseShape The shape for the randomly generated keep/drop flags, as + * an array of numbers. Optional. + * @returns Normalized noise shape. + */ + function getNoiseShape(x, noiseShape) { + if (noiseShape == null) { + return x.shape.slice(); + } + if (arraysEqual(x.shape, noiseShape)) { + return noiseShape; + } + if (x.shape.length === noiseShape.length) { + const newDimension = []; + for (let i = 0; i < x.shape.length; i++) { + if (noiseShape[i] == null && x.shape[i] != null) { + newDimension.push(x.shape[i]); + } + else { + newDimension.push(noiseShape[i]); + } + } + return newDimension; + } + return noiseShape; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes dropout. + * + * ```js + * const x = tf.tensor1d([1, 2, 2, 1]); + * const rate = 0.75; + * const output = tf.dropout(x, rate); + * output.print(); + * ``` + * + * @param x A floating point Tensor or TensorLike. + * @param rate A float in the range [0, 1). The probability that each element + * of x is discarded. + * @param noiseShape An array of numbers of type int32, representing the + * shape for randomly generated keep/drop flags. If the noiseShape has null + * value, it will be automatically replaced with the x's relative dimension + * size. Optional. + * @param seed Used to create random seeds. Optional. + * @returns A Tensor of the same shape of x. + * + * @doc {heading: 'Operations', subheading: 'Dropout'} + */ + function dropout_(x, rate, noiseShape, seed) { + const $x = convertToTensor(x, 'x', 'dropout'); + assert$1($x.dtype === 'float32', () => `x has to be a floating point tensor since it's going to be ` + + `scaled, but got a ${$x.dtype} tensor instead.`); + assert$1(rate >= 0 && rate < 1, () => `rate must be a float in the range [0, 1), but got ${rate}.`); + if (rate === 0) { + return x instanceof Tensor ? $x.clone() : $x; + } + const $noiseShape = getNoiseShape($x, noiseShape); + const keepProb = 1 - rate; + const multiplier = div$1(floor$2(add$3(randomUniform$1($noiseShape, 0, 1, 'float32', seed), keepProb)), keepProb); + return mul($x, multiplier); + } + const dropout$2 = /* @__PURE__ */ op({ dropout_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function enclosingPowerOfTwo(value) { + // Return 2**N for integer N such that 2**N >= value. + return Math.floor(Math.pow(2, Math.ceil(Math.log(value) / Math.log(2.0)))); + } + function cosineWindow(windowLength, a, b) { + const even = 1 - windowLength % 2; + const newValues = new Float32Array(windowLength); + for (let i = 0; i < windowLength; ++i) { + const cosArg = (2.0 * Math.PI * i) / (windowLength + even - 1); + newValues[i] = a - b * Math.cos(cosArg); + } + return tensor1d(newValues, 'float32'); + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Returns whether the targets are in the top K predictions. + * + * ```js + * const predictions = tf.tensor2d([[20, 10, 40, 30], [30, 50, -20, 10]]); + * const targets = tf.tensor1d([2, 0]); + * const precision = await tf.inTopKAsync(predictions, targets); + * precision.print(); + * ``` + * @param predictions 2-D or higher `tf.Tensor` with last dimension being + * at least `k`. + * @param targets 1-D or higher `tf.Tensor`. + * @param k Optional Number of top elements to look at for computing precision, + * default to 1. + * + * @doc {heading: 'Operations', subheading: 'Evaluation'} + */ + async function inTopKAsync_(predictions, targets, k = 1) { + const $predictions = convertToTensor(predictions, 'predictions', 'inTopK'); + const $targets = convertToTensor(targets, 'targets', 'inTopK'); + assert$1($predictions.rank > 1, () => 'inTopK() expects the predictions to be of rank 2 or higher, ' + + `but got ${$predictions.rank}`); + assert$1($predictions.rank - 1 === $targets.rank, () => `predictions rank should be 1 larger than ` + + `targets rank, but got predictions rank ` + + `${$predictions.rank} and targets rank ${$targets.rank}`); + assertShapesMatch($predictions.shape.slice(0, $predictions.shape.length - 1), $targets.shape, `predictions's shape should be align with the targets' shape, ` + + 'except the last dimension.'); + const lastDim = $predictions.shape[$predictions.shape.length - 1]; + assert$1(k > 0 && k <= lastDim, () => `'k' passed to inTopK() must be > 0 && <= the predictions last ` + + `dimension (${lastDim}), but got ${k}`); + const predictionsVals = await $predictions.data(); + const targetsVals = await $targets.data(); + // Reshape predictionsVals into a 2d tensor [batch, lastDim] + // and look up topK along lastDim. + const [batch, size] = [predictionsVals.length / lastDim, lastDim]; + const precision = getTypedArrayFromDType('bool', batch); + for (let b = 0; b < batch; b++) { + const offset = b * size; + const vals = predictionsVals.subarray(offset, offset + size); + const valAndInd = []; + for (let i = 0; i < vals.length; i++) { + valAndInd.push({ value: vals[i], index: i }); + } + valAndInd.sort((a, b) => b.value - a.value); + precision[b] = 0; + for (let i = 0; i < k; i++) { + if (valAndInd[i].index === targetsVals[b]) { + precision[b] = 1; + break; + } + } + } + if (predictions !== $predictions) { + $predictions.dispose(); + } + if (targets !== $targets) { + $targets.dispose(); + } + // Output precision has the same shape as targets. + return tensor(precision, $targets.shape, 'bool'); + } + const inTopKAsync = inTopKAsync_; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the derivative of the filter of a 2D convolution. + * + * @param x The input tensor, of rank 4 or rank 3 of shape + * [batch, height, width, inChannels]. If rank 3, batch of 1 is assumed. + * @param dy The dy image, of rank 4 or rank 3, of shape + * [batch, height, width, outDepth]. If rank 3, batch of 1 is assumed. + * @param filterShape The shape of the filter, length 4, + * [filterHeight, filterWidth, inDepth, outDepth]. + * @param strides The strides of the convolution: [strideHeight, + * strideWidth]. + * @param pad A string from: 'same', 'valid'. The type of padding algorithm + * used in the forward prop of the op. + * @param dataFormat: An optional string from: "NHWC", "NCHW". Defaults to + * "NHWC". Specify the data format of the input and output data. With the + * default format "NHWC", the data is stored in the order of: [batch, + * height, width, channels]. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + */ + function conv2DBackpropFilter_(x, dy, filterShape, strides, pad, dataFormat = 'NHWC', dimRoundingMode) { + let x4D = x; + if (x.rank === 3) { + x4D = reshape$3(x, [1, x.shape[0], x.shape[1], x.shape[2]]); + } + let dy4D = dy; + if (dy4D.rank === 3) { + dy4D = reshape$3(dy, [1, dy.shape[0], dy.shape[1], dy.shape[2]]); + } + assert$1(x4D.rank === 4, () => `Error in conv2dDerFilter: input must be rank 4, but got shape ` + + `${x4D.shape}.`); + assert$1(dy4D.rank === 4, () => `Error in conv2dDerFilter: dy must be rank 4, but got shape ` + + `${dy4D.shape}.`); + assert$1(filterShape.length === 4, () => `Error in conv2dDerFilter: filterShape must be length 4, but got ` + + `${filterShape}.`); + const inDepth = dataFormat === 'NHWC' ? x4D.shape[3] : x4D.shape[1]; + const outDepth = dataFormat === 'NHWC' ? dy4D.shape[3] : dy4D.shape[1]; + assert$1(inDepth === filterShape[2], () => `Error in conv2dDerFilter: depth of input ${inDepth}) must ` + + `match input depth in filter (${filterShape[2]}.`); + assert$1(outDepth === filterShape[3], () => `Error in conv2dDerFilter: depth of dy (${outDepth}) must ` + + `match output depth for filter (${filterShape[3]}).`); + checkPadOnDimRoundingMode('conv2dDerFilter', pad, dimRoundingMode); + const inputs = { x: x4D, dy: dy4D }; + const attrs = { strides, pad, dataFormat, dimRoundingMode, filterShape }; + // tslint:disable-next-line: no-unnecessary-type-assertion + return ENGINE.runKernel(Conv2DBackpropFilter, inputs, attrs); + } + const conv2DBackpropFilter$2 = /* @__PURE__ */ op({ conv2DBackpropFilter_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Returns gradient for fused activation. + function getFusedDyActivation(dy, y, activation) { + if (activation == null || activation === 'linear') { + return dy; + } + if (activation === 'relu') { + return mul(dy, step$2(y)); + } + throw new Error(`Cannot compute gradient for fused activation ${activation}.`); + } + // Returns gradient for fused bias. + function getFusedBiasGradient(bias, dyActivation) { + let res = dyActivation; + const reduceAxes = getReductionAxes(bias.shape, dyActivation.shape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(res, bias.shape); + } + function applyActivation$1(x, activation, preluActivationWeights, leakyreluAlpha) { + if (activation === 'linear') { + return x; + } + else if (activation === 'relu') { + return relu$2(x); + } + else if (activation === 'elu') { + return elu$4(x); + } + else if (activation === 'relu6') { + return relu6$2(x); + } + else if (activation === 'prelu') { + return prelu$3(x, preluActivationWeights); + } + else if (activation === 'leakyrelu') { + return leakyRelu$2(x, leakyreluAlpha); + } + else if (activation === 'sigmoid') { + return sigmoid$2(x); + } + throw new Error(`Unknown fused activation ${activation}.`); + } + // Whether we should call fused ops. + const shouldFuse = (gradientDepth, activation) => { + const gradientMode = gradientDepth > 0; + return !gradientMode || activation === 'linear'; + }; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes a 2D convolution over the input x, optionally fused with adding a + * bias and applying an activation. + * + * ```js + * const inputDepth = 2; + * const inShape = [2, 2, 2, inputDepth]; + * const outputDepth = 2; + * const fSize = 1; + * const pad = 0; + * const strides = 1; + * + * const x = tf.tensor4d( [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + * 16], inShape); + * const w = tf.tensor4d([-1, 1, -2, 0.5], [fSize, fSize, inputDepth, + * outputDepth]); + * + * tf.fused.conv2d({ x, filter: w, strides, pad, dataFormat: 'NHWC', + * dilations: [1, 1], bias: tf.scalar(5), activation: 'relu' }).print(); + * ``` + * + * @param obj An object with the following properties: + * @param x The input tensor, of rank 4 or rank 3, of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is + * assumed. + * @param filter The filter, rank 4, of shape + * `[filterHeight, filterWidth, inDepth, outDepth]`. + * @param strides The strides of the convolution: `[strideHeight, + * strideWidth]`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid` output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dataFormat An optional string from: "NHWC", "NCHW". Defaults to + * "NHWC". Specify the data format of the input and output data. With the + * default format "NHWC", the data is stored in the order of: [batch, + * height, width, channels]. Only "NHWC" is currently supported. + * @param dilations The dilation rates: `[dilationHeight, dilationWidth]` + * in which we sample input values across the height and width dimensions + * in atrous convolution. Defaults to `[1, 1]`. If `dilations` is a single + * number, then `dilationHeight == dilationWidth`. If it is greater than + * 1, then all values of `strides` must be 1. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * @param bias Tensor to be added to the result. + * @param activation Name of activation kernel (defaults to `linear`) to be + * applied + * after biasAdd. + * @param preluActivationWeights Tensor of prelu weights to be applied as part + * of a `prelu` activation, typically the same shape as `x`. + * @param leakyreluAlpha Optional. Alpha to be applied as part of a `leakyrelu` + * activation. + */ + function fusedConv2d_({ x, filter, strides, pad, dataFormat = 'NHWC', dilations = [1, 1], dimRoundingMode, bias, activation = 'linear', preluActivationWeights, leakyreluAlpha }) { + activation = activation || 'linear'; + if (shouldFuse(ENGINE.state.gradientDepth, activation) === false) { + // TODO: Transpose bias and preluActivationWeights properly for NCHW + // format before computation. + assert$1(dataFormat === 'NHWC', () => `Error in fused conv2d: got dataFormat of ${dataFormat} but ` + + `only NHWC is currently supported for the case of gradient depth ` + + `is 0 and the activation is not linear.`); + let result = conv2d$4(x, filter, strides, pad, dataFormat, dilations, dimRoundingMode); + if (bias != null) { + result = add$3(result, bias); + } + return applyActivation$1(result, activation, preluActivationWeights, leakyreluAlpha); + } + const $x = convertToTensor(x, 'x', 'conv2d', 'float32'); + const $filter = convertToTensor(filter, 'filter', 'conv2d', 'float32'); + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + reshapedTo4D = true; + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + } + assert$1(x4D.rank === 4, () => `Error in fused conv2d: input must be rank 4, but got rank ` + + `${x4D.rank}.`); + assert$1($filter.rank === 4, () => `Error in fused conv2d: filter must be rank 4, but got rank ` + + `${$filter.rank}.`); + checkPadOnDimRoundingMode('fused conv2d', pad, dimRoundingMode); + const inputChannels = dataFormat === 'NHWC' ? x4D.shape[3] : x4D.shape[1]; + assert$1($filter.shape[2] === inputChannels, () => `Error in conv2d: depth of input (${inputChannels}) must match ` + + `input depth for filter ${$filter.shape[2]}.`); + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in conv2D: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + const convInfo = computeConv2DInfo(x4D.shape, $filter.shape, strides, dilations, pad, dimRoundingMode); + let $bias; + if (bias != null) { + $bias = convertToTensor(bias, 'bias', 'fused conv2d'); + [$bias] = makeTypesMatch($bias, $x); + // According to TensorFlow, the bias is supposed be a 1-D tensor or a + // scalar. + // + // 3-D or 4-D bias is not disabled for NHWC format, because they are + // currently being used in some cases. For examplem in our code base, + // https://github.com/tensorflow/tfjs/blob/b53bd47e880367ae57493f0ea628abaf08db2d5d/tfjs-core/src/ops/fused/fused_conv2d_test.ts#L1972. + if (dataFormat === 'NHWC') { + assertAndGetBroadcastShape(convInfo.outShape, $bias.shape); + } + else { + assert$1($bias.shape.length <= 1, () => `Error in fused conv2d: only supports scalar or 1-D Tensor ` + + `bias for NCHW format but got the bias of ` + + `rank-${$bias.shape.length}.`); + assert$1($bias.shape.length === 0 || $bias.shape[0] === convInfo.outChannels || + $bias.shape[0] === 1, () => `Error in fused conv2d: bias shape (${$bias.shape}) is not ` + + `compatible with the number of output channels ` + + `(${convInfo.outChannels})`); + } + } + let $preluActivationWeights; + if (preluActivationWeights != null) { + // PReLU's activation weights could be a scalar, a 1-D tensor or a 3-D + // tensor. + const alphaShape = preluActivationWeights.shape; + assert$1(alphaShape.length <= 1 || alphaShape.length === 3, () => `Error in fused conv2d: only supports scalar, 1-D Tensor or ` + + `3-D Tensor PReLU activation weights but got a tensor of ` + + `rank-${alphaShape.length}.`); + if (alphaShape.length === 1) { + // Whether the data format is NCHW or NHWC, the 1-D PReLU activation + // weights tensor should be aligned with the output channels of conv2d + // result. + assert$1(alphaShape[0] === 1 || alphaShape[0] === convInfo.outChannels, () => `Error in fused conv2d: PReLU activation weights ` + + `(${alphaShape}) is not compatible with the number of output ` + + `channels (${convInfo.outChannels}).`); + } + else if (alphaShape.length === 3) { + // Whether the data format is NCHW or NHWC, the PReLU activation weights + // tensor should has the compatible shape with the result of conv2d. + try { + assertAndGetBroadcastShape(alphaShape, convInfo.outShape); + } + catch (e) { + const errMsg = `Error in fused conv2d: PReLU activation weights (${alphaShape}) ` + + `is not compatible with the output shape of the conv2d ` + + `(${convInfo.outShape}).`; + throw Error(errMsg); + } + } + $preluActivationWeights = convertToTensor(preluActivationWeights, 'prelu weights', 'fused conv2d'); + } + const grad = (dy, saved) => { + assert$1(dataFormat === 'NHWC', () => `Error in gradient of fused conv2D: got dataFormat of ${dataFormat} but only NHWC is currently supported.`); + const [$filter, x4D, y, $bias] = saved; + const dyActivation = getFusedDyActivation(dy, y, activation); + assert$1(tupleValuesAreOne(dilations), () => 'Error in gradient of fused conv2D: ' + + `dilation rates greater than 1 ` + + `are not yet supported in gradients. Got dilations '${dilations}'`); + const xDer = conv2DBackpropInput$2(x4D.shape, dyActivation, $filter, strides, pad); + const filterDer = conv2DBackpropFilter$2(x4D, dyActivation, $filter.shape, strides, pad); + const der = [xDer, filterDer]; + if ($bias != null) { + const biasDer = getFusedBiasGradient($bias, dyActivation); + der.push(biasDer); + } + return der; + }; + const inputs = { + x: x4D, + filter: $filter, + bias: $bias, + preluActivationWeights: $preluActivationWeights + }; + const attrs = { + strides, + pad, + dataFormat, + dilations, + dimRoundingMode, + activation, + leakyreluAlpha + }; + // Depending on the the params passed in we will have different number of + // inputs and thus a a different number of elements in the gradient. + if (bias == null) { + const customOp = customGrad((x4D, filter, save) => { + let res = + // tslint:disable-next-line: no-unnecessary-type-assertion + ENGINE.runKernel(FusedConv2D, inputs, attrs); + save([filter, x4D, res]); + if (reshapedTo4D) { + // tslint:disable-next-line: no-unnecessary-type-assertion + res = reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return { value: res, gradFunc: grad }; + }); + return customOp(x4D, $filter); + } + else { + const customOpWithBias = customGrad((x4D, filter, bias, save) => { + let res = ENGINE.runKernel(FusedConv2D, inputs, attrs); + save([filter, x4D, res, bias]); + if (reshapedTo4D) { + // tslint:disable-next-line: no-unnecessary-type-assertion + res = reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return { value: res, gradFunc: grad }; + }); + return customOpWithBias(x4D, $filter, $bias); + } + } + const conv2d$3 = /* @__PURE__ */ op({ fusedConv2d_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthwiseConv2dNativeBackpropFilter_(x, dy, filterShape, strides, pad, dilations = [1, 1], dimRoundingMode) { + let x4D = x; + if (x.rank === 3) { + x4D = reshape$3(x, [1, x.shape[0], x.shape[1], x.shape[2]]); + } + let dy4D = dy; + if (dy4D.rank === 3) { + dy4D = reshape$3(dy, [1, dy.shape[0], dy.shape[1], dy.shape[2]]); + } + const inputs = { x: x4D, dy: dy4D }; + const attrs = { strides, pad, dimRoundingMode, dilations, filterShape }; + // tslint:disable-next-line: no-unnecessary-type-assertion + return ENGINE.runKernel(DepthwiseConv2dNativeBackpropFilter, inputs, attrs); + } + const depthwiseConv2dNativeBackpropFilter$2 = op({ depthwiseConv2dNativeBackpropFilter_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthwiseConv2dNativeBackpropInput_(xShape, dy, filter, strides, pad, dilations = [1, 1], dimRoundingMode) { + let dy4D = dy; + let reshapedTo4D = false; + if (dy.rank === 3) { + reshapedTo4D = true; + dy4D = reshape$3(dy, [1, dy.shape[0], dy.shape[1], dy.shape[2]]); + } + const inputs = { dy: dy4D, filter }; + const attrs = { strides, pad, dimRoundingMode, dilations, inputShape: xShape }; + const res = + // tslint:disable-next-line: no-unnecessary-type-assertion + ENGINE.runKernel(DepthwiseConv2dNativeBackpropInput, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const depthwiseConv2dNativeBackpropInput$2 = op({ depthwiseConv2dNativeBackpropInput_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes depthwise 2D convolution, optionally fused with adding a + * bias and applying an activation. + * + * Given a 4D `input` array and a `filter` array of shape + * `[filterHeight, filterWidth, inChannels, channelMultiplier]` containing + * `inChannels` convolutional filters of depth 1, this op applies a + * different filter to each input channel (expanding from 1 channel to + * `channelMultiplier` channels for each), then concatenates the results + * together. The output has `inChannels * channelMultiplier` channels. + * + * See + * [https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d]( + * https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d) + * for more details. + * + * @param obj An object with the following properties: + * @param x The input tensor, of rank 4 or rank 3, of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is + * assumed. + * @param filter The filter tensor, rank 4, of shape + * `[filterHeight, filterWidth, inChannels, channelMultiplier]`. + * @param strides The strides of the convolution: `[strideHeight, + * strideWidth]`. If strides is a single number, then `strideHeight == + * strideWidth`. + * @param pad The type of padding algorithm. + * - `same` and stride 1: output will be of same size as input, + * regardless of filter size. + * - `valid`: output will be smaller than input if filter is larger + * than 1x1. + * - For more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dilations The dilation rates: `[dilationHeight, dilationWidth]` + * in which we sample input values across the height and width dimensions + * in atrous convolution. Defaults to `[1, 1]`. If `rate` is a single + * number, then `dilationHeight == dilationWidth`. If it is greater than + * 1, then all values of `strides` must be 1. + * @param dataFormat: An optional string from: "NHWC", "NCHW". Defaults to + * "NHWC". Specify the data format of the input and output data. With the + * default format "NHWC", the data is stored in the order of: [batch, + * height, width, channels]. Only "NHWC" is currently supported. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + * @param bias Tensor to be added to the result. + * @param activation Name of activation kernel (defaults to `linear`). + * @param preluActivationWeights Tensor of prelu weights to be applied as part + * of a `prelu` activation, typically the same shape as `x`. + * @param leakyreluAlpha Optional. Alpha to be applied as part of a `leakyrelu` + * activation. + */ + function fusedDepthwiseConv2d_({ x, filter, strides, pad, dataFormat = 'NHWC', dilations = [1, 1], dimRoundingMode, bias, activation = 'linear', preluActivationWeights, leakyreluAlpha }) { + if (shouldFuse(ENGINE.state.gradientDepth, activation) === false) { + let result = depthwiseConv2d$3(x, filter, strides, pad, dataFormat, dilations, dimRoundingMode); + if (bias != null) { + result = add$3(result, bias); + } + return applyActivation$1(result, activation, preluActivationWeights, leakyreluAlpha); + } + const $x = convertToTensor(x, 'x', 'depthwiseConv2d', 'float32'); + const $filter = convertToTensor(filter, 'filter', 'depthwiseConv2d', 'float32'); + let x4D = $x; + let reshapedTo4D = false; + if ($x.rank === 3) { + reshapedTo4D = true; + x4D = reshape$3($x, [1, $x.shape[0], $x.shape[1], $x.shape[2]]); + } + assert$1(x4D.rank === 4, () => `Error in fused depthwiseConv2d: input must be rank 4, but got ` + + `rank ${x4D.rank}.`); + assert$1($filter.rank === 4, () => `Error in fused depthwiseConv2d: filter must be rank 4, ` + + `but got rank ${$filter.rank}.`); + assert$1(x4D.shape[3] === $filter.shape[2], () => `Error in fused depthwiseConv2d: number of input channels ` + + `(${x4D.shape[3]}) must match the inChannels dimension in ` + + `filter ${$filter.shape[2]}.`); + if (dilations == null) { + dilations = [1, 1]; + } + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in fused depthwiseConv2d: Either strides or dilations must ' + + `be 1. Got strides ${strides} and dilations '${dilations}'`); + checkPadOnDimRoundingMode('fused depthwiseConv2d', pad, dimRoundingMode); + const convInfo = computeConv2DInfo(x4D.shape, $filter.shape, strides, dilations, pad, dimRoundingMode, true /* depthwise */); + let $bias; + if (bias != null) { + $bias = convertToTensor(bias, 'bias', 'fused conv2d'); + [$bias] = makeTypesMatch($bias, $x); + assertAndGetBroadcastShape(convInfo.outShape, $bias.shape); + } + let $preluActivationWeights; + if (preluActivationWeights != null) { + $preluActivationWeights = convertToTensor(preluActivationWeights, 'prelu weights', 'fused depthwiseConv2d'); + } + const grad = (dy, saved) => { + assert$1(tupleValuesAreOne(dilations), () => 'Error in gradient of fused depthwiseConv2d: dilation rates ' + + `greater than 1 are not yet supported. Got dilations ` + + `'${dilations}'`); + const [$filter, x4D, y, bias] = saved; + const dyActivation = getFusedDyActivation(dy, y, activation); + const xDer = depthwiseConv2dNativeBackpropInput$2(x4D.shape, dyActivation, $filter, strides, pad, dilations, dimRoundingMode); + const filterDer = depthwiseConv2dNativeBackpropFilter$2(x4D, dyActivation, $filter.shape, strides, pad, dilations, dimRoundingMode); + if (bias != null) { + const biasDer = getFusedBiasGradient($bias, dyActivation); + return [xDer, filterDer, biasDer]; + } + return [xDer, filterDer]; + }; + const inputs = { + x: x4D, + filter: $filter, + bias: $bias, + preluActivationWeights: $preluActivationWeights + }; + const attrs = { + strides, + pad, + dataFormat, + dilations, + dimRoundingMode, + activation, + leakyreluAlpha + }; + // Depending on the the params passed in we will have different number of + // inputs and thus a a different number of elements in the gradient. + if (bias == null) { + const customOp = customGrad((x4D, filter, save) => { + // tslint:disable-next-line: no-unnecessary-type-assertion + let res = ENGINE.runKernel(FusedDepthwiseConv2D, inputs, attrs); + save([filter, x4D, res]); + if (reshapedTo4D) { + // tslint:disable-next-line: no-unnecessary-type-assertion + res = reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return { value: res, gradFunc: grad }; + }); + return customOp(x4D, $filter); + } + else { + const customOpWithBias = customGrad((x4D, filter, bias, save) => { + // tslint:disable-next-line: no-unnecessary-type-assertion + let res = ENGINE.runKernel(FusedDepthwiseConv2D, inputs, attrs); + save([filter, x4D, res, bias]); + if (reshapedTo4D) { + // tslint:disable-next-line: no-unnecessary-type-assertion + res = reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return { value: res, gradFunc: grad }; + }); + return customOpWithBias(x4D, $filter, $bias); + } + } + const depthwiseConv2d$2 = /* @__PURE__ */ op({ fusedDepthwiseConv2d_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the dot product of two matrices with optional activation and bias. + * + * ```js + * const a = tf.tensor2d([-1, -2], [1, 2]); + * const b = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * const bias = tf.tensor2d([1, 2], [1, 2]); + * + * tf.fused.matMul({a, b, bias, activation: 'relu'}).print(); + * ``` + * + * @param obj An object with the following properties: + * - `a` First matrix in dot product operation. + * - `b` Second matrix in dot product operation. + * - `transposeA` If true, `a` is transposed before multiplication. + * - `transposeB` If true, `b` is transposed before multiplication. + * - `bias` Matrix to be added to the result. + * - `activation` Name of activation kernel (defaults to `linear`). + * - `preluActivationWeights` Tensor of prelu weights. + * - `leakyreluAlpha` Alpha of leakyrelu. + */ + function fusedMatMul_({ a, b, transposeA = false, transposeB = false, bias, activation = 'linear', preluActivationWeights, leakyreluAlpha = 0.2, }) { + if (shouldFuse(ENGINE.state.gradientDepth, activation) === false) { + let result = matMul$1(a, b, transposeA, transposeB); + if (bias != null) { + result = add$3(result, bias); + } + return applyActivation$1(result, activation, preluActivationWeights, leakyreluAlpha); + } + let $a = convertToTensor(a, 'a', 'fused matMul'); + let $b = convertToTensor(b, 'b', 'fused matMul'); + [$a, $b] = makeTypesMatch($a, $b); + const innerShapeA = transposeA ? $a.shape[$a.rank - 2] : $a.shape[$a.rank - 1]; + const innerShapeB = transposeB ? $b.shape[$b.rank - 1] : $b.shape[$b.rank - 2]; + const outerShapeA = transposeA ? $a.shape[$a.rank - 1] : $a.shape[$a.rank - 2]; + const outerShapeB = transposeB ? $b.shape[$b.rank - 2] : $b.shape[$b.rank - 1]; + const outerDimsA = $a.shape.slice(0, -2); + const outerDimsB = $b.shape.slice(0, -2); + const batchDimA = sizeFromShape(outerDimsA); + const batchDimB = sizeFromShape(outerDimsB); + assert$1(innerShapeA === innerShapeB, () => `Error in fused matMul: inner shapes (${innerShapeA}) and (` + + `${innerShapeB}) of Tensors with shapes ${$a.shape} and ` + + `${$b.shape} and transposeA=${transposeA}` + + ` and transposeB=${transposeB} must match.`); + const outShapeOuterDims = assertAndGetBroadcastShape($a.shape.slice(0, -2), $b.shape.slice(0, -2)); + const outShape = outShapeOuterDims.concat([outerShapeA, outerShapeB]); + const a3D = transposeA ? + reshape$3($a, [batchDimA, innerShapeA, outerShapeA]) : + reshape$3($a, [batchDimA, outerShapeA, innerShapeA]); + const b3D = transposeB ? + reshape$3($b, [batchDimB, outerShapeB, innerShapeB]) : + reshape$3($b, [batchDimB, innerShapeB, outerShapeB]); + let $bias; + if (bias != null) { + $bias = convertToTensor(bias, 'bias', 'fused matMul'); + [$bias] = makeTypesMatch($bias, $a); + assertAndGetBroadcastShape(outShape, $bias.shape); + } + let $preluActivationWeights; + if (preluActivationWeights != null) { + $preluActivationWeights = convertToTensor(preluActivationWeights, 'prelu weights', 'fused matMul'); + } + const grad = (dy, saved) => { + const [a3D, b3D, y, $bias] = saved; + // we reshape dy because the result of the forward is not + // necessarily going to be a 3d tensor due to a reshape done at the end of + // the customOp. + const dyActivation = getFusedDyActivation(reshape$3(dy, y.shape), y, activation); + let aDer; + let bDer; + if (!transposeA && !transposeB) { + aDer = matMul$1(dyActivation, b3D, false, true); + bDer = matMul$1(a3D, dyActivation, true, false); + } + else if (!transposeA && transposeB) { + aDer = matMul$1(dyActivation, b3D, false, false); + bDer = matMul$1(dyActivation, a3D, true, false); + } + else if (transposeA && !transposeB) { + aDer = matMul$1(b3D, dyActivation, false, true); + bDer = matMul$1(a3D, dyActivation, false, false); + } + else { + aDer = matMul$1(b3D, dyActivation, true, true); + bDer = matMul$1(dyActivation, a3D, true, true); + } + if (bias != null) { + const biasDer = getFusedBiasGradient($bias, dyActivation); + return [aDer, bDer, biasDer]; + } + else { + return [aDer, bDer]; + } + }; + const inputs = { + a: a3D, + b: b3D, + bias: $bias, + preluActivationWeights: $preluActivationWeights + }; + const attrs = { transposeA, transposeB, activation, leakyreluAlpha }; + // Depending on the the params passed in we will have different number of + // inputs and thus a a different number of elements in the gradient. + if (bias == null) { + const customOp = customGrad((a3D, b3D, save) => { + const res = + // tslint:disable-next-line: no-unnecessary-type-assertion + ENGINE.runKernel(_FusedMatMul, inputs, attrs); + save([a3D, b3D, res]); + return { value: reshape$3(res, outShape), gradFunc: grad }; + }); + return customOp(a3D, b3D); + } + else { + const customOpWithBias = customGrad((a3D, b3D, $bias, save) => { + const res = + // tslint:disable-next-line: no-unnecessary-type-assertion + ENGINE.runKernel(_FusedMatMul, inputs, attrs); + save([a3D, b3D, res, $bias]); + return { value: reshape$3(res, outShape), gradFunc: grad }; + }); + return customOpWithBias(a3D, b3D, $bias); + } + } + const matMul = /* @__PURE__ */ op({ fusedMatMul_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + var fused_ops = /*#__PURE__*/Object.freeze({ + __proto__: null, + conv2d: conv2d$3, + depthwiseConv2d: depthwiseConv2d$2, + matMul: matMul + }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Generate a hamming window. + * + * See: https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows + * + * ```js + * tf.signal.hammingWindow(10).print(); + * ``` + * @param The length of window + * + * @doc {heading: 'Operations', subheading: 'Signal', namespace: 'signal'} + */ + function hammingWindow_(windowLength) { + return cosineWindow(windowLength, 0.54, 0.46); + } + const hammingWindow = /* @__PURE__ */ op({ hammingWindow_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Generate a Hann window. + * + * See: https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows + * + * ```js + * tf.signal.hannWindow(10).print(); + * ``` + * @param The length of window + * + * @doc {heading: 'Operations', subheading: 'Signal', namespace: 'signal'} + */ + function hannWindow_(windowLength) { + return cosineWindow(windowLength, 0.5, 0.5); + } + const hannWindow = /* @__PURE__ */ op({ hannWindow_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Expands input into frames of frameLength. + * Slides a window size with frameStep. + * + * ```js + * tf.signal.frame([1, 2, 3], 2, 1).print(); + * ``` + * @param signal The input tensor to be expanded + * @param frameLength Length of each frame + * @param frameStep The frame hop size in samples. + * @param padEnd Whether to pad the end of signal with padValue. + * @param padValue A number to use where the input signal does + * not exist when padEnd is True. + * + * @doc {heading: 'Operations', subheading: 'Signal', namespace: 'signal'} + */ + function frame_(signal, frameLength, frameStep, padEnd = false, padValue = 0) { + let start = 0; + const output = []; + while (start + frameLength <= signal.size) { + output.push(slice$2(signal, start, frameLength)); + start += frameStep; + } + if (padEnd) { + while (start < signal.size) { + const padLen = (start + frameLength) - signal.size; + const pad = concat$2([ + slice$2(signal, start, frameLength - padLen), fill$2([padLen], padValue) + ]); + output.push(pad); + start += frameStep; + } + } + if (output.length === 0) { + return tensor2d([], [0, frameLength]); + } + return reshape$3(concat$2(output), [output.length, frameLength]); + } + const frame = /* @__PURE__ */ op({ frame_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the Short-time Fourier Transform of signals + * See: https://en.wikipedia.org/wiki/Short-time_Fourier_transform + * + * ```js + * const input = tf.tensor1d([1, 1, 1, 1, 1]) + * tf.signal.stft(input, 3, 1).print(); + * ``` + * @param signal 1-dimensional real value tensor. + * @param frameLength The window length of samples. + * @param frameStep The number of samples to step. + * @param fftLength The size of the FFT to apply. + * @param windowFn A callable that takes a window length and returns 1-d tensor. + * + * @doc {heading: 'Operations', subheading: 'Signal', namespace: 'signal'} + */ + function stft_(signal, frameLength, frameStep, fftLength, windowFn = hannWindow) { + if (fftLength == null) { + fftLength = enclosingPowerOfTwo(frameLength); + } + const framedSignal = frame(signal, frameLength, frameStep); + const windowedSignal = mul(framedSignal, windowFn(frameLength)); + return rfft(windowedSignal, fftLength); + } + const stft = /* @__PURE__ */ op({ stft_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Extracts crops from the input image tensor and resizes them using bilinear + * sampling or nearest neighbor sampling (possibly with aspect ratio change) + * to a common output size specified by cropSize. + * + * @param image 4d tensor of shape `[batch,imageHeight,imageWidth, depth]`, + * where imageHeight and imageWidth must be positive, specifying the + * batch of images from which to take crops + * @param boxes 2d float32 tensor of shape `[numBoxes, 4]`. Each entry is + * `[y1, x1, y2, x2]`, where `(y1, x1)` and `(y2, x2)` are the normalized + * coordinates of the box in the `boxInd[i]`th image in the batch + * @param boxInd 1d int32 tensor of shape `[numBoxes]` with values in range + * `[0, batch)` that specifies the image that the `i`-th box refers to. + * @param cropSize 1d int32 tensor of 2 elements `[cropHeigh, cropWidth]` + * specifying the size to which all crops are resized to. + * @param method Optional string from `'bilinear' | 'nearest'`, + * defaults to bilinear, which specifies the sampling method for resizing + * @param extrapolationValue A threshold for deciding when to remove boxes based + * on score. Defaults to 0. + * @return A 4D tensor of the shape `[numBoxes,cropHeight,cropWidth,depth]` + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function cropAndResize_(image, boxes, boxInd, cropSize, method = 'bilinear', extrapolationValue = 0) { + const $image = convertToTensor(image, 'image', 'cropAndResize'); + const $boxes = convertToTensor(boxes, 'boxes', 'cropAndResize', 'float32'); + const $boxInd = convertToTensor(boxInd, 'boxInd', 'cropAndResize', 'int32'); + const numBoxes = $boxes.shape[0]; + assert$1($image.rank === 4, () => 'Error in cropAndResize: image must be rank 4,' + + `but got rank ${$image.rank}.`); + assert$1($boxes.rank === 2 && $boxes.shape[1] === 4, () => `Error in cropAndResize: boxes must be have size [${numBoxes},4] ` + + `but had shape ${$boxes.shape}.`); + assert$1($boxInd.rank === 1 && $boxInd.shape[0] === numBoxes, () => `Error in cropAndResize: boxInd must be have size [${numBoxes}] ` + + `but had shape ${$boxes.shape}.`); + assert$1(cropSize.length === 2, () => `Error in cropAndResize: cropSize must be of length 2, but got ` + + `length ${cropSize.length}.`); + assert$1(cropSize[0] >= 1 && cropSize[1] >= 1, () => `cropSize must be atleast [1,1], but was ${cropSize}`); + assert$1(method === 'bilinear' || method === 'nearest', () => `method must be bilinear or nearest, but was ${method}`); + const inputs = { image: $image, boxes: $boxes, boxInd: $boxInd }; + const attrs = { method, extrapolationValue, cropSize }; + const res = ENGINE.runKernel(CropAndResize, inputs, attrs); + return res; + } + const cropAndResize$3 = /* @__PURE__ */ op({ cropAndResize_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Flips the image left to right. Currently available in the CPU, WebGL, and + * WASM backends. + * + * @param image 4d tensor of shape `[batch, imageHeight, imageWidth, depth]`. + */ + /** @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} */ + function flipLeftRight_(image) { + const $image = convertToTensor(image, 'image', 'flipLeftRight', 'float32'); + assert$1($image.rank === 4, () => 'Error in flipLeftRight: image must be rank 4,' + + `but got rank ${$image.rank}.`); + const inputs = { image: $image }; + const res = ENGINE.runKernel(FlipLeftRight, inputs, {}); + return res; + } + const flipLeftRight = /* @__PURE__ */ op({ flipLeftRight_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts images from grayscale to RGB format. + * + * @param image A grayscale tensor to convert. The `image`'s last dimension must + * be size 1 with at least a two-dimensional shape. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function grayscaleToRGB_(image) { + const $image = convertToTensor(image, 'image', 'grayscaleToRGB'); + const lastDimsIdx = $image.rank - 1; + const lastDims = $image.shape[lastDimsIdx]; + assert$1($image.rank >= 2, () => 'Error in grayscaleToRGB: images must be at least rank 2, ' + + `but got rank ${$image.rank}.`); + assert$1(lastDims === 1, () => 'Error in grayscaleToRGB: last dimension of a grayscale image ' + + `should be size 1, but got size ${lastDims}.`); + const reps = new Array($image.rank); + reps.fill(1, 0, lastDimsIdx); + reps[lastDimsIdx] = 3; + return tile$3($image, reps); + } + const grayscaleToRGB = /* @__PURE__ */ op({ grayscaleToRGB_ }); + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts images from RGB format to grayscale. + * + * @param image A RGB tensor to convert. The `image`'s last dimension must + * be size 3 with at least a two-dimensional shape. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function rgbToGrayscale_(image) { + const $image = convertToTensor(image, 'image', 'RGBToGrayscale'); + const lastDimsIdx = $image.rank - 1; + const lastDims = $image.shape[lastDimsIdx]; + assert$1($image.rank >= 2, () => 'Error in RGBToGrayscale: images must be at least rank 2, ' + + `but got rank ${$image.rank}.`); + assert$1(lastDims === 3, () => 'Error in RGBToGrayscale: last dimension of an RGB image ' + + `should be size 3, but got size ${lastDims}.`); + // Remember original dtype so we can convert back if needed + const origDtype = $image.dtype; + const fltImage = cast$3($image, 'float32'); + const rgbWeights = tensor1d([0.2989, 0.5870, 0.1140]); + let grayFloat; + switch ($image.rank) { + case 2: + grayFloat = einsum$2('ij,j->i', fltImage, rgbWeights); + break; + case 3: + grayFloat = einsum$2('ijk,k->ij', fltImage, rgbWeights); + break; + case 4: + grayFloat = einsum$2('ijkl,l->ijk', fltImage, rgbWeights); + break; + case 5: + grayFloat = einsum$2('ijklm,m->ijkl', fltImage, rgbWeights); + break; + case 6: + grayFloat = einsum$2('ijklmn,n->ijklm', fltImage, rgbWeights); + break; + default: + throw new Error('Not a valid tensor rank.'); + } + grayFloat = expandDims$3(grayFloat, -1); + return cast$3(grayFloat, origDtype); + } + const rgbToGrayscale = /* @__PURE__ */ op({ rgbToGrayscale_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Rotates the input image tensor counter-clockwise with an optional offset + * center of rotation. Currently available in the CPU, WebGL, and WASM backends. + * + * @param image 4d tensor of shape `[batch, imageHeight, imageWidth, depth]`. + * @param radians The amount of rotation. + * @param fillValue The value to fill in the empty space leftover + * after rotation. Can be either a single grayscale value (0-255), or an + * array of three numbers `[red, green, blue]` specifying the red, green, + * and blue channels. Defaults to `0` (black). + * @param center The center of rotation. Can be either a single value (0-1), or + * an array of two numbers `[centerX, centerY]`. Defaults to `0.5` (rotates + * the image around its center). + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function rotateWithOffset_(image, radians, fillValue = 0, center = 0.5) { + const $image = convertToTensor(image, 'image', 'rotateWithOffset', 'float32'); + assert$1($image.rank === 4, () => 'Error in rotateWithOffset: image must be rank 4,' + + `but got rank ${$image.rank}.`); + const inputs = { image: $image }; + const attrs = { radians, fillValue, center }; + const res = ENGINE.runKernel(RotateWithOffset, inputs, attrs); + return res; + } + const rotateWithOffset = /* @__PURE__ */ op({ rotateWithOffset_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function nonMaxSuppSanityCheck(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma) { + if (iouThreshold == null) { + iouThreshold = 0.5; + } + if (scoreThreshold == null) { + scoreThreshold = Number.NEGATIVE_INFINITY; + } + if (softNmsSigma == null) { + softNmsSigma = 0.0; + } + const numBoxes = boxes.shape[0]; + maxOutputSize = Math.min(maxOutputSize, numBoxes); + assert$1(0 <= iouThreshold && iouThreshold <= 1, () => `iouThreshold must be in [0, 1], but was '${iouThreshold}'`); + assert$1(boxes.rank === 2, () => `boxes must be a 2D tensor, but was of rank '${boxes.rank}'`); + assert$1(boxes.shape[1] === 4, () => `boxes must have 4 columns, but 2nd dimension was ${boxes.shape[1]}`); + assert$1(scores.rank === 1, () => 'scores must be a 1D tensor'); + assert$1(scores.shape[0] === numBoxes, () => `scores has incompatible shape with boxes. Expected ${numBoxes}, ` + + `but was ${scores.shape[0]}`); + assert$1(0 <= softNmsSigma && softNmsSigma <= 1, () => `softNmsSigma must be in [0, 1], but was '${softNmsSigma}'`); + return { maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Performs non maximum suppression of bounding boxes based on + * iou (intersection over union). + * + * @param boxes a 2d tensor of shape `[numBoxes, 4]`. Each entry is + * `[y1, x1, y2, x2]`, where `(y1, x1)` and `(y2, x2)` are the corners of + * the bounding box. + * @param scores a 1d tensor providing the box scores of shape `[numBoxes]`. + * @param maxOutputSize The maximum number of boxes to be selected. + * @param iouThreshold A float representing the threshold for deciding whether + * boxes overlap too much with respect to IOU. Must be between [0, 1]. + * Defaults to 0.5 (50% box overlap). + * @param scoreThreshold A threshold for deciding when to remove boxes based + * on score. Defaults to -inf, which means any score is accepted. + * @return A 1D tensor with the selected box indices. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function nonMaxSuppression_(boxes, scores, maxOutputSize, iouThreshold = 0.5, scoreThreshold = Number.NEGATIVE_INFINITY) { + const $boxes = convertToTensor(boxes, 'boxes', 'nonMaxSuppression', 'float32'); + const $scores = convertToTensor(scores, 'scores', 'nonMaxSuppression', 'float32'); + const inputs = nonMaxSuppSanityCheck($boxes, $scores, maxOutputSize, iouThreshold, scoreThreshold); + maxOutputSize = inputs.maxOutputSize; + iouThreshold = inputs.iouThreshold; + scoreThreshold = inputs.scoreThreshold; + const attrs = { maxOutputSize, iouThreshold, scoreThreshold }; + return ENGINE.runKernel(NonMaxSuppressionV3, { boxes: $boxes, scores: $scores }, attrs); + } + const nonMaxSuppression = /* @__PURE__ */ op({ nonMaxSuppression_ }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Inserts a value into a sorted array. This method allows duplicate, meaning it + * allows inserting duplicate value, in which case, the element will be inserted + * at the lowest index of the value. + * @param arr The array to modify. + * @param element The element to insert. + * @param comparator Optional. If no comparator is specified, elements are + * compared using array_util.defaultComparator, which is suitable for Strings + * and Numbers in ascending arrays. If the array contains multiple instances of + * the target value, the left-most instance will be returned. To provide a + * comparator, it should take 2 arguments to compare and return a negative, + * zero, or a positive number. + */ + function binaryInsert(arr, element, comparator) { + const index = binarySearch(arr, element, comparator); + const insertionPoint = index < 0 ? -(index + 1) : index; + arr.splice(insertionPoint, 0, element); + } + /** + * Searches the array for the target using binary search, returns the index + * of the found element, or position to insert if element not found. If no + * comparator is specified, elements are compared using array_ + * util.defaultComparator, which is suitable for Strings and Numbers in + * ascending arrays. If the array contains multiple instances of the target + * value, the left-most instance will be returned. + * @param arr The array to be searched in. + * @param target The target to be searched for. + * @param comparator Should take 2 arguments to compare and return a negative, + * zero, or a positive number. + * @return Lowest index of the target value if found, otherwise the insertion + * point where the target should be inserted, in the form of + * (-insertionPoint - 1). + */ + function binarySearch(arr, target, comparator) { + return binarySearch_(arr, target, comparator || defaultComparator); + } + /** + * Compares its two arguments for order. + * @param a The first element to be compared. + * @param b The second element to be compared. + * @return A negative number, zero, or a positive number as the first + * argument is less than, equal to, or greater than the second. + */ + function defaultComparator(a, b) { + return a > b ? 1 : a < b ? -1 : 0; + } + function binarySearch_(arr, target, comparator) { + let left = 0; + let right = arr.length; + let middle = 0; + let found = false; + while (left < right) { + middle = left + ((right - left) >>> 1); + const compareResult = comparator(target, arr[middle]); + if (compareResult > 0) { + left = middle + 1; + } + else { + right = middle; + // If compareResult is 0, the value is found. We record it is found, + // and then keep looking because there may be duplicate. + found = !compareResult; + } + } + return found ? left : -left - 1; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function nonMaxSuppressionV3Impl$2(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold) { + return nonMaxSuppressionImpl_(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, 0 /* softNmsSigma */); + } + function nonMaxSuppressionV4Impl$2(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, padToMaxOutputSize) { + return nonMaxSuppressionImpl_(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, 0 /* softNmsSigma */, false /* returnScoresTensor */, padToMaxOutputSize /* padToMaxOutputSize */, true + /* returnValidOutputs */ ); + } + function nonMaxSuppressionV5Impl$2(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma) { + return nonMaxSuppressionImpl_(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma, true /* returnScoresTensor */); + } + function nonMaxSuppressionImpl_(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma, returnScoresTensor = false, padToMaxOutputSize = false, returnValidOutputs = false) { + // The list is sorted in ascending order, so that we can always pop the + // candidate with the largest score in O(1) time. + const candidates = []; + for (let i = 0; i < scores.length; i++) { + if (scores[i] > scoreThreshold) { + candidates.push({ score: scores[i], boxIndex: i, suppressBeginIndex: 0 }); + } + } + candidates.sort(ascendingComparator); + // If softNmsSigma is 0, the outcome of this algorithm is exactly same as + // before. + const scale = softNmsSigma > 0 ? (-0.5 / softNmsSigma) : 0.0; + const selectedIndices = []; + const selectedScores = []; + while (selectedIndices.length < maxOutputSize && candidates.length > 0) { + const candidate = candidates.pop(); + const { score: originalScore, boxIndex, suppressBeginIndex } = candidate; + if (originalScore < scoreThreshold) { + break; + } + // Overlapping boxes are likely to have similar scores, therefore we + // iterate through the previously selected boxes backwards in order to + // see if candidate's score should be suppressed. We use + // suppressBeginIndex to track and ensure a candidate can be suppressed + // by a selected box no more than once. Also, if the overlap exceeds + // iouThreshold, we simply ignore the candidate. + let ignoreCandidate = false; + for (let j = selectedIndices.length - 1; j >= suppressBeginIndex; --j) { + const iou = intersectionOverUnion(boxes, boxIndex, selectedIndices[j]); + if (iou >= iouThreshold) { + ignoreCandidate = true; + break; + } + candidate.score = + candidate.score * suppressWeight(iouThreshold, scale, iou); + if (candidate.score <= scoreThreshold) { + break; + } + } + // At this point, if `candidate.score` has not dropped below + // `scoreThreshold`, then we know that we went through all of the + // previous selections and can safely update `suppressBeginIndex` to the + // end of the selected array. Then we can re-insert the candidate with + // the updated score and suppressBeginIndex back in the candidate list. + // If on the other hand, `candidate.score` has dropped below the score + // threshold, we will not add it back to the candidates list. + candidate.suppressBeginIndex = selectedIndices.length; + if (!ignoreCandidate) { + // Candidate has passed all the tests, and is not suppressed, so + // select the candidate. + if (candidate.score === originalScore) { + selectedIndices.push(boxIndex); + selectedScores.push(candidate.score); + } + else if (candidate.score > scoreThreshold) { + // Candidate's score is suppressed but is still high enough to be + // considered, so add back to the candidates list. + binaryInsert(candidates, candidate, ascendingComparator); + } + } + } + // NonMaxSuppressionV4 feature: padding output to maxOutputSize. + const validOutputs = selectedIndices.length; + const elemsToPad = maxOutputSize - validOutputs; + if (padToMaxOutputSize && elemsToPad > 0) { + selectedIndices.push(...new Array(elemsToPad).fill(0)); + selectedScores.push(...new Array(elemsToPad).fill(0.0)); + } + const result = { selectedIndices }; + if (returnScoresTensor) { + result['selectedScores'] = selectedScores; + } + if (returnValidOutputs) { + result['validOutputs'] = validOutputs; + } + return result; + } + function intersectionOverUnion(boxes, i, j) { + const iCoord = boxes.subarray(i * 4, i * 4 + 4); + const jCoord = boxes.subarray(j * 4, j * 4 + 4); + const yminI = Math.min(iCoord[0], iCoord[2]); + const xminI = Math.min(iCoord[1], iCoord[3]); + const ymaxI = Math.max(iCoord[0], iCoord[2]); + const xmaxI = Math.max(iCoord[1], iCoord[3]); + const yminJ = Math.min(jCoord[0], jCoord[2]); + const xminJ = Math.min(jCoord[1], jCoord[3]); + const ymaxJ = Math.max(jCoord[0], jCoord[2]); + const xmaxJ = Math.max(jCoord[1], jCoord[3]); + const areaI = (ymaxI - yminI) * (xmaxI - xminI); + const areaJ = (ymaxJ - yminJ) * (xmaxJ - xminJ); + if (areaI <= 0 || areaJ <= 0) { + return 0.0; + } + const intersectionYmin = Math.max(yminI, yminJ); + const intersectionXmin = Math.max(xminI, xminJ); + const intersectionYmax = Math.min(ymaxI, ymaxJ); + const intersectionXmax = Math.min(xmaxI, xmaxJ); + const intersectionArea = Math.max(intersectionYmax - intersectionYmin, 0.0) * + Math.max(intersectionXmax - intersectionXmin, 0.0); + return intersectionArea / (areaI + areaJ - intersectionArea); + } + // A Gaussian penalty function, this method always returns values in [0, 1]. + // The weight is a function of similarity, the more overlap two boxes are, the + // smaller the weight is,meaning highly overlapping boxes will be significantly + // penalized. On the other hand, a non-overlapping box will not be penalized. + function suppressWeight(iouThreshold, scale, iou) { + const weight = Math.exp(scale * iou * iou); + return iou <= iouThreshold ? weight : 0.0; + } + function ascendingComparator(c1, c2) { + // For objects with same scores, we make the object with the larger index go + // first. In an array that pops from the end, this means that the object with + // the smaller index will be popped first. This ensures the same output as + // the TensorFlow python version. + return (c1.score - c2.score) || + ((c1.score === c2.score) && (c2.boxIndex - c1.boxIndex)); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Performs non maximum suppression of bounding boxes based on + * iou (intersection over union). + * + * This is the async version of `nonMaxSuppression` + * + * @param boxes a 2d tensor of shape `[numBoxes, 4]`. Each entry is + * `[y1, x1, y2, x2]`, where `(y1, x1)` and `(y2, x2)` are the corners of + * the bounding box. + * @param scores a 1d tensor providing the box scores of shape `[numBoxes]`. + * @param maxOutputSize The maximum number of boxes to be selected. + * @param iouThreshold A float representing the threshold for deciding whether + * boxes overlap too much with respect to IOU. Must be between [0, 1]. + * Defaults to 0.5 (50% box overlap). + * @param scoreThreshold A threshold for deciding when to remove boxes based + * on score. Defaults to -inf, which means any score is accepted. + * @return A 1D tensor with the selected box indices. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + async function nonMaxSuppressionAsync_(boxes, scores, maxOutputSize, iouThreshold = 0.5, scoreThreshold = Number.NEGATIVE_INFINITY) { + const $boxes = convertToTensor(boxes, 'boxes', 'nonMaxSuppressionAsync'); + const $scores = convertToTensor(scores, 'scores', 'nonMaxSuppressionAsync'); + const inputs = nonMaxSuppSanityCheck($boxes, $scores, maxOutputSize, iouThreshold, scoreThreshold); + maxOutputSize = inputs.maxOutputSize; + iouThreshold = inputs.iouThreshold; + scoreThreshold = inputs.scoreThreshold; + const boxesAndScores = await Promise.all([$boxes.data(), $scores.data()]); + const boxesVals = boxesAndScores[0]; + const scoresVals = boxesAndScores[1]; + // We call a cpu based impl directly with the typedarray data here rather + // than a kernel because all kernels are synchronous (and thus cannot await + // .data()). + const { selectedIndices } = nonMaxSuppressionV3Impl$2(boxesVals, scoresVals, maxOutputSize, iouThreshold, scoreThreshold); + if ($boxes !== boxes) { + $boxes.dispose(); + } + if ($scores !== scores) { + $scores.dispose(); + } + return tensor1d(selectedIndices, 'int32'); + } + const nonMaxSuppressionAsync = nonMaxSuppressionAsync_; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Performs non maximum suppression of bounding boxes based on + * iou (intersection over union). + * + * This op also supports a Soft-NMS mode (cf. + * Bodla et al, https://arxiv.org/abs/1704.04503) where boxes reduce the score + * of other overlapping boxes, therefore favoring different regions of the image + * with high scores. To enable this Soft-NMS mode, set the `softNmsSigma` + * parameter to be larger than 0. + * + * @param boxes a 2d tensor of shape `[numBoxes, 4]`. Each entry is + * `[y1, x1, y2, x2]`, where `(y1, x1)` and `(y2, x2)` are the corners of + * the bounding box. + * @param scores a 1d tensor providing the box scores of shape `[numBoxes]`. + * @param maxOutputSize The maximum number of boxes to be selected. + * @param iouThreshold A float representing the threshold for deciding whether + * boxes overlap too much with respect to IOU. Must be between [0, 1]. + * Defaults to 0.5 (50% box overlap). + * @param scoreThreshold A threshold for deciding when to remove boxes based + * on score. Defaults to -inf, which means any score is accepted. + * @param softNmsSigma A float representing the sigma parameter for Soft NMS. + * When sigma is 0, it falls back to nonMaxSuppression. + * @return A map with the following properties: + * - selectedIndices: A 1D tensor with the selected box indices. + * - selectedScores: A 1D tensor with the corresponding scores for each + * selected box. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function nonMaxSuppressionWithScore_(boxes, scores, maxOutputSize, iouThreshold = 0.5, scoreThreshold = Number.NEGATIVE_INFINITY, softNmsSigma = 0.0) { + const $boxes = convertToTensor(boxes, 'boxes', 'nonMaxSuppression'); + const $scores = convertToTensor(scores, 'scores', 'nonMaxSuppression'); + const params = nonMaxSuppSanityCheck($boxes, $scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma); + maxOutputSize = params.maxOutputSize; + iouThreshold = params.iouThreshold; + scoreThreshold = params.scoreThreshold; + softNmsSigma = params.softNmsSigma; + const inputs = { boxes: $boxes, scores: $scores }; + const attrs = { maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const result = ENGINE.runKernel(NonMaxSuppressionV5, inputs, attrs); + return { selectedIndices: result[0], selectedScores: result[1] }; + } + const nonMaxSuppressionWithScore = /* @__PURE__ */ op({ nonMaxSuppressionWithScore_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Asynchronously performs non maximum suppression of bounding boxes based on + * iou (intersection over union). + * + * This op also supports a Soft-NMS mode (cf. + * Bodla et al, https://arxiv.org/abs/1704.04503) where boxes reduce the score + * of other overlapping boxes, therefore favoring different regions of the image + * with high scores. To enable this Soft-NMS mode, set the `softNmsSigma` + * parameter to be larger than 0. + * + * @param boxes a 2d tensor of shape `[numBoxes, 4]`. Each entry is + * `[y1, x1, y2, x2]`, where `(y1, x1)` and `(y2, x2)` are the corners of + * the bounding box. + * @param scores a 1d tensor providing the box scores of shape `[numBoxes]`. + * @param maxOutputSize The maximum number of boxes to be selected. + * @param iouThreshold A float representing the threshold for deciding whether + * boxes overlap too much with respect to IOU. Must be between [0, 1]. + * Defaults to 0.5 (50% box overlap). + * @param scoreThreshold A threshold for deciding when to remove boxes based + * on score. Defaults to -inf, which means any score is accepted. + * @param softNmsSigma A float representing the sigma parameter for Soft NMS. + * When sigma is 0, it falls back to nonMaxSuppression. + * @return A map with the following properties: + * - selectedIndices: A 1D tensor with the selected box indices. + * - selectedScores: A 1D tensor with the corresponding scores for each + * selected box. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + async function nonMaxSuppressionWithScoreAsync_(boxes, scores, maxOutputSize, iouThreshold = 0.5, scoreThreshold = Number.NEGATIVE_INFINITY, softNmsSigma = 0.0) { + const $boxes = convertToTensor(boxes, 'boxes', 'nonMaxSuppressionAsync'); + const $scores = convertToTensor(scores, 'scores', 'nonMaxSuppressionAsync'); + const params = nonMaxSuppSanityCheck($boxes, $scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma); + maxOutputSize = params.maxOutputSize; + iouThreshold = params.iouThreshold; + scoreThreshold = params.scoreThreshold; + softNmsSigma = params.softNmsSigma; + const boxesAndScores = await Promise.all([$boxes.data(), $scores.data()]); + const boxesVals = boxesAndScores[0]; + const scoresVals = boxesAndScores[1]; + // We call a cpu based impl directly with the typedarray data here rather + // than a kernel because all kernels are synchronous (and thus cannot await + // .data()). + const { selectedIndices, selectedScores } = nonMaxSuppressionV5Impl$2(boxesVals, scoresVals, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma); + if ($boxes !== boxes) { + $boxes.dispose(); + } + if ($scores !== scores) { + $scores.dispose(); + } + return { + selectedIndices: tensor1d(selectedIndices, 'int32'), + selectedScores: tensor1d(selectedScores) + }; + } + const nonMaxSuppressionWithScoreAsync = nonMaxSuppressionWithScoreAsync_; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Asynchronously performs non maximum suppression of bounding boxes based on + * iou (intersection over union), with an option to pad results. + * + * @param boxes a 2d tensor of shape `[numBoxes, 4]`. Each entry is + * `[y1, x1, y2, x2]`, where `(y1, x1)` and `(y2, x2)` are the corners of + * the bounding box. + * @param scores a 1d tensor providing the box scores of shape `[numBoxes]`. + * @param maxOutputSize The maximum number of boxes to be selected. + * @param iouThreshold A float representing the threshold for deciding whether + * boxes overlap too much with respect to IOU. Must be between [0, 1]. + * Defaults to 0.5 (50% box overlap). + * @param scoreThreshold A threshold for deciding when to remove boxes based + * on score. Defaults to -inf, which means any score is accepted. + * @param padToMaxOutputSize Defaults to false. If true, size of output + * `selectedIndices` is padded to maxOutputSize. + * @return A map with the following properties: + * - selectedIndices: A 1D tensor with the selected box indices. + * - validOutputs: A scalar denoting how many elements in `selectedIndices` + * are valid. Valid elements occur first, then padding. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function nonMaxSuppressionPadded_(boxes, scores, maxOutputSize, iouThreshold = 0.5, scoreThreshold = Number.NEGATIVE_INFINITY, padToMaxOutputSize = false) { + const $boxes = convertToTensor(boxes, 'boxes', 'nonMaxSuppression'); + const $scores = convertToTensor(scores, 'scores', 'nonMaxSuppression'); + const params = nonMaxSuppSanityCheck($boxes, $scores, maxOutputSize, iouThreshold, scoreThreshold, null /* softNmsSigma */); + const $maxOutputSize = params.maxOutputSize; + const $iouThreshold = params.iouThreshold; + const $scoreThreshold = params.scoreThreshold; + const inputs = { boxes: $boxes, scores: $scores }; + const attrs = { + maxOutputSize: $maxOutputSize, + iouThreshold: $iouThreshold, + scoreThreshold: $scoreThreshold, + padToMaxOutputSize + }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const result = ENGINE.runKernel(NonMaxSuppressionV4, inputs, attrs); + return { selectedIndices: result[0], validOutputs: result[1] }; + } + const nonMaxSuppressionPadded = /* @__PURE__ */ op({ nonMaxSuppressionPadded_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Asynchronously performs non maximum suppression of bounding boxes based on + * iou (intersection over union), with an option to pad results. + * + * @param boxes a 2d tensor of shape `[numBoxes, 4]`. Each entry is + * `[y1, x1, y2, x2]`, where `(y1, x1)` and `(y2, x2)` are the corners of + * the bounding box. + * @param scores a 1d tensor providing the box scores of shape `[numBoxes]`. + * @param maxOutputSize The maximum number of boxes to be selected. + * @param iouThreshold A float representing the threshold for deciding whether + * boxes overlap too much with respect to IOU. Must be between [0, 1]. + * Defaults to 0.5 (50% box overlap). + * @param scoreThreshold A threshold for deciding when to remove boxes based + * on score. Defaults to -inf, which means any score is accepted. + * @param padToMaxOutputSize Defaults to false. If true, size of output + * `selectedIndices` is padded to maxOutputSize. + * @return A map with the following properties: + * - selectedIndices: A 1D tensor with the selected box indices. + * - validOutputs: A scalar denoting how many elements in `selectedIndices` + * are valid. Valid elements occur first, then padding. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + async function nonMaxSuppressionPaddedAsync_(boxes, scores, maxOutputSize, iouThreshold = 0.5, scoreThreshold = Number.NEGATIVE_INFINITY, padToMaxOutputSize = false) { + const $boxes = convertToTensor(boxes, 'boxes', 'nonMaxSuppressionAsync'); + const $scores = convertToTensor(scores, 'scores', 'nonMaxSuppressionAsync'); + const params = nonMaxSuppSanityCheck($boxes, $scores, maxOutputSize, iouThreshold, scoreThreshold, null /* softNmsSigma */); + const $maxOutputSize = params.maxOutputSize; + const $iouThreshold = params.iouThreshold; + const $scoreThreshold = params.scoreThreshold; + const [boxesVals, scoresVals] = await Promise.all([$boxes.data(), $scores.data()]); + // We call a cpu based impl directly with the typedarray data here rather + // than a kernel because all kernels are synchronous (and thus cannot await + // .data()). + const { selectedIndices, validOutputs } = nonMaxSuppressionV4Impl$2(boxesVals, scoresVals, $maxOutputSize, $iouThreshold, $scoreThreshold, padToMaxOutputSize); + if ($boxes !== boxes) { + $boxes.dispose(); + } + if ($scores !== scores) { + $scores.dispose(); + } + return { + selectedIndices: tensor1d(selectedIndices, 'int32'), + validOutputs: scalar(validOutputs, 'int32') + }; + } + const nonMaxSuppressionPaddedAsync = nonMaxSuppressionPaddedAsync_; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Bilinear resize a single 3D image or a batch of 3D images to a new shape. + * + * @param images The images, of rank 4 or rank 3, of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is assumed. + * @param size The new shape `[newHeight, newWidth]` to resize the + * images to. Each channel is resized individually. + * @param alignCorners Defaults to `false`. If true, rescale + * input by `(new_height - 1) / (height - 1)`, which exactly aligns the 4 + * corners of images and resized images. If false, rescale by + * `new_height / height`. Treat similarly the width dimension. + * @param halfPixelCenters Defaults to `false`. Whether to assume pixel centers + * are at 0.5, which would make the floating point coordinates of the top + * left pixel 0.5, 0.5. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function resizeBilinear_(images, size, alignCorners = false, halfPixelCenters = false) { + const $images = convertToTensor(images, 'images', 'resizeBilinear'); + assert$1($images.rank === 3 || $images.rank === 4, () => `Error in resizeBilinear: x must be rank 3 or 4, but got ` + + `rank ${$images.rank}.`); + assert$1(size.length === 2, () => `Error in resizeBilinear: new shape must 2D, but got shape ` + + `${size}.`); + assert$1(halfPixelCenters === false || alignCorners === false, () => `Error in resizeBilinear: If halfPixelCenters is true, ` + + `alignCorners must be false.`); + let batchImages = $images; + let reshapedTo4D = false; + if ($images.rank === 3) { + reshapedTo4D = true; + batchImages = reshape$3($images, [1, $images.shape[0], $images.shape[1], $images.shape[2]]); + } + const [] = size; + const inputs = { images: batchImages }; + const attrs = { alignCorners, halfPixelCenters, size }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(ResizeBilinear, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const resizeBilinear$3 = /* @__PURE__ */ op({ resizeBilinear_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * NearestNeighbor resize a batch of 3D images to a new shape. + * + * @param images The images, of rank 4 or rank 3, of shape + * `[batch, height, width, inChannels]`. If rank 3, batch of 1 is assumed. + * @param size The new shape `[newHeight, newWidth]` to resize the + * images to. Each channel is resized individually. + * @param alignCorners Defaults to False. If true, rescale + * input by `(new_height - 1) / (height - 1)`, which exactly aligns the 4 + * corners of images and resized images. If false, rescale by + * `new_height / height`. Treat similarly the width dimension. + * @param halfPixelCenters Defaults to `false`. Whether to assume pixels are of + * half the actual dimensions, and yield more accurate resizes. This flag + * would also make the floating point coordinates of the top left pixel + * 0.5, 0.5. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function resizeNearestNeighbor_(images, size, alignCorners = false, halfPixelCenters = false) { + const $images = convertToTensor(images, 'images', 'resizeNearestNeighbor'); + assert$1($images.rank === 3 || $images.rank === 4, () => `Error in resizeNearestNeighbor: x must be rank 3 or 4, but got ` + + `rank ${$images.rank}.`); + assert$1(size.length === 2, () => `Error in resizeNearestNeighbor: new shape must 2D, but got shape ` + + `${size}.`); + assert$1($images.dtype === 'float32' || $images.dtype === 'int32', () => '`images` must have `int32` or `float32` as dtype'); + assert$1(halfPixelCenters === false || alignCorners === false, () => `Error in resizeNearestNeighbor: If halfPixelCenters is true, ` + + `alignCorners must be false.`); + let batchImages = $images; + let reshapedTo4D = false; + if ($images.rank === 3) { + reshapedTo4D = true; + batchImages = reshape$3($images, [1, $images.shape[0], $images.shape[1], $images.shape[2]]); + } + const [] = size; + const inputs = { images: batchImages }; + const attrs = { alignCorners, halfPixelCenters, size }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(ResizeNearestNeighbor, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const resizeNearestNeighbor$2 = /* @__PURE__ */ op({ resizeNearestNeighbor_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Performs image binarization with corresponding threshold + * (depends on the method)value, which creates a binary image from a grayscale. + * @param image 3d tensor of shape [imageHeight,imageWidth, depth], + * where imageHeight and imageWidth must be positive.The image color + * range should be [0, 255]. + * @param method Optional string from `'binary' | 'otsu'` + * which specifies the method for thresholding. Defaults to 'binary'. + * @param inverted Optional boolean whichspecifies + * if colours should be inverted. Defaults to false. + * @param threshValue Optional number which defines threshold value from 0 to 1. + * Defaults to 0.5. + * @return A 3d tensor of shape [imageHeight,imageWidth, depth], which + * contains binarized image. + */ + function threshold_(image, method = 'binary', inverted = false, threshValue = 0.5) { + const $image = convertToTensor(image, 'image', 'threshold'); + /* 0.2989, 0.5870, 0.1140 are represent luma coefficients in CCIR601. + Reference for converting between RGB and grayscale: https://en.wikipedia.org/wiki/Luma_%28video%29 */ + const RED_INTENCITY_COEF = 0.2989; + const GREEN_INTENCITY_COEF = 0.5870; + const BLUE_INTENCITY_COEF = 0.1140; + const totalPixelsInImage = $image.shape[0] * $image.shape[1]; + let $threshold = mul(tensor1d([threshValue]), 255); + let r, g, b, grayscale; + assert$1($image.rank === 3, () => 'Error in threshold: image must be rank 3,' + + `but got rank ${$image.rank}.`); + assert$1($image.shape[2] === 3 || $image.shape[2] === 1, () => 'Error in threshold: ' + + 'image color channel must be equal to 3 or 1' + + `but got ${$image.shape[2]}.`); + assert$1($image.dtype === 'int32' || $image.dtype === 'float32', () => 'Error in dtype: image dtype must be int32 or float32,' + + `but got dtype ${$image.dtype}.`); + assert$1(method === 'otsu' || method === 'binary', () => `Method must be binary or otsu, but was ${method}`); + if ($image.shape[2] === 3) { + [r, g, b] = split$3($image, [1, 1, 1], -1); + const $r = mul(r, RED_INTENCITY_COEF); + const $g = mul(g, GREEN_INTENCITY_COEF); + const $b = mul(b, BLUE_INTENCITY_COEF); + grayscale = add$3(add$3($r, $g), $b); + } + else { + grayscale = image; + } + if (method === 'otsu') { + const $histogram = bincount$2(cast$3(round$2(grayscale), 'int32'), tensor([]), 256); + $threshold = otsu($histogram, totalPixelsInImage); + } + const invCondition = inverted ? + lessEqual$2(grayscale, $threshold) : greater$3(grayscale, $threshold); + const result = cast$3(mul(invCondition, 255), 'int32'); + return result; + } + function otsu(histogram, total) { + let bestThresh = tensor1d([-1]); + let bestInBetVar = tensor1d([0]); + let cInBetVar = tensor1d([0]); + let classFirst, classSecond, meanFirst, meanSec, weightForeground, weightBack; + for (let index = 0; index < histogram.size - 1; index++) { + classFirst = slice$2(histogram, 0, index + 1); + classSecond = slice$2(histogram, index + 1); + weightForeground = div$1(sum$3(classFirst), total); + weightBack = div$1(sum$3(classSecond), total); + const meanFirstDivA = sum$3(mul(classFirst, range$3(0, classFirst.size))); + meanFirst = div$1(meanFirstDivA, sum$3(classFirst)); + const meanSecFill = fill$2(classSecond.shape, classFirst.size); + const meanSecAdd = add$3(range$3(0, classSecond.size), meanSecFill); + const meanSecMul = mul(classSecond, (meanSecAdd)); + meanSec = div$1(sum$3(meanSecMul), sum$3(classSecond)); + const cInBetVarSubA = sub$2(meanFirst, meanSec); + const cInBetVarSubB = sub$2(meanFirst, meanSec); + const cInBetVarMul = mul(weightForeground, weightBack); + cInBetVar = mul(mul(cInBetVarMul, cInBetVarSubA), cInBetVarSubB); + const condition = greater$3(cInBetVar, bestInBetVar); + bestInBetVar = where(condition, cInBetVar, bestInBetVar); + bestThresh = where(condition, tensor1d([index]), bestThresh); + } + return bestThresh; + } + const threshold$1 = /* @__PURE__ */ op({ threshold_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Applies the given transform(s) to the image(s). + * + * @param image 4d tensor of shape `[batch, imageHeight, imageWidth, depth]`. + * @param transforms Projective transform matrix/matrices. A tensor1d of length + * 8 or tensor of size N x 8. If one row of transforms is [a0, a1, a2, b0, + * b1, b2, c0, c1], then it maps the output point (x, y) to a transformed + * input point (x', y') = ((a0 x + a1 y + a2) / k, (b0 x + b1 y + b2) / k), + * where k = c0 x + c1 y + 1. The transforms are inverted compared to the + * transform mapping input points to output points. + * @param interpolation Interpolation mode. + * Supported values: 'nearest', 'bilinear'. Default to 'nearest'. + * @param fillMode Points outside the boundaries of the input are filled + * according to the given mode, one of 'constant', 'reflect', 'wrap', + * 'nearest'. Default to 'constant'. + * 'reflect': (d c b a | a b c d | d c b a ) The input is extended by + * reflecting about the edge of the last pixel. + * 'constant': (k k k k | a b c d | k k k k) The input is extended by + * filling all values beyond the edge with the same constant value k. + * 'wrap': (a b c d | a b c d | a b c d) The input is extended by + * wrapping around to the opposite edge. + * 'nearest': (a a a a | a b c d | d d d d) The input is extended by + * the nearest pixel. + * @param fillValue A float represents the value to be filled outside the + * boundaries when fillMode is 'constant'. + * @param Output dimension after the transform, [height, width]. If undefined, + * output is the same size as input image. + * + * @doc {heading: 'Operations', subheading: 'Images', namespace: 'image'} + */ + function transform_(image, transforms, interpolation = 'nearest', fillMode = 'constant', fillValue = 0, outputShape) { + const $image = convertToTensor(image, 'image', 'transform', 'float32'); + const $transforms = convertToTensor(transforms, 'transforms', 'transform', 'float32'); + assert$1($image.rank === 4, () => 'Error in transform: image must be rank 4,' + + `but got rank ${$image.rank}.`); + assert$1($transforms.rank === 2 && + ($transforms.shape[0] === $image.shape[0] || + $transforms.shape[0] === 1) && + $transforms.shape[1] === 8, () => `Error in transform: Input transform should be batch x 8 or 1 x 8`); + assert$1(outputShape == null || outputShape.length === 2, () => 'Error in transform: outputShape must be [height, width] or null, ' + + `but got ${outputShape}.`); + const inputs = { image: $image, transforms: $transforms }; + const attrs = { interpolation, fillMode, fillValue, outputShape }; + return ENGINE.runKernel(Transform, inputs, attrs); + } + const transform$2 = /* @__PURE__ */ op({ transform_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Copy a tensor setting everything outside a central band in each innermost + * matrix to zero. + * + * The band part is computed as follows: Assume input has `k` dimensions + * `[I, J, K, ..., M, N]`, then the output is a tensor with the same shape where + * `band[i, j, k, ..., m, n] = in_band(m, n) * input[i, j, k, ..., m, n]`. + * The indicator function + * `in_band(m, n) = (num_lower < 0 || (m-n) <= num_lower)` + * `&& (num_upper < 0 || (n-m) <= num_upper)` + * + * ```js + * const x = tf.tensor2d([[ 0, 1, 2, 3], + * [-1, 0, 1, 2], + * [-2, -1, 0, 1], + * [-3, -2, -1, 0]]); + * let y = tf.linalg.bandPart(x, 1, -1); + * y.print(); // [[ 0, 1, 2, 3], + * // [-1, 0, 1, 2], + * // [ 0, -1, 0, 1], + * // [ 0, 0 , -1, 0]] + * let z = tf.linalg.bandPart(x, 2, 1); + * z.print(); // [[ 0, 1, 0, 0], + * // [-1, 0, 1, 0], + * // [-2, -1, 0, 1], + * // [ 0, -2, -1, 0]] + * ``` + * + * @param x Rank `k` tensor + * @param numLower Number of subdiagonals to keep. + * If negative, keep entire lower triangle. + * @param numUpper Number of subdiagonals to keep. + * If negative, keep entire upper triangle. + * @returns Rank `k` tensor of the same shape as input. + * The extracted banded tensor. + * + * @doc {heading:'Operations', subheading:'Linear Algebra', namespace:'linalg'} + */ + function bandPart_(a, numLower, numUpper) { + const $a = convertToTensor(a, 'a', 'bandPart'); + assert$1($a.rank >= 2, () => `bandPart(): Rank must be at least 2, got ${$a.rank}.`); + const shape = $a.shape; + const [M, N] = $a.shape.slice(-2); + let $numLower; + let $numUpper; + if (typeof numLower === 'number') { + assert$1(numLower % 1 === 0, () => `bandPart(): numLower must be an integer, got ${numLower}.`); + assert$1(numLower <= M, () => `bandPart(): numLower (${numLower})` + + ` must not be greater than the number of rows (${M}).`); + $numLower = + convertToTensor(numLower < 0 ? M : numLower, 'numLower', 'bandPart'); + } + else { + assert$1(numLower.dtype === 'int32', () => `bandPart(): numLower's dtype must be an int32.`); + // If numLower is a Scalar, checking `numLower <= M` could hurt performance, + // but minimum(numLower, M) could avoid unexpected results. + $numLower = where(less$3(numLower, 0), M, minimum$4(numLower, M)); + } + if (typeof numUpper === 'number') { + assert$1(numUpper % 1 === 0, () => `bandPart(): numUpper must be an integer, got ${numUpper}.`); + assert$1(numUpper <= N, () => `bandPart(): numUpper (${numUpper})` + + ` must not be greater than the number of columns (${N}).`); + $numUpper = + convertToTensor(numUpper < 0 ? N : numUpper, 'numUpper', 'bandPart'); + } + else { + assert$1(numUpper.dtype === 'int32', () => `bandPart(): numUpper's dtype must be an int32.`); + $numUpper = where(less$3(numUpper, 0), N, minimum$4(numUpper, N)); + } + const i = reshape$3(range$3(0, M, 1, 'int32'), [-1, 1]); + const j = range$3(0, N, 1, 'int32'); + const ij = sub$2(i, j); + const inBand = logicalAnd$2(lessEqual$2(ij, $numLower), greaterEqual$2(ij, neg$2($numUpper))); + const zero = zeros$2([M, N], $a.dtype); + return reshape$3(stack(unstack(reshape$3($a, [-1, M, N])) + .map(mat => where(inBand, mat, zero))), shape); + } + const bandPart = /* @__PURE__ */ op({ bandPart_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Gram-Schmidt orthogonalization. + * + * ```js + * const x = tf.tensor2d([[1, 2], [3, 4]]); + * let y = tf.linalg.gramSchmidt(x); + * y.print(); + * console.log('Orthogonalized:'); + * y.dot(y.transpose()).print(); // should be nearly the identity matrix. + * console.log('First row direction maintained:'); + * const data = await y.array(); + * console.log(data[0][1] / data[0][0]); // should be nearly 2. + * ``` + * + * @param xs The vectors to be orthogonalized, in one of the two following + * formats: + * - An Array of `tf.Tensor1D`. + * - A `tf.Tensor2D`, i.e., a matrix, in which case the vectors are the rows + * of `xs`. + * In each case, all the vectors must have the same length and the length + * must be greater than or equal to the number of vectors. + * @returns The orthogonalized and normalized vectors or matrix. + * Orthogonalization means that the vectors or the rows of the matrix + * are orthogonal (zero inner products). Normalization means that each + * vector or each row of the matrix has an L2 norm that equals `1`. + * + * @doc {heading:'Operations', subheading:'Linear Algebra', namespace:'linalg'} + */ + function gramSchmidt_(xs) { + let inputIsTensor2D; + if (Array.isArray(xs)) { + inputIsTensor2D = false; + assert$1(xs != null && xs.length > 0, () => 'Gram-Schmidt process: input must not be null, undefined, or ' + + 'empty'); + const dim = xs[0].shape[0]; + for (let i = 1; i < xs.length; ++i) { + assert$1(xs[i].shape[0] === dim, () => 'Gram-Schmidt: Non-unique lengths found in the input vectors: ' + + `(${xs[i].shape[0]} vs. ${dim})`); + } + } + else { + inputIsTensor2D = true; + xs = split$3(xs, xs.shape[0], 0).map(x => squeeze(x, [0])); + } + assert$1(xs.length <= xs[0].shape[0], () => `Gram-Schmidt: Number of vectors (${xs.length}) exceeds ` + + `number of dimensions (${xs[0].shape[0]}).`); + const ys = []; + const xs1d = xs; + for (let i = 0; i < xs.length; ++i) { + ys.push(ENGINE.tidy(() => { + let x = xs1d[i]; + if (i > 0) { + for (let j = 0; j < i; ++j) { + const proj = mul(sum$3(mul(ys[j], x)), ys[j]); + x = sub$2(x, proj); + } + } + return div$1(x, norm(x, 'euclidean')); + })); + } + if (inputIsTensor2D) { + return stack(ys, 0); + } + else { + return ys; + } + } + const gramSchmidt = /* @__PURE__ */ op({ gramSchmidt_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Compute QR decomposition of m-by-n matrix using Householder transformation. + * + * Implementation based on + * [http://www.cs.cornell.edu/~bindel/class/cs6210-f09/lec18.pdf] + * (http://www.cs.cornell.edu/~bindel/class/cs6210-f09/lec18.pdf) + * + * ```js + * const a = tf.tensor2d([[1, 2], [3, 4]]); + * let [q, r] = tf.linalg.qr(a); + * console.log('Q'); + * q.print(); + * console.log('R'); + * r.print(); + * console.log('Orthogonalized'); + * q.dot(q.transpose()).print() // should be nearly the identity matrix. + * console.log('Reconstructed'); + * q.dot(r).print(); // should be nearly [[1, 2], [3, 4]]; + * ``` + * + * @param x The `tf.Tensor` to be QR-decomposed. Must have rank >= 2. Suppose + * it has the shape `[..., M, N]`. + * @param fullMatrices An optional boolean parameter. Defaults to `false`. + * If `true`, compute full-sized `Q`. If `false` (the default), + * compute only the leading N columns of `Q` and `R`. + * @returns An `Array` of two `tf.Tensor`s: `[Q, R]`. `Q` is a unitary matrix, + * i.e., its columns all have unit norm and are mutually orthogonal. + * If `M >= N`, + * If `fullMatrices` is `false` (default), + * - `Q` has a shape of `[..., M, N]`, + * - `R` has a shape of `[..., N, N]`. + * If `fullMatrices` is `true` (default), + * - `Q` has a shape of `[..., M, M]`, + * - `R` has a shape of `[..., M, N]`. + * If `M < N`, + * - `Q` has a shape of `[..., M, M]`, + * - `R` has a shape of `[..., M, N]`. + * @throws If the rank of `x` is less than 2. + * + * @doc {heading:'Operations', + * subheading:'Linear Algebra', + * namespace:'linalg'} + */ + function qr_(x, fullMatrices = false) { + assert$1(x.rank >= 2, () => `qr() requires input tensor to have a rank >= 2, but got rank ${x.rank}`); + if (x.rank === 2) { + return qr2d(x, fullMatrices); + } + else { + // Rank > 2. + // TODO(cais): Below we split the input into individual 2D tensors, + // perform QR decomposition on them and then stack the results back + // together. We should explore whether this can be parallelized. + const outerDimsProd = x.shape.slice(0, x.shape.length - 2) + .reduce((value, prev) => value * prev); + const x2ds = unstack(reshape$3(x, [ + outerDimsProd, x.shape[x.shape.length - 2], + x.shape[x.shape.length - 1] + ]), 0); + const q2ds = []; + const r2ds = []; + x2ds.forEach(x2d => { + const [q2d, r2d] = qr2d(x2d, fullMatrices); + q2ds.push(q2d); + r2ds.push(r2d); + }); + const q = reshape$3(stack(q2ds, 0), x.shape); + const r = reshape$3(stack(r2ds, 0), x.shape); + return [q, r]; + } + } + function qr2d(x, fullMatrices = false) { + return ENGINE.tidy(() => { + assert$1(x.shape.length === 2, () => `qr2d() requires a 2D Tensor, but got a ${x.shape.length}D Tensor.`); + const m = x.shape[0]; + const n = x.shape[1]; + let q = eye(m); // Orthogonal transform so far. + let r = clone(x); // Transformed matrix so far. + const one2D = tensor2d([[1]], [1, 1]); + let w = clone(one2D); + const iters = m >= n ? n : m; + for (let j = 0; j < iters; ++j) { + // This tidy within the for-loop ensures we clean up temporary + // tensors as soon as they are no longer needed. + const rTemp = r; + const wTemp = w; + const qTemp = q; + [w, r, q] = ENGINE.tidy(() => { + // Find H = I - tau * w * w', to put zeros below R(j, j). + const rjEnd1 = slice$2(r, [j, j], [m - j, 1]); + const normX = norm(rjEnd1); + const rjj = slice$2(r, [j, j], [1, 1]); + // The sign() function returns 0 on 0, which causes division by zero. + const s = where(greater$3(rjj, 0), tensor2d([[-1]]), tensor2d([[1]])); + const u1 = sub$2(rjj, mul(s, normX)); + const wPre = div$1(rjEnd1, u1); + if (wPre.shape[0] === 1) { + w = clone(one2D); + } + else { + w = concat$2([ + one2D, + slice$2(wPre, [1, 0], [wPre.shape[0] - 1, wPre.shape[1]]) + ], 0); + } + const tau = neg$2(div$1(matMul$1(s, u1), normX)); + // -- R := HR, Q := QH. + const rjEndAll = slice$2(r, [j, 0], [m - j, n]); + const tauTimesW = mul(tau, w); + const wT = transpose$2(w); + if (j === 0) { + r = sub$2(rjEndAll, matMul$1(tauTimesW, matMul$1(wT, rjEndAll))); + } + else { + const rTimesTau = sub$2(rjEndAll, matMul$1(tauTimesW, matMul$1(wT, rjEndAll))); + r = concat$2([slice$2(r, [0, 0], [j, n]), rTimesTau], 0); + } + const tawTimesWT = transpose$2(tauTimesW); + const qAllJEnd = slice$2(q, [0, j], [m, q.shape[1] - j]); + if (j === 0) { + q = sub$2(qAllJEnd, matMul$1(matMul$1(qAllJEnd, w), tawTimesWT)); + } + else { + const qTimesTau = sub$2(qAllJEnd, matMul$1(matMul$1(qAllJEnd, w), tawTimesWT)); + q = concat$2([slice$2(q, [0, 0], [m, j]), qTimesTau], 1); + } + return [w, r, q]; + }); + dispose([rTemp, wTemp, qTemp]); + } + if (!fullMatrices && m > n) { + q = slice$2(q, [0, 0], [m, n]); + r = slice$2(r, [0, 0], [n, n]); + } + return [q, r]; + }); + } + const qr = /* @__PURE__ */ op({ qr_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + exports.Reduction = void 0; + (function (Reduction) { + Reduction[Reduction["NONE"] = 0] = "NONE"; + Reduction[Reduction["MEAN"] = 1] = "MEAN"; + Reduction[Reduction["SUM"] = 2] = "SUM"; + Reduction[Reduction["SUM_BY_NONZERO_WEIGHTS"] = 3] = "SUM_BY_NONZERO_WEIGHTS"; + })(exports.Reduction || (exports.Reduction = {})); + + /** + * Computes the weighted loss between two tensors. + * + * @param losses Tensor of shape `[batch_size, d1, ..., dN]`. + * @param weights Tensor whose rank is either 0, or the same rank as + * `losses`, and must be broadcastable to `losses` (i.e., all + * dimensions must be either `1`, or the same as the corresponding + * `losses` dimension). + * + * @doc {heading: 'Training', subheading: 'Losses', namespace: 'losses'} + */ + function computeWeightedLoss_(losses, weights, reduction = exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + const $losses = convertToTensor(losses, 'losses', 'computeWeightedLoss'); + let $weights = null; + if (weights != null) { + $weights = convertToTensor(weights, 'weights', 'computeWeightedLoss'); + } + const weightedLoss = ($weights == null) ? $losses : mul($losses, $weights); + if (reduction === exports.Reduction.NONE) { + return weightedLoss; + } + if (reduction === exports.Reduction.SUM) { + return sum$3(weightedLoss); + } + if (reduction === exports.Reduction.MEAN) { + if ($weights == null) { + return mean$3(weightedLoss); + } + else { + const broadcastFactor = $losses.size / $weights.size; + const result = div$1(sum$3(weightedLoss), sum$3($weights)); + return broadcastFactor > 1 ? div$1(result, scalar(broadcastFactor)) : + result; + } + } + if (reduction === exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + if ($weights == null) { + return div$1(sum$3(weightedLoss), scalar($losses.size)); + } + else { + const broadcastedWeights = mul($weights, ones$1($losses.shape)); + const numNonZeros = cast$3(sum$3(notEqual$2(broadcastedWeights, scalar(0))), 'float32'); + return div$1(sum$3(weightedLoss), numNonZeros); + } + } + throw Error(`Unknown reduction: ${reduction}`); + } + const computeWeightedLoss$1 = /* @__PURE__ */ op({ computeWeightedLoss_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the absolute difference loss between two tensors. + * + * @param labels The ground truth output tensor, same dimensions as + * 'predictions'. + * @param predictions The predicted outputs. + * @param weights Tensor whose rank is either 0, or the same rank as + * `labels`, and must be broadcastable to `labels` (i.e., all dimensions + * must be either `1`, or the same as the corresponding `losses` + * dimension). + * @param reduction Type of reduction to apply to loss. Should be of type + * `Reduction` + * + * @doc {heading: 'Training', subheading: 'Losses', namespace: 'losses'} + */ + function absoluteDifference_(labels, predictions, weights, reduction = exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + const $labels = convertToTensor(labels, 'labels', 'absoluteDifference'); + const $predictions = convertToTensor(predictions, 'predictions', 'absoluteDifference'); + let $weights = null; + if (weights != null) { + $weights = convertToTensor(weights, 'weights', 'absoluteDifference'); + } + assertShapesMatch($labels.shape, $predictions.shape, 'Error in absoluteDifference: '); + const losses = abs$2(sub$2($labels, $predictions)); + return computeWeightedLoss$1(losses, $weights, reduction); + } + const absoluteDifference = /* @__PURE__ */ op({ absoluteDifference_ }); + + /** + * Computes the cosine distance loss between two tensors. + * + * @param labels The ground truth output tensor, same dimensions as + * 'predictions'. + * @param predictions The predicted outputs. + * @param axis The dimension along which the cosine distance is computed. + * @param weights Tensor whose rank is either 0, or the same rank as + * `labels`, and must be broadcastable to `labels` (i.e., all dimensions + * must be either `1`, or the same as the corresponding `losses` + * dimension). + * @param reduction Type of reduction to apply to loss. Should be of type + * `Reduction` + * + * @doc {heading: 'Training', subheading: 'Losses', namespace: 'losses'} + */ + function cosineDistance_(labels, predictions, axis, weights, reduction = exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + const $labels = convertToTensor(labels, 'labels', 'cosineDistance'); + const $predictions = convertToTensor(predictions, 'predictions', 'cosineDistance'); + let $weights = null; + if (weights != null) { + $weights = convertToTensor(weights, 'weights', 'cosineDistance'); + } + assertShapesMatch($labels.shape, $predictions.shape, 'Error in cosineDistance: '); + const one = scalar(1); + const losses = sub$2(one, sum$3(mul($labels, $predictions), axis, true)); + return computeWeightedLoss$1(losses, $weights, reduction); + } + const cosineDistance = /* @__PURE__ */ op({ cosineDistance_ }); + + /** + * Computes the Hinge loss between two tensors. + * + * @param labels The ground truth output tensor, same dimensions as + * 'predictions'. + * @param predictions The predicted outputs. + * @param weights Tensor whose rank is either 0, or the same rank as + * `labels`, and must be broadcastable to `labels` (i.e., all dimensions + * must be either `1`, or the same as the corresponding `losses` + * dimension). + * @param reduction Type of reduction to apply to loss. Should be of type + * `Reduction` + * + * @doc {heading: 'Training', subheading: 'Losses', namespace: 'losses'} + */ + function hingeLoss_(labels, predictions, weights, reduction = exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + let $labels = convertToTensor(labels, 'labels', 'hingeLoss'); + const $predictions = convertToTensor(predictions, 'predictions', 'hingeLoss'); + let $weights = null; + if (weights != null) { + $weights = convertToTensor(weights, 'weights', 'hingeLoss'); + } + assertShapesMatch($labels.shape, $predictions.shape, 'Error in hingeLoss: '); + const one = scalar(1); + // Convert binary labels to (-1, 1) + $labels = sub$2(mul(scalar(2), $labels), one); + const losses = relu$2(sub$2(one, mul($labels, $predictions))); + return computeWeightedLoss$1(losses, $weights, reduction); + } + const hingeLoss = /* @__PURE__ */ op({ hingeLoss_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the Huber loss between two tensors. + * + * @param labels The ground truth output tensor, same dimensions as + * 'predictions'. + * @param predictions The predicted outputs. + * @param weights Tensor whose rank is either 0, or the same rank as + * `labels`, and must be broadcastable to `labels` (i.e., all dimensions + * must be either `1`, or the same as the corresponding `losses` + * dimension). + * @param delta Point where Huber loss changes from quadratic to linear. + * @param reduction Type of reduction to apply to loss. Should be of type + * `Reduction`. + * + * @doc {heading: 'Training', subheading: 'Losses', namespace: 'losses'} + */ + function huberLoss_(labels, predictions, weights, delta = 1.0, reduction = exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + const $labels = convertToTensor(labels, 'labels', 'huberLoss'); + const $predictions = convertToTensor(predictions, 'predictions', 'huberLoss'); + let $weights = null; + if (weights != null) { + $weights = convertToTensor(weights, 'weights', 'huberLoss'); + } + assertShapesMatch($labels.shape, $predictions.shape, 'Error in huberLoss: '); + const deltaScalar = scalar(delta); + const error = abs$2(sub$2($predictions, $labels)); + const quadratic = minimum$4(error, deltaScalar); + const linear = sub$2(error, quadratic); + const losses = add$3(mul(scalar(0.5), square$2(quadratic)), mul(deltaScalar, linear)); + return computeWeightedLoss$1(losses, $weights, reduction); + } + const huberLoss = /* @__PURE__ */ op({ huberLoss_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the log loss between two tensors. + * + * @param labels The ground truth output tensor, same dimensions as + * 'predictions'. + * @param predictions The predicted outputs. + * @param weights Tensor whose rank is either 0, or the same rank as + * `labels`, and must be broadcastable to `labels` (i.e., all dimensions + * must be either `1`, or the same as the corresponding `losses` + * dimension). + * @param epsilon A small increment to avoid taking log of zero + * @param reduction Type of reduction to apply to loss. Should be of type + * `Reduction` + * + * @doc {heading: 'Training', subheading: 'Losses', namespace: 'losses'} + */ + function logLoss_(labels, predictions, weights, epsilon = 1e-7, reduction = exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + const $labels = convertToTensor(labels, 'labels', 'logLoss'); + const $predictions = convertToTensor(predictions, 'predictions', 'logLoss'); + let $weights = null; + if (weights != null) { + $weights = convertToTensor(weights, 'weights', 'logLoss'); + } + assertShapesMatch($labels.shape, $predictions.shape, 'Error in logLoss: '); + const one = scalar(1); + const epsilonScalar = scalar(epsilon); + const l1 = neg$2(mul($labels, log$2(add$3($predictions, epsilonScalar)))); + const l2 = mul(sub$2(one, $labels), log$2(add$3(sub$2(one, $predictions), epsilonScalar))); + const losses = sub$2(l1, l2); + return computeWeightedLoss$1(losses, $weights, reduction); + } + const logLoss = /* @__PURE__ */ op({ logLoss_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the mean squared error between two tensors. + * + * @param labels The ground truth output tensor, same dimensions as + * 'predictions'. + * @param predictions The predicted outputs. + * @param weights Tensor whose rank is either 0, or the same rank as + * `labels`, and must be broadcastable to `labels` (i.e., all dimensions + * must be either `1`, or the same as the corresponding `losses` + * dimension). + * @param reduction Type of reduction to apply to loss. Should be of type + * `Reduction` + * + * @doc {heading: 'Training', subheading: 'Losses', namespace: 'losses'} + */ + function meanSquaredError_(labels, predictions, weights, reduction = exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + const $labels = convertToTensor(labels, 'labels', 'meanSquaredError'); + const $predictions = convertToTensor(predictions, 'predictions', 'meanSquaredError'); + let $weights = null; + if (weights != null) { + $weights = convertToTensor(weights, 'weights', 'meanSquaredError'); + } + assertShapesMatch($labels.shape, $predictions.shape, 'Error in meanSquaredError: '); + const losses = squaredDifference$2($labels, $predictions); + return computeWeightedLoss$1(losses, $weights, reduction); + } + const meanSquaredError$2 = /* @__PURE__ */ op({ meanSquaredError_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sigmoidCrossEntropyWithLogits_(labels, logits) { + const $labels = convertToTensor(labels, 'labels', 'sigmoidCrossEntropyWithLogits'); + const $logits = convertToTensor(logits, 'logits', 'sigmoidCrossEntropyWithLogits'); + assertShapesMatch($labels.shape, $logits.shape, 'Error in sigmoidCrossEntropyWithLogits: '); + /** + * Implementation Details: + * + * For brevity, let `x = logits`, `z = labels`. The logistic loss is + * z * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x)) + * = z * -log(1 / (1 + exp(-x))) + (1 - z) * -log(exp(-x) / (1 + exp(-x))) + * = z * log(1 + exp(-x)) + (1 - z) * (-log(exp(-x)) + log(1 + exp(-x))) + * = z * log(1 + exp(-x)) + (1 - z) * (x + log(1 + exp(-x)) + * = (1 - z) * x + log(1 + exp(-x)) + * = x - x * z + log(1 + exp(-x)) + * + * For x < 0, to avoid overflow in exp(-x), we reformulate the above + * x - x * z + log(1 + exp(-x)) + * = log(exp(x)) - x * z + log(1 + exp(-x)) + * = - x * z + log(1 + exp(x)) + * + * Hence, to ensure stability and avoid overflow, the implementation uses + * this equivalent formulation: + * max(x, 0) - x * z + log(1 + exp(-abs(x))) + */ + const maxOutput = relu$2($logits); + const outputXTarget = mul($logits, $labels); + const sigmoidOutput = log1p$2(exp$2(neg$2(abs$2($logits)))); + return add$3(sub$2(maxOutput, outputXTarget), sigmoidOutput); + } + /** + * Computes the sigmoid cross entropy loss between two tensors. + * + * If labelSmoothing is nonzero, smooth the labels towards 1/2: + * + * newMulticlassLabels = multiclassLabels * (1 - labelSmoothing) + * + 0.5 * labelSmoothing + * + * @param multiClassLabels The ground truth output tensor of shape + * [batch_size, num_classes], same dimensions as 'predictions'. + * @param logits The predicted outputs. + * @param weights Tensor whose rank is either 0, or the same rank as + * `labels`, and must be broadcastable to `labels` (i.e., all dimensions + * must be either `1`, or the same as the corresponding `losses` + * dimension). + * @param labelSmoothing If greater than 0, then smooth the labels. + * @param reduction Type of reduction to apply to loss. Should be of type + * `Reduction` + * + * @doc { heading: 'Training', subheading: 'Losses', namespace: 'losses' } + */ + function sigmoidCrossEntropy_(multiClassLabels, logits, weights, labelSmoothing = 0, reduction = exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + let $multiClassLabels = convertToTensor(multiClassLabels, 'multiClassLabels', 'sigmoidCrossEntropy'); + const $logits = convertToTensor(logits, 'logits', 'sigmoidCrossEntropy'); + let $weights = null; + if (weights != null) { + $weights = convertToTensor(weights, 'weights', 'sigmoidCrossEntropy'); + } + assertShapesMatch($multiClassLabels.shape, $logits.shape, 'Error in sigmoidCrossEntropy: '); + if (labelSmoothing > 0) { + const labelSmoothingScalar = scalar(labelSmoothing); + const one = scalar(1); + const half = scalar(0.5); + $multiClassLabels = + add$3(mul($multiClassLabels, sub$2(one, labelSmoothingScalar)), mul(half, labelSmoothingScalar)); + } + const losses = sigmoidCrossEntropyWithLogits_($multiClassLabels, $logits); + return computeWeightedLoss$1(losses, $weights, reduction); + } + const sigmoidCrossEntropy = /* @__PURE__ */ op({ sigmoidCrossEntropy_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes softmax cross entropy between logits and labels. + * + * Measures the probability error in discrete classification tasks in which + * the classes are mutually exclusive (each entry is in exactly one class). + * For example, each CIFAR-10 image is labeled with one and only one label: an + * image can be a dog or a truck, but not both. + * + * `NOTE`: While the classes are mutually exclusive, their probabilities need + * not be. All that is required is that each row of labels is a valid + * probability distribution. If they are not, the computation of the gradient + * will be incorrect. + * + * `WARNING`: This op expects unscaled logits, since it performs a softmax on + * logits internally for efficiency. Do not call this op with the output of + * softmax, as it will produce incorrect results. + * + * logits and labels must have the same shape, e.g. [batch_size, num_classes] + * and the same dtype. + * @param labels The labels array. + * @param logits The logits array. + * @param dim The dimension softmax would be performed on. Defaults to `-1` + * which indicates the last dimension. + */ + function softmaxCrossEntropyWithLogits_(labels, logits, dim = -1) { + if (dim === -1) { + dim = logits.rank - 1; + } + if (dim !== logits.rank - 1) { + throw Error(`Softmax cross entropy along a non-last dimension is not yet ` + + `supported. Labels / logits was rank ${logits.rank} ` + + `and dim was ${dim}`); + } + // Use a custom gradient for numerical stability. + const customOp = customGrad((labels, logits, save) => { + // Reference: + // 1. http://cs231n.github.io/linear-classify/#softmax + // 2. https://blog.feedly.com/tricks-of-the-trade-logsumexp/ + const keepDims = true; + const lse = logSumExp(logits, [dim], keepDims); + const logResult = sub$2(cast$3(logits, 'float32'), lse); + save([labels, logResult]); + const costVector = neg$2(mul(logResult, labels)); + const value = sum$3(costVector, [dim]); + const gradFunc = (dy, saved) => { + const [labels, logResult] = saved; + const dyShape = expandShapeToKeepDim(dy.shape, [dim]); + return [ + mul(reshape$3(dy, dyShape), sub$2(cast$3(labels, 'float32'), exp$2(logResult))), + mul(reshape$3(dy, dyShape), sub$2(exp$2(logResult), cast$3(labels, 'float32'))), + ]; + }; + return { value, gradFunc }; + }); + return customOp(labels, logits); + } + /** + * Computes the softmax cross entropy loss between two tensors. + * + * If labelSmoothing is nonzero, smooth the labels towards 1/2: + * + * newOnehotLabels = onehotLabels * (1 - labelSmoothing) + * + labelSmoothing / numClasses + * + * @param onehotLabels One hot encoded labels + * [batch_size, num_classes], same dimensions as 'predictions'. + * @param logits The predicted outputs. + * @param weights Tensor whose rank is either 0, or 1, and must be + * broadcastable to `loss` of shape [batch_size] + * @param labelSmoothing If greater than 0, then smooth the labels. + * @param reduction Type of reduction to apply to loss. Should be of type + * `Reduction` + * + * @doc { heading: 'Training', subheading: 'Losses', namespace: 'losses' } + */ + function softmaxCrossEntropy_(onehotLabels, logits, weights, labelSmoothing = 0, reduction = exports.Reduction.SUM_BY_NONZERO_WEIGHTS) { + let $onehotLabels = convertToTensor(onehotLabels, 'onehotLabels', 'softmaxCrossEntropy'); + const $logits = convertToTensor(logits, 'logits', 'softmaxCrossEntropy'); + let $weights = null; + if (weights != null) { + $weights = convertToTensor(weights, 'weights', 'softmaxCrossEntropy'); + } + assertShapesMatch($onehotLabels.shape, $logits.shape, 'Error in softmaxCrossEntropy: '); + if (labelSmoothing > 0) { + const labelSmoothingScalar = scalar(labelSmoothing); + const one = scalar(1); + const numClasses = scalar($onehotLabels.shape[1]); + $onehotLabels = + add$3(mul($onehotLabels, sub$2(one, labelSmoothingScalar)), div$1(labelSmoothingScalar, numClasses)); + } + const losses = softmaxCrossEntropyWithLogits_($onehotLabels, $logits); + return computeWeightedLoss$1(losses, $weights, reduction); + } + const softmaxCrossEntropy = /* @__PURE__ */ op({ softmaxCrossEntropy_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * The input SparseTensor is represented via the map of inputs {`indices`, + * `values`, `denseShape`}. The output SparseTensor has the same `denseShape` + * but with indices `outputIndices` and values `outputValues`. This op inserts a + * single entry for every row that doesn't have any values. The index is created + * as `[row, 0, ..., 0]` and the inserted value is `defaultValue`. + * + * For example, suppose `spInput` has shape [5, 6] and non-empty values: + * [0, 1]: a + * [0, 3]: b + * [2, 0]: c + * [3, 1]: d + * + * Rows 1 and 4 are empty, so the output will be of shape [5, 6] with values: + * [0, 1]: a + * [0, 3]: b + * [1, 0]: `defaultValue` + * [2, 0]: c + * [3, 1]: d + * [4, 0]: `defaultValue` + * + * The output SparseTensor will be in row-major order and will have the same + * shape as the input. + * + * This op also returns an indicator vector shaped [dense_shape[0]] such that + * emptyRowIndicator[i] = True iff row i was an empty row. + * + * And a reverse index map vector shaped [indices.shape[0]] that is used during + * backpropagation, reverseIndexMap[i] = outi s.t. indices[i, j] == + * outputIndices[outi, j] for all j + * + * ```js + * const result = tf.sparse.sparseFillEmptyRows( + * [[0, 0], [1, 0], [1, 3], [1, 4], [3, 2], [3, 3]], + * [0, 10, 13, 14, 32, 33], [5, 6], -1); + * console.log(result); + * result['outputIndices'].print(); // [[0, 0], [1, 0], [1, 3], [1, 4], + * // [2, 0], [3, 2], [3, 3], [4, 0]] + * result['outputValues'].print(); // [0, 10, 13, 14,-1, 32, 33, -1] + * result['emptyRowIndicator'].print(); // [false, false, true, false, true] + * result['reverseIndexMap'].print(); // [0, 1, 2, 3, 5, 6] + * ``` + * @param indices: 2-D. The indices of the sparse tensor. + * @param values: 1-D. The values of the sparse tensor. + * @param denseShape: 1-D. The shape of the sparse tensor. + * @param defaultValue: 0-D. Default value to insert into location [row, 0, ..., + * 0] for rows missing from the input sparse tensor. + * @return A map with the following properties: + * - outputIndices + * - outputValues: 1-D. The values of the filled sparse tensor. + * - emptyRowIndicator: 1-D. Whether the dense row was missing in the input + * sparse tensor. + * - reverseIndexMap: 1-D. A map from the input indices to the output + * indices. + * @doc {heading: 'Operations', subheading: 'Sparse'} + */ + function sparseFillEmptyRows_(indices, values, denseShape, defaultValue) { + const $indices = convertToTensor(indices, 'indices', 'sparseFillEmptyRows', 'int32'); + const $values = convertToTensor(values, 'values', 'sparseFillEmptyRows'); + const $denseShape = convertToTensor(denseShape, 'denseShape', 'sparseFillEmptyRows', 'int32'); + const $defaultValue = convertToTensor(defaultValue, 'defaultValue', 'sparseFillEmptyRows', $values.dtype); + if ($indices.rank !== 2) { + throw new Error(`Indices should be Tensor2D but received shape + ${$indices.shape}`); + } + if ($values.rank !== 1) { + throw new Error(`Values should be Tensor1D but received shape ${$values.shape}`); + } + if ($denseShape.rank !== 1) { + throw new Error(`Dense shape should be Tensor1D but received shape ${$denseShape.shape}`); + } + if ($defaultValue.rank !== 0) { + throw new Error(`Default value should be a scalar but received shape ${$defaultValue.shape}`); + } + const inputs = { + indices: $indices, + values: $values, + denseShape: $denseShape, + defaultValue: $defaultValue + }; + const result = ENGINE.runKernel(SparseFillEmptyRows, inputs); + return { + outputIndices: result[0], + outputValues: result[1], + emptyRowIndicator: result[2], + reverseIndexMap: result[3] + }; + } + const sparseFillEmptyRows$2 = /* @__PURE__ */ op({ sparseFillEmptyRows_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * This operation has the same semantics as reshape on the represented dense + * tensor. The `inputIndices` are recomputed based on the requested `newShape`. + * If one component of `newShape` is the special value -1, the size of that + * dimension is computed so that the total dense size remains constant. At most + * one component of `newShape` can be -1. The number of dense elements implied + * by `newShape` must be the same as the number of dense elements originally + * implied by `inputShape`. Reshaping does not affect the order of values in the + * SparseTensor. If the input tensor has rank R_in and N non-empty values, and + * `newShape` has length R_out, then `inputIndices` has shape [N, R_in], + * `inputShape` has length R_in, `outputIndices` has shape [N, R_out], and + * `outputShape` has length R_out. + * + * ```js + * const result = tf.sparse.sparseReshape( + * [[0, 0, 0], [0, 0, 1], [0, 1, 0], [1, 0, 0], [1, 2, 3]], + * [2, 3, 6], [9, -1]); + * console.log(result); + * result['outputIndices'].print(); //[[0, 0], [0, 1], [1, 2], [4, 2], [8, 1]] + * result['outputShape'].print(); // [9, 4] + * ``` + * @param inputIndices: 2-D. N x R_in matrix with the indices of non-empty + * values in a SparseTensor. + * @param inputShape: 1-D. R_in Tensor1D with the input SparseTensor's dense + * shape. + * @param newShape: 1-D. R_out Tensor1D with the requested new dense shape. + * @return A map with the following properties: + * - outputIndices: 2-D. N x R_out matrix with the updated indices of + * non-empty values in the output SparseTensor. + * - outputShape: 1-D. R_out vector with the full dense shape of the output + * SparseTensor. This is the same as newShape but with any -1 dimensions + * filled in. + * @doc {heading: 'Operations', subheading: 'Sparse'} + */ + function sparseReshape_(inputIndices, inputShape, newShape) { + const $inputIndices = convertToTensor(inputIndices, 'inputIndices', 'sparseReshape', 'int32'); + const $inputShape = convertToTensor(inputShape, 'inputShape', 'sparseReshape', 'int32'); + const $newShape = convertToTensor(newShape, 'newShape', 'sparseReshape', 'int32'); + if ($inputIndices.rank !== 2) { + throw new Error(`Input indices should be Tensor2D but received shape + ${$inputIndices.shape}`); + } + if ($inputShape.rank !== 1) { + throw new Error(`Input shape should be Tensor1D but received shape ${$inputShape.shape}`); + } + if ($newShape.rank !== 1) { + throw new Error(`New shape should be Tensor1D but received shape ${$newShape.shape}`); + } + const inputs = { + inputIndices: $inputIndices, + inputShape: $inputShape, + newShape: $newShape + }; + const result = ENGINE.runKernel(SparseReshape, inputs); + return { outputIndices: result[0], outputShape: result[1] }; + } + const sparseReshape$2 = /* @__PURE__ */ op({ sparseReshape_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the mean along sparse segments of a tensor. + * + * ```js + * const c = tf.tensor2d([[1,2,3,4], [-1,-2,-3,-4], [6,7,8,9]]); + * // Select two rows, one segment. + * const result1 = tf.sparse.sparseSegmentMean(c, + * tf.tensor1d([0, 1], 'int32'), + * tf.tensor1d([0, 0], 'int32')); + * result1.print(); // [[0, 0, 0, 0]] + * + * // Select two rows, two segments. + * const result2 = tf.sparse.sparseSegmentMean(c, + * tf.tensor1d([0, 1], 'int32'), + * tf.tensor1d([0, 1], 'int32')); + * result2.print(); // [[1, 2, 3, 4], [-1, -2, -3, -4]] + * + * // Select all rows, two segments. + * const result3 = tf.sparse.sparseSegmentMean(c, + * tf.tensor1d([0, 1, 2], 'int32'), + * tf.tensor1d([0, 1, 1], 'int32')); + * result3.print(); // [[1.0, 2.0, 3.0, 4.0], [2.5, 2.5, 2.5, 2.5]] + * ``` + * @param data: A Tensor of at least one dimension with data that will be + * assembled in the output. + * @param indices: A 1-D Tensor with indices into data. Has same rank as + * segmentIds. + * @param segmentIds: A 1-D Tensor with indices into the output Tensor. Values + * should be sorted and can be repeated. + * @return Has same shape as data, except for dimension 0 which has equal to + * the number of segments. + * + * @doc {heading: 'Operations', subheading: 'Sparse'} + */ + function sparseSegmentMean_(data, indices, segmentIds) { + const $data = convertToTensor(data, 'data', 'sparseSegmentMean'); + const $indices = convertToTensor(indices, 'indices', 'sparseSegmentMean', 'int32'); + const $segmentIds = convertToTensor(segmentIds, 'segmentIds', 'sparseSegmentMean', 'int32'); + if ($data.rank < 1) { + throw new Error(`Data should be at least 1 dimensional but received scalar`); + } + if ($indices.rank !== 1) { + throw new Error(`Indices should be Tensor1D but received shape + ${$indices.shape}`); + } + if ($segmentIds.rank !== 1) { + throw new Error(`Segment ids should be Tensor1D but received shape + ${$segmentIds.shape}`); + } + const inputs = { + data: $data, + indices: $indices, + segmentIds: $segmentIds + }; + return ENGINE.runKernel(SparseSegmentMean, inputs); + } + const sparseSegmentMean$2 = /* @__PURE__ */ op({ sparseSegmentMean_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the sum along sparse segments of a tensor. + * + * ```js + * const c = tf.tensor2d([[1,2,3,4], [-1,-2,-3,-4], [5,6,7,8]]); + * // Select two rows, one segment. + * const result1 = tf.sparse.sparseSegmentSum(c, + * tf.tensor1d([0, 1], 'int32'), + * tf.tensor1d([0, 0], 'int32')); + * result1.print(); // [[0, 0, 0, 0]] + * + * // Select two rows, two segments. + * const result2 = tf.sparse.sparseSegmentSum(c, + * tf.tensor1d([0, 1], 'int32'), + * tf.tensor1d([0, 1], 'int32')); + * result2.print(); // [[1, 2, 3, 4], [-1, -2, -3, -4]] + * + * // Select all rows, two segments. + * const result3 = tf.sparse.sparseSegmentSum(c, + * tf.tensor1d([0, 1, 2], 'int32'), + * tf.tensor1d([0, 0, 1], 'int32')); + * result3.print(); // [[0, 0, 0, 0], [5, 6, 7, 8]] + * ``` + * @param data: A Tensor of at least one dimension with data that will be + * assembled in the output. + * @param indices: A 1-D Tensor with indices into data. Has same rank as + * segmentIds. + * @param segmentIds: A 1-D Tensor with indices into the output Tensor. Values + * should be sorted and can be repeated. + * @return Has same shape as data, except for dimension 0 which has equal to + * the number of segments. + * + * @doc {heading: 'Operations', subheading: 'Sparse'} + */ + function sparseSegmentSum_(data, indices, segmentIds) { + const $data = convertToTensor(data, 'data', 'sparseSegmentSum'); + const $indices = convertToTensor(indices, 'indices', 'sparseSegmentSum', 'int32'); + const $segmentIds = convertToTensor(segmentIds, 'segmentIds', 'sparseSegmentSum', 'int32'); + if ($data.rank < 1) { + throw new Error(`Data should be at least 1 dimensional but received scalar`); + } + if ($indices.rank !== 1) { + throw new Error(`Indices should be Tensor1D but received shape + ${$indices.shape}`); + } + if ($segmentIds.rank !== 1) { + throw new Error(`Segment ids should be Tensor1D but received shape + ${$segmentIds.shape}`); + } + const inputs = { + data: $data, + indices: $indices, + segmentIds: $segmentIds + }; + return ENGINE.runKernel(SparseSegmentSum, inputs); + } + const sparseSegmentSum$2 = /* @__PURE__ */ op({ sparseSegmentSum_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Creates ngrams from ragged string data. + * + * This op accepts a ragged tensor with 1 ragged dimension containing only + * strings and outputs a ragged tensor with 1 ragged dimension containing ngrams + * of that string, joined along the innermost axis. + * + * ```js + * const result = tf.string.stringNGrams( + * ['a', 'b', 'c', 'd'], tf.tensor1d([0, 2, 4], 'int32'), + * '|', [1, 2], 'LP', 'RP', -1, false); + * result['nGrams'].print(); // ['a', 'b', 'LP|a', 'a|b', 'b|RP', + * // 'c', 'd', 'LP|c', 'c|d', 'd|RP'] + * result['nGramsSplits'].print(); // [0, 5, 10] + * ``` + * @param data: The values tensor of the ragged string tensor to make ngrams out + * of. Must be a 1D string tensor. + * @param dataSplits: The splits tensor of the ragged string tensor to make + * ngrams out of. + * @param separator: The string to append between elements of the token. Use "" + * for no separator. + * @param nGramWidths: The sizes of the ngrams to create. + * @param leftPad: The string to use to pad the left side of the ngram sequence. + * Only used if pad_width !== 0. + * @param rightPad: The string to use to pad the right side of the ngram + * sequence. Only used if pad_width !== 0. + * @param padWidth: The number of padding elements to add to each side of each + * sequence. Note that padding will never be greater than `nGramWidths`-1 + * regardless of this value. If `padWidth`=-1, then add max(`nGramWidths`)-1 + * elements. + * @param preserveShortSequences: If true, then ensure that at least one ngram + * is generated for each input sequence. In particular, if an input sequence + * is shorter than min(ngramWidth) + 2*padWidth, then generate a single + * ngram containing the entire sequence. If false, then no ngrams are + * generated for these short input sequences. + * @return A map with the following properties: + * - nGrams: The values tensor of the output ngrams ragged tensor. + * - nGramsSplits: The splits tensor of the output ngrams ragged tensor. + * + * @doc {heading: 'Operations', subheading: 'String'} + */ + function stringNGrams_(data, dataSplits, separator, nGramWidths, leftPad, rightPad, padWidth, preserveShortSequences) { + const $data = convertToTensor(data, 'data', 'stringNGrams', 'string'); + if ($data.dtype !== 'string') { + throw new Error('Data must be of datatype string'); + } + if ($data.shape.length !== 1) { + throw new Error(`Data must be a vector, saw: ${$data.shape}`); + } + const $dataSplits = convertToTensor(dataSplits, 'dataSplits', 'stringNGrams'); + if ($dataSplits.dtype !== 'int32') { + throw new Error('Data splits must be of datatype int32'); + } + const attrs = { + separator, + nGramWidths, + leftPad, + rightPad, + padWidth, + preserveShortSequences + }; + const inputs = { data: $data, dataSplits: $dataSplits }; + const result = ENGINE.runKernel(StringNGrams, inputs, attrs); + return { nGrams: result[0], nGramsSplits: result[1] }; + } + const stringNGrams$2 = /* @__PURE__ */ op({ stringNGrams_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Split elements of `input` based on `delimiter` into a SparseTensor . + * + * Let N be the size of source (typically N will be the batch size). Split each + * element of `input` based on `delimiter` and return a SparseTensor containing + * the splitted tokens. Empty tokens are ignored if `skipEmpty` is set to True. + * + * `delimiter` can be empty, or a string of split characters. If `delimiter` is + * an empty string, each element of `input` is split into individual + * character strings. Otherwise every character of `delimiter` is a potential + * split point. + * + * ```js + * const result = tf.string.stringSplit(['hello world', 'a b c'], ' '); + * result['indices'].print(); // [[0, 0], [0, 1], [1, 0], [1, 1], [1, 2]] + * result['values'].print(); // ['hello', 'world', 'a', 'b', 'c'] + * result['shape'].print(); // [2, 3] + * ``` + * @param input: 1-D. Strings to split. + * @param delimiter: 0-D. Delimiter characters, or empty string. + * @param skipEmpty: Optional. If true, skip the empty strings from the result. + * Defaults to true. + * @return A map with the following properties: + * - indices: A dense matrix of int32 representing the indices of the sparse + * tensor. + * - values: A vector of strings corresponding to the splited values. + * - shape: a length-2 vector of int32 representing the shape of the sparse + * tensor, where the first value is N and the second value is the maximum number + * of tokens in a single input entry. + * + * @doc {heading: 'Operations', subheading: 'String'} + */ + function stringSplit_(input, delimiter, skipEmpty = true) { + const $input = convertToTensor(input, 'input', 'stringSplit', 'string'); + const $delimiter = convertToTensor(delimiter, 'delimiter', 'stringSplit', 'string'); + if ($input.rank !== 1) { + throw new Error(`Input should be Tensor1D but received shape ${$input.shape}`); + } + if ($delimiter.rank !== 0) { + throw new Error(`Delimiter should be a scalar but received shape ${$delimiter.shape}`); + } + const attrs = { skipEmpty }; + const inputs = { input: $input, delimiter: $delimiter }; + const result = ENGINE.runKernel(StringSplit, inputs, attrs); + return { indices: result[0], values: result[1], shape: result[2] }; + } + const stringSplit$2 = /* @__PURE__ */ op({ stringSplit_ }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts each string in the input Tensor to its hash mod by a number of + * buckets. + * + * The hash function is deterministic on the content of the string within the + * process and will never change. However, it is not suitable for cryptography. + * This function may be used when CPU time is scarce and inputs are trusted or + * unimportant. There is a risk of adversaries constructing inputs that all hash + * to the same bucket. + * + * ```js + * const result = tf.string.stringToHashBucketFast( + * ['Hello', 'TensorFlow', '2.x'], 3); + * result.print(); // [0, 2, 2] + * ``` + * @param input: The strings to assign a hash bucket. + * @param numBuckets: The number of buckets. + * @return A Tensor of the same shape as the input tensor. + * + * @doc {heading: 'Operations', subheading: 'String'} + */ + function stringToHashBucketFast_(input, numBuckets) { + const $input = convertToTensor(input, 'input', 'stringToHashBucketFast', 'string'); + const attrs = { numBuckets }; + if (numBuckets <= 0) { + throw new Error(`Number of buckets must be at least 1`); + } + const inputs = { input: $input }; + return ENGINE.runKernel(StringToHashBucketFast, inputs, attrs); + } + const stringToHashBucketFast$2 = /* @__PURE__ */ op({ stringToHashBucketFast_ }); + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Replace the match of a `pattern` in `input` with `rewrite`. + * + * ```js + * const result = tf.string.staticRegexReplace( + * ['format this spacing better'], ' +', ' '); + * result.print(); // ['format this spacing better'] + * ``` + * @param input: A Tensor of type string. The text to be processed. + * @param pattern: A string. The regular expression to match the input. + * @param rewrite: A string. The rewrite to be applied to the matched + * expression. + * @param replaceGlobal: An optional bool. Defaults to True. If True, the + * replacement is global, otherwise the replacement is done only on the + * first match. + * @return A Tensor of type string. + * + * @doc {heading: 'Operations', subheading: 'String'} + */ + function staticRegexReplace_(input, pattern, rewrite, replaceGlobal = true) { + const $input = convertToTensor(input, 'input', 'staticRegexReplace', 'string'); + const attrs = { pattern, rewrite, replaceGlobal }; + return ENGINE.runKernel(StaticRegexReplace, { x: $input }, attrs); + } + const staticRegexReplace$2 = /* @__PURE__ */ op({ staticRegexReplace_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const spectral$1 = { + fft: fft$2, + ifft: ifft$2, + rfft, + irfft + }; + const signal = { + hammingWindow, + hannWindow, + frame, + stft, + }; + const image$1 = { + flipLeftRight, + grayscaleToRGB, + resizeNearestNeighbor: resizeNearestNeighbor$2, + resizeBilinear: resizeBilinear$3, + rgbToGrayscale, + rotateWithOffset, + cropAndResize: cropAndResize$3, + nonMaxSuppression, + nonMaxSuppressionAsync, + nonMaxSuppressionWithScore, + nonMaxSuppressionWithScoreAsync, + nonMaxSuppressionPadded, + nonMaxSuppressionPaddedAsync, + threshold: threshold$1, + transform: transform$2 + }; + const linalg = { + bandPart, + gramSchmidt, + qr + }; + const losses = { + absoluteDifference, + computeWeightedLoss: computeWeightedLoss$1, + cosineDistance, + hingeLoss, + huberLoss, + logLoss, + meanSquaredError: meanSquaredError$2, + sigmoidCrossEntropy, + softmaxCrossEntropy + }; + const sparse$1 = { + sparseFillEmptyRows: sparseFillEmptyRows$2, + sparseReshape: sparseReshape$2, + sparseSegmentMean: sparseSegmentMean$2, + sparseSegmentSum: sparseSegmentSum$2 + }; + // tslint:disable-next-line:variable-name + const string$1 = { + stringNGrams: stringNGrams$2, + stringSplit: stringSplit$2, + stringToHashBucketFast: stringToHashBucketFast$2, + staticRegexReplace: staticRegexReplace$2, + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Maps to mapping between the custom object and its name. + * + * After registering a custom class, these two maps will add key-value pairs + * for the class object and the registered name. + * + * Therefore we can get the relative registered name by calling + * getRegisteredName() function. + * + * For example: + * GLOBAL_CUSTOM_OBJECT: {key=registeredName: value=corresponding + * CustomObjectClass} + * + * GLOBAL_CUSTOM_NAMES: {key=CustomObjectClass: value=corresponding + * registeredName} + * + */ + const GLOBAL_CUSTOM_OBJECT = new Map(); + const GLOBAL_CUSTOM_NAMES = new Map(); + /** + * Serializable defines the serialization contract. + * + * TFJS requires serializable classes to return their className when asked + * to avoid issues with minification. + */ + class Serializable { + /** + * Return the class name for this class to use in serialization contexts. + * + * Generally speaking this will be the same thing that constructor.name + * would have returned. However, the class name needs to be robust + * against minification for serialization/deserialization to work properly. + * + * There's also places such as initializers.VarianceScaling, where + * implementation details between different languages led to different + * class hierarchies and a non-leaf node is used for serialization purposes. + */ + getClassName() { + return this.constructor + .className; + } + /** + * Creates an instance of T from a ConfigDict. + * + * This works for most descendants of serializable. A few need to + * provide special handling. + * @param cls A Constructor for the class to instantiate. + * @param config The Configuration for the object. + */ + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config); + } + } + /** + * Maps string keys to class constructors. + * + * Used during (de)serialization from the cross-language JSON format, which + * requires the class name in the serialization format matches the class + * names as used in Python, should it exist. + */ + class SerializationMap { + constructor() { + this.classNameMap = {}; + } + /** + * Returns the singleton instance of the map. + */ + static getMap() { + if (SerializationMap.instance == null) { + SerializationMap.instance = new SerializationMap(); + } + return SerializationMap.instance; + } + /** + * Registers the class as serializable. + */ + static register(cls) { + SerializationMap.getMap().classNameMap[cls.className] = + [cls, cls.fromConfig]; + } + } + /** + * Register a class with the serialization map of TensorFlow.js. + * + * This is often used for registering custom Layers, so they can be + * serialized and deserialized. + * + * Example 1. Register the class without package name and specified name. + * + * ```js + * class MyCustomLayer extends tf.layers.Layer { + * static className = 'MyCustomLayer'; + * + * constructor(config) { + * super(config); + * } + * } + * tf.serialization.registerClass(MyCustomLayer); + * console.log(tf.serialization.GLOBALCUSTOMOBJECT.get("Custom>MyCustomLayer")); + * console.log(tf.serialization.GLOBALCUSTOMNAMES.get(MyCustomLayer)); + * ``` + * + * Example 2. Register the class with package name: "Package" and specified + * name: "MyLayer". + * ```js + * class MyCustomLayer extends tf.layers.Layer { + * static className = 'MyCustomLayer'; + * + * constructor(config) { + * super(config); + * } + * } + * tf.serialization.registerClass(MyCustomLayer, "Package", "MyLayer"); + * console.log(tf.serialization.GLOBALCUSTOMOBJECT.get("Package>MyLayer")); + * console.log(tf.serialization.GLOBALCUSTOMNAMES.get(MyCustomLayer)); + * ``` + * + * Example 3. Register the class with specified name: "MyLayer". + * ```js + * class MyCustomLayer extends tf.layers.Layer { + * static className = 'MyCustomLayer'; + * + * constructor(config) { + * super(config); + * } + * } + * tf.serialization.registerClass(MyCustomLayer, undefined, "MyLayer"); + * console.log(tf.serialization.GLOBALCUSTOMOBJECT.get("Custom>MyLayer")); + * console.log(tf.serialization.GLOBALCUSTOMNAMES.get(MyCustomLayer)); + * ``` + * + * Example 4. Register the class with specified package name: "Package". + * ```js + * class MyCustomLayer extends tf.layers.Layer { + * static className = 'MyCustomLayer'; + * + * constructor(config) { + * super(config); + * } + * } + * tf.serialization.registerClass(MyCustomLayer, "Package"); + * console.log(tf.serialization.GLOBALCUSTOMOBJECT + * .get("Package>MyCustomLayer")); + * console.log(tf.serialization.GLOBALCUSTOMNAMES + * .get(MyCustomLayer)); + * ``` + * + * @param cls The class to be registered. It must have a public static member + * called `className` defined and the value must be a non-empty string. + * @param pkg The package name that this class belongs to. This used to define + * the key in GlobalCustomObject. If not defined, it defaults to `Custom`. + * @param name The name that user specified. It defaults to the actual name of + * the class as specified by its static `className` property. + * @doc {heading: 'Models', subheading: 'Serialization', ignoreCI: true} + */ + function registerClass(cls, pkg, name) { + assert$1(cls.className != null, () => `Class being registered does not have the static className ` + + `property defined.`); + assert$1(typeof cls.className === 'string', () => `className is required to be a string, but got type ` + + typeof cls.className); + assert$1(cls.className.length > 0, () => `Class being registered has an empty-string as its className, ` + + `which is disallowed.`); + if (typeof pkg === 'undefined') { + pkg = 'Custom'; + } + if (typeof name === 'undefined') { + name = cls.className; + } + const className = name; + const registerName = pkg + '>' + className; + SerializationMap.register(cls); + GLOBAL_CUSTOM_OBJECT.set(registerName, cls); + GLOBAL_CUSTOM_NAMES.set(cls, registerName); + return cls; + } + /** + * Get the registered name of a class. If the class has not been registered, + * return the class name. + * + * @param cls The class we want to get register name for. It must have a public + * static member called `className` defined. + * @returns registered name or class name. + */ + function getRegisteredName(cls) { + if (GLOBAL_CUSTOM_NAMES.has(cls)) { + return GLOBAL_CUSTOM_NAMES.get(cls); + } + else { + return cls.className; + } + } + + var serialization = /*#__PURE__*/Object.freeze({ + __proto__: null, + Serializable: Serializable, + SerializationMap: SerializationMap, + getRegisteredName: getRegisteredName, + registerClass: registerClass + }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** @doc {heading: 'Training', subheading: 'Classes', namespace: 'train'} */ + class Optimizer extends Serializable { + /** + * Executes `f()` and minimizes the scalar output of `f()` by computing + * gradients of y with respect to the list of trainable variables provided by + * `varList`. If no list is provided, it defaults to all trainable variables. + * + * @param f The function to execute and whose output to minimize. + * @param returnCost Whether to return the scalar cost value produced by + * executing `f()`. + * @param varList An optional list of variables to update. If specified, only + * the trainable variables in varList will be updated by minimize. Defaults to + * all trainable variables. + * + * @doc {heading: 'Training', subheading: 'Optimizers'} + */ + minimize(f, returnCost = false, varList) { + const { value, grads } = this.computeGradients(f, varList); + if (varList != null) { + const gradArray = varList.map(v => ({ name: v.name, tensor: grads[v.name] })); + this.applyGradients(gradArray); + } + else { + this.applyGradients(grads); + } + // Dispose gradients. + dispose(grads); + if (returnCost) { + return value; + } + else { + value.dispose(); + return null; + } + } + /** + * The number of iterations that this optimizer instance has been invoked for. + */ + get iterations() { + if (this.iterations_ == null) { + this.iterations_ = 0; + } + return this.iterations_; + } + incrementIterations() { + this.iterations_ = this.iterations + 1; + } + /** + * Executes f() and computes the gradient of the scalar output of f() with + * respect to the list of trainable variables provided by `varList`. If no + * list is provided, it defaults to all trainable variables. + * + * @param f The function to execute and whose output to use for computing + * gradients with respect to variables. + * @param varList An optional list of variables to compute gradients with + * respect to. If specified, only the trainable variables in varList will have + * gradients computed with respect to. Defaults to all trainable variables. + * + * @doc {heading: 'Training', subheading: 'Optimizers'} + */ + computeGradients(f, varList) { + return variableGrads(f, varList); + } + /** + * Dispose the variables (if any) owned by this optimizer instance. + */ + dispose() { + if (this.iterations_ != null) { + dispose(this.iterations_); + } + } + async saveIterations() { + if (this.iterations_ == null) { + this.iterations_ = 0; + } + return { + name: 'iter', + // TODO(cais): Use 'int64' type when available. + tensor: scalar(this.iterations_, 'int32') + }; + } + async getWeights() { + throw new Error('getWeights() is not implemented for this optimizer yet.'); + } + async setWeights(weightValues) { + throw new Error(`setWeights() is not implemented for this optimizer class ` + + `${this.getClassName()}`); + } + /** + * Extract the first element of the weight values and set it + * as the iterations counter variable of this instance of optimizer. + * + * @param weightValues + * @returns Weight values with the first element consumed and excluded. + */ + async extractIterations(weightValues) { + this.iterations_ = (await weightValues[0].tensor.data())[0]; + return weightValues.slice(1); + } + } + Object.defineProperty(Optimizer, Symbol.hasInstance, { + value: (instance) => { + return instance.minimize != null && instance.computeGradients != null && + instance.applyGradients != null; + } + }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** @doclink Optimizer */ + class AdadeltaOptimizer extends Optimizer { + /** @nocollapse */ + static get className() { + // Name matters for Python compatibility. + // This is a getter instead of a property because when it's a property, it + // prevents the entire class from being tree-shaken. + return 'Adadelta'; + } + constructor(learningRate, rho, epsilon = null) { + super(); + this.learningRate = learningRate; + this.rho = rho; + this.epsilon = epsilon; + this.accumulatedGrads = []; + this.accumulatedUpdates = []; + if (epsilon == null) { + this.epsilon = ENGINE.backend.epsilon(); + } + } + applyGradients(variableGradients) { + const variableNames = Array.isArray(variableGradients) ? + variableGradients.map(item => item.name) : + Object.keys(variableGradients); + variableNames.forEach((name, i) => { + const value = ENGINE.registeredVariables[name]; + const trainable = false; + if (this.accumulatedGrads[i] == null) { + this.accumulatedGrads[i] = { + originalName: `${name}/accum_grad`, + variable: tidy(() => zerosLike$3(value).variable(trainable)) + }; + } + if (this.accumulatedUpdates[i] == null) { + this.accumulatedUpdates[i] = { + originalName: `${name}/accum_var`, + variable: tidy(() => zerosLike$3(value).variable(trainable)) + }; + } + const gradient = Array.isArray(variableGradients) ? + variableGradients[i].tensor : + variableGradients[name]; + if (gradient == null) { + return; + } + const accumulatedGrad = this.accumulatedGrads[i].variable; + const accumulatedUpdate = this.accumulatedUpdates[i].variable; + tidy(() => { + const newAccumulatedGrad = add$3(mul(accumulatedGrad, this.rho), mul(square$2(gradient), 1 - this.rho)); + const updates = mul(div$1(sqrt$2(add$3(accumulatedUpdate, this.epsilon)), sqrt$2(add$3(accumulatedGrad, this.epsilon))), gradient); + const newAccumulatedUpdate = add$3(mul(accumulatedUpdate, this.rho), mul(square$2(updates), 1 - this.rho)); + accumulatedGrad.assign(newAccumulatedGrad); + accumulatedUpdate.assign(newAccumulatedUpdate); + const newValue = add$3(mul(updates, -this.learningRate), value); + value.assign(newValue); + }); + }); + this.incrementIterations(); + } + dispose() { + if (this.accumulatedUpdates != null) { + dispose(this.accumulatedGrads.map(v => v.variable)); + dispose(this.accumulatedUpdates.map(v => v.variable)); + } + } + async getWeights() { + // Order matters for Python compatibility. + const variables = [...this.accumulatedGrads, ...this.accumulatedUpdates]; + return [await this.saveIterations()].concat(variables.map(v => ({ name: v.originalName, tensor: v.variable }))); + } + async setWeights(weightValues) { + weightValues = await this.extractIterations(weightValues); + const variableCount = weightValues.length / 2; + const trainable = false; + this.accumulatedGrads = + weightValues.slice(0, variableCount).map(v => ({ + originalName: v.name, + variable: v.tensor.variable(trainable) + })); + this.accumulatedUpdates = + weightValues.slice(variableCount, variableCount * 2) + .map(v => ({ + originalName: v.name, + variable: v.tensor.variable(trainable) + })); + } + getConfig() { + return { + 'learningRate': this.learningRate, + 'rho': this.rho, + 'epsilon': this.epsilon + }; + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config['learningRate'], config['rho'], config['epsilon']); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** @doclink Optimizer */ + class AdagradOptimizer extends Optimizer { + /** @nocollapse */ + static get className() { + // Name matters for Python compatibility. + // This is a getter instead of a property because when it's a property, it + // prevents the entire class from being tree-shaken. + return 'Adagrad'; + } + constructor(learningRate, initialAccumulatorValue = 0.1) { + super(); + this.learningRate = learningRate; + this.initialAccumulatorValue = initialAccumulatorValue; + this.accumulatedGrads = []; + } + applyGradients(variableGradients) { + const variableNames = Array.isArray(variableGradients) ? + variableGradients.map(item => item.name) : + Object.keys(variableGradients); + variableNames.forEach((name, i) => { + const value = ENGINE.registeredVariables[name]; + if (this.accumulatedGrads[i] == null) { + const trainable = false; + this.accumulatedGrads[i] = { + originalName: `${name}/accumulator`, + variable: tidy(() => fill$2(value.shape, this.initialAccumulatorValue) + .variable(trainable)) + }; + } + const gradient = Array.isArray(variableGradients) ? + variableGradients[i].tensor : + variableGradients[name]; + if (gradient == null) { + return; + } + const accumulatedGrad = this.accumulatedGrads[i].variable; + tidy(() => { + const newAccumulatedGrad = add$3(accumulatedGrad, square$2(gradient)); + accumulatedGrad.assign(newAccumulatedGrad); + const newValue = add$3(mul(div$1(gradient, sqrt$2(add$3(newAccumulatedGrad, ENGINE.backend.epsilon()))), -this.learningRate), value); + value.assign(newValue); + }); + }); + this.incrementIterations(); + } + dispose() { + if (this.accumulatedGrads != null) { + dispose(this.accumulatedGrads.map(v => v.variable)); + } + } + async getWeights() { + // Order matters for Python compatibility. + return [await this.saveIterations()].concat(this.accumulatedGrads.map(v => ({ name: v.originalName, tensor: v.variable }))); + } + async setWeights(weightValues) { + weightValues = await this.extractIterations(weightValues); + const trainable = false; + this.accumulatedGrads = weightValues.map(v => ({ originalName: v.name, variable: v.tensor.variable(trainable) })); + } + getConfig() { + return { + 'learningRate': this.learningRate, + 'initialAccumulatorValue': this.initialAccumulatorValue, + }; + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config['learningRate'], config['initialAccumulatorValue']); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class AdamOptimizer extends Optimizer { + /** @nocollapse */ + static get className() { + // Name matters for Python compatibility. + // This is a getter instead of a property because when it's a property, it + // prevents the entire class from being tree-shaken. + return 'Adam'; + } + constructor(learningRate, beta1, beta2, epsilon = null) { + super(); + this.learningRate = learningRate; + this.beta1 = beta1; + this.beta2 = beta2; + this.epsilon = epsilon; + this.accumulatedFirstMoment = []; + this.accumulatedSecondMoment = []; + tidy(() => { + // accB* will be updated by batch. + this.accBeta1 = scalar(beta1).variable(); + this.accBeta2 = scalar(beta2).variable(); + }); + if (epsilon == null) { + this.epsilon = ENGINE.backend.epsilon(); + } + } + applyGradients(variableGradients) { + const varNames = Array.isArray(variableGradients) ? + variableGradients.map(v => v.name) : + Object.keys(variableGradients); + tidy(() => { + const oneMinusAccBeta1 = sub$2(1, this.accBeta1); + const oneMinusAccBeta2 = sub$2(1, this.accBeta2); + varNames.forEach((name, i) => { + const value = ENGINE.registeredVariables[name]; + const trainable = false; + if (this.accumulatedFirstMoment[i] == null) { + this.accumulatedFirstMoment[i] = { + originalName: `${name}/m`, + variable: tidy(() => zerosLike$3(value).variable(trainable)) + }; + } + if (this.accumulatedSecondMoment[i] == null) { + this.accumulatedSecondMoment[i] = { + originalName: `${name}/v`, + variable: tidy(() => zerosLike$3(value).variable(trainable)) + }; + } + const gradient = Array.isArray(variableGradients) ? + variableGradients[i].tensor : + variableGradients[name]; + if (gradient == null) { + return; + } + const firstMoment = this.accumulatedFirstMoment[i].variable; + const secondMoment = this.accumulatedSecondMoment[i].variable; + const newFirstMoment = add$3(mul(firstMoment, this.beta1), mul(gradient, 1 - this.beta1)); + const newSecondMoment = add$3(mul(secondMoment, this.beta2), mul(square$2(gradient), 1 - this.beta2)); + const biasCorrectedFirstMoment = div$1(newFirstMoment, oneMinusAccBeta1); + const biasCorrectedSecondMoment = div$1(newSecondMoment, oneMinusAccBeta2); + firstMoment.assign(newFirstMoment); + secondMoment.assign(newSecondMoment); + const newValue = add$3(mul(div$1(biasCorrectedFirstMoment, add$3(sqrt$2(biasCorrectedSecondMoment), this.epsilon)), -this.learningRate), value); + value.assign(newValue); + }); + this.accBeta1.assign(mul(this.accBeta1, this.beta1)); + this.accBeta2.assign(mul(this.accBeta2, this.beta2)); + }); + this.incrementIterations(); + } + dispose() { + this.accBeta1.dispose(); + this.accBeta2.dispose(); + if (this.accumulatedFirstMoment != null) { + dispose(this.accumulatedFirstMoment.map(v => v.variable)); + } + if (this.accumulatedSecondMoment != null) { + dispose(this.accumulatedSecondMoment.map(v => v.variable)); + } + } + async getWeights() { + // Order matters for Python compatibility. + const variables = [...this.accumulatedFirstMoment, ...this.accumulatedSecondMoment]; + return [await this.saveIterations()].concat(variables.map(v => ({ name: v.originalName, tensor: v.variable }))); + } + async setWeights(weightValues) { + weightValues = await this.extractIterations(weightValues); + tidy(() => { + this.accBeta1.assign(pow$3(this.beta1, this.iterations_ + 1)); + this.accBeta2.assign(pow$3(this.beta2, this.iterations_ + 1)); + }); + const variableCount = weightValues.length / 2; + const trainable = false; + this.accumulatedFirstMoment = + weightValues.slice(0, variableCount).map(v => ({ + originalName: v.name, + variable: v.tensor.variable(trainable) + })); + this.accumulatedSecondMoment = + weightValues.slice(variableCount, variableCount * 2) + .map(v => ({ + originalName: v.name, + variable: v.tensor.variable(trainable) + })); + } + getConfig() { + return { + 'learningRate': this.learningRate, + 'beta1': this.beta1, + 'beta2': this.beta2, + 'epsilon': this.epsilon, + }; + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config['learningRate'], config['beta1'], config['beta2'], config['epsilon']); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class AdamaxOptimizer extends Optimizer { + /** @nocollapse */ + static get className() { + // Name matters for Python compatibility. + // This is a getter instead of a property because when it's a property, it + // prevents the entire class from being tree-shaken. + return 'Adamax'; + } + constructor(learningRate, beta1, beta2, epsilon = null, decay = 0.0) { + super(); + this.learningRate = learningRate; + this.beta1 = beta1; + this.beta2 = beta2; + this.epsilon = epsilon; + this.decay = decay; + this.accumulatedFirstMoment = []; + this.accumulatedWeightedInfNorm = []; + tidy(() => { + this.iteration = scalar(0).variable(); + this.accBeta1 = scalar(beta1).variable(); + }); + if (epsilon == null) { + this.epsilon = ENGINE.backend.epsilon(); + } + } + applyGradients(variableGradients) { + const variableNames = Array.isArray(variableGradients) ? + variableGradients.map(item => item.name) : + Object.keys(variableGradients); + tidy(() => { + const oneMinusAccBeta1 = sub$2(1, this.accBeta1); + const lr = div$1(-this.learningRate, add$3(mul(this.iteration, this.decay), 1)); + variableNames.forEach((name, i) => { + const value = ENGINE.registeredVariables[name]; + const trainable = false; + if (this.accumulatedFirstMoment[i] == null) { + this.accumulatedFirstMoment[i] = { + originalName: `${name}/m`, + variable: zerosLike$3(value).variable(trainable) + }; + } + if (this.accumulatedWeightedInfNorm[i] == null) { + this.accumulatedWeightedInfNorm[i] = { + originalName: `${name}/v`, + variable: zerosLike$3(value).variable(trainable) + }; + } + const gradient = Array.isArray(variableGradients) ? + variableGradients[i].tensor : + variableGradients[name]; + if (gradient == null) { + return; + } + const firstMoment = this.accumulatedFirstMoment[i].variable; + const weightedInfNorm = this.accumulatedWeightedInfNorm[i].variable; + const newFirstMoment = add$3(mul(firstMoment, this.beta1), mul(gradient, 1 - this.beta1)); + const ut0 = mul(weightedInfNorm, this.beta2); + const ut1 = abs$2(gradient); + const newWeightedInfNorm = maximum$4(ut0, ut1); + firstMoment.assign(newFirstMoment); + weightedInfNorm.assign(newWeightedInfNorm); + const newValue = add$3(mul(div$1(lr, oneMinusAccBeta1), div$1(newFirstMoment, add$3(newWeightedInfNorm, this.epsilon))), value); + value.assign(newValue); + }); + this.iteration.assign(add$3(this.iteration, 1)); + this.accBeta1.assign(mul(this.accBeta1, this.beta1)); + }); + this.incrementIterations(); + } + dispose() { + this.accBeta1.dispose(); + this.iteration.dispose(); + if (this.accumulatedFirstMoment != null) { + dispose(this.accumulatedFirstMoment.map(v => v.variable)); + } + if (this.accumulatedWeightedInfNorm != null) { + dispose(this.accumulatedWeightedInfNorm.map(v => v.variable)); + } + } + async getWeights() { + throw new Error('getWeights() is not implemented for Adamax yet.'); + } + async setWeights(weightValues) { + throw new Error('setWeights() is not implemented for Adamax yet.'); + } + getConfig() { + return { + 'learningRate': this.learningRate, + 'beta1': this.beta1, + 'beta2': this.beta2, + 'epsilon': this.epsilon, + 'decay': this.decay + }; + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config['learningRate'], config['beta1'], config['beta2'], config['epsilon'], config['decay']); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** @doclink Optimizer */ + class SGDOptimizer extends Optimizer { + /** @nocollapse */ + static get className() { + // Name matters for Python compatibility. + // This is a getter instead of a property because when it's a property, it + // prevents the entire class from being tree-shaken. + return 'SGD'; + } + constructor(learningRate) { + super(); + this.learningRate = learningRate; + this.setLearningRate(learningRate); + } + applyGradients(variableGradients) { + const varNames = Array.isArray(variableGradients) ? + variableGradients.map(v => v.name) : + Object.keys(variableGradients); + varNames.forEach((name, i) => { + const gradient = Array.isArray(variableGradients) ? + variableGradients[i].tensor : + variableGradients[name]; + if (gradient == null) { + return; + } + const value = ENGINE.registeredVariables[name]; + tidy(() => { + const newValue = add$3(mul(this.c, gradient), value); + value.assign(newValue); + }); + }); + this.incrementIterations(); + } + /** + * Sets the learning rate of the optimizer. + */ + setLearningRate(learningRate) { + this.learningRate = learningRate; + if (this.c != null) { + this.c.dispose(); + } + this.c = keep(scalar(-learningRate)); + } + dispose() { + this.c.dispose(); + } + async getWeights() { + return [await this.saveIterations()]; + } + async setWeights(weightValues) { + weightValues = await this.extractIterations(weightValues); + if (weightValues.length !== 0) { + throw new Error('SGD optimizer does not have settable weights.'); + } + } + getConfig() { + return { 'learningRate': this.learningRate }; + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config['learningRate']); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** @doclink Optimizer */ + class MomentumOptimizer extends SGDOptimizer { + /** @nocollapse */ + // Name matters for Python compatibility. + static get className() { + // Name matters for Python compatibility. + // This is a getter instead of a property because when it's a property, it + // prevents the entire class from being tree-shaken. + return 'Momentum'; + } + constructor(learningRate, momentum, useNesterov = false) { + super(learningRate); + this.learningRate = learningRate; + this.momentum = momentum; + this.useNesterov = useNesterov; + this.accumulations = []; + this.m = scalar(this.momentum); + } + applyGradients(variableGradients) { + const variableNames = Array.isArray(variableGradients) ? + variableGradients.map(item => item.name) : + Object.keys(variableGradients); + variableNames.forEach((name, i) => { + const value = ENGINE.registeredVariables[name]; + if (this.accumulations[i] == null) { + const trainable = false; + this.accumulations[i] = { + originalName: `${name}/momentum`, + variable: tidy(() => zerosLike$3(value).variable(trainable)) + }; + } + const accumulation = this.accumulations[i].variable; + const gradient = Array.isArray(variableGradients) ? + variableGradients[i].tensor : + variableGradients[name]; + if (gradient == null) { + return; + } + tidy(() => { + let newValue; + const newAccumulation = add$3(mul(this.m, accumulation), gradient); + if (this.useNesterov) { + newValue = add$3(mul(this.c, add$3(gradient, mul(newAccumulation, this.m))), value); + } + else { + newValue = add$3(mul(this.c, newAccumulation), value); + } + accumulation.assign(newAccumulation); + value.assign(newValue); + }); + }); + this.incrementIterations(); + } + dispose() { + this.m.dispose(); + if (this.accumulations != null) { + dispose(this.accumulations.map(v => v.variable)); + } + } + /** + * Sets the momentum of the optimizer. + * + * @param momentum + */ + setMomentum(momentum) { + this.momentum = momentum; + } + async getWeights() { + // Order matters for Python compatibility. + return [await this.saveIterations()].concat(this.accumulations.map(v => ({ name: v.originalName, tensor: v.variable }))); + } + async setWeights(weightValues) { + weightValues = await this.extractIterations(weightValues); + const trainable = false; + this.accumulations = weightValues.map(v => ({ originalName: v.name, variable: v.tensor.variable(trainable) })); + } + getConfig() { + return { + 'learningRate': this.learningRate, + 'momentum': this.momentum, + 'useNesterov': this.useNesterov + }; + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config['learningRate'], config['momentum'], config['useNesterov']); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** @doclink Optimizer */ + class RMSPropOptimizer extends Optimizer { + /** @nocollapse */ + static get className() { + // Name matters for Python compatibility. + // This is a getter instead of a property because when it's a property, it + // prevents the entire class from being tree-shaken. + return 'RMSProp'; + } + constructor(learningRate, decay = 0.9, momentum = 0.0, epsilon = null, centered = false) { + super(); + this.learningRate = learningRate; + this.decay = decay; + this.momentum = momentum; + this.epsilon = epsilon; + this.accumulatedMeanSquares = []; + this.accumulatedMoments = []; + this.accumulatedMeanGrads = []; + this.centered = centered; + if (epsilon == null) { + this.epsilon = ENGINE.backend.epsilon(); + } + if (learningRate == null) { + throw new Error(`learningRate for RMSPropOptimizer must be defined.`); + } + } + applyGradients(variableGradients) { + const variableNames = Array.isArray(variableGradients) ? + variableGradients.map(item => item.name) : + Object.keys(variableGradients); + variableNames.forEach((name, i) => { + const value = ENGINE.registeredVariables[name]; + const trainable = false; + if (this.accumulatedMeanSquares[i] == null) { + this.accumulatedMeanSquares[i] = { + originalName: `${name}/rms`, + variable: tidy(() => zerosLike$3(value).variable(trainable)) + }; + } + if (this.accumulatedMoments[i] == null) { + this.accumulatedMoments[i] = { + originalName: `${name}/momentum`, + variable: tidy(() => zerosLike$3(value).variable(trainable)) + }; + } + if (this.accumulatedMeanGrads[i] == null && this.centered) { + this.accumulatedMeanGrads[i] = { + originalName: `${name}/mg`, + variable: tidy(() => zerosLike$3(value).variable(trainable)) + }; + } + const gradient = Array.isArray(variableGradients) ? + variableGradients[i].tensor : + variableGradients[name]; + if (gradient == null) { + return; + } + const accumulatedMeanSquare = this.accumulatedMeanSquares[i].variable; + const accumulatedMoments = this.accumulatedMoments[i].variable; + tidy(() => { + const newAccumulatedMeanSquare = add$3(mul(accumulatedMeanSquare, this.decay), mul(square$2(gradient), 1 - this.decay)); + if (this.centered) { + const accumulatedMeanGrad = this.accumulatedMeanGrads[i].variable; + // Centered gradient + const newAccumulatedMeanGrad = add$3(mul(accumulatedMeanGrad, this.decay), mul(gradient, 1 - this.decay)); + const gradContribution = div$1(mul(gradient, this.learningRate), sqrt$2(sub$2(newAccumulatedMeanSquare, add$3(square$2(newAccumulatedMeanGrad), this.epsilon)))); + const newAccumulatedMoments = add$3(mul(accumulatedMoments, this.momentum), gradContribution); + accumulatedMeanSquare.assign(newAccumulatedMeanSquare); + accumulatedMeanGrad.assign(newAccumulatedMeanGrad); + accumulatedMoments.assign(newAccumulatedMoments); + const newValue = sub$2(value, newAccumulatedMoments); + value.assign(newValue); + } + else { + // Plain gradient + const newAccumulatedMeanSquare = add$3(mul(accumulatedMeanSquare, this.decay), mul(square$2(gradient), 1 - this.decay)); + const newAccumulatedMoments = add$3(mul(accumulatedMoments, this.momentum), div$1(mul(gradient, this.learningRate), sqrt$2(add$3(newAccumulatedMeanSquare, this.epsilon)))); + accumulatedMeanSquare.assign(newAccumulatedMeanSquare); + accumulatedMoments.assign(newAccumulatedMoments); + const newValue = sub$2(value, newAccumulatedMoments); + value.assign(newValue); + } + }); + }); + this.incrementIterations(); + } + dispose() { + if (this.accumulatedMeanSquares != null) { + dispose(this.accumulatedMeanSquares.map(v => v.variable)); + } + if (this.accumulatedMeanGrads != null && this.centered) { + dispose(this.accumulatedMeanGrads.map(v => v.variable)); + } + if (this.accumulatedMoments != null) { + dispose(this.accumulatedMoments.map(v => v.variable)); + } + } + async getWeights() { + // Order matters for Python compatibility. + const variables = [...this.accumulatedMeanSquares, ...this.accumulatedMoments]; + if (this.centered) { + variables.push(...this.accumulatedMeanGrads); + } + return [await this.saveIterations()].concat(variables.map(v => ({ name: v.originalName, tensor: v.variable }))); + } + async setWeights(weightValues) { + weightValues = await this.extractIterations(weightValues); + const variableCount = this.centered ? weightValues.length / 3 : weightValues.length / 2; + const trainable = false; + this.accumulatedMeanSquares = + weightValues.slice(0, variableCount).map(v => ({ + originalName: v.name, + variable: v.tensor.variable(trainable) + })); + this.accumulatedMoments = + weightValues.slice(variableCount, variableCount * 2) + .map(v => ({ + originalName: v.name, + variable: v.tensor.variable(trainable) + })); + if (this.centered) { + this.accumulatedMeanGrads = + weightValues.slice(variableCount * 2, variableCount * 3) + .map(v => ({ + originalName: v.name, + variable: v.tensor.variable(trainable) + })); + } + } + getConfig() { + return { + 'learningRate': this.learningRate, + 'decay': this.decay, + 'momentum': this.momentum, + 'epsilon': this.epsilon, + 'centered': this.centered + }; + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config['learningRate'], config['decay'], config['momentum'], config['epsilon'], config['centered']); + } + } + + /** + * @license + * Copyright 2022 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const OPTIMIZERS = [ + AdadeltaOptimizer, + AdagradOptimizer, + AdamOptimizer, + AdamaxOptimizer, + MomentumOptimizer, + RMSPropOptimizer, + SGDOptimizer, + ]; + function registerOptimizers() { + for (const optimizer of OPTIMIZERS) { + registerClass(optimizer); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const DEFAULT_FILE_NAME_PREFIX = 'model'; + const DEFAULT_JSON_EXTENSION_NAME = '.json'; + const DEFAULT_WEIGHT_DATA_EXTENSION_NAME = '.weights.bin'; + function defer(f) { + return new Promise(resolve => setTimeout(resolve)).then(f); + } + class BrowserDownloads { + constructor(fileNamePrefix) { + if (!env().getBool('IS_BROWSER')) { + // TODO(cais): Provide info on what IOHandlers are available under the + // current environment. + throw new Error('browserDownloads() cannot proceed because the current environment ' + + 'is not a browser.'); + } + if (fileNamePrefix.startsWith(BrowserDownloads.URL_SCHEME)) { + fileNamePrefix = fileNamePrefix.slice(BrowserDownloads.URL_SCHEME.length); + } + if (fileNamePrefix == null || fileNamePrefix.length === 0) { + fileNamePrefix = DEFAULT_FILE_NAME_PREFIX; + } + this.modelJsonFileName = fileNamePrefix + DEFAULT_JSON_EXTENSION_NAME; + this.weightDataFileName = + fileNamePrefix + DEFAULT_WEIGHT_DATA_EXTENSION_NAME; + } + async save(modelArtifacts) { + if (typeof (document) === 'undefined') { + throw new Error('Browser downloads are not supported in ' + + 'this environment since `document` is not present'); + } + // TODO(mattsoulanille): Support saving models over 2GB that exceed + // Chrome's ArrayBuffer size limit. + const weightBuffer = CompositeArrayBuffer.join(modelArtifacts.weightData); + const weightsURL = window.URL.createObjectURL(new Blob([weightBuffer], { type: 'application/octet-stream' })); + if (modelArtifacts.modelTopology instanceof ArrayBuffer) { + throw new Error('BrowserDownloads.save() does not support saving model topology ' + + 'in binary formats yet.'); + } + else { + const weightsManifest = [{ + paths: ['./' + this.weightDataFileName], + weights: modelArtifacts.weightSpecs + }]; + const modelJSON = getModelJSONForModelArtifacts(modelArtifacts, weightsManifest); + const modelJsonURL = window.URL.createObjectURL(new Blob([JSON.stringify(modelJSON)], { type: 'application/json' })); + // If anchor elements are not provided, create them without attaching them + // to parents, so that the downloaded file names can be controlled. + const jsonAnchor = this.modelJsonAnchor == null ? + document.createElement('a') : + this.modelJsonAnchor; + jsonAnchor.download = this.modelJsonFileName; + jsonAnchor.href = modelJsonURL; + // Trigger downloads by evoking a click event on the download anchors. + // When multiple downloads are started synchronously, Firefox will only + // save the last one. + await defer(() => jsonAnchor.dispatchEvent(new MouseEvent('click'))); + if (modelArtifacts.weightData != null) { + const weightDataAnchor = this.weightDataAnchor == null ? + document.createElement('a') : + this.weightDataAnchor; + weightDataAnchor.download = this.weightDataFileName; + weightDataAnchor.href = weightsURL; + await defer(() => weightDataAnchor.dispatchEvent(new MouseEvent('click'))); + } + return { modelArtifactsInfo: getModelArtifactsInfoForJSON(modelArtifacts) }; + } + } + } + BrowserDownloads.URL_SCHEME = 'downloads://'; + class BrowserFiles { + constructor(files) { + if (files == null || files.length < 1) { + throw new Error(`When calling browserFiles, at least 1 file is required, ` + + `but received ${files}`); + } + this.jsonFile = files[0]; + this.weightsFiles = files.slice(1); + } + async load() { + return new Promise((resolve, reject) => { + const jsonReader = new FileReader(); + jsonReader.onload = (event) => { + // tslint:disable-next-line:no-any + const modelJSON = JSON.parse(event.target.result); + const modelTopology = modelJSON.modelTopology; + if (modelTopology == null) { + reject(new Error(`modelTopology field is missing from file ${this.jsonFile.name}`)); + return; + } + const weightsManifest = modelJSON.weightsManifest; + if (weightsManifest == null) { + reject(new Error(`weightManifest field is missing from file ${this.jsonFile.name}`)); + return; + } + if (this.weightsFiles.length === 0) { + resolve({ modelTopology }); + return; + } + const modelArtifactsPromise = getModelArtifactsForJSON(modelJSON, (weightsManifest) => this.loadWeights(weightsManifest)); + resolve(modelArtifactsPromise); + }; + jsonReader.onerror = error => reject(`Failed to read model topology and weights manifest JSON ` + + `from file '${this.jsonFile.name}'. BrowserFiles supports loading ` + + `Keras-style tf.Model artifacts only.`); + jsonReader.readAsText(this.jsonFile); + }); + } + loadWeights(weightsManifest) { + const weightSpecs = []; + const paths = []; + for (const entry of weightsManifest) { + weightSpecs.push(...entry.weights); + paths.push(...entry.paths); + } + const pathToFile = this.checkManifestAndWeightFiles(weightsManifest); + const promises = paths.map(path => this.loadWeightsFile(path, pathToFile[path])); + return Promise.all(promises).then(buffers => [weightSpecs, buffers]); + } + loadWeightsFile(path, file) { + return new Promise((resolve, reject) => { + const weightFileReader = new FileReader(); + weightFileReader.onload = (event) => { + // tslint:disable-next-line:no-any + const weightData = event.target.result; + resolve(weightData); + }; + weightFileReader.onerror = error => reject(`Failed to weights data from file of path '${path}'.`); + weightFileReader.readAsArrayBuffer(file); + }); + } + /** + * Check the compatibility between weights manifest and weight files. + */ + checkManifestAndWeightFiles(manifest) { + const basenames = []; + const fileNames = this.weightsFiles.map(file => basename(file.name)); + const pathToFile = {}; + for (const group of manifest) { + group.paths.forEach(path => { + const pathBasename = basename(path); + if (basenames.indexOf(pathBasename) !== -1) { + throw new Error(`Duplicate file basename found in weights manifest: ` + + `'${pathBasename}'`); + } + basenames.push(pathBasename); + if (fileNames.indexOf(pathBasename) === -1) { + throw new Error(`Weight file with basename '${pathBasename}' is not provided.`); + } + else { + pathToFile[path] = this.weightsFiles[fileNames.indexOf(pathBasename)]; + } + }); + } + if (basenames.length !== this.weightsFiles.length) { + throw new Error(`Mismatch in the number of files in weights manifest ` + + `(${basenames.length}) and the number of weight files provided ` + + `(${this.weightsFiles.length}).`); + } + return pathToFile; + } + } + const browserDownloadsRouter = (url) => { + if (!env().getBool('IS_BROWSER')) { + return null; + } + else { + if (!Array.isArray(url) && url.startsWith(BrowserDownloads.URL_SCHEME)) { + return browserDownloads(url.slice(BrowserDownloads.URL_SCHEME.length)); + } + else { + return null; + } + } + }; + IORouterRegistry.registerSaveRouter(browserDownloadsRouter); + /** + * Creates an IOHandler that triggers file downloads from the browser. + * + * The returned `IOHandler` instance can be used as model exporting methods such + * as `tf.Model.save` and supports only saving. + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.dense( + * {units: 1, inputShape: [10], activation: 'sigmoid'})); + * const saveResult = await model.save('downloads://mymodel'); + * // This will trigger downloading of two files: + * // 'mymodel.json' and 'mymodel.weights.bin'. + * console.log(saveResult); + * ``` + * + * @param fileNamePrefix Prefix name of the files to be downloaded. For use with + * `tf.Model`, `fileNamePrefix` should follow either of the following two + * formats: + * 1. `null` or `undefined`, in which case the default file + * names will be used: + * - 'model.json' for the JSON file containing the model topology and + * weights manifest. + * - 'model.weights.bin' for the binary file containing the binary weight + * values. + * 2. A single string or an Array of a single string, as the file name prefix. + * For example, if `'foo'` is provided, the downloaded JSON + * file and binary weights file will be named 'foo.json' and + * 'foo.weights.bin', respectively. + * @param config Additional configuration for triggering downloads. + * @returns An instance of `BrowserDownloads` `IOHandler`. + * + * @doc { + * heading: 'Models', + * subheading: 'Loading', + * namespace: 'io', + * ignoreCI: true + * } + */ + function browserDownloads(fileNamePrefix = 'model') { + return new BrowserDownloads(fileNamePrefix); + } + /** + * Creates an IOHandler that loads model artifacts from user-selected files. + * + * This method can be used for loading from files such as user-selected files + * in the browser. + * When used in conjunction with `tf.loadLayersModel`, an instance of + * `tf.LayersModel` (Keras-style) can be constructed from the loaded artifacts. + * + * ```js + * // Note: This code snippet won't run properly without the actual file input + * // elements in the HTML DOM. + * + * // Suppose there are two HTML file input (``) + * // elements. + * const uploadJSONInput = document.getElementById('upload-json'); + * const uploadWeightsInput = document.getElementById('upload-weights'); + * const model = await tf.loadLayersModel(tf.io.browserFiles( + * [uploadJSONInput.files[0], uploadWeightsInput.files[0]])); + * ``` + * + * @param files `File`s to load from. Currently, this function supports only + * loading from files that contain Keras-style models (i.e., `tf.Model`s), for + * which an `Array` of `File`s is expected (in that order): + * - A JSON file containing the model topology and weight manifest. + * - Optionally, one or more binary files containing the binary weights. + * These files must have names that match the paths in the `weightsManifest` + * contained by the aforementioned JSON file, or errors will be thrown + * during loading. These weights files have the same format as the ones + * generated by `tensorflowjs_converter` that comes with the `tensorflowjs` + * Python PIP package. If no weights files are provided, only the model + * topology will be loaded from the JSON file above. + * @returns An instance of `Files` `IOHandler`. + * + * @doc { + * heading: 'Models', + * subheading: 'Loading', + * namespace: 'io', + * ignoreCI: true + * } + */ + function browserFiles(files) { + return new BrowserFiles(files); + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Monitor Promise.all progress, fire onProgress callback function. + * + * @param promises Promise list going to be monitored + * @param onProgress Callback function. Fired when a promise resolved. + * @param startFraction Optional fraction start. Default to 0. + * @param endFraction Optional fraction end. Default to 1. + */ + function monitorPromisesProgress(promises, onProgress, startFraction, endFraction) { + checkPromises(promises); + startFraction = startFraction == null ? 0 : startFraction; + endFraction = endFraction == null ? 1 : endFraction; + checkFraction(startFraction, endFraction); + let resolvedPromise = 0; + const registerMonitor = (promise) => { + promise.then(value => { + const fraction = startFraction + + ++resolvedPromise / promises.length * (endFraction - startFraction); + // pass fraction as parameter to callback function. + onProgress(fraction); + return value; + }); + return promise; + }; + function checkPromises(promises) { + assert$1(promises != null && Array.isArray(promises) && promises.length > 0, () => 'promises must be a none empty array'); + } + function checkFraction(startFraction, endFraction) { + assert$1(startFraction >= 0 && startFraction <= 1, () => `Progress fraction must be in range [0, 1], but ` + + `got startFraction ${startFraction}`); + assert$1(endFraction >= 0 && endFraction <= 1, () => `Progress fraction must be in range [0, 1], but ` + + `got endFraction ${endFraction}`); + assert$1(endFraction >= startFraction, () => `startFraction must be no more than endFraction, but ` + + `got startFraction ${startFraction} and endFraction ` + + `${endFraction}`); + } + return Promise.all(promises.map(registerMonitor)); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Reads binary weights data from a number of URLs. + * + * @param fetchURLs URLs to send the HTTP requests at, using `fetch` calls. + * @param requestOptions RequestInit (options) for the HTTP requests. + * @param fetchFunc Optional overriding value for the `window.fetch` function. + * @param onProgress Optional, progress callback function, fired periodically + * before the load is completed. + * @returns A `Promise` of an Array of `ArrayBuffer`. The Array has the same + * length as `fetchURLs`. + */ + async function loadWeightsAsArrayBuffer(fetchURLs, loadOptions) { + if (loadOptions == null) { + loadOptions = {}; + } + const fetchFunc = loadOptions.fetchFunc == null ? env().platform.fetch : + loadOptions.fetchFunc; + // Create the requests for all of the weights in parallel. + const requests = fetchURLs.map(fetchURL => fetchFunc(fetchURL, loadOptions.requestInit, { isBinary: true })); + const fetchStartFraction = 0; + const fetchEndFraction = 0.5; + const responses = loadOptions.onProgress == null ? + await Promise.all(requests) : + await monitorPromisesProgress(requests, loadOptions.onProgress, fetchStartFraction, fetchEndFraction); + const bufferPromises = responses.map(response => response.arrayBuffer()); + const bufferStartFraction = 0.5; + const bufferEndFraction = 1; + const buffers = loadOptions.onProgress == null ? + await Promise.all(bufferPromises) : + await monitorPromisesProgress(bufferPromises, loadOptions.onProgress, bufferStartFraction, bufferEndFraction); + return buffers; + } + function streamWeights(fetchURLs, loadOptions) { + var _a; + const fetchFunc = loadOptions.fetchFunc == null ? env().platform.fetch : + loadOptions.fetchFunc; + let fetchIndex = 0; + let chunkReader; + (_a = loadOptions.onProgress) === null || _a === void 0 ? void 0 : _a.call(loadOptions, 0); + return new ReadableStream({ + pull: async (controller) => { + var _a; + while (fetchIndex < fetchURLs.length) { + if (!chunkReader) { + const body = (await fetchFunc(fetchURLs[fetchIndex], loadOptions.requestInit, { isBinary: true })).body; + chunkReader = body.getReader(); + } + const { done, value } = await chunkReader.read(); + if (done) { + fetchIndex++; + chunkReader = undefined; + (_a = loadOptions.onProgress) === null || _a === void 0 ? void 0 : _a.call(loadOptions, fetchIndex / fetchURLs.length); + continue; + } + controller.enqueue(value); + return; + } + controller.close(); + }, + }); + } + /** + * Reads a weights manifest JSON configuration, fetches the weights and + * returns them as `Tensor`s. + * + * @param manifest The weights manifest JSON. + * @param filePathPrefix The path prefix for filenames given in the manifest. + * Defaults to the empty string. + * @param weightNames The names of the weights to be fetched. + */ + async function loadWeights(manifest, filePathPrefix = '', weightNames, requestInit) { + // TODO(nsthorat): Groups are currently fetched atomically. If you need a + // single weight from a group, the whole group will be fetched. At a future + // date, we should support fetching only the individual shards within a + // group that are needed to reconstruct the requested weight. + // TODO(cais): Use `decodeWeights` for implementation. + const fetchWeights = (fetchUrls) => loadWeightsAsArrayBuffer(fetchUrls, { requestInit }); + const loadWeights = weightsLoaderFactory(fetchWeights); + return loadWeights(manifest, filePathPrefix, weightNames); + } + /** + * Creates a function, which reads a weights manifest JSON configuration, + * fetches the weight files using the specified function and returns them as + * `Tensor`s. + * + * ```js + * // example for creating a nodejs weight loader, which reads the weight files + * // from disk using fs.readFileSync + * + * import * as fs from 'fs' + * + * const fetchWeightsFromDisk = (filePaths: string[]) => + * filePaths.map(filePath => fs.readFileSync(filePath).buffer) + * + * const loadWeights = tf.io.weightsLoaderFactory(fetchWeightsFromDisk) + * + * const manifest = JSON.parse( + * fs.readFileSync('./my_model-weights_manifest').toString() + * ) + * const weightMap = await loadWeights(manifest, './') + * ``` + * @param fetchWeightsFunction The function used for fetching the weight files. + * @returns Weight loading function. + */ + function weightsLoaderFactory(fetchWeightsFunction) { + return async (manifest, filePathPrefix = '', weightNames) => { + // Collect all the groups, weights, and their relative offsets to be + // fetched. + const groupIndicesToFetchMap = manifest.map(() => false); + const groupWeightsToFetch = {}; + const weightsFound = weightNames != null ? weightNames.map(() => false) : []; + const allManifestWeightNames = []; + manifest.forEach((manifestGroupConfig, groupIndex) => { + let groupOffset = 0; + manifestGroupConfig.weights.forEach(weightsEntry => { + const rawDtype = ('quantization' in weightsEntry) ? + weightsEntry.quantization.dtype : + weightsEntry.dtype; + const weightsBytes = DTYPE_VALUE_SIZE_MAP[rawDtype] * + sizeFromShape(weightsEntry.shape); + const enqueueWeightsForFetchingFn = () => { + groupIndicesToFetchMap[groupIndex] = true; + if (groupWeightsToFetch[groupIndex] == null) { + groupWeightsToFetch[groupIndex] = []; + } + groupWeightsToFetch[groupIndex].push({ + manifestEntry: weightsEntry, + groupOffset, + sizeBytes: weightsBytes + }); + }; + if (weightNames != null) { + weightNames.forEach((weightName, weightIndex) => { + if (weightName === weightsEntry.name) { + enqueueWeightsForFetchingFn(); + weightsFound[weightIndex] = true; + } + }); + } + else { + enqueueWeightsForFetchingFn(); + } + allManifestWeightNames.push(weightsEntry.name); + groupOffset += weightsBytes; + }); + }); + if (!weightsFound.every(found => found)) { + const weightsNotFound = weightNames.filter((_, i) => !weightsFound[i]); + throw new Error(`Could not find weights in manifest with names: ` + + `${weightsNotFound.join(', ')}. \n` + + `Manifest JSON has weights with names: ` + + `${allManifestWeightNames.join(', ')}.`); + } + // Convert the one-hot boolean groupId => shouldFetch map to a list of group + // IDs. + const groupIndicesToFetch = groupIndicesToFetchMap.reduce((accumulator, shouldFetch, i) => { + if (shouldFetch) { + accumulator.push(i); + } + return accumulator; + }, []); + const fetchUrls = []; + groupIndicesToFetch.forEach(i => { + manifest[i].paths.forEach(filepath => { + const fetchUrl = filePathPrefix + + (!filePathPrefix.endsWith('/') ? '/' : '') + filepath; + fetchUrls.push(fetchUrl); + }); + }); + const buffers = await fetchWeightsFunction(fetchUrls); + const weightsTensorMap = {}; + let bufferIndexOffset = 0; + groupIndicesToFetch.forEach(i => { + const numBuffers = manifest[i].paths.length; + const weightsBuffer = new CompositeArrayBuffer(buffers.slice(bufferIndexOffset, bufferIndexOffset + numBuffers)); + const weightsEntries = groupWeightsToFetch[i]; + weightsEntries.forEach(weightsEntry => { + const byteBuffer = weightsBuffer.slice(weightsEntry.groupOffset, weightsEntry.groupOffset + weightsEntry.sizeBytes); + const nameToTensorMap = decodeWeights(byteBuffer, [weightsEntry.manifestEntry]); + for (const name in nameToTensorMap) { + weightsTensorMap[name] = nameToTensorMap[name]; + } + }); + bufferIndexOffset += numBuffers; + }); + return weightsTensorMap; + }; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const OCTET_STREAM_MIME_TYPE = 'application/octet-stream'; + const JSON_TYPE = 'application/json'; + class HTTPRequest { + constructor(path, loadOptions) { + this.DEFAULT_METHOD = 'POST'; + if (loadOptions == null) { + loadOptions = {}; + } + this.weightPathPrefix = loadOptions.weightPathPrefix; + this.weightUrlConverter = loadOptions.weightUrlConverter; + if (loadOptions.fetchFunc != null) { + assert$1(typeof loadOptions.fetchFunc === 'function', () => 'Must pass a function that matches the signature of ' + + '`fetch` (see ' + + 'https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)'); + this.fetch = loadOptions.fetchFunc; + } + else { + this.fetch = env().platform.fetch; + } + assert$1(path != null && path.length > 0, () => 'URL path for http must not be null, undefined or ' + + 'empty.'); + if (Array.isArray(path)) { + assert$1(path.length === 2, () => 'URL paths for http must have a length of 2, ' + + `(actual length is ${path.length}).`); + } + this.path = path; + if (loadOptions.requestInit != null && + loadOptions.requestInit.body != null) { + throw new Error('requestInit is expected to have no pre-existing body, but has one.'); + } + this.requestInit = loadOptions.requestInit || {}; + this.loadOptions = loadOptions; + } + async save(modelArtifacts) { + if (modelArtifacts.modelTopology instanceof ArrayBuffer) { + throw new Error('BrowserHTTPRequest.save() does not support saving model topology ' + + 'in binary formats yet.'); + } + const init = Object.assign({ method: this.DEFAULT_METHOD }, this.requestInit); + init.body = new FormData(); + const weightsManifest = [{ + paths: ['./model.weights.bin'], + weights: modelArtifacts.weightSpecs, + }]; + const modelTopologyAndWeightManifest = getModelJSONForModelArtifacts(modelArtifacts, weightsManifest); + init.body.append('model.json', new Blob([JSON.stringify(modelTopologyAndWeightManifest)], { type: JSON_TYPE }), 'model.json'); + if (modelArtifacts.weightData != null) { + // TODO(mattsoulanille): Support saving models over 2GB that exceed + // Chrome's ArrayBuffer size limit. + const weightBuffer = CompositeArrayBuffer.join(modelArtifacts.weightData); + init.body.append('model.weights.bin', new Blob([weightBuffer], { type: OCTET_STREAM_MIME_TYPE }), 'model.weights.bin'); + } + const response = await this.fetch(this.path, init); + if (response.ok) { + return { + modelArtifactsInfo: getModelArtifactsInfoForJSON(modelArtifacts), + responses: [response], + }; + } + else { + throw new Error(`BrowserHTTPRequest.save() failed due to HTTP response status ` + + `${response.status}.`); + } + } + async loadModelJSON() { + const modelConfigRequest = await this.fetch(this.path, this.requestInit); + if (!modelConfigRequest.ok) { + throw new Error(`Request to ${this.path} failed with status code ` + + `${modelConfigRequest.status}. Please verify this URL points to ` + + `the model JSON of the model to load.`); + } + let modelJSON; + try { + modelJSON = await modelConfigRequest.json(); + } + catch (e) { + let message = `Failed to parse model JSON of response from ${this.path}.`; + // TODO(nsthorat): Remove this after some time when we're comfortable that + // .pb files are mostly gone. + if (this.path.endsWith('.pb')) { + message += ' Your path contains a .pb file extension. ' + + 'Support for .pb models have been removed in TensorFlow.js 1.0 ' + + 'in favor of .json models. You can re-convert your Python ' + + 'TensorFlow model using the TensorFlow.js 1.0 conversion scripts ' + + 'or you can convert your.pb models with the \'pb2json\'' + + 'NPM script in the tensorflow/tfjs-converter repository.'; + } + else { + message += ' Please make sure the server is serving valid ' + + 'JSON for this request.'; + } + throw new Error(message); + } + // We do not allow both modelTopology and weightsManifest to be missing. + const modelTopology = modelJSON.modelTopology; + const weightsManifest = modelJSON.weightsManifest; + if (modelTopology == null && weightsManifest == null) { + throw new Error(`The JSON from HTTP path ${this.path} contains neither model ` + + `topology or manifest for weights.`); + } + return modelJSON; + } + /** + * Load model artifacts via HTTP request(s). + * + * See the documentation to `tf.io.http` for details on the saved + * artifacts. + * + * @returns The loaded model artifacts (if loading succeeds). + */ + async load() { + if (this.loadOptions.streamWeights) { + return this.loadStream(); + } + const modelJSON = await this.loadModelJSON(); + return getModelArtifactsForJSON(modelJSON, (weightsManifest) => this.loadWeights(weightsManifest)); + } + async loadStream() { + const modelJSON = await this.loadModelJSON(); + const fetchURLs = await this.getWeightUrls(modelJSON.weightsManifest); + const weightSpecs = getWeightSpecs(modelJSON.weightsManifest); + const stream = () => streamWeights(fetchURLs, this.loadOptions); + return Object.assign(Object.assign({}, modelJSON), { weightSpecs, getWeightStream: stream }); + } + async getWeightUrls(weightsManifest) { + const weightPath = Array.isArray(this.path) ? this.path[1] : this.path; + const [prefix, suffix] = parseUrl(weightPath); + const pathPrefix = this.weightPathPrefix || prefix; + const fetchURLs = []; + const urlPromises = []; + for (const weightsGroup of weightsManifest) { + for (const path of weightsGroup.paths) { + if (this.weightUrlConverter != null) { + urlPromises.push(this.weightUrlConverter(path)); + } + else { + fetchURLs.push(pathPrefix + path + suffix); + } + } + } + if (this.weightUrlConverter) { + fetchURLs.push(...await Promise.all(urlPromises)); + } + return fetchURLs; + } + async loadWeights(weightsManifest) { + const fetchURLs = await this.getWeightUrls(weightsManifest); + const weightSpecs = getWeightSpecs(weightsManifest); + const buffers = await loadWeightsAsArrayBuffer(fetchURLs, this.loadOptions); + return [weightSpecs, buffers]; + } + } + HTTPRequest.URL_SCHEME_REGEX = /^https?:\/\//; + /** + * Extract the prefix and suffix of the url, where the prefix is the path before + * the last file, and suffix is the search params after the last file. + * ``` + * const url = 'http://tfhub.dev/model/1/tensorflowjs_model.pb?tfjs-format=file' + * [prefix, suffix] = parseUrl(url) + * // prefix = 'http://tfhub.dev/model/1/' + * // suffix = '?tfjs-format=file' + * ``` + * @param url the model url to be parsed. + */ + function parseUrl(url) { + const lastSlash = url.lastIndexOf('/'); + const lastSearchParam = url.lastIndexOf('?'); + const prefix = url.substring(0, lastSlash); + const suffix = lastSearchParam > lastSlash ? url.substring(lastSearchParam) : ''; + return [prefix + '/', suffix]; + } + function isHTTPScheme(url) { + return url.match(HTTPRequest.URL_SCHEME_REGEX) != null; + } + const httpRouter = (url, loadOptions) => { + if (typeof fetch === 'undefined' && + (loadOptions == null || loadOptions.fetchFunc == null)) { + // `http` uses `fetch` or `node-fetch`, if one wants to use it in + // an environment that is not the browser or node they have to setup a + // global fetch polyfill. + return null; + } + else { + let isHTTP = true; + if (Array.isArray(url)) { + isHTTP = url.every(urlItem => isHTTPScheme(urlItem)); + } + else { + isHTTP = isHTTPScheme(url); + } + if (isHTTP) { + return http(url, loadOptions); + } + } + return null; + }; + IORouterRegistry.registerSaveRouter(httpRouter); + IORouterRegistry.registerLoadRouter(httpRouter); + /** + * Creates an IOHandler subtype that sends model artifacts to HTTP server. + * + * An HTTP request of the `multipart/form-data` mime type will be sent to the + * `path` URL. The form data includes artifacts that represent the topology + * and/or weights of the model. In the case of Keras-style `tf.Model`, two + * blobs (files) exist in form-data: + * - A JSON file consisting of `modelTopology` and `weightsManifest`. + * - A binary weights file consisting of the concatenated weight values. + * These files are in the same format as the one generated by + * [tfjs_converter](https://js.tensorflow.org/tutorials/import-keras.html). + * + * The following code snippet exemplifies the client-side code that uses this + * function: + * + * ```js + * const model = tf.sequential(); + * model.add( + * tf.layers.dense({units: 1, inputShape: [100], activation: 'sigmoid'})); + * + * const saveResult = await model.save(tf.io.http( + * 'http://model-server:5000/upload', {requestInit: {method: 'PUT'}})); + * console.log(saveResult); + * ``` + * + * If the default `POST` method is to be used, without any custom parameters + * such as headers, you can simply pass an HTTP or HTTPS URL to `model.save`: + * + * ```js + * const saveResult = await model.save('http://model-server:5000/upload'); + * ``` + * + * The following GitHub Gist + * https://gist.github.com/dsmilkov/1b6046fd6132d7408d5257b0976f7864 + * implements a server based on [flask](https://github.com/pallets/flask) that + * can receive the request. Upon receiving the model artifacts via the request, + * this particular server reconstitutes instances of [Keras + * Models](https://keras.io/models/model/) in memory. + * + * + * @param path A URL path to the model. + * Can be an absolute HTTP path (e.g., + * 'http://localhost:8000/model-upload)') or a relative path (e.g., + * './model-upload'). + * @param requestInit Request configurations to be used when sending + * HTTP request to server using `fetch`. It can contain fields such as + * `method`, `credentials`, `headers`, `mode`, etc. See + * https://developer.mozilla.org/en-US/docs/Web/API/Request/Request + * for more information. `requestInit` must not have a body, because the + * body will be set by TensorFlow.js. File blobs representing the model + * topology (filename: 'model.json') and the weights of the model (filename: + * 'model.weights.bin') will be appended to the body. If `requestInit` has a + * `body`, an Error will be thrown. + * @param loadOptions Optional configuration for the loading. It includes the + * following fields: + * - weightPathPrefix Optional, this specifies the path prefix for weight + * files, by default this is calculated from the path param. + * - fetchFunc Optional, custom `fetch` function. E.g., in Node.js, + * the `fetch` from node-fetch can be used here. + * - onProgress Optional, progress callback function, fired periodically + * before the load is completed. + * @returns An instance of `IOHandler`. + * + * @doc { + * heading: 'Models', + * subheading: 'Loading', + * namespace: 'io', + * ignoreCI: true + * } + */ + function http(path, loadOptions) { + return new HTTPRequest(path, loadOptions); + } + /** + * Deprecated. Use `tf.io.http`. + * @param path + * @param loadOptions + */ + function browserHTTPRequest(path, loadOptions) { + return http(path, loadOptions); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class PassthroughLoader { + constructor(modelArtifacts) { + this.modelArtifacts = modelArtifacts; + } + load() { + return this.modelArtifacts; + } + } + class PassthroughSaver { + constructor(saveHandler) { + this.saveHandler = saveHandler; + } + save(modelArtifacts) { + return this.saveHandler(modelArtifacts); + } + } + class PassthroughAsync { + constructor(handler) { + if (handler.load) { + this.load = () => Promise.resolve(handler.load()); + } + if (handler.save) { + this.save = (modelArtifacts) => Promise.resolve(handler.save(modelArtifacts)); + } + } + } + /** + * Creates an IOHandler that loads model artifacts from memory. + * + * When used in conjunction with `tf.loadLayersModel`, an instance of + * `tf.LayersModel` (Keras-style) can be constructed from the loaded artifacts. + * + * ```js + * const model = await tf.loadLayersModel(tf.io.fromMemory( + * modelTopology, weightSpecs, weightData)); + * ``` + * + * @param modelArtifacts a object containing model topology (i.e., parsed from + * the JSON format). + * @param weightSpecs An array of `WeightsManifestEntry` objects describing the + * names, shapes, types, and quantization of the weight data. Optional. + * @param weightData A single `ArrayBuffer` containing the weight data, + * concatenated in the order described by the weightSpecs. Optional. + * @param trainingConfig Model training configuration. Optional. + * + * @returns A passthrough `IOHandler` that simply loads the provided data. + */ + function fromMemory(modelArtifacts, weightSpecs, weightData, trainingConfig) { + const args = arguments; + return new PassthroughAsync(fromMemorySync(...args)); + } + /** + * Creates an IOHandler that loads model artifacts from memory. + * + * When used in conjunction with `tf.loadLayersModel`, an instance of + * `tf.LayersModel` (Keras-style) can be constructed from the loaded artifacts. + * + * ```js + * const model = await tf.loadLayersModel(tf.io.fromMemory( + * modelTopology, weightSpecs, weightData)); + * ``` + * + * @param modelArtifacts a object containing model topology (i.e., parsed from + * the JSON format). + * @param weightSpecs An array of `WeightsManifestEntry` objects describing the + * names, shapes, types, and quantization of the weight data. Optional. + * @param weightData A single `ArrayBuffer` containing the weight data, + * concatenated in the order described by the weightSpecs. Optional. + * @param trainingConfig Model training configuration. Optional. + * + * @returns A passthrough `IOHandlerSync` that simply loads the provided data. + */ + function fromMemorySync(modelArtifacts, weightSpecs, weightData, trainingConfig) { + if (arguments.length === 1) { + const isModelArtifacts = modelArtifacts.modelTopology != null || + modelArtifacts.weightSpecs != null; + if (isModelArtifacts) { + return new PassthroughLoader(modelArtifacts); + } + else { + // Legacy support: with only modelTopology. + // TODO(cais): Remove this deprecated API. + console.warn('Please call tf.io.fromMemory() with only one argument. ' + + 'The argument should be of type ModelArtifacts. ' + + 'The multi-argument signature of tf.io.fromMemory() has been ' + + 'deprecated and will be removed in a future release.'); + return new PassthroughLoader({ modelTopology: modelArtifacts }); + } + } + else { + // Legacy support. + // TODO(cais): Remove this deprecated API. + console.warn('Please call tf.io.fromMemory() with only one argument. ' + + 'The argument should be of type ModelArtifacts. ' + + 'The multi-argument signature of tf.io.fromMemory() has been ' + + 'deprecated and will be removed in a future release.'); + return new PassthroughLoader({ + modelTopology: modelArtifacts, + weightSpecs, + weightData, + trainingConfig + }); + } + } + /** + * Creates an IOHandler that passes saved model artifacts to a callback. + * + * ```js + * function handleSave(artifacts) { + * // ... do something with the artifacts ... + * return {modelArtifactsInfo: {...}, ...}; + * } + * + * const saveResult = model.save(tf.io.withSaveHandler(handleSave)); + * ``` + * + * @param saveHandler A function that accepts a `ModelArtifacts` and returns a + * promise that resolves to a `SaveResult`. + */ + function withSaveHandler(saveHandler) { + return new PassthroughSaver(saveHandler); + } + /** + * Creates an IOHandlerSync that passes saved model artifacts to a callback. + * + * ```js + * function handleSave(artifacts) { + * // ... do something with the artifacts ... + * return {modelArtifactsInfo: {...}, ...}; + * } + * + * const saveResult = model.save(tf.io.withSaveHandler(handleSave)); + * ``` + * + * @param saveHandler A function that accepts a `ModelArtifacts` and returns a + * `SaveResult`. + */ + function withSaveHandlerSync(saveHandler) { + return new PassthroughSaver(saveHandler); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + var io = /*#__PURE__*/Object.freeze({ + __proto__: null, + CompositeArrayBuffer: CompositeArrayBuffer, + browserFiles: browserFiles, + browserHTTPRequest: browserHTTPRequest, + concatenateArrayBuffers: concatenateArrayBuffers, + copyModel: copyModel, + decodeWeights: decodeWeights, + decodeWeightsStream: decodeWeightsStream, + encodeWeights: encodeWeights, + fromMemory: fromMemory, + fromMemorySync: fromMemorySync, + getLoadHandlers: getLoadHandlers, + getModelArtifactsForJSON: getModelArtifactsForJSON, + getModelArtifactsForJSONSync: getModelArtifactsForJSONSync, + getModelArtifactsInfoForJSON: getModelArtifactsInfoForJSON, + getSaveHandlers: getSaveHandlers, + getWeightSpecs: getWeightSpecs, + http: http, + isHTTPScheme: isHTTPScheme, + listModels: listModels, + loadWeights: loadWeights, + moveModel: moveModel, + registerLoadRouter: registerLoadRouter, + registerSaveRouter: registerSaveRouter, + removeModel: removeModel, + weightsLoaderFactory: weightsLoaderFactory, + withSaveHandler: withSaveHandler, + withSaveHandlerSync: withSaveHandlerSync + }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the confusion matrix from true labels and predicted labels. + * + * ```js + * const labels = tf.tensor1d([0, 1, 2, 1, 0], 'int32'); + * const predictions = tf.tensor1d([0, 2, 2, 1, 0], 'int32'); + * const numClasses = 3; + * const out = tf.math.confusionMatrix(labels, predictions, numClasses); + * out.print(); + * // Expected output matrix: + * // [[2, 0, 0], + * // [0, 1, 1], + * // [0, 0, 1]] + * ``` + * + * @param labels The target labels, assumed to be 0-based integers + * for the classes. The shape is `[numExamples]`, where + * `numExamples` is the number of examples included. + * @param predictions The predicted classes, assumed to be + * 0-based integers for the classes. Must have the same shape as `labels`. + * @param numClasses Number of all classes, as an integer. + * Its value must be larger than the largest element in `labels` and + * `predictions`. + * @returns The confusion matrix as a int32-type 2D tensor. The value at + * row `r` and column `c` is the number of times examples of actual class + * `r` were predicted as class `c`. + * + * @doc {heading: 'Operations', subheading: 'Evaluation'} + */ + function confusionMatrix_(labels, predictions, numClasses) { + const $labels = convertToTensor(labels, 'labels', 'confusionMatrix'); + const $predictions = convertToTensor(predictions, 'predictions', 'confusionMatrix'); + assert$1(numClasses == null || numClasses > 0 && Number.isInteger(numClasses), () => `If provided, numClasses must be a positive integer, ` + + `but got ${numClasses}`); + assert$1($labels.rank === 1, () => `Expected the rank of labels to be 1, but got ${$labels.rank}`); + assert$1($predictions.rank === 1, () => `Expected the rank of predictions to be 1, ` + + `but got ${$predictions.rank}`); + assert$1($labels.shape[0] === $predictions.shape[0], () => `Mismatch in the number of examples: ` + + `${$labels.shape[0]} vs. ${$predictions.shape[0]}. ` + + `Labels and predictions should have the same number of elements.`); + assert$1(numClasses > 0 && Number.isInteger(numClasses), () => `numClasses is required to be a positive integer, but got ` + + `${numClasses}`); + // TODO(cais): In the future, if oneHot supports tensors inputs for + // `numClasses`, `confusionMatrix` can make `numClasses` optional. + const oneHotLabels = oneHot$3(cast$3($labels, 'int32'), numClasses); + const oneHotPredictions = oneHot$3(cast$3($predictions, 'int32'), numClasses); + const oneHotLabelsT = transpose$2(oneHotLabels); + const product = matMul$1(oneHotLabelsT, oneHotPredictions); + return cast$3(product, 'int32'); + } + const confusionMatrix = /* @__PURE__ */ op({ confusionMatrix_ }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + var math = /*#__PURE__*/Object.freeze({ + __proto__: null, + confusionMatrix: confusionMatrix + }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + let fromPixels2DContext$1; + let hasToPixelsWarned = false; + /** + * Creates a `tf.Tensor` from an image. + * + * ```js + * const image = new ImageData(1, 1); + * image.data[0] = 100; + * image.data[1] = 150; + * image.data[2] = 200; + * image.data[3] = 255; + * + * tf.browser.fromPixels(image).print(); + * ``` + * + * @param pixels The input image to construct the tensor from. The + * supported image types are all 4-channel. You can also pass in an image + * object with following attributes: + * `{data: Uint8Array; width: number; height: number}` + * @param numChannels The number of channels of the output tensor. A + * numChannels value less than 4 allows you to ignore channels. Defaults to + * 3 (ignores alpha channel of input image). + * + * @returns A Tensor3D with the shape `[height, width, numChannels]`. + * + * Note: fromPixels can be lossy in some cases, same image may result in + * slightly different tensor values, if rendered by different rendering + * engines. This means that results from different browsers, or even same + * browser with CPU and GPU rendering engines can be different. See discussion + * in details: + * https://github.com/tensorflow/tfjs/issues/5482 + * + * @doc {heading: 'Browser', namespace: 'browser', ignoreCI: true} + */ + function fromPixels_(pixels, numChannels = 3) { + // Sanity checks. + if (numChannels > 4) { + throw new Error('Cannot construct Tensor with more than 4 channels from pixels.'); + } + if (pixels == null) { + throw new Error('pixels passed to tf.browser.fromPixels() can not be null'); + } + let isPixelData = false; + let isImageData = false; + let isVideo = false; + let isImage = false; + let isCanvasLike = false; + let isImageBitmap = false; + if (pixels.data instanceof Uint8Array) { + isPixelData = true; + } + else if (typeof (ImageData) !== 'undefined' && pixels instanceof ImageData) { + isImageData = true; + } + else if (typeof (HTMLVideoElement) !== 'undefined' && + pixels instanceof HTMLVideoElement) { + isVideo = true; + } + else if (typeof (HTMLImageElement) !== 'undefined' && + pixels instanceof HTMLImageElement) { + isImage = true; + // tslint:disable-next-line: no-any + } + else if (pixels.getContext != null) { + isCanvasLike = true; + } + else if (typeof (ImageBitmap) !== 'undefined' && pixels instanceof ImageBitmap) { + isImageBitmap = true; + } + else { + throw new Error('pixels passed to tf.browser.fromPixels() must be either an ' + + `HTMLVideoElement, HTMLImageElement, HTMLCanvasElement, ImageData ` + + `in browser, or OffscreenCanvas, ImageData in webworker` + + ` or {data: Uint32Array, width: number, height: number}, ` + + `but was ${pixels.constructor.name}`); + } + // If the current backend has 'FromPixels' registered, it has a more + // efficient way of handling pixel uploads, so we call that. + const kernel = getKernel(FromPixels, ENGINE.backendName); + if (kernel != null) { + const inputs = { pixels }; + const attrs = { numChannels }; + return ENGINE.runKernel(FromPixels, inputs, attrs); + } + const [width, height] = isVideo ? + [ + pixels.videoWidth, + pixels.videoHeight + ] : + [pixels.width, pixels.height]; + let vals; + if (isCanvasLike) { + vals = + // tslint:disable-next-line:no-any + pixels.getContext('2d').getImageData(0, 0, width, height).data; + } + else if (isImageData || isPixelData) { + vals = pixels.data; + } + else if (isImage || isVideo || isImageBitmap) { + if (fromPixels2DContext$1 == null) { + if (typeof document === 'undefined') { + if (typeof OffscreenCanvas !== 'undefined' && + typeof OffscreenCanvasRenderingContext2D !== 'undefined') { + // @ts-ignore + fromPixels2DContext$1 = new OffscreenCanvas(1, 1).getContext('2d'); + } + else { + throw new Error('Cannot parse input in current context. ' + + 'Reason: OffscreenCanvas Context2D rendering is not supported.'); + } + } + else { + fromPixels2DContext$1 = document.createElement('canvas').getContext('2d', { willReadFrequently: true }); + } + } + fromPixels2DContext$1.canvas.width = width; + fromPixels2DContext$1.canvas.height = height; + fromPixels2DContext$1.drawImage(pixels, 0, 0, width, height); + vals = fromPixels2DContext$1.getImageData(0, 0, width, height).data; + } + let values; + if (numChannels === 4) { + values = new Int32Array(vals); + } + else { + const numPixels = width * height; + values = new Int32Array(numPixels * numChannels); + for (let i = 0; i < numPixels; i++) { + for (let channel = 0; channel < numChannels; ++channel) { + values[i * numChannels + channel] = vals[i * 4 + channel]; + } + } + } + const outShape = [height, width, numChannels]; + return tensor3d(values, outShape, 'int32'); + } + // Helper functions for |fromPixelsAsync| to check whether the input can + // be wrapped into imageBitmap. + function isPixelData(pixels) { + return (pixels != null) && (pixels.data instanceof Uint8Array); + } + function isImageBitmapFullySupported() { + return typeof window !== 'undefined' && + typeof (ImageBitmap) !== 'undefined' && + window.hasOwnProperty('createImageBitmap'); + } + function isNonEmptyPixels(pixels) { + return pixels != null && pixels.width !== 0 && pixels.height !== 0; + } + function canWrapPixelsToImageBitmap(pixels) { + return isImageBitmapFullySupported() && !(pixels instanceof ImageBitmap) && + isNonEmptyPixels(pixels) && !isPixelData(pixels); + } + /** + * Creates a `tf.Tensor` from an image in async way. + * + * ```js + * const image = new ImageData(1, 1); + * image.data[0] = 100; + * image.data[1] = 150; + * image.data[2] = 200; + * image.data[3] = 255; + * + * (await tf.browser.fromPixelsAsync(image)).print(); + * ``` + * This API is the async version of fromPixels. The API will first + * check |WRAP_TO_IMAGEBITMAP| flag, and try to wrap the input to + * imageBitmap if the flag is set to true. + * + * @param pixels The input image to construct the tensor from. The + * supported image types are all 4-channel. You can also pass in an image + * object with following attributes: + * `{data: Uint8Array; width: number; height: number}` + * @param numChannels The number of channels of the output tensor. A + * numChannels value less than 4 allows you to ignore channels. Defaults to + * 3 (ignores alpha channel of input image). + * + * @doc {heading: 'Browser', namespace: 'browser', ignoreCI: true} + */ + async function fromPixelsAsync(pixels, numChannels = 3) { + let inputs = null; + // Check whether the backend needs to wrap |pixels| to imageBitmap and + // whether |pixels| can be wrapped to imageBitmap. + if (env().getBool('WRAP_TO_IMAGEBITMAP') && + canWrapPixelsToImageBitmap(pixels)) { + // Force the imageBitmap creation to not do any premultiply alpha + // ops. + let imageBitmap; + try { + // wrap in try-catch block, because createImageBitmap may not work + // properly in some browsers, e.g. + // https://bugzilla.mozilla.org/show_bug.cgi?id=1335594 + // tslint:disable-next-line: no-any + imageBitmap = await createImageBitmap(pixels, { premultiplyAlpha: 'none' }); + } + catch (e) { + imageBitmap = null; + } + // createImageBitmap will clip the source size. + // In some cases, the input will have larger size than its content. + // E.g. new Image(10, 10) but with 1 x 1 content. Using + // createImageBitmap will clip the size from 10 x 10 to 1 x 1, which + // is not correct. We should avoid wrapping such resouce to + // imageBitmap. + if (imageBitmap != null && imageBitmap.width === pixels.width && + imageBitmap.height === pixels.height) { + inputs = imageBitmap; + } + else { + inputs = pixels; + } + } + else { + inputs = pixels; + } + return fromPixels_(inputs, numChannels); + } + function validateImgTensor(img) { + if (img.rank !== 2 && img.rank !== 3) { + throw new Error(`toPixels only supports rank 2 or 3 tensors, got rank ${img.rank}.`); + } + const depth = img.rank === 2 ? 1 : img.shape[2]; + if (depth > 4 || depth === 2) { + throw new Error(`toPixels only supports depth of size ` + + `1, 3 or 4 but got ${depth}`); + } + if (img.dtype !== 'float32' && img.dtype !== 'int32') { + throw new Error(`Unsupported type for toPixels: ${img.dtype}.` + + ` Please use float32 or int32 tensors.`); + } + } + function validateImageOptions(imageOptions) { + const alpha = (imageOptions === null || imageOptions === void 0 ? void 0 : imageOptions.alpha) || 1; + if (alpha > 1 || alpha < 0) { + throw new Error(`Alpha value ${alpha} is suppoed to be in range [0 - 1].`); + } + } + /** + * Draws a `tf.Tensor` of pixel values to a byte array or optionally a + * canvas. + * + * When the dtype of the input is 'float32', we assume values in the range + * [0-1]. Otherwise, when input is 'int32', we assume values in the range + * [0-255]. + * + * Returns a promise that resolves when the canvas has been drawn to. + * + * @param img A rank-2 tensor with shape `[height, width]`, or a rank-3 tensor + * of shape `[height, width, numChannels]`. If rank-2, draws grayscale. If + * rank-3, must have depth of 1, 3 or 4. When depth of 1, draws + * grayscale. When depth of 3, we draw with the first three components of + * the depth dimension corresponding to r, g, b and alpha = 1. When depth of + * 4, all four components of the depth dimension correspond to r, g, b, a. + * @param canvas The canvas to draw to. + * + * @doc {heading: 'Browser', namespace: 'browser'} + */ + async function toPixels(img, canvas) { + let $img = convertToTensor(img, 'img', 'toPixels'); + if (!(img instanceof Tensor)) { + // Assume int32 if user passed a native array. + const originalImgTensor = $img; + $img = cast$3(originalImgTensor, 'int32'); + originalImgTensor.dispose(); + } + validateImgTensor($img); + const [height, width] = $img.shape.slice(0, 2); + const depth = $img.rank === 2 ? 1 : $img.shape[2]; + const data = await $img.data(); + const multiplier = $img.dtype === 'float32' ? 255 : 1; + const bytes = new Uint8ClampedArray(width * height * 4); + for (let i = 0; i < height * width; ++i) { + const rgba = [0, 0, 0, 255]; + for (let d = 0; d < depth; d++) { + const value = data[i * depth + d]; + if ($img.dtype === 'float32') { + if (value < 0 || value > 1) { + throw new Error(`Tensor values for a float32 Tensor must be in the ` + + `range [0 - 1] but encountered ${value}.`); + } + } + else if ($img.dtype === 'int32') { + if (value < 0 || value > 255) { + throw new Error(`Tensor values for a int32 Tensor must be in the ` + + `range [0 - 255] but encountered ${value}.`); + } + } + if (depth === 1) { + rgba[0] = value * multiplier; + rgba[1] = value * multiplier; + rgba[2] = value * multiplier; + } + else { + rgba[d] = value * multiplier; + } + } + const j = i * 4; + bytes[j + 0] = Math.round(rgba[0]); + bytes[j + 1] = Math.round(rgba[1]); + bytes[j + 2] = Math.round(rgba[2]); + bytes[j + 3] = Math.round(rgba[3]); + } + if (canvas != null) { + if (!hasToPixelsWarned) { + const kernel = getKernel(Draw, ENGINE.backendName); + if (kernel != null) { + console.warn('tf.browser.toPixels is not efficient to draw tensor on canvas. ' + + 'Please try tf.browser.draw instead.'); + hasToPixelsWarned = true; + } + } + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext('2d'); + const imageData = new ImageData(bytes, width, height); + ctx.putImageData(imageData, 0, 0); + } + if ($img !== img) { + $img.dispose(); + } + return bytes; + } + /** + * Draws a `tf.Tensor` to a canvas. + * + * When the dtype of the input is 'float32', we assume values in the range + * [0-1]. Otherwise, when input is 'int32', we assume values in the range + * [0-255]. + * + * @param image The tensor to draw on the canvas. Must match one of + * these shapes: + * - Rank-2 with shape `[height, width`]: Drawn as grayscale. + * - Rank-3 with shape `[height, width, 1]`: Drawn as grayscale. + * - Rank-3 with shape `[height, width, 3]`: Drawn as RGB with alpha set in + * `imageOptions` (defaults to 1, which is opaque). + * - Rank-3 with shape `[height, width, 4]`: Drawn as RGBA. + * @param canvas The canvas to draw to. + * @param options The configuration arguments for image to be drawn and the + * canvas to draw to. + * + * @doc {heading: 'Browser', namespace: 'browser'} + */ + function draw$1(image, canvas, options) { + let $img = convertToTensor(image, 'img', 'draw'); + if (!(image instanceof Tensor)) { + // Assume int32 if user passed a native array. + const originalImgTensor = $img; + $img = cast$3(originalImgTensor, 'int32'); + originalImgTensor.dispose(); + } + validateImgTensor($img); + validateImageOptions(options === null || options === void 0 ? void 0 : options.imageOptions); + const inputs = { image: $img }; + const attrs = { canvas, options }; + ENGINE.runKernel(Draw, inputs, attrs); + } + const fromPixels$1 = /* @__PURE__ */ op({ fromPixels_ }); + + var browser = /*#__PURE__*/Object.freeze({ + __proto__: null, + draw: draw$1, + fromPixels: fromPixels$1, + fromPixelsAsync: fromPixelsAsync, + toPixels: toPixels + }); + + /** + * Validate gather nd inputs. + * + * @param tensor The tensor contains the source values. + * @param indices The tensor contains the indices to slice the source. + * + * @returns [resultShape, numUpdates, sliceSize, strides] + */ + function prepareAndValidate(tensor, indices) { + const tensorRank = tensor.shape.length; + const indicesRank = indices.shape.length; + if (tensorRank < 1) { + throw new Error('tf.gatherND() expects the input to be rank 1 or higher,' + + ` but the rank was ${tensorRank}.`); + } + if (indicesRank < 1) { + throw new Error('tf.gatherND() expects the indices to be rank 1 or higher,' + + ` but the rank was ${indicesRank}.`); + } + if (indices.dtype !== 'int32') { + throw new Error('tf.gatherND() expects the indices to be int32 type,' + + ` but the dtype was ${indices.dtype}.`); + } + if (indices.shape[indicesRank - 1] > tensorRank) { + throw new Error('index innermost dimension length must be <= tensor rank; saw: ' + + `${indices.shape[indicesRank - 1]} vs. ${tensorRank}`); + } + if (sizeFromShape(tensor.shape) === 0) { + throw new Error('Requested more than 0 entries, but input is empty.' + + ` Input shape: ${tensor.shape}.`); + } + const indicesShape = indices.shape; + const sliceRank = indicesShape[indicesShape.length - 1]; + // The result shape is + // indices.shape[:-1] + params.shape[indices.shape[-1]:] + let nResult = 1; + for (let i = 0; i < indicesShape.length - 1; ++i) { + nResult *= indicesShape[i]; + } + const inputShape = tensor.shape; + const resultShape = indicesShape.slice(); + resultShape.pop(); + let sliceSize = 1; + for (let i = sliceRank; i < tensorRank; ++i) { + sliceSize *= inputShape[i]; + resultShape.push(inputShape[i]); + } + const strides = [...computeStrides(tensor.shape).map(stride => stride / sliceSize), + 1].slice(0, sliceRank); + return [resultShape, nResult, sliceSize, strides]; + } + + var gather_nd_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + prepareAndValidate: prepareAndValidate + }); + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const NEW_AXIS = -2; + const SHRINK_AXIS = -1; + function assertParamsValid(input, begin, size) { + const inputRank = input.shape.length; + assert$1(inputRank === begin.length, () => `Error in slice${inputRank}D: Length of begin ${begin} must ` + + `match the rank of the array (${inputRank}).`); + assert$1(inputRank === size.length, () => `Error in slice${inputRank}D: Length of size ${size} must ` + + `match the rank of the array (${inputRank}).`); + for (let i = 0; i < inputRank; ++i) { + assert$1(begin[i] + size[i] <= input.shape[i], () => `Error in slice${inputRank}D: begin[${i}] + size[${i}] ` + + `(${begin[i] + size[i]}) would overflow input.shape[${i}] (${input.shape[i]})`); + } + } + /** Converts a binary mask to an array of axes. Used in stridedSlice(). */ + function maskToAxes(mask) { + const axes = []; + let axis = 0; + while (mask > 0) { + if (mask & 1) { + axes.push(axis); + } + mask /= 2; + axis++; + } + return axes; + } + /** Computes the output shape given the strided slice params. */ + function computeOutShape$2(begin, end, strides) { + const size = []; + for (let axis = 0; axis < begin.length; axis++) { + size[axis] = Math.ceil((end[axis] - begin[axis]) / strides[axis]); + } + return size; + } + // Creates full selection at the elided dimensions. If the dimension matches + // the ellipsis mask, override the current stride value. Otherwise, insert. + function stridesWithElidedDims(strides, ellipsisInsertionIndex, numElidedAxes, inputShape) { + const newStrides = [...strides]; + for (let i = newStrides.length; i < inputShape.length; i++) { + newStrides.push(1); + } + for (let i = 0; i < numElidedAxes; i++) { + if (i === 0) { + newStrides[ellipsisInsertionIndex] = 1; + } + else { + newStrides.splice(ellipsisInsertionIndex, 0 /* num elements to delete */, 1 /* element to add */); + newStrides.pop(); + } + } + return newStrides; + } + function unnormalizeAxis(ellipsisInsertionIndex, numElidedAxes, normalizedAxis) { + if (normalizedAxis <= ellipsisInsertionIndex) { + return normalizedAxis; + } + return normalizedAxis - (numElidedAxes - 1); + } + function getElidedAxes(numElidedAxes, ellipsisInsertionIndex) { + const elidedAxes = []; + for (let i = 0; i < numElidedAxes; i++) { + elidedAxes.push(ellipsisInsertionIndex + i); + } + return elidedAxes; + } + // Normalize the start, end and strides. + function getNormalizedAxes(inputShape, ellipsisAxes, numInterpolatedAxes, begin, end, strides, beginMask, endMask, ellipsisMask) { + const inputRank = inputShape.length; + let normalizedBegin = new Array(inputRank), normalizedEnd = new Array(inputRank), normalizedStrides = new Array(inputRank); + if (ellipsisAxes.length && numInterpolatedAxes > 0) { + const fullIndex = ellipsisAxes[0]; + // The ellipsis applies to the masked index as well as any dimensions + // that are interpolated. + const numElidedAxes = numInterpolatedAxes + 1; + normalizedBegin = startIndicesWithElidedDims(beginMask, fullIndex, numElidedAxes, begin, inputShape); + normalizedEnd = stopIndicesWithElidedDims(endMask, fullIndex, numElidedAxes, end, inputShape); + normalizedStrides = + stridesWithElidedDims(strides, fullIndex, numElidedAxes, inputShape); + } + else { + for (let axis = 0; axis < inputRank; axis++) { + normalizedBegin[axis] = startForAxis(beginMask, begin, strides, inputShape, axis, ellipsisMask); + normalizedEnd[axis] = + stopForAxis(endMask, end, strides, inputShape, axis, ellipsisMask); + normalizedStrides[axis] = stridesForAxis(strides, axis, ellipsisMask); + } + } + return { + begin: normalizedBegin, + end: normalizedEnd, + strides: normalizedStrides + }; + } + // Creates full selection at the elided dimensions. If the dimension matches + // the ellipsis mask, override the current start value. Otherwise, insert. + function startIndicesWithElidedDims(beginMask, ellipsisInsertionIndex, numElidedAxes, originalBegin, inputShape) { + const newIndices = [...inputShape]; + const elidedAxes = getElidedAxes(numElidedAxes, ellipsisInsertionIndex); + for (let axis = 0; axis < newIndices.length; axis++) { + if (elidedAxes.indexOf(axis) > -1) { + newIndices[axis] = 0; + } + else { + const originalAxis = unnormalizeAxis(ellipsisInsertionIndex, numElidedAxes, axis); + let originalValue = originalBegin[originalAxis]; + if (beginMask & 1 << originalAxis) { + originalValue = 0; + } + newIndices[axis] = originalValue; + } + } + return newIndices; + } + // Creates full selection at the elided dimensions. If the dimension matches + // the ellipsis mask, override the current stop value. Otherwise, insert. + function stopIndicesWithElidedDims(endMask, ellipsisInsertionIndex, numElidedAxes, originalEnd, inputShape) { + const newIndices = [...inputShape]; + const elidedAxes = getElidedAxes(numElidedAxes, ellipsisInsertionIndex); + for (let axis = 0; axis < newIndices.length; axis++) { + if (elidedAxes.indexOf(axis) > -1) { + newIndices[axis] = Number.MAX_SAFE_INTEGER; + } + else { + const originalAxis = unnormalizeAxis(ellipsisInsertionIndex, numElidedAxes, axis); + let originalValue = originalEnd[originalAxis]; + if (endMask & 1 << originalAxis) { + originalValue = Number.MAX_SAFE_INTEGER; + } + newIndices[axis] = originalValue; + } + } + for (let i = 0; i < newIndices.length; i++) { + // Handle negative indices + const axisSize = inputShape[i]; + if (newIndices[i] < 0) { + newIndices[i] += axisSize; + } + newIndices[i] = clamp(0, newIndices[i], inputShape[i]); + } + return newIndices; + } + function stridesForAxis(strides, axis, ellipsisMask) { + let stride = strides[axis]; + if (ellipsisMask & (1 << axis) || stride == null) { + stride = 1; + } + return stride; + } + function startForAxis(beginMask, startIndices, strides, inputShape, axis, ellipsisMask) { + // Begin with the specified index + let start = startIndices[axis]; + const stride = strides[axis] || 1; + // Check the axis bit from right of masked axes, or the begin index is not set + // for the axis. + if (beginMask & 1 << axis || ellipsisMask & 1 << axis || start == null) { + if (stride > 0) { + // Forward iteration - use the first element. These values will get + // clamped below (Note: We could have set them to 0 and axis_size-1, but + // use lowest() and max() to maintain symmetry with StopForAxis()) + start = Number.MIN_SAFE_INTEGER; + } + else { + // Backward iteration - use the last element. + start = Number.MAX_SAFE_INTEGER; + } + } + // Handle negative indices + const axisSize = inputShape[axis]; + if (start < 0) { + start += axisSize; + } + // Clamping + start = clamp(0, start, axisSize - 1); + return start; + } + function stopForAxis(endMask, stopIndices, strides, inputShape, axis, ellipsisMask) { + // Begin with the specified index + let stop = stopIndices[axis]; + const stride = strides[axis] || 1; + // Check the axis bit from right of masked axes, or if the stop index is not + // set for this axis. + if (endMask & (1 << axis) || ellipsisMask & (1 << axis) || stop == null) { + if (stride > 0) { + // Forward iteration - use the last element. These values will get + // clamped below + stop = Number.MAX_SAFE_INTEGER; + } + else { + // Backward iteration - use the first element. + stop = Number.MIN_SAFE_INTEGER; + } + } + // Handle negative indices + const axisSize = inputShape[axis]; + if (stop < 0) { + stop += axisSize; + } + // Clamping + // Because the end index points one past the last element, we need slightly + // different clamping ranges depending on the direction. + if (stride > 0) { + // Forward iteration + stop = clamp(0, stop, axisSize); + } + else { + // Backward iteration + stop = clamp(-1, stop, axisSize - 1); + } + return stop; + } + /** + * Returns true if the slice occupies a continous set of elements in the + * 'flat' space. + */ + function isSliceContinous(shape, begin, size) { + // Index of the first axis that has size > 1. + let firstNonOneAxis = size.length; + for (let i = 0; i < size.length; i++) { + if (size[i] > 1) { + firstNonOneAxis = i; + break; + } + } + for (let i = firstNonOneAxis + 1; i < size.length; i++) { + if (begin[i] > 0 || size[i] !== shape[i]) { + return false; + } + } + return true; + } + function computeFlatOffset(begin, strides) { + let flatOffset = begin.length > 0 ? begin[begin.length - 1] : 1; + for (let i = 0; i < begin.length - 1; i++) { + flatOffset += begin[i] * strides[i]; + } + return flatOffset; + } + function parseSliceParams(x, begin, size) { + // The following logic allows for more ergonomic calls. + let begin_; + const xRank = x.shape.length; + if (typeof begin === 'number') { + begin_ = [begin, ...new Array(xRank - 1).fill(0)]; + } + else if (begin.length < xRank) { + begin_ = begin.concat(new Array(xRank - begin.length).fill(0)); + } + else { + begin_ = begin.slice(); + } + begin_.forEach(d => { + assert$1(d !== -1, () => 'slice() does not support negative begin indexing.'); + }); + let size_; + if (size == null) { + size_ = new Array(xRank).fill(-1); + } + else if (typeof size === 'number') { + size_ = [size, ...new Array(xRank - 1).fill(-1)]; + } + else if (size.length < xRank) { + size_ = size.concat(new Array(xRank - size.length).fill(-1)); + } + else { + size_ = size; + } + size_ = size_.map((d, i) => { + if (d >= 0) { + return d; + } + else { + assert$1(d === -1, () => `Negative size values should be exactly -1 but got ` + + `${d} for the slice() size at index ${i}.`); + return x.shape[i] - begin_[i]; + } + }); + return [begin_, size_]; + } + // Convert the slicing specification from a sparse representation to a dense + // representation. This means that all ellipses and newaxis are expanded out. + function sliceInfo(xShape, begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask) { + let stridesNonNull; + if (strides == null) { + stridesNonNull = new Array(begin.length); + stridesNonNull.fill(1); + } + else { + stridesNonNull = strides; + } + // Only one non-zero bit is allowed in ellipsisMask, which means ellipsisMask + // is a power of 2. Use bit compares to ensure ellipsisMask is 0 or a power + // of 2. When i is a power of 2, i & (i - 1) is always 0. + // Also ref: + // https://stackoverflow.com/questions/600293/how-to-check-if-a-number-is-a-power-of-2 + if (ellipsisMask != null && (ellipsisMask & (ellipsisMask - 1)) !== 0) { + throw new Error('Multiple ellipses in slice is not allowed.'); + } + // Step 1: Account for ellipsis and new axis. + // Check for ellipsis and count how many non-newaxis there are after. + let ellipsisSeen = false; + const sparseSpec = { + dims: stridesNonNull.length, + numAddAxisAfterEllipsis: 0, + begin: begin.slice(), + end: end.slice(), + strides: stridesNonNull.slice(), + beginMask, + endMask, + ellipsisMask, + newAxisMask, + shrinkAxisMask + }; + for (let i = 0; i < sparseSpec.dims; i++) { + if (ellipsisSeen && ((1 << i) & newAxisMask) !== 0) { + sparseSpec.numAddAxisAfterEllipsis++; + } + if ((1 << i) & ellipsisMask) { + ellipsisSeen = true; + } + } + // If no ellipsis insert one at the end. + if (!ellipsisSeen) { + sparseSpec.ellipsisMask |= (1 << sparseSpec.dims); + sparseSpec.dims++; // this effects loop iteration below + } + // Step 2: Make a sparse spec into a full index spec. + // + // The sparse spec deos not correspond to the number of dimensions. + // Make a dense spec that cooresponds to the number of dimensions. + // + // For example suppose foo[...,3:] on foo.shape = [2, 2, 3] then we need to + // produce the missing beginMask for the first two dimensions i.e. from + // beginMaskSpec = 0, endMaskSpec = 2, we achieve beginMask = 6 (110), + // endMask = 7 (111). + const denseSpec = { + dims: xShape.length, + beginMask: 0, + endMask: 0, + beginValid: false, + endValid: false + }; + buildDenseSpec(sparseSpec, denseSpec); + // Step 3: Make implicit ranges (non-zero beginMasks and endMasks) explicit + // and bounds check. + let isIdentity = true; + let sliceDim0 = true; + let isSimpleSlice = true; + const processingShape = []; + const finalShape = []; + for (let i = 0; i < xShape.length; ++i) { + if (denseSpec.strides[i] === 0) { + throw Error(`strides[${i}] must be non-zero`); + } + const shrinkI = !!(denseSpec.shrinkAxisMask & (1 << i)); + const dimI = xShape[i]; + if (dimI === -1) { + processingShape.push(shrinkI ? 1 : -1); + continue; + } + const masks = [denseSpec.beginMask & (1 << i), denseSpec.endMask & (1 << i)]; + const validRange = [ + denseSpec.strides[i] > 0 ? 0 : -1, + denseSpec.strides[i] > 0 ? dimI : dimI - 1 + ]; + if (shrinkI && denseSpec.strides[i] <= 0) { + throw Error('only stride 1 allowed on non-range indexing.'); + } + isSimpleSlice = isSimpleSlice && (denseSpec.strides[i] === 1); + const beginAndEndMasked = !!((denseSpec.beginMask & (1 << i)) && (denseSpec.endMask & (1 << i))); + if (denseSpec.beginValid && denseSpec.endValid) { + if (shrinkI) { + // If we are shrinking, the end index is now possibly incorrect. In + // particular foo[-1] produces sparseBegin = -1, sparseEnd = 0. + // and canonical puts these to n-1 and 0, which implies a degenerate + // interval. Fortunately, it is now safe to re-create end as begin + 1. + const xFwd = denseSpec.begin[i] < 0 ? dimI + denseSpec.begin[i] : + denseSpec.begin[i]; + denseSpec.begin[i] = xFwd; + denseSpec.end[i] = denseSpec.begin[i] + 1; + if (xFwd < 0 || xFwd >= dimI) { + throw Error(`slice index ${denseSpec.begin[i]} of dimension ${i} out of bounds.`); + } + } + else { + denseSpec.begin[i] = canonical(denseSpec.begin[i], 0, denseSpec.strides[i], dimI, masks, validRange); + denseSpec.end[i] = canonical(denseSpec.end[i], 1, denseSpec.strides[i], dimI, masks, validRange); + } + // Update optimization values + const takeAllInDimension = denseSpec.strides[i] === 1 && + denseSpec.begin[i] === 0 && denseSpec.end[i] === dimI; + isIdentity = isIdentity && takeAllInDimension; + sliceDim0 = sliceDim0 && + ((i === 0 && denseSpec.strides[i] === 1) || takeAllInDimension); + } + else { + isIdentity = + isIdentity && ((denseSpec.strides[i] === 1) && beginAndEndMasked); + sliceDim0 = sliceDim0 && + ((i === 0 && denseSpec.strides[i] === 1) || beginAndEndMasked); + } + // Compute the processing shape (the intermediate Eigen will produce) + let intervalLength; + let knownInterval = false; + if (denseSpec.beginValid && denseSpec.endValid) { + intervalLength = denseSpec.end[i] - denseSpec.begin[i]; + knownInterval = true; + } + else if (shrinkI) { + // The dimension is still known as 1 for the processingShape, but will be + // discarded for the final shape. + intervalLength = 1; + knownInterval = true; + } + else if (beginAndEndMasked) { + // Even if we don't have values for begin or end, we do know that this + // dimension covers the whole interval. If we have shape information for + // this dimension, that tells us the interval length. + if (dimI >= 0) { + if (denseSpec.strides[i] < 0) { + intervalLength = -dimI; + } + else { + intervalLength = dimI; + } + knownInterval = true; + } + } + if (knownInterval) { + let sizeI; + // Hold zero if the interval is degenerate, otherwise account for + // remainder + if (intervalLength === 0 || + ((intervalLength < 0) !== (denseSpec.strides[i] < 0))) { + sizeI = 0; + } + else { + sizeI = Math.trunc(intervalLength / denseSpec.strides[i]) + + (intervalLength % denseSpec.strides[i] !== 0 ? 1 : 0); + } + processingShape.push(sizeI); + } + else { + processingShape.push(-1); + } + } + // Step 4: Compute the final shape + // + // newAxis will increase dimension by 1 (with a one-size dimension) + // slices like foo[3, ...] will reduce dimension by 1. + // This cannot be done earlier, because it depends on Step 3. + for (let denseDim = 0; denseDim < denseSpec.finalShapeGatherIndices.length; ++denseDim) { + const gatherIndex = denseSpec.finalShapeGatherIndices[denseDim]; + if (gatherIndex >= 0) { + finalShape.push(processingShape[gatherIndex]); + } + else if (gatherIndex === NEW_AXIS) { + finalShape.push(1); + } + } + const finalShapeSparse = finalShape.filter((dim, i) => denseSpec.finalShapeGatherIndices[i] !== NEW_AXIS); + return { + finalShapeSparse, + finalShape, + isIdentity, + sliceDim0, + isSimpleSlice, + begin: denseSpec.begin, + end: denseSpec.end, + strides: denseSpec.strides + }; + } + function buildDenseSpec(sparse, dense) { + dense.beginMask = 0; + dense.endMask = 0; + dense.shrinkAxisMask = 0; + let fullIndex = 0; + dense.beginValid = sparse.begin != null; + dense.endValid = sparse.end != null; + dense.begin = new Array(dense.dims); + dense.end = new Array(dense.dims); + dense.strides = new Array(dense.dims); + dense.finalShapeGatherIndices = []; + dense.finalShapeGatherIndicesSparse = []; + dense.inputShapeGatherIndicesSparse = new Array(dense.dims); + for (let i = 0; i < sparse.dims; i++) { + if ((1 << i) & sparse.ellipsisMask) { + // Only the bit that has ellipsis will fall in this condition. + // Expand the ellipsis into the appropriate indices + // Note: this only works because we guaranteed one ellipsis. + const nextIndex = Math.min(dense.dims - (sparse.dims - i) + 1 + sparse.numAddAxisAfterEllipsis, dense.dims); + for (; fullIndex < nextIndex; fullIndex++) { + // newAxis aren't real axis so you have to skip. + dense.begin[fullIndex] = 0; + dense.end[fullIndex] = 0; + dense.strides[fullIndex] = 1; + dense.beginMask |= (1 << fullIndex); + dense.endMask |= (1 << fullIndex); + dense.finalShapeGatherIndices.push(fullIndex); + dense.finalShapeGatherIndicesSparse.push(-1); + dense.inputShapeGatherIndicesSparse[fullIndex] = i; + } + } + else if ((1 << i) & sparse.newAxisMask) { + // Only the bit that has newAxis will fall in this condition. + dense.finalShapeGatherIndices.push(NEW_AXIS); + dense.finalShapeGatherIndicesSparse.push(-1); + } + else { + if (fullIndex === dense.begin.length) { + throw Error(`Index out of range using input dim ${fullIndex}; input ` + + `has only ${dense.dims} dims, ${dense.begin.length}.`); + } + // Gather slicing spec into appropriate index. + if (sparse.begin != null) { + dense.begin[fullIndex] = sparse.begin[i]; + } + if (sparse.end != null) { + dense.end[fullIndex] = sparse.end[i]; + } + dense.strides[fullIndex] = sparse.strides[i]; + if (sparse.beginMask & (1 << i)) { + dense.beginMask |= (1 << fullIndex); + } + if (sparse.endMask & (1 << i)) { + dense.endMask |= (1 << fullIndex); + } + // If shrink, record where to get the dimensionality from (i.e. newAxis) + // creates a fake 1 size dimension. Also remember shrink axis (now in + // dense form) so we can ignore dense.end below. + if (sparse.shrinkAxisMask & (1 << i)) { + dense.finalShapeGatherIndices.push(SHRINK_AXIS); + dense.finalShapeGatherIndicesSparse.push(-1); + dense.shrinkAxisMask |= (1 << fullIndex); + } + else { + dense.finalShapeGatherIndices.push(fullIndex); + // Remember that where in the sparse shape the dense dim comes from. + dense.finalShapeGatherIndicesSparse.push(i); + } + dense.inputShapeGatherIndicesSparse[fullIndex] = i; + fullIndex++; + } + } + } + function canonical(x, c, strideI, dimI, masks, validRange) { + if (masks[c]) { + return strideI > 0 ? validRange[c] : validRange[(c + 1) & 1]; + } + else { + const xFwd = x < 0 ? dimI + x : x; // make negative indices positive + return xFwd < validRange[0] ? validRange[0] : + xFwd > validRange[1] ? validRange[1] : xFwd; + } + } + + var slice_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + assertParamsValid: assertParamsValid, + computeFlatOffset: computeFlatOffset, + computeOutShape: computeOutShape$2, + getNormalizedAxes: getNormalizedAxes, + isSliceContinous: isSliceContinous, + maskToAxes: maskToAxes, + parseSliceParams: parseSliceParams, + sliceInfo: sliceInfo, + startForAxis: startForAxis, + startIndicesWithElidedDims: startIndicesWithElidedDims, + stopForAxis: stopForAxis, + stopIndicesWithElidedDims: stopIndicesWithElidedDims, + stridesForAxis: stridesForAxis, + stridesWithElidedDims: stridesWithElidedDims + }); + + /** @license See the LICENSE file. */ + // This code is auto-generated, do not modify this file! + const version$7 = '4.22.0'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class OptimizerConstructors { + /** + * Constructs a `tf.SGDOptimizer` that uses stochastic gradient descent. + * + * ```js + * // Fit a quadratic function by learning the coefficients a, b, c. + * const xs = tf.tensor1d([0, 1, 2, 3]); + * const ys = tf.tensor1d([1.1, 5.9, 16.8, 33.9]); + * + * const a = tf.scalar(Math.random()).variable(); + * const b = tf.scalar(Math.random()).variable(); + * const c = tf.scalar(Math.random()).variable(); + * + * // y = a * x^2 + b * x + c. + * const f = x => a.mul(x.square()).add(b.mul(x)).add(c); + * const loss = (pred, label) => pred.sub(label).square().mean(); + * + * const learningRate = 0.01; + * const optimizer = tf.train.sgd(learningRate); + * + * // Train the model. + * for (let i = 0; i < 10; i++) { + * optimizer.minimize(() => loss(f(xs), ys)); + * } + * + * // Make predictions. + * console.log( + * `a: ${a.dataSync()}, b: ${b.dataSync()}, c: ${c.dataSync()}`); + * const preds = f(xs).dataSync(); + * preds.forEach((pred, i) => { + * console.log(`x: ${i}, pred: ${pred}`); + * }); + * ``` + * + * @param learningRate The learning rate to use for the SGD algorithm. + * + * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'} + */ + static sgd(learningRate) { + return new SGDOptimizer(learningRate); + } + /** + * Constructs a `tf.MomentumOptimizer` that uses momentum gradient + * descent. + * + * See + * [http://proceedings.mlr.press/v28/sutskever13.pdf]( + * http://proceedings.mlr.press/v28/sutskever13.pdf) + * + * @param learningRate The learning rate to use for the Momentum gradient + * descent algorithm. + * @param momentum The momentum to use for the momentum gradient descent + * algorithm. + * + * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'} + */ + static momentum(learningRate, momentum, useNesterov = false) { + return new MomentumOptimizer(learningRate, momentum, useNesterov); + } + /** + * Constructs a `tf.RMSPropOptimizer` that uses RMSProp gradient + * descent. This implementation uses plain momentum and is not centered + * version of RMSProp. + * + * See + * [http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf]( + * http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf) + * + * @param learningRate The learning rate to use for the RMSProp gradient + * descent algorithm. + * @param decay The discounting factor for the history/coming gradient. + * @param momentum The momentum to use for the RMSProp gradient descent + * algorithm. + * @param epsilon Small value to avoid zero denominator. + * @param centered If true, gradients are normalized by the estimated + * variance of the gradient. + * + * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'} + */ + static rmsprop(learningRate, decay = .9, momentum = 0.0, epsilon = null, centered = false) { + return new RMSPropOptimizer(learningRate, decay, momentum, epsilon, centered); + } + /** + * Constructs a `tf.AdamOptimizer` that uses the Adam algorithm. + * See [https://arxiv.org/abs/1412.6980](https://arxiv.org/abs/1412.6980) + * + * @param learningRate The learning rate to use for the Adam gradient + * descent algorithm. + * @param beta1 The exponential decay rate for the 1st moment estimates. + * @param beta2 The exponential decay rate for the 2nd moment estimates. + * @param epsilon A small constant for numerical stability. + * + * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'} + */ + static adam(learningRate = 0.001, beta1 = 0.9, beta2 = 0.999, epsilon = null) { + return new AdamOptimizer(learningRate, beta1, beta2, epsilon); + } + /** + * Constructs a `tf.AdadeltaOptimizer` that uses the Adadelta algorithm. + * See [https://arxiv.org/abs/1212.5701](https://arxiv.org/abs/1212.5701) + * + * @param learningRate The learning rate to use for the Adadelta gradient + * descent algorithm. + * @param rho The learning rate decay over each update. + * @param epsilon A constant epsilon used to better condition the grad + * update. + * + * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'} + */ + static adadelta(learningRate = .001, rho = .95, epsilon = null) { + return new AdadeltaOptimizer(learningRate, rho, epsilon); + } + /** + * Constructs a `tf.AdamaxOptimizer` that uses the Adamax algorithm. + * See [https://arxiv.org/abs/1412.6980](https://arxiv.org/abs/1412.6980) + * + * @param learningRate The learning rate to use for the Adamax gradient + * descent algorithm. + * @param beta1 The exponential decay rate for the 1st moment estimates. + * @param beta2 The exponential decay rate for the 2nd moment estimates. + * @param epsilon A small constant for numerical stability. + * @param decay The learning rate decay over each update. + * + * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'} + */ + static adamax(learningRate = 0.002, beta1 = 0.9, beta2 = 0.999, epsilon = null, decay = 0.0) { + return new AdamaxOptimizer(learningRate, beta1, beta2, epsilon, decay); + } + /** + * Constructs a `tf.AdagradOptimizer` that uses the Adagrad algorithm. + * See + * [http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf]( + * http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf) + * or + * [http://ruder.io/optimizing-gradient-descent/index.html#adagrad]( + * http://ruder.io/optimizing-gradient-descent/index.html#adagrad) + * + * @param learningRate The learning rate to use for the Adagrad gradient + * descent algorithm. + * @param initialAccumulatorValue Starting value for the accumulators, must be + * positive. + * + * @doc {heading: 'Training', subheading: 'Optimizers', namespace: 'train'} + */ + static adagrad(learningRate, initialAccumulatorValue = 0.1) { + return new AdagradOptimizer(learningRate, initialAccumulatorValue); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const train = OptimizerConstructors; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const delayCallback = (() => { + if (typeof requestAnimationFrame !== 'undefined') { + return requestAnimationFrame; + } + else if (typeof setImmediate !== 'undefined') { + return setImmediate; + } + return (f) => f(); // no delays + })(); + /** + * Returns a promise that resolves when a requestAnimationFrame has completed. + * + * On Node.js this uses setImmediate instead of requestAnimationFrame. + * + * This is simply a sugar method so that users can do the following: + * `await tf.nextFrame();` + * + * @doc {heading: 'Performance', subheading: 'Timing'} + */ + function nextFrame() { + return new Promise(resolve => delayCallback(() => resolve())); + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function assertParamsConsistent(shapes, axis) { + const rank = shapes[0].length; + shapes.forEach((shape, i) => { + assert$1(shape.length === rank, () => `Error in concat${rank}D: rank of tensors[${i}] must be the same ` + + `as the rank of the rest (${rank})`); + }); + assert$1(axis >= 0 && axis < rank, () => `Error in concat${rank}D: axis must be between 0 and ${rank - 1}.`); + const firstShape = shapes[0]; + shapes.forEach((shape, i) => { + for (let r = 0; r < rank; r++) { + assert$1((r === axis) || (shape[r] === firstShape[r]), () => `Error in concat${rank}D: Shape of tensors[${i}] (${shape}) ` + + `does not match the shape of the rest (${firstShape}) ` + + `along the non-concatenated axis ${i}.`); + } + }); + } + function computeOutShape$1(shapes, axis) { + const outputShape = shapes[0].slice(); + for (let i = 1; i < shapes.length; i++) { + outputShape[axis] += shapes[i][axis]; + } + return outputShape; + } + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + var RowPartitionType$1; + (function (RowPartitionType) { + RowPartitionType[RowPartitionType["FIRST_DIM_SIZE"] = 0] = "FIRST_DIM_SIZE"; + RowPartitionType[RowPartitionType["VALUE_ROWIDS"] = 1] = "VALUE_ROWIDS"; + RowPartitionType[RowPartitionType["ROW_LENGTHS"] = 2] = "ROW_LENGTHS"; + RowPartitionType[RowPartitionType["ROW_SPLITS"] = 3] = "ROW_SPLITS"; + RowPartitionType[RowPartitionType["ROW_LIMITS"] = 4] = "ROW_LIMITS"; + RowPartitionType[RowPartitionType["ROW_STARTS"] = 5] = "ROW_STARTS"; + })(RowPartitionType$1 || (RowPartitionType$1 = {})); + function combineRaggedTensorToTensorShapes(raggedRank, shape, valueShape) { + // Test for consistency of valueShape and shape specified. + // If shape is unspecified and valueShape is specified, then copy + // over the size from the valueShape dimension. + let outputShape = new Array(); + if (valueShape == null && shape == null) { + return outputShape; + } + if (shape == null) { + // Here, value_shape must be of known size. + while (outputShape.length < raggedRank + valueShape.length) { + outputShape.push(-1); + } + } + else { + outputShape = shape.slice(); + } + if (valueShape == null) { + return outputShape; + } + // At this point, valueShape and output_shape have known ranks. + if (raggedRank + valueShape.length !== outputShape.length) { + throw new Error(`rt input.shape and shape=${shape} are incompatible: rt input.rank = ${raggedRank + + valueShape.length}, but shape.rank = ${outputShape.length}`); + } + for (let i = 1; i < valueShape.length; ++i) { + const valueDim = valueShape[i]; + const outputShapeDimIndex = outputShape[outputShape.length - valueShape.length + i]; + const outputShapeDim = outputShape[outputShapeDimIndex]; + if (valueDim >= 0) { + if (outputShapeDim >= 0) { + if (outputShapeDim !== valueDim) { + throw new Error(`rt input.shape and shape=${shape} are incompatible: rt input.shape[${i + raggedRank}] = ${valueDim} but shape[${i + raggedRank}] = ${outputShapeDim}`); + } + } + else { + outputShape[outputShapeDimIndex] = valueDim; + } + } + } + return outputShape; + } + function getRowPartitionTypesHelper(rowPartitionTypeStrings) { + const stringToType = { + 'FIRST_DIM_SIZE': RowPartitionType$1.FIRST_DIM_SIZE, + 'VALUE_ROWIDS': RowPartitionType$1.VALUE_ROWIDS, + 'ROW_LENGTHS': RowPartitionType$1.ROW_LENGTHS, + 'ROW_SPLITS': RowPartitionType$1.ROW_SPLITS, + 'ROW_LIMITS': RowPartitionType$1.ROW_LIMITS, + 'ROW_STARTS': RowPartitionType$1.ROW_STARTS + }; + const result = []; + for (const typeStr of rowPartitionTypeStrings) { + if (typeStr in stringToType) { + result.push(stringToType[typeStr]); + } + else { + break; + } + } + return result; + } + function getRaggedRank(rowPartitionTypes) { + if (rowPartitionTypes.length === 0) { + return 0; + } + if (rowPartitionTypes[0] === RowPartitionType$1.FIRST_DIM_SIZE) { + return rowPartitionTypes.length - 1; + } + return rowPartitionTypes.length; + } + function validateDefaultValueShape(defaultValueShape, valueShape) { + if (defaultValueShape == null || valueShape == null) { + return; + } + const defaultNDims = defaultValueShape.length; + const valuesNDims = valueShape.length; + if (defaultNDims >= valuesNDims) { + throw new Error(`defaultValue.shape=${defaultValueShape} and ragged tensor flatValues.shape=${valueShape}, are incompatible: defaultValue.rank = ${defaultNDims} must be less than ragged tensor input flatValues.rank = ${valuesNDims})`); + } + for (let i = 0; i < Math.min(defaultNDims, valuesNDims - 1); ++i) { + const defaultDim = defaultValueShape[i]; + const valueDim = valueShape[i + 1]; + if (defaultDim >= 0 && valueDim >= 0 && defaultDim !== 1 && + defaultDim !== valueDim) { + throw new Error(`defaultValue.shape=${defaultValueShape}, and ragged tensor input flatValues.shape=${valueShape} are incompatible: defaultValue.shape[${i - defaultValueShape.length}] = ${defaultDim} but ragged tensor input.flatValues.shape[${i - defaultValueShape.length}] = ${valueDim}`); + } + } + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const PARALLELIZE_THRESHOLD = 30; + function computeOptimalWindowSize(inSize) { + if (inSize <= PARALLELIZE_THRESHOLD) { + return inSize; + } + return nearestDivisor(inSize, Math.floor(Math.sqrt(inSize))); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Returns the image center in pixels. + function getImageCenter(center, imageHeight, imageWidth) { + const centerX = imageWidth * (typeof center === 'number' ? center : center[0]); + const centerY = imageHeight * (typeof center === 'number' ? center : center[1]); + return [centerX, centerY]; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Gets the new shape of the input Tensor after it's been reshaped + * to: + * [blockShape[0], ..., blockShape[M-1], batch / prod(blockShape), + * inputShape[1], ..., inputShape[N-1]] + * + * See step 1: https://www.tensorflow.org/api_docs/python/tf/batch_to_space_nd + */ + function getReshaped(inputShape, blockShape, prod, batchToSpace = true) { + let reshaped = []; + if (batchToSpace) { + reshaped = reshaped.concat(blockShape.slice(0)); + reshaped.push(inputShape[0] / prod); + reshaped = reshaped.concat(inputShape.slice(1)); + } + else { + reshaped = reshaped.concat(inputShape[0]); + const spatialLength = blockShape.length; + for (let i = 0; i < spatialLength; ++i) { + reshaped = + reshaped.concat([inputShape[i + 1] / blockShape[i], blockShape[i]]); + } + reshaped = reshaped.concat(inputShape.slice(spatialLength + 1)); + } + return reshaped; + } + /** + * Gets the permutation that will transpose the dimensions of the + * reshaped tensor to shape: + * + * [batch / prod(block_shape),inputShape[1], blockShape[0], ..., + * inputShape[M], blockShape[M-1],inputShape[M+1], ..., inputShape[N-1]] + * + * see step 2: https://www.tensorflow.org/api_docs/python/tf/batch_to_space_nd + */ + function getPermuted(reshapedRank, blockShapeRank, batchToSpace = true) { + const permuted = []; + if (batchToSpace) { + permuted.push(blockShapeRank); + for (let i = blockShapeRank + 1; i < reshapedRank; ++i) { + if (i <= 2 * blockShapeRank) { + permuted.push(i); + permuted.push(i - (blockShapeRank + 1)); + } + else { + permuted.push(i); + } + } + } + else { + const permutedBeforeBatch = []; + const permutedAfterBatch = []; + for (let i = 1; i < reshapedRank; ++i) { + if (i >= blockShapeRank * 2 + 1 || i % 2 === 1) { + permutedAfterBatch.push(i); + } + else { + permutedBeforeBatch.push(i); + } + } + permuted.push(...permutedBeforeBatch); + permuted.push(0); + permuted.push(...permutedAfterBatch); + } + return permuted; + } + /** + * Gets the shape of the reshaped and permuted input Tensor before any cropping + * is applied. The new shape will be: + * + * [batch / prod(blockShape),inputShape[1] * blockShape[0], ..., + * inputShape[M] * blockShape[M-1],inputShape[M+1], ..., inputShape[N-1]] + * + * See step 3: https://www.tensorflow.org/api_docs/python/tf/batch_to_space_nd + */ + function getReshapedPermuted(inputShape, blockShape, prod, batchToSpace = true) { + const reshapedPermuted = []; + if (batchToSpace) { + reshapedPermuted.push(inputShape[0] / prod); + } + else { + reshapedPermuted.push(inputShape[0] * prod); + } + for (let i = 1; i < inputShape.length; ++i) { + if (i <= blockShape.length) { + if (batchToSpace) { + reshapedPermuted.push(blockShape[i - 1] * inputShape[i]); + } + else { + reshapedPermuted.push(inputShape[i] / blockShape[i - 1]); + } + } + else { + reshapedPermuted.push(inputShape[i]); + } + } + return reshapedPermuted; + } + /** + * Converts the crops argument into the beginning coordinates of a slice + * operation. + */ + function getSliceBeginCoords(crops, blockShape) { + const sliceBeginCoords = [0]; + for (let i = 0; i < blockShape; ++i) { + sliceBeginCoords.push(crops[i][0]); + } + return sliceBeginCoords; + } + /** + * Converts the crops argument into the size of a slice operation. When + * combined with getSliceBeginCoords this function allows the reshaped and + * permuted Tensor to be cropped to its final output shape of: + * + * inputShape[1] * blockShape[0] - crops[0,0] - crops[0,1], ..., + * inputShape[M] * blockShape[M-1] -crops[M-1,0] - + * crops[M-1,1],inputShape[M+1], ..., inputShape[N-1]] + * + * See step 4: https://www.tensorflow.org/api_docs/python/tf/batch_to_space_nd + */ + function getSliceSize(uncroppedShape, crops, blockShape) { + const sliceSize = uncroppedShape.slice(0, 1); + for (let i = 0; i < blockShape; ++i) { + sliceSize.push(uncroppedShape[i + 1] - crops[i][0] - crops[i][1]); + } + return sliceSize; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SELU_SCALEALPHA = 1.7580993408473768599402175208123; + const SELU_SCALE = 1.0507009873554804934193349852946; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ERF_P = 0.3275911; + const ERF_A1 = 0.254829592; + const ERF_A2 = -0.284496736; + const ERF_A3 = 1.421413741; + const ERF_A4 = -1.453152027; + const ERF_A5 = 1.061405429; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Merges real and imaginary Float32Arrays into a single complex Float32Array. + * + * The memory layout is interleaved as follows: + * real: [r0, r1, r2] + * imag: [i0, i1, i2] + * complex: [r0, i0, r1, i1, r2, i2] + * + * This is the inverse of splitRealAndImagArrays. + * + * @param real The real values of the complex tensor values. + * @param imag The imag values of the complex tensor values. + * @returns A complex tensor as a Float32Array with merged values. + */ + function mergeRealAndImagArrays(real, imag) { + if (real.length !== imag.length) { + throw new Error(`Cannot merge real and imag arrays of different lengths. real:` + + `${real.length}, imag: ${imag.length}.`); + } + const result = new Float32Array(real.length * 2); + for (let i = 0; i < result.length; i += 2) { + result[i] = real[i / 2]; + result[i + 1] = imag[i / 2]; + } + return result; + } + /** + * Splits a complex Float32Array into real and imag parts. + * + * The memory layout is interleaved as follows: + * complex: [r0, i0, r1, i1, r2, i2] + * real: [r0, r1, r2] + * imag: [i0, i1, i2] + * + * This is the inverse of mergeRealAndImagArrays. + * + * @param complex The complex tensor values. + * @returns An object with real and imag Float32Array components of the complex + * tensor. + */ + function splitRealAndImagArrays(complex) { + const real = new Float32Array(complex.length / 2); + const imag = new Float32Array(complex.length / 2); + for (let i = 0; i < complex.length; i += 2) { + real[i / 2] = complex[i]; + imag[i / 2] = complex[i + 1]; + } + return { real, imag }; + } + /** + * Extracts even indexed complex values in the given array. + * @param complex The complex tensor values + */ + function complexWithEvenIndex(complex) { + const len = Math.ceil(complex.length / 4); + const real = new Float32Array(len); + const imag = new Float32Array(len); + for (let i = 0; i < complex.length; i += 4) { + real[Math.floor(i / 4)] = complex[i]; + imag[Math.floor(i / 4)] = complex[i + 1]; + } + return { real, imag }; + } + /** + * Extracts odd indexed complete values in the given array. + * @param complex The complex tensor values + */ + function complexWithOddIndex(complex) { + const len = Math.floor(complex.length / 4); + const real = new Float32Array(len); + const imag = new Float32Array(len); + for (let i = 2; i < complex.length; i += 4) { + real[Math.floor(i / 4)] = complex[i]; + imag[Math.floor(i / 4)] = complex[i + 1]; + } + return { real, imag }; + } + /** + * Get the map representing a complex value in the given array. + * @param complex The complex tensor values. + * @param index An index of the target complex value. + */ + function getComplexWithIndex(complex, index) { + const real = complex[index * 2]; + const imag = complex[index * 2 + 1]; + return { real, imag }; + } + /** + * Insert a given complex value into the TypedArray. + * @param data The array in which the complex value is inserted. + * @param c The complex value to be inserted. + * @param index An index of the target complex value. + */ + function assignToTypedArray(data, real, imag, index) { + data[index * 2] = real; + data[index * 2 + 1] = imag; + } + /** + * Make the list of exponent terms used by FFT. + */ + function exponents(n, inverse) { + const real = new Float32Array(n / 2); + const imag = new Float32Array(n / 2); + for (let i = 0; i < Math.ceil(n / 2); i++) { + const x = (inverse ? 2 : -2) * Math.PI * (i / n); + real[i] = Math.cos(x); + imag[i] = Math.sin(x); + } + return { real, imag }; + } + /** + * Make the exponent term used by FFT. + */ + function exponent(k, n, inverse) { + const x = (inverse ? 2 : -2) * Math.PI * (k / n); + const real = Math.cos(x); + const imag = Math.sin(x); + return { real, imag }; + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ARROW = '->'; + const ARROW_REGEX = /->/g; + const COMMA = ','; + const ELLIPSIS = '...'; + /** + * Parse an equation for einsum. + * + * @param equation The einsum equation (e.g., "ij,jk->ik"). + * @param numTensors Number of tensors provided along with `equation`. Used to + * check matching number of input tensors. + * @returns An object consisting of the following fields: + * - allDims: all dimension names as strings. + * - summedDims: a list of all dimensions being summed over, as indices to + * the elements of `allDims`. + * - idDims: indices of the dimensions in each input tensor, as indices to + * the elements of `allDims. + */ + function decodeEinsumEquation(equation, numTensors) { + equation = equation.replace(/\s/g, ''); // Remove witespace in equation. + const numArrows = (equation.length - equation.replace(ARROW_REGEX, '').length) / + ARROW.length; + if (numArrows < 1) { + throw new Error('Equations without an arrow are not supported.'); + } + else if (numArrows > 1) { + throw new Error(`Equation must contain exactly one arrow ("${ARROW}").`); + } + const [inputString, outputString] = equation.split(ARROW); + assert$1(inputString.indexOf(ELLIPSIS) === -1, () => `The ellipsis notation ("${ELLIPSIS}") is not supported yet.`); + const inputTerms = inputString.split(COMMA); + const numInputs = inputTerms.length; + if (numTensors !== numInputs) { + throw new Error(`Expected ${numInputs} input tensors, received ${numTensors}`); + } + if (numInputs > 2) { + throw new Error('Support for more than 2 input tensors is not implemented yet.'); + } + const allDims = []; + for (let i = 0; i < outputString.length; ++i) { + const dimName = outputString[i]; + if (!inputTerms.some(inputTerm => inputTerm.indexOf(dimName) !== -1)) { + throw new Error(`Output subscripts contain the label ${dimName} ` + + `not present in the input subscripts.`); + } + if (allDims.indexOf(dimName) === -1) { + allDims.push(dimName); + } + } + for (let i = 0; i < inputString.length; ++i) { + const dimName = inputString[i]; + if (allDims.indexOf(dimName) === -1 && dimName !== COMMA) { + allDims.push(dimName); + } + } + const idDims = new Array(inputTerms.length); + for (let i = 0; i < numInputs; ++i) { + if (new Set(inputTerms[i].split('')).size !== inputTerms[i].length) { + throw new Error(`Found duplicate axes in input component ${inputTerms[i]}. ` + + `Support for duplicate axes in input is not implemented yet.`); + } + idDims[i] = []; + for (let j = 0; j < inputTerms[i].length; ++j) { + idDims[i].push(allDims.indexOf(inputTerms[i][j])); + } + } + const numDims = allDims.length; // Number of unique dimensions. + const numOutDims = outputString.length; // Number of output dimensions. + const summedDims = []; // Dimensions being summed over. + for (let i = numOutDims; i < numDims; ++i) { + summedDims.push(i); + } + return { allDims, summedDims, idDims }; + } + /** + * Get the permutation for a given input tensor. + * + * @param nDims Total number of dimension of all tensors involved in the einsum + * operation. + * @param idDims Dimension indices involve in the tensor in question. + * @returns An object consisting of the following fields: + * - permutationIndices: Indices to permute the axes of the tensor with. + * - expandDims: Indices to the dimension that need to be expanded from the + * tensor after permutation. + */ + function getEinsumPermutation(nDims, idDims) { + let permutationIndices = new Array(nDims); + permutationIndices.fill(-1); + for (let i = 0; i < idDims.length; ++i) { + permutationIndices[idDims[i]] = i; + } + const expandDims = []; + for (let i = 0; i < nDims; ++i) { + if (permutationIndices[i] === -1) { + expandDims.push(i); + } + } + permutationIndices = permutationIndices.filter(d => d !== -1); + return { permutationIndices, expandDims }; + } + /** + * Checks that the dimension sizes from different input tensors match the + * equation. + */ + function checkEinsumDimSizes(nDims, idDims, tensors) { + const dimSizes = new Array(nDims); + for (let i = 0; i < tensors.length; ++i) { + const shape = tensors[i].shape; + for (let j = 0; j < idDims[i].length; ++j) { + if (dimSizes[idDims[i][j]] === undefined) { + dimSizes[idDims[i][j]] = shape[j]; + } + else { + assert$1(dimSizes[idDims[i][j]] === shape[j], () => `Expected dimension ${dimSizes[idDims[i][j]]} at axis ${j} ` + + `of input shaped ${JSON.stringify(shape)}, ` + + `but got dimension ${shape[j]}`); + } + } + } + } + /** + * Gets path of computation for einsum. + * + * @param summedDims indices to the dimensions being summed over. + * @param idDims A look up table for the dimensions present in each input + * tensor.Each constituent array contains indices for the dimensions in the + * corresponding input tensor. + * + * @return A map with two fields: + * - path: The path of computation, with each element indicating the dimension + * being summed over after the element-wise multiplication in that step. + * - steps: With the same length as `path`. Each element contains the indices + * to the input tensors being used for element-wise multiplication in the + * corresponding step. + */ + function getEinsumComputePath(summedDims, idDims) { + const path = summedDims; + const steps = []; + let nSteps = 0; + if (summedDims.length === 0) { + // Einsum that involes no summing: e.g., transpose and outer product. + path.push(-1); + } + nSteps = summedDims.length + 1; + for (let i = 0; i < nSteps; ++i) { + steps.push([]); + } + const computedTermIndices = []; + for (let i = 0; i < path.length; ++i) { + const summedDim = path[i]; + const termIndices = findTermsWithDim(idDims, summedDim); + for (const termIndex of termIndices) { + if (computedTermIndices.indexOf(termIndex) === -1) { + steps[i].push(termIndex); + computedTermIndices.push(termIndex); + } + } + } + return { path, steps }; + } + /** Determines if an axes permutation is the identity permutation. */ + function isIdentityPermutation(perm) { + return perm.every((dim, index) => dim === index); + } + function findTermsWithDim(idDims, dim) { + const termIndices = []; + for (let i = 0; i < idDims.length; ++i) { + if (idDims[i].length === 0 || idDims[i].indexOf(dim) !== -1 || dim === -1) { + termIndices.push(i); + } + } + return termIndices; + } + + /** + * Prepare the split size array. When the input is a number, the axis is evenly + * divided among the split size. When the input contains the negative value, the + * rest of the axis is allocated toward that. + */ + function prepareSplitSize(x, numOrSizeSplits, axis = 0) { + let splitSizes = []; + if (typeof (numOrSizeSplits) === 'number') { + assert$1(x.shape[axis] % numOrSizeSplits === 0, () => 'Number of splits must evenly divide the axis.'); + splitSizes = + new Array(numOrSizeSplits).fill(x.shape[axis] / numOrSizeSplits); + } + else { + const numOfNegs = numOrSizeSplits.reduce((count, value) => { + if (value === -1) { + count += 1; + } + return count; + }, 0); + assert$1(numOfNegs <= 1, () => 'There should be only one negative value in split array.'); + const negIndex = numOrSizeSplits.indexOf(-1); + // Allow the number of split array to be -1, which indicates the rest + // of dimension is allocated to that split. + if (negIndex !== -1) { + const total = numOrSizeSplits.reduce((a, b) => b > 0 ? a + b : a); + numOrSizeSplits[negIndex] = x.shape[axis] - total; + } + assert$1(x.shape[axis] === numOrSizeSplits.reduce((a, b) => a + b), () => 'The sum of sizes must match the size of the axis dimension.'); + splitSizes = numOrSizeSplits; + } + return splitSizes; + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Generates sparse fill empty rows indices, dense shape mismatch error message. + * + * @param indicesLength The first dimension of indices. + */ + function getSparseFillEmptyRowsIndicesDenseShapeMismatch(indicesLength) { + return `Received SparseTensor with denseShape[0] = 0 but + indices.shape[0] = ${indicesLength}`; + } + /** + * Generates sparse fill empty rows negative index error message. + * + * @param index The index with a negative value. + * @param value The negative value. + */ + function getSparseFillEmptyRowsNegativeIndexErrorMessage(index, value) { + return `indices(${index}, 0) is invalid: ${value} < 0`; + } + /** + * Generates sparse fill empty rows out of range index error message. + * + * @param index The index with an out of range value. + * @param value The out of range value. + * @param limit The upper limit for indices. + */ + function getSparseFillEmptyRowsOutOfRangeIndexErrorMessage(index, value, limit) { + return `indices(${index}, 0) is invalid: ${value} >= ${limit}`; + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Generates sparse reshape multiple negative 1 output dimension error message. + * + * @param dim1 The first dimension with a negative 1 value. + * @param dim2 The second dimension with a negative 1 value. + */ + function getSparseReshapeMultipleNegativeOneOutputDimErrorMessage(dim1, dim2) { + return `only one output dimension may be -1, not both ${dim1} and ${dim2}`; + } + /** + * Generates sparse reshape negative output dimension error message. + * + * @param dim The dimension with a negative value. + * @param value The negative value. + */ + function getSparseReshapeNegativeOutputDimErrorMessage(dim, value) { + return `size ${dim} must be non-negative, not ${value}`; + } + /** + * Generates sparse reshape empty tensor zero output dimension error message. + * + */ + function getSparseReshapeEmptyTensorZeroOutputDimErrorMessage() { + return 'reshape cannot infer the missing input size for an empty tensor ' + + 'unless all specified input sizes are non-zero'; + } + /** + * Generates sparse reshape input output multiple mismatch error message. + * + * @param inputShape the input shape. + * @param outputShape the requested output shape. + */ + function getSparseReshapeInputOutputMultipleErrorMessage(inputShape, outputShape) { + const inputSize = sizeFromShape(inputShape); + const outputSize = sizeFromShape(outputShape); + return `Input to reshape is a SparseTensor with ${inputSize} + dense values, but the requested shape requires a multiple of ${outputSize}. inputShape=${inputShape} outputShape= ${outputShape}`; + } + /** + * Generates sparse reshape input output inequality error message. + * + * @param inputShape the input shape. + * @param outputShape the requested output shape. + */ + function getSparseReshapeInputOutputMismatchErrorMessage(inputShape, outputShape) { + const inputSize = sizeFromShape(inputShape); + const outputSize = sizeFromShape(outputShape); + return `Input to reshape is a tensor with ${inputSize} dense values, but the requested shape has ${outputSize}. inputShape=${inputShape} outputShape=${outputShape}`; + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Generates sparse segment reduction negative segment ids error message. + * + */ + function getSparseSegmentReductionNegativeSegmentIdsErrorMessage() { + return `segment ids must be >= 0`; + } + /** + * Generates sparse segment reduction non increasing segment ids error message. + * + */ + function getSparseSegmentReductionNonIncreasingSegmentIdsErrorMessage() { + return `segment ids are not increasing`; + } + /** + * Generates sparse segment reduction segment id out of range error message. + * + * @param segmentId The segment id index that is out of range. + * @param outputRows Upper bound of valid segment id values. + */ + function getSparseSegmentReductionSegmentIdOutOfRangeErrorMessage(segmentId, outputRows) { + return `Segment id ${segmentId} out of range [0, ${outputRows}), possibly because segmentIds input is not sorted.`; + } + /** + * Generates sparse segment reduction input indice out of range error message. + * + * @param index The index that holds the out of range value. + * @param indexValue The value that is out of range. + * @param inputRows Upper bound of valid index values. + */ + function getSparseSegmentReductionIndicesOutOfRangeErrorMessage(index, indexValue, inputRows) { + return `Bad: indices[${index}] == ${indexValue} out of range [0, ${inputRows})`; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function segOpComputeOptimalWindowSize(inSize, numSegments) { + let done = false; + let res; + if (inSize <= PARALLELIZE_THRESHOLD) { + res = inSize; + done = true; + } + else { + res = nearestDivisor(inSize, Math.floor(Math.sqrt(inSize))); + } + while (!done) { + if (res > numSegments || res === inSize) { + done = true; + } + else { + res = nearestDivisor(inSize, res + 1); + } + } + return res; + } + function computeOutShape(aShape, axis, numSegments) { + const outShape = []; + const rank = aShape.length; + for (let dim = 0; dim < rank; dim++) { + if (dim !== axis) { + outShape.push(aShape[dim]); + } + else { + outShape.push(numSegments); + } + } + return outShape; + } + function collectGatherOpShapeInfo(x, indices, axis, batchDims) { + const indicesRank = indices.shape.length; + const xRank = x.shape.length; + if (batchDims !== 0) { + if (batchDims < -indicesRank || batchDims > indicesRank) { + throw new Error(`Expect batchDims in the range of [-${indicesRank}, ${indicesRank}], but got ${batchDims}`); + } + } + if (batchDims < 0) { + batchDims += indicesRank; + } + if (batchDims > xRank) { + throw new Error(`batchDims (${batchDims}) must be less than rank(x) ( + ${xRank}).`); + } + if (axis < batchDims) { + throw new Error(`batchDims (${batchDims}) must be less than or equal to axis (${axis}).`); + } + for (let i = 0; i < batchDims; ++i) { + if (x.shape[i] !== indices.shape[i]) { + throw new Error(`x.shape[${i}]: ${x.shape[i]} should be equal to indices.shape[${i}]: ${indices.shape[i]}.`); + } + } + const dimSize = x.shape[axis]; + const outputShape = []; + let batchSize = 1; + let outerSize = 1; + let sliceSize = 1; + for (let i = 0; i < batchDims; ++i) { + outputShape.push(x.shape[i]); + batchSize *= x.shape[i]; + } + for (let i = batchDims; i < axis; i++) { + outputShape.push(x.shape[i]); + outerSize *= x.shape[i]; + } + for (let i = batchDims; i < indicesRank; i++) { + outputShape.push(indices.shape[i]); + } + for (let i = axis + 1; i < xRank; i++) { + outputShape.push(x.shape[i]); + sliceSize *= x.shape[i]; + } + return { batchSize, sliceSize, outerSize, dimSize, outputShape }; + } + + var segment_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + collectGatherOpShapeInfo: collectGatherOpShapeInfo, + computeOutShape: computeOutShape, + segOpComputeOptimalWindowSize: segOpComputeOptimalWindowSize + }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fromUint8ToStringArray(vals) { + try { + // Decode the bytes into string. + return vals.map(val => decodeString(val)); + } + catch (err) { + throw new Error(`Failed to decode encoded string bytes into utf-8, error: ${err}`); + } + } + function fromStringArrayToUint8(strings) { + return strings.map(s => encodeString(s)); + } + + var backend_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + ERF_A1: ERF_A1, + ERF_A2: ERF_A2, + ERF_A3: ERF_A3, + ERF_A4: ERF_A4, + ERF_A5: ERF_A5, + ERF_P: ERF_P, + PARALLELIZE_THRESHOLD: PARALLELIZE_THRESHOLD, + get RowPartitionType () { return RowPartitionType$1; }, + SELU_SCALE: SELU_SCALE, + SELU_SCALEALPHA: SELU_SCALEALPHA, + applyActivation: applyActivation$1, + assertAndGetBroadcastShape: assertAndGetBroadcastShape, + assertAxesAreInnerMostDims: assertAxesAreInnerMostDims, + assertParamsConsistent: assertParamsConsistent, + assignToTypedArray: assignToTypedArray, + axesAreInnerMostDims: axesAreInnerMostDims, + calculateShapes: calculateShapes, + checkEinsumDimSizes: checkEinsumDimSizes, + checkPadOnDimRoundingMode: checkPadOnDimRoundingMode, + combineLocations: combineLocations, + combineRaggedTensorToTensorShapes: combineRaggedTensorToTensorShapes, + complexWithEvenIndex: complexWithEvenIndex, + complexWithOddIndex: complexWithOddIndex, + computeConv2DInfo: computeConv2DInfo, + computeConv3DInfo: computeConv3DInfo, + computeDefaultPad: computeDefaultPad, + computeDilation2DInfo: computeDilation2DInfo, + computeOptimalWindowSize: computeOptimalWindowSize, + computeOutAndReduceShapes: computeOutAndReduceShapes, + computeOutShape: computeOutShape$1, + computePool2DInfo: computePool2DInfo, + computePool3DInfo: computePool3DInfo, + convertConv2DDataFormat: convertConv2DDataFormat, + decodeEinsumEquation: decodeEinsumEquation, + eitherStridesOrDilationsAreOne: eitherStridesOrDilationsAreOne, + expandShapeToKeepDim: expandShapeToKeepDim, + exponent: exponent, + exponents: exponents, + fromStringArrayToUint8: fromStringArrayToUint8, + fromUint8ToStringArray: fromUint8ToStringArray, + getAxesPermutation: getAxesPermutation, + getBroadcastDims: getBroadcastDims$1, + getComplexWithIndex: getComplexWithIndex, + getEinsumComputePath: getEinsumComputePath, + getEinsumPermutation: getEinsumPermutation, + getFusedBiasGradient: getFusedBiasGradient, + getFusedDyActivation: getFusedDyActivation, + getImageCenter: getImageCenter, + getInnerMostAxes: getInnerMostAxes, + getPermuted: getPermuted, + getRaggedRank: getRaggedRank, + getReductionAxes: getReductionAxes, + getReshaped: getReshaped, + getReshapedPermuted: getReshapedPermuted, + getRowPartitionTypesHelper: getRowPartitionTypesHelper, + getSliceBeginCoords: getSliceBeginCoords, + getSliceSize: getSliceSize, + getSparseFillEmptyRowsIndicesDenseShapeMismatch: getSparseFillEmptyRowsIndicesDenseShapeMismatch, + getSparseFillEmptyRowsNegativeIndexErrorMessage: getSparseFillEmptyRowsNegativeIndexErrorMessage, + getSparseFillEmptyRowsOutOfRangeIndexErrorMessage: getSparseFillEmptyRowsOutOfRangeIndexErrorMessage, + getSparseReshapeEmptyTensorZeroOutputDimErrorMessage: getSparseReshapeEmptyTensorZeroOutputDimErrorMessage, + getSparseReshapeInputOutputMismatchErrorMessage: getSparseReshapeInputOutputMismatchErrorMessage, + getSparseReshapeInputOutputMultipleErrorMessage: getSparseReshapeInputOutputMultipleErrorMessage, + getSparseReshapeMultipleNegativeOneOutputDimErrorMessage: getSparseReshapeMultipleNegativeOneOutputDimErrorMessage, + getSparseReshapeNegativeOutputDimErrorMessage: getSparseReshapeNegativeOutputDimErrorMessage, + getSparseSegmentReductionIndicesOutOfRangeErrorMessage: getSparseSegmentReductionIndicesOutOfRangeErrorMessage, + getSparseSegmentReductionNegativeSegmentIdsErrorMessage: getSparseSegmentReductionNegativeSegmentIdsErrorMessage, + getSparseSegmentReductionNonIncreasingSegmentIdsErrorMessage: getSparseSegmentReductionNonIncreasingSegmentIdsErrorMessage, + getSparseSegmentReductionSegmentIdOutOfRangeErrorMessage: getSparseSegmentReductionSegmentIdOutOfRangeErrorMessage, + getUndoAxesPermutation: getUndoAxesPermutation, + isIdentityPermutation: isIdentityPermutation, + log: log$3, + mergeRealAndImagArrays: mergeRealAndImagArrays, + prepareAndValidate: prepareAndValidate, + prepareSplitSize: prepareSplitSize, + segment_util: segment_util, + shouldFuse: shouldFuse, + slice_util: slice_util, + splitRealAndImagArrays: splitRealAndImagArrays, + stridesOrDilationsArePositive: stridesOrDilationsArePositive, + tupleValuesAreOne: tupleValuesAreOne, + upcastType: upcastType, + validateDefaultValueShape: validateDefaultValueShape, + validateInput: validateInput$1, + validateUpdateShape: validateUpdateShape, + warn: warn + }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + var kernel_impls = /*#__PURE__*/Object.freeze({ + __proto__: null, + nonMaxSuppressionV3Impl: nonMaxSuppressionV3Impl$2, + nonMaxSuppressionV4Impl: nonMaxSuppressionV4Impl$2, + nonMaxSuppressionV5Impl: nonMaxSuppressionV5Impl$2, + whereImpl: whereImpl$2 + }); + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + registerOptimizers(); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const absGradConfig = { + kernelName: Abs, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => mul(dy, step$2(cast$3(x, 'float32'), -1)) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const acosGradConfig = { + kernelName: Acos, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { + x: () => { + const a = square$2(cast$3(x, 'float32')); + const b = sqrt$2(sub$2(scalar(1), a)); + return neg$2(div$1(dy, b)); + } + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const acoshGradConfig = { + kernelName: Acosh, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { + x: () => { + const a = sqrt$2(sub$2(square$2(cast$3(x, 'float32')), 1)); + return div$1(dy, a); + } + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const addGradConfig = { + kernelName: Add$1, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const outShape = assertAndGetBroadcastShape(a.shape, b.shape); + const derA = () => { + let res = dy; + const reduceAxes = getReductionAxes(a.shape, outShape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(res, a.shape); + }; + const derB = () => { + let res = dy; + const reduceAxes = getReductionAxes(b.shape, outShape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(res, b.shape); + }; + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const addNGradConfig = { + kernelName: AddN, + saveAllInputs: true, + gradFunc: (dy, saved) => { + const ders = {}; + saved.forEach((_, i) => { + ders[i] = () => dy.clone(); + }); + return ders; + } + }; + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const argMaxGradConfig = { + kernelName: ArgMax, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => zerosLike$3(x) }; + } + }; + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const argMinGradConfig = { + kernelName: ArgMin, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => zerosLike$3(x) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const asinGradConfig = { + kernelName: Asin, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => div$1(dy, sqrt$2(sub$2(scalar(1), square$2(cast$3(x, 'float32'))))) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const asinhGradConfig = { + kernelName: Asinh, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { + x: () => { + const a = sqrt$2(add$3(scalar(1), square$2(cast$3(x, 'float32')))); + return div$1(dy, a); + } + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const atan2GradConfig = { + kernelName: Atan2, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const outShape = assertAndGetBroadcastShape(a.shape, b.shape); + const derA = () => { + const d = add$3(square$2(a), square$2(b)); + let res = mul(dy, div$1(b, d)); + const reduceAxes = getReductionAxes(a.shape, outShape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(res, a.shape); + }; + const derB = () => { + const d = add$3(square$2(a), square$2(b)); + let res = neg$2(mul(dy, div$1(a, d))); + const reduceAxes = getReductionAxes(b.shape, outShape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(res, b.shape); + }; + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const atanGradConfig = { + kernelName: Atan, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => div$1(dy, add$3(square$2(cast$3(x, 'float32')), 1)) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const atanhGradConfig = { + kernelName: Atanh, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => div$1(dy, sub$2(scalar(1), square$2(cast$3(x, 'float32')))) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the backprop of a 3d avg pool. + * + * @param dy The dy error, of rank 5 of shape + * [batchSize, depth, height, width, channels]. + * assumed. + * @param input The original input image, of rank 5 or rank4 of shape + * [batchSize, depth, height, width, channels]. + * @param filterSize The filter size: + * `[filterDepth, filterHeight, filterWidth]`. + * `filterSize` is a single number, + * then `filterDepth == filterHeight == filterWidth`. + * @param strides The strides of the pooling: + * `[strideDepth, strideHeight, strideWidth]`. If + * `strides` is a single number, then `strideHeight == strideWidth`. + * @param pad A string from: 'same', 'valid'. The type of padding algorithm + * used in the forward prop of the op. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + */ + function avgPool3dGrad_(dy, input, filterSize, strides, pad, dimRoundingMode) { + const $dy = convertToTensor(dy, 'dy', 'avgPool3dGrad'); + const $input = convertToTensor(input, 'input', 'avgPool3dGrad'); + let dy5D = $dy; + let input5D = $input; + let reshapedTo5D = false; + if ($input.rank === 4) { + reshapedTo5D = true; + dy5D = reshape$3($dy, [1, $dy.shape[0], $dy.shape[1], $dy.shape[2], $dy.shape[3]]); + input5D = reshape$3($input, [ + 1, $input.shape[0], $input.shape[1], $input.shape[2], $input.shape[3] + ]); + } + assert$1(dy5D.rank === 5, () => `Error in avgPool3dGrad: dy must be rank 5 but got rank ` + + `${dy5D.rank}.`); + assert$1(input5D.rank === 5, () => `Error in avgPool3dGrad: input must be rank 5 but got rank ` + + `${input5D.rank}.`); + checkPadOnDimRoundingMode('avgPool3dGrad', pad, dimRoundingMode); + const inputs = { dy: dy5D, input: input5D }; + const attrs = { filterSize, strides, pad, dimRoundingMode }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(AvgPool3DGrad, inputs, attrs); + if (reshapedTo5D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3], res.shape[4]]); + } + return res; + } + const avgPool3dGrad = /* @__PURE__ */ op({ avgPool3dGrad_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const avgPool3DGradConfig$2 = { + kernelName: AvgPool3D, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const { filterSize, strides, pad, dimRoundingMode } = attrs; + return { + x: () => avgPool3dGrad(dy, x, filterSize, strides, pad, dimRoundingMode) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the backprop of an 2D avg pool. + * + * @param dy The dy error, of rank 4 or rank 3 of shape + * [batchSize, height, width, channels]. If rank 3, batch of 1 is + * assumed. + * @param input The input image, of rank 4 or rank 3 of shape + * [batchSize, height, width, channels]. If rank 3, batch of 1 is + * assumed. + * @param filterSize The filter size: `[filterHeight, filterWidth]`. If + * `filterSize` is a single number, then `filterHeight == filterWidth`. + * @param strides The strides of the pooling: `[strideHeight, strideWidth]`. If + * `strides` is a single number, then `strideHeight == strideWidth`. + * @param pad The type of padding algorithm used in the forward prop of the op. + * 'same', 'valid', for more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + */ + function avgPoolGrad_(dy, input, filterSize, strides, pad) { + const $dy = convertToTensor(dy, 'dy', 'avgPoolGrad'); + const $input = convertToTensor(input, 'input', 'avgPoolGrad'); + assert$1($input.rank === $dy.rank, () => `Rank of input (${$input.rank}) does not match rank of dy (${$dy.rank})`); + let input4D = $input; + let dy4D = $dy; + let reshapedTo4D = false; + if ($input.rank === 3) { + reshapedTo4D = true; + input4D = + reshape$3($input, [1, $input.shape[0], $input.shape[1], $input.shape[2]]); + dy4D = reshape$3($dy, [1, $dy.shape[0], $dy.shape[1], $dy.shape[2]]); + } + assert$1(dy4D.rank === 4, () => `Error in avgPoolGrad: dy must be rank 4 but got rank ` + + `${dy4D.rank}.`); + assert$1(input4D.rank === 4, () => `Error in avgPoolGrad: input must be rank 4 but got rank ` + + `${input4D.rank}.`); + const inputs = { dy: dy4D, input: input4D }; + const attrs = { filterSize, strides, pad }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(AvgPoolGrad, inputs, attrs); + if (reshapedTo4D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3]]); + } + return res; + } + const avgPoolGrad$2 = /* @__PURE__ */ op({ avgPoolGrad_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const avgPoolGradConfig$2 = { + kernelName: AvgPool, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const { filterSize, strides, pad } = attrs; + return { x: () => avgPoolGrad$2(dy, x, filterSize, strides, pad) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const batchMatMulGradConfig = { + kernelName: BatchMatMul, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved, attrs) => { + const [a, b] = saved; + const { transposeA, transposeB } = attrs; + if (!transposeA && !transposeB) { + return { + a: () => matMul$1(dy, b, false, true), + b: () => matMul$1(a, dy, true, false) + }; + } + else if (!transposeA && transposeB) { + return { + a: () => matMul$1(dy, b, false, false), + b: () => matMul$1(dy, a, true, false) + }; + } + else if (transposeA && !transposeB) { + return { + a: () => matMul$1(b, dy, false, true), + b: () => matMul$1(a, dy, false, false) + }; + } + else { + return { + a: () => matMul$1(b, dy, true, true), + b: () => matMul$1(dy, a, true, true) + }; + } + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const batchToSpaceNDGradConfig = { + kernelName: BatchToSpaceND, + gradFunc: (dy, saved, attrs) => { + const { blockShape, crops } = attrs; + return { x: () => spaceToBatchND$2(dy, blockShape, crops) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const broadcastToGradConfig = { + kernelName: BroadcastTo, + gradFunc: (dy, saved, attrs) => { + const broadCastToAttrs = attrs; + const inputShape = broadCastToAttrs.inputShape; + const outputShape = broadCastToAttrs.shape; + const reps = Array.from(outputShape); + for (let i = inputShape.length - 1; i >= 0; i--) { + if (inputShape[i] === outputShape[i]) { + reps[i] = 1; + } + else if (inputShape[i] !== 1) { + throw new Error(`broadcastTo(): [${inputShape}] cannot be broadcast to [${outputShape}].`); + } + } + const axes = []; + for (let i = 0; i < reps.length; i++) { + if (reps[i] > 1) { + axes.push(i); + } + } + return { x: () => sum$3(dy, axes, true /* keepDims */) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const castGradConfig = { + kernelName: Cast, + gradFunc: (dy) => { + return { x: () => dy.clone() }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ceilGradConfig = { + kernelName: Ceil, + gradFunc: (dy) => { + // TODO(manrajgrover): Return null for gradients when backprop supports it. + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const clipByValueGradConfig = { + kernelName: ClipByValue, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const { clipValueMin, clipValueMax } = attrs; + return { + x: () => where(logicalAnd$2(greaterEqual$2(x, clipValueMin), lessEqual$2(x, clipValueMax)), dy, zerosLike$3(dy)), + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const complexAbsGradConfig = { + kernelName: ComplexAbs, + inputsToSave: ['x'], + gradFunc: absGradConfig.gradFunc, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const concatGradConfig = { + kernelName: Concat, + saveAllInputs: true, + gradFunc: (dy, saved, attrs) => { + const shapes = saved.map(t => t.shape); + const { axis } = attrs; + const $axis = parseAxisParam(axis, saved[0].shape)[0]; + const sizeSplits = shapes.map(s => s[$axis]); + const derTensors = split$3(dy, sizeSplits, $axis); + return derTensors.map(t => () => t); + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const conv2DGradConfig = { + kernelName: Conv2D$1, + inputsToSave: ['x', 'filter'], + gradFunc: (dy, saved, attrs) => { + const [x4D, $filter] = saved; + const { dilations, strides, pad, dataFormat } = attrs; + assert$1(tupleValuesAreOne(dilations), () => 'Error in gradient of conv2D: dilation rates greater than 1 ' + + `are not yet supported in gradients. Got dilations '${dilations}'`); + return { + x: () => conv2DBackpropInput$2(x4D.shape, dy, $filter, strides, pad, dataFormat), + filter: () => conv2DBackpropFilter$2(x4D, dy, $filter.shape, strides, pad, dataFormat) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const conv2DBackpropInputGradConfig = { + kernelName: Conv2DBackpropInput, + inputsToSave: ['dy', 'filter'], + gradFunc: (ddx, saved, attrs) => { + const [dy, filter] = saved; + const { strides, pad, dataFormat, dimRoundingMode } = attrs; + return { + dy: () => conv2d$4(ddx, filter, strides, pad, dataFormat, 1 /* dilations */, dimRoundingMode), + filter: () => conv2DBackpropFilter$2(ddx, dy, filter.shape, strides, pad, dataFormat, dimRoundingMode) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the derivative of the filter of a 3D convolution. + * + * @param x The input tensor, of rank 5 or rank 4 of shape + * [batch, depth, height, width, inChannels]. If rank 4, batch of 1 is + * assumed. + * @param dy The dy image, of rank 5 or rank 4, of shape + * [batch, depth, height, width, outDepth]. If rank 4, batch of 1 is + * assumed. + * @param filterShape The shape of the filter, length 5, + * [filterDepth, filterHeight, filterWidth, inDepth, outDepth]. + * @param strides The strides of the convolution: [strideDepth, strideHeight, + * strideWidth]. + * @param pad A string from: 'same', 'valid'. The type of padding algorithm + * used in the forward prop of the op. + */ + function conv3DBackpropFilter_(x, dy, filterShape, strides, pad) { + let x5D = x; + if (x.rank === 4) { + x5D = reshape$3(x, [1, x.shape[0], x.shape[1], x.shape[2], x.shape[3]]); + } + let dy5D = dy; + if (dy5D.rank === 4) { + dy5D = reshape$3(dy, [1, dy.shape[0], dy.shape[1], dy.shape[2], dy.shape[3]]); + } + assert$1(x5D.rank === 5, () => `Error in conv3dDerFilter: input must be rank 5, but got shape ` + + `${x5D.shape}.`); + assert$1(dy5D.rank === 5, () => `Error in conv3dDerFilter: dy must be rank 5, but got shape ` + + `${dy5D.shape}.`); + assert$1(filterShape.length === 5, () => `Error in conv3dDerFilter: filterShape must be length 5, but got ` + + `${filterShape}.`); + assert$1(x5D.shape[4] === filterShape[3], () => `Error in conv3dDerFilter: depth of input ${x5D.shape[4]}) must ` + + `match input depth in filter (${filterShape[3]}.`); + assert$1(dy5D.shape[4] === filterShape[4], () => `Error in conv3dDerFilter: depth of dy (${dy5D.shape[4]}) must ` + + `match output depth for filter (${filterShape[4]}).`); + const inputs = { x: x5D, dy: dy5D }; + const attrs = { strides, pad, filterShape }; + // tslint:disable-next-line: no-unnecessary-type-assertion + return ENGINE.runKernel(Conv3DBackpropFilterV2, inputs, attrs); + } + const conv3DBackpropFilter = /* @__PURE__ */ op({ conv3DBackpropFilter_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const conv3DGradConfig = { + kernelName: Conv3D$1, + inputsToSave: ['x', 'filter'], + gradFunc: (dy, saved, attrs) => { + const { dilations, strides, pad } = attrs; + assert$1(tupleValuesAreOne(dilations), () => 'Error in gradient of conv3D: dilation rates greater than 1 are ' + + `not yet supported in gradients. Got dilations '${dilations}'`); + const [x5D, $filter] = saved; + return { + x: () => conv3DBackpropInput$1(x5D.shape, dy, $filter, strides, pad), + filter: () => conv3DBackpropFilter(x5D, dy, $filter.shape, strides, pad) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const cosGradConfig = { + kernelName: Cos, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => mul(neg$2(sin$2(cast$3(x, 'float32'))), dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const coshGradConfig = { + kernelName: Cosh, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => mul(sinh$2(cast$3(x, 'float32')), dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const cumsumGradConfig = { + kernelName: Cumsum, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const { axis, exclusive, reverse } = attrs; + return { + x: () => { + const permutation = getAxesPermutation([axis], x.rank); + let out = cumsum$2(dy, axis, exclusive, !reverse); + if (permutation != null) { + out = transpose$2(out, permutation); + } + return out; + } + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const depthwiseConv2dNativeGradConfig = { + kernelName: DepthwiseConv2dNative, + inputsToSave: ['x', 'filter'], + gradFunc: (dy, saved, attrs) => { + const { dilations, strides, pad, dimRoundingMode } = attrs; + const $dilations = dilations == null ? [1, 1] : dilations; + assert$1(tupleValuesAreOne($dilations), () => 'Error in gradient of depthwiseConv2dNative: dilation rates ' + + `greater than 1 are not yet supported. Got dilations ` + + `'${$dilations}'`); + const [x, filter] = saved; + assert$1(x.rank === 4, () => `Error in gradient of depthwiseConv2dNative: input must be ` + + `rank 4, but got rank ${x.rank}.`); + assert$1(filter.rank === 4, () => `Error in gradient of depthwiseConv2dNative: filter must be ` + + `rank 4, but got rank ${filter.rank}.`); + assert$1(x.shape[3] === filter.shape[2], () => `Error in gradient of depthwiseConv2d: number of input ` + + `channels (${x.shape[3]}) must match the inChannels dimension ` + + `in filter ${filter.shape[2]}.`); + assert$1(eitherStridesOrDilationsAreOne(strides, $dilations), () => 'Error in gradient of depthwiseConv2d: Either strides or ' + + `dilations must be 1. Got strides ${strides} and dilations ` + + `'${$dilations}'.`); + checkPadOnDimRoundingMode('depthwiseConv2d', pad, dimRoundingMode); + return { + x: () => depthwiseConv2dNativeBackpropInput$2(x.shape, dy, filter, strides, pad, $dilations, dimRoundingMode), + filter: () => depthwiseConv2dNativeBackpropFilter$2(x, dy, filter.shape, strides, pad, $dilations, dimRoundingMode), + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const dilation2dGradConfig = { + kernelName: Dilation2D, + inputsToSave: ['x', 'filter'], + gradFunc: (dy, saved, attrs) => { + const [x, filter] = saved; + const inputInputs = { x, filter, dy }; + const filterInputs = { x, filter, dy }; + return { + x: () => ENGINE.runKernel(Dilation2DBackpropInput, inputInputs, attrs), + filter: () => ENGINE.runKernel(Dilation2DBackpropFilter, filterInputs, attrs) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const eluGradConfig$2 = { + kernelName: Elu$1, + outputsToSave: [true], + gradFunc: (dy, saved) => { + const [y] = saved; + const inputs = { dy, y }; + return { x: () => ENGINE.runKernel(EluGrad, inputs) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const erfGradConfig = { + kernelName: Erf, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + const a = mul(exp$2(neg$2(square$2(x))), 2 / Math.sqrt(Math.PI)); + return { x: () => mul(dy, a) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const expGradConfig = { + kernelName: Exp, + outputsToSave: [true], + gradFunc: (dy, saved) => { + const [y] = saved; + return { x: () => mul(dy, y) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const expandDimsGradConfig = { + kernelName: ExpandDims, + inputsToSave: ['input'], + gradFunc: (dy, saved) => { + const [input] = saved; + return { input: () => reshape$3(dy, input.shape) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const expm1GradConfig = { + kernelName: Expm1, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => mul(dy, exp$2(x)) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const floorGradConfig = { + kernelName: Floor, + gradFunc: (dy) => { + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const floorDivGradConfig = { + kernelName: FloorDiv, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const outShape = assertAndGetBroadcastShape(a.shape, b.shape); + const derA = () => { + const res = div$1(dy, cast$3(b, 'float32')); + const reduceAxes = getReductionAxes(a.shape, outShape); + if (reduceAxes.length > 0) { + return reshape$3(sum$3(res, reduceAxes), a.shape); + } + return res; + }; + const derB = () => { + let res = mul(dy, cast$3(a, 'float32')); + const reduceAxes = getReductionAxes(b.shape, outShape); + if (reduceAxes.length > 0) { + res = reshape$3(sum$3(res, reduceAxes), b.shape); + } + const tmp = square$2(b); + return neg$2(div$1(res, cast$3(tmp, 'float32'))); + }; + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const fusedBatchNormGradConfig = { + kernelName: FusedBatchNorm, + inputsToSave: ['x', 'mean', 'variance', 'scale'], + gradFunc: (dy, saved, attrs) => { + const { varianceEpsilon } = attrs; + const [x, mean, variance, scale] = saved; + const scaleValue = scale == null ? scalar(1) : scale; + const reductionAxes = getReductionAxes(mean.shape, x.shape); + const tileShape = []; + if (mean.rank === 1) { + for (let i = 0; i < x.shape.length - 1; ++i) { + tileShape.push(x.shape[i]); + } + tileShape.push(1); + } + const xMinusMean = sub$2(x, mean); + const dyTimesScaleValue = mul(dy, scaleValue); + const oneOverSqrtVariance = rsqrt$2(add$3(variance, scalar(varianceEpsilon))); + const minusHalfRCube = mul(mul(mul(oneOverSqrtVariance, oneOverSqrtVariance), oneOverSqrtVariance), scalar(-0.5)); + const derX = () => { + if (mean.rank === 1) { + return reshape$3(mul(mul(dy, tile$3(reshape$3(oneOverSqrtVariance, [1, 1, 1, mean.shape[0]]), tileShape)), scaleValue), x.shape); + } + else { + return reshape$3(mul(mul(dy, oneOverSqrtVariance), scaleValue), x.shape); + } + }; + const derMean = () => { + let meanDer = mul(mul(oneOverSqrtVariance, scalar(-1)), dyTimesScaleValue); + if (mean.rank === 1) { + meanDer = sum$3(meanDer, reductionAxes); + } + return reshape$3(meanDer, mean.shape); + }; + const derVariance = () => { + let varianceDer = mul(mul(minusHalfRCube, xMinusMean), dyTimesScaleValue); + if (mean.rank === 1) { + varianceDer = sum$3(varianceDer, reductionAxes); + } + return reshape$3(varianceDer, mean.shape); + }; + const derScale = () => { + const xMinusMean2TimesRsqrt = mul(xMinusMean, oneOverSqrtVariance); + let scaleDer = mul(dy, xMinusMean2TimesRsqrt); + if (mean.rank === 1) { + scaleDer = sum$3(scaleDer, reductionAxes); + } + return reshape$3(scaleDer, mean.shape); + }; + const derOffset = () => { + let offsetDer = dy; + if (mean.rank === 1) { + offsetDer = sum$3(offsetDer, reductionAxes); + } + return reshape$3(offsetDer, mean.shape); + }; + return { + x: derX, + mean: derMean, + variance: derVariance, + scale: derScale, + offset: derOffset + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const gatherGradConfig = { + kernelName: GatherV2, + inputsToSave: ['x', 'indices'], + gradFunc: (dy, saved, attrs) => { + const [x, indices] = saved; + const { axis, batchDims } = attrs; + const parsedAxis = parseAxisParam(axis, x.shape)[0]; + const derXBatch = (x, indices, dy) => { + return () => { + const paramsShape = x.shape; + const indicesSize = indices.size; + const outerShape = paramsShape.slice(0, parsedAxis); + const outerDims = outerShape.length; + const innerShape = paramsShape.slice(axis, paramsShape.length).slice(1); + const innerDims = innerShape.length; + const outerAxesIndices = arrayRange(0, outerDims); + const innerAxesIndices = arrayRange(outerDims + 1, outerDims + 1 + innerDims); + const valuesShape = arrayConcat([outerShape, [indicesSize], + innerShape]); + const values = reshape$3(dy, valuesShape); + const reshapedIndices = reshape$3(indices, [indicesSize]); + const transposeDims = arrayConcat([[outerDims], outerAxesIndices, innerAxesIndices]); + const valuesTranspose = transpose$2(values, transposeDims); + let paramsGrad = unsortedSegmentSum$2(valuesTranspose, reshapedIndices, x.shape[parsedAxis]); + const invertTransposeDims = getUndoAxesPermutation(transposeDims); + paramsGrad = transpose$2(paramsGrad, invertTransposeDims); + return paramsGrad; + }; + }; + if (batchDims === 1) { + const batchSize = x.shape[0]; + const xBatch = x.split(batchSize, 0); + const derXBatched = () => { + const stacked = stack(xBatch.map((x, i) => { + return derXBatch(x, indices.slice(i, 1), dy.slice(i, 1))(); + })); + return stacked.reshape(x.shape); + }; + return { x: derXBatched, indices: () => indices }; + } + else { + return { x: derXBatch(x, indices, dy), indices: () => indices }; + } + } + }; + function arrayRange(start, stop) { + const result = []; + for (let i = start; i < stop; ++i) { + result.push(i); + } + return result; + } + function arrayConcat(arrays) { + const result = []; + for (let i = 0; i < arrays.length; ++i) { + for (let j = 0; j < arrays[i].length; ++j) { + result.push(arrays[i][j]); + } + } + return result; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const greaterEqualGradConfig = { + kernelName: GreaterEqual, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + return { a: () => zerosLike$3(a), b: () => zerosLike$3(b) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const identityGradConfig = { + kernelName: Identity$1, + gradFunc: (dy) => { + return { x: () => cast$3(dy, 'float32') }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const isFiniteGradConfig = { + kernelName: IsFinite, + gradFunc: (dy) => { + // TODO(nsthorat): Let gradients be null for cases where we want to stop + // backpropgation. + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const isInfGradConfig = { + kernelName: IsInf, + gradFunc: (dy) => { + // TODO(nsthorat): Let gradients be null for cases where we want to stop + // backpropgation. + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const isNanGradConfig = { + kernelName: IsNan, + gradFunc: (dy) => { + // TODO(nsthorat): Let gradients be null for cases where we want to stop + // backpropgation. + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const leakyReluGradConfig = { + kernelName: LeakyRelu, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const { alpha } = attrs; + const mask = greater$3(x, 0); + // Returns `gradients * (features > 0) + alpha * gradients * (features <= + // 0)`. + return { x: () => where(mask, dy, mul(dy, alpha)) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const log1pGradConfig = { + kernelName: Log1p, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => div$1(dy, add$3(x, 1)) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const logGradConfig = { + kernelName: Log, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => div$1(dy, cast$3(x, 'float32')) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const logSoftmaxGradConfig = { + kernelName: LogSoftmax$1, + inputsToSave: [], + outputsToSave: [true], + gradFunc: (dy, saved, attrs) => { + const [value] = saved; + const { axis } = attrs; + return { + logits: () => { + const keepDims = true; + const softmax = exp$2(value); + return sub$2(dy, mul(sum$3(dy, axis, keepDims), softmax)); + } + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function localResponseNormalizationBackprop_(x, y, dy, depthRadius = 5, bias = 1, alpha = 1, beta = 0.5) { + const inputs = { x, y, dy }; + const attrs = { depthRadius, bias, alpha, beta }; + return ENGINE.runKernel(LRNGrad, inputs, attrs); + } + const localResponseNormalizationBackprop = op({ localResponseNormalizationBackprop_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const lrnGradConfig = { + kernelName: LRN, + inputsToSave: ['x'], + outputsToSave: [true], + gradFunc: (dy, saved, attrs) => { + const [x, y] = saved; + const { depthRadius, bias, alpha, beta } = attrs; + return { + x: () => localResponseNormalizationBackprop(x, y, dy, depthRadius, bias, alpha, beta) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Gradient helper function for the min and max operations. + */ + function gradForMinAndMax(dy, y, xOrig, origAxes) { + if (y.rank < xOrig.rank) { + y = reshape$3(y, expandShapeToKeepDim(y.shape, origAxes)); + } + if (dy.rank < xOrig.rank) { + dy = reshape$3(dy, expandShapeToKeepDim(dy.shape, origAxes)); + } + return { + x: () => { + const dx = mul(dy, cast$3(equal$2(xOrig, y), dy.dtype)); + return dx; + } + }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const maxGradConfig = { + kernelName: Max, + inputsToSave: ['x'], + outputsToSave: [true], + gradFunc: (dy, saved, attrs) => { + const maxAttrs = attrs; + const { reductionIndices } = maxAttrs; + const x = saved[0]; + const y = saved[1]; + const origAxes = parseAxisParam(reductionIndices, x.shape); + const maxGrad = gradForMinAndMax(dy, y, x, origAxes); + return { + x: () => { + return maxGrad['x'](); + } + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const maximumGradConfig = { + kernelName: Maximum$1, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const derA = () => mul(dy, cast$3(greaterEqual$2(a, b), 'float32')); + const derB = () => mul(dy, cast$3(less$3(a, b), 'float32')); + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the backprop of a 3d max pool. + * + * @param dy The dy error, of rank 5 of shape + * [batchSize, depth, height, width, channels]. + * assumed. + * @param input The original input image, of rank 5 or rank 4 of shape + * [batchSize, depth, height, width, channels]. + * @param output The original output image, of rank 5 of shape + * [batchSize, outDepth, outHeight, outWidth, channels]. + * @param filterSize The filter size: + * `[filterDepth, filterHeight, filterWidth]`. + * `filterSize` is a single number, + * then `filterDepth == filterHeight == filterWidth`. + * @param strides The strides of the pooling: + * `[strideDepth, strideHeight, strideWidth]`. If + * `strides` is a single number, then `strideHeight == strideWidth`. + * @param pad A string from: 'same', 'valid'. The type of padding algorithm + * used in the forward prop of the op. + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + */ + function maxPool3dGrad_(dy, input, output, filterSize, strides, pad, dimRoundingMode) { + const $dy = convertToTensor(dy, 'dy', 'maxPool3dGrad'); + const $input = convertToTensor(input, 'input', 'maxPool3dGrad'); + const $output = convertToTensor(output, 'output', 'maxPool3dGrad'); + let dy5D = $dy; + let input5D = $input; + let output5D = $output; + let reshapedTo5D = false; + if ($input.rank === 4) { + reshapedTo5D = true; + dy5D = reshape$3($dy, [1, $dy.shape[0], $dy.shape[1], $dy.shape[2], $dy.shape[3]]); + input5D = reshape$3($input, [ + 1, $input.shape[0], $input.shape[1], $input.shape[2], $input.shape[3] + ]); + output5D = reshape$3($output, [ + 1, $output.shape[0], $output.shape[1], $output.shape[2], $output.shape[3] + ]); + } + assert$1(dy5D.rank === 5, () => `Error in maxPool3dGrad: dy must be rank 5 but got rank ` + + `${dy5D.rank}.`); + assert$1(input5D.rank === 5, () => `Error in maxPool3dGrad: input must be rank 5 but got rank ` + + `${input5D.rank}.`); + assert$1(output5D.rank === 5, () => `Error in maxPool3dGrad: output must be rank 5 but got rank ` + + `${output5D.rank}.`); + checkPadOnDimRoundingMode('maxPool3dGrad', pad, dimRoundingMode); + const inputs = { dy: dy5D, input: input5D, output: output5D }; + const attrs = { filterSize, strides, pad, dimRoundingMode }; + // tslint:disable-next-line: no-unnecessary-type-assertion + const res = ENGINE.runKernel(MaxPool3DGrad, inputs, attrs); + if (reshapedTo5D) { + return reshape$3(res, [res.shape[1], res.shape[2], res.shape[3], res.shape[4]]); + } + return res; + } + const maxPool3dGrad = /* @__PURE__ */ op({ maxPool3dGrad_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const maxPool3DGradConfig$2 = { + kernelName: MaxPool3D, + inputsToSave: ['x'], + outputsToSave: [true], + gradFunc: (dy, saved, attrs) => { + const [x, y] = saved; + const { filterSize, strides, pad, dimRoundingMode } = attrs; + return { + x: () => maxPool3dGrad(dy, x, y, filterSize, strides, pad, dimRoundingMode) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Computes the backprop of a 2D max pool. + * + * @param dy The dy error, of rank 4 or rank 3 of shape + * [batchSize, height, width, channels]. If rank 3, batch of 1 is + * assumed. + * @param input The original input image, of rank 4, of shape + * [batchSize, height, width, channels]. + * @param output The original output image, of rank 4, of shape + * [batchSize, outHeight, outWidth, channels]. + * @param filterSize The filter size: `[filterHeight, filterWidth]`. If + * `filterSize` is a single number, then `filterHeight == filterWidth`. + * @param strides The strides of the pooling: `[strideHeight, strideWidth]`. If + * `strides` is a single number, then `strideHeight == strideWidth`. + * @param pad The type of padding algorithm used in the forward prop of the op. + * 'same', 'valid', for more info, see this guide: + * [https://www.tensorflow.org/api_docs/python/tf/nn/convolution]( + * https://www.tensorflow.org/api_docs/python/tf/nn/convolution) + * @param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is + * provided, it will default to truncate. + */ + function maxPoolGrad_(dy, input, output, filterSize, strides, pad, dimRoundingMode) { + const $dy = convertToTensor(dy, 'dy', 'maxPoolGrad'); + const $input = convertToTensor(input, 'input', 'maxPoolGrad'); + const $output = convertToTensor(output, 'output', 'maxPoolGrad'); + assert$1($input.rank === $dy.rank, () => `Rank of input (${$input.rank}) does not match rank of dy ` + + `(${$dy.rank})`); + assert$1($dy.rank === 4, () => `Error in maxPoolGrad: dy must be rank 4 but got rank ` + + `${$dy.rank}.`); + assert$1($input.rank === 4, () => `Error in maxPoolGrad: input must be rank 4 but got rank ` + + `${$input.rank}.`); + checkPadOnDimRoundingMode('maxPoolGrad', pad, dimRoundingMode); + const inputs = { dy: $dy, input: $input, output: $output }; + const attrs = { filterSize, strides, pad, dimRoundingMode }; + // tslint:disable-next-line: no-unnecessary-type-assertion + return ENGINE.runKernel(MaxPoolGrad, inputs, attrs); + } + const maxPoolGrad$2 = /* @__PURE__ */ op({ maxPoolGrad_ }); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const maxPoolGradConfig$2 = { + kernelName: MaxPool, + inputsToSave: ['x'], + outputsToSave: [true], + gradFunc: (dy, saved, attrs) => { + const [x, y] = saved; + const { filterSize, strides, pad } = attrs; + return { + x: () => maxPoolGrad$2(dy, x, y, filterSize, strides, pad) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const meanGradConfig = { + kernelName: Mean, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const { axis } = attrs; + const axes = parseAxisParam(axis, x.shape); + const shapes = computeOutAndReduceShapes(x.shape, axes); + const reduceShape = shapes[1]; + const reduceSize = sizeFromShape(reduceShape); + const derX = () => { + const expandedDyShape = x.shape.slice(); + axes.forEach(axis => { + expandedDyShape[axis] = 1; + }); + const expandedDy = reshape$3(dy, expandedDyShape); + const res = div$1(mul(expandedDy, ones$1(x.shape, 'float32')), reduceSize); + return res; + }; + return { x: derX }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const minGradConfig = { + kernelName: Min, + inputsToSave: ['x'], + outputsToSave: [true], + gradFunc: (dy, saved, attrs) => { + const minAttrs = attrs; + const { axis } = minAttrs; + const [x, y] = saved; + const origAxes = parseAxisParam(axis, x.shape); + const minGrad = gradForMinAndMax(dy, y, x, origAxes); + return { + x: () => { + return minGrad['x'](); + } + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const minimumGradConfig = { + kernelName: Minimum$1, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const derA = () => mul(dy, cast$3(lessEqual$2(a, b), 'float32')); + const derB = () => mul(dy, cast$3(greater$3(a, b), 'float32')); + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const mirrorPadGradConfig = { + kernelName: MirrorPad, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + // Pad introduces values around the original tensor, so the gradient + // slices the original shape out of the gradient. + const x = saved[0]; + const { paddings } = attrs; + const begin = paddings.map(p => p[0]); + return { x: () => slice$2(dy, begin, x.shape) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const modGradConfig = { + kernelName: Mod, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const outShape = assertAndGetBroadcastShape(a.shape, b.shape); + const derA = () => { + const reduceAxes = getReductionAxes(a.shape, outShape); + if (reduceAxes.length > 0) { + return reshape$3(sum$3(dy, reduceAxes), a.shape); + } + return dy; + }; + const derB = () => { + const res = mul(dy, neg$2(floor$2(div$1(a, b)))); + const reduceAxes = getReductionAxes(b.shape, outShape); + if (reduceAxes.length > 0) { + return reshape$3(sum$3(res, reduceAxes), b.shape); + } + return res; + }; + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const multiplyGradConfig = { + kernelName: Multiply$1, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const outShape = assertAndGetBroadcastShape(a.shape, b.shape); + const derA = () => { + const res = mul(dy, cast$3(b, 'float32')); + const reduceAxes = getReductionAxes(a.shape, outShape); + if (reduceAxes.length > 0) { + return reshape$3(sum$3(res, reduceAxes), a.shape); + } + return res; + }; + const derB = () => { + const res = mul(dy, cast$3(a, 'float32')); + const reduceAxes = getReductionAxes(b.shape, outShape); + if (reduceAxes.length > 0) { + return reshape$3(sum$3(res, reduceAxes), b.shape); + } + return res; + }; + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const negGradConfig = { + kernelName: Neg, + gradFunc: (dy) => { + return { x: () => neg$2(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const oneHotGradConfig = { + kernelName: OneHot, + inputsToSave: ['indices'], + gradFunc: (dy, saved) => { + const indices = saved[0]; + return { indices: () => zeros$2(indices.shape, 'float32') }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const onesLikeGradConfig = { + kernelName: OnesLike, + gradFunc: (dy) => { + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const packGradConfig = { + kernelName: Pack, + saveAllInputs: true, + gradFunc: (dy, saved, attrs) => { + const { axis } = attrs; + const derTensors = unstack(dy, axis); + return derTensors.map(t => () => t); + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const padV2GradConfig = { + kernelName: PadV2, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + // Pad introduces values around the original tensor, so the gradient + // slices the original shape out of the gradient. + const x = saved[0]; + const { paddings } = attrs; + const begin = paddings.map(p => p[0]); + return { x: () => slice$2(dy, begin, x.shape) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const powGradConfig = { + kernelName: Pow, + inputsToSave: ['a', 'b'], + outputsToSave: [true], + gradFunc: (dy, saved) => { + const [a, b, y] = saved; + const base = a; + const exp = b; + const outShape = assertAndGetBroadcastShape(base.shape, exp.shape); + const derBase = () => { + const expFloat = cast$3(exp, 'float32'); + let res = mul(dy, mul(expFloat, pow$3(base, sub$2(expFloat, scalar(1))))); + const reduceAxes = getReductionAxes(base.shape, outShape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(res, base.shape); + }; + const derExp = () => { + const condition = greater$3(base, 0); + const logBase = where(condition, log$2(base), zerosLike$3(base)); + let res = mul(dy, mul(y, logBase)); + const reduceAxes = getReductionAxes(exp.shape, outShape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(res, exp.shape); + }; + return { a: derBase, b: derExp }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const preluGradConfig = { + kernelName: Prelu, + inputsToSave: ['x', 'alpha'], + gradFunc: (dy, saved) => { + const [x, alpha] = saved; + const mask = greater$3(x, 0); + return { + x: () => where(mask, dy, mul(dy, alpha)), + alpha: () => { + let res = where(mask, zerosLike$3(dy), mul(dy, x)); + const reduceAxes = getReductionAxes(alpha.shape, dy.shape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(res, alpha.shape); + } + }; + } + }; + + /** + * @license + * Copyright 2022 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Gradient for product operation on a single axis. + function prodGradFn_(x, dy, axis) { + // The gradient tensor (dy) has a set of axes removed, so we create re-shaped + // versions (of size 1) for the removed axis; this supports broadcasting over + // those dimensions. + const expandedYShape = x.shape.slice(); + expandedYShape[axis] = 1; + // The actual gradient computation. + const expandedDy = reshape$3(dy, expandedYShape); + const xCumProd = cumprod$2(x, axis, true, false); + const xCumRevProd = cumprod$2(x, axis, true, true); + const dx = mul(xCumProd, xCumRevProd); + return mul(expandedDy, dx); + } + // Support gradients when the product is done on many axes at once. + // This done py pushing all the axes on which the product is applied into a + // single axis. + function prodsGradFn_(x, dy, axis) { + // Move all axes for doing prod over to the end of the tensor. + const xRank = x.shape.length; + const finalProdAxis = xRank - axis.length; + const xPermutation = getAxesPermutation(axis, xRank); + let permutedX = x; + if (xPermutation != null) { + permutedX = transpose$2(x, xPermutation); + } + // Reshape all the prod dimensions into a single one, and do compute prod + // gradients on that. + const newShape = permutedX.shape.slice(); + const removedShape = newShape.splice(xRank - axis.length, axis.length); + const endPartShape = removedShape.reduce((p, c) => p * c, 1); + newShape.push(endPartShape); + const reshapedPermutedX = permutedX.reshape(newShape); + let prodGrad = prodGradFn_(reshapedPermutedX, dy, finalProdAxis); + // Undo the re-shaping now we have the dx vector, and permute back to + // original axes order. + prodGrad = prodGrad.reshape(permutedX.shape); + if (xPermutation != null) { + const undoPermutation = getUndoAxesPermutation(xPermutation); + prodGrad = transpose$2(prodGrad, undoPermutation); + } + return prodGrad; + } + // Running example: + // [ + // [ + // [3.0, 4.0], + // [5.0, 6.0], + // [7.0, 8.0] + // ], + // [ + // [3.0, 5.0], + // [0.0, 6.0], + // [5.0, 6.0] + // ] + // ] + // + const prodGradConfig = { + kernelName: Prod, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const { axis } = attrs; + let axisArr = []; + if (axis === undefined || axis === null) { + axisArr = x.shape.map((_, i) => i); + } + else if (typeof axis === 'number') { + axisArr = [axis]; + } + else { + axisArr = axis; + } + return { x: () => prodsGradFn_(x, dy, axisArr) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const divGradConfig = { + kernelName: RealDiv, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const outShape = assertAndGetBroadcastShape(a.shape, b.shape); + const derA = () => { + const res = div$1(dy, cast$3(b, 'float32')); + const reduceAxes = getReductionAxes(a.shape, outShape); + if (reduceAxes.length > 0) { + return reshape$3(sum$3(res, reduceAxes), a.shape); + } + return res; + }; + const derB = () => { + let res = mul(dy, cast$3(a, 'float32')); + const reduceAxes = getReductionAxes(b.shape, outShape); + if (reduceAxes.length > 0) { + res = reshape$3(sum$3(res, reduceAxes), b.shape); + } + const tmp = square$2(b); + return neg$2(div$1(res, cast$3(tmp, 'float32'))); + }; + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const reciprocalGradConfig = { + kernelName: Reciprocal, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => div$1(dy, neg$2(square$2(x))) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const relu6GradConfig = { + kernelName: Relu6$1, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + const mask = mul(lessEqual$2(x, 6), step$2(x)); + return { x: () => mul(dy, cast$3(mask, 'float32')) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const reluGradConfig = { + kernelName: Relu$1, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => mul(dy, cast$3(step$2(x), 'float32')) }; + } + }; + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const reshapeGradConfig = { + kernelName: Reshape$1, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => reshape$3(dy, x.shape) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const resizeBilinearGradConfig$2 = { + kernelName: ResizeBilinear, + inputsToSave: ['images'], + gradFunc: (dy, saved, attrs) => { + const [images] = saved; + const inputs = { dy, images }; + const imagesDer = () => + // tslint:disable-next-line: no-unnecessary-type-assertion + ENGINE.runKernel(ResizeBilinearGrad, inputs, attrs); + return { images: imagesDer }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const resizeNearestNeighborGradConfig$2 = { + kernelName: ResizeNearestNeighbor, + inputsToSave: ['images'], + gradFunc: (dy, saved, attrs) => { + const [images] = saved; + const inputs = { dy, images }; + const imagesDer = () => + // tslint:disable-next-line: no-unnecessary-type-assertion + ENGINE.runKernel(ResizeNearestNeighborGrad, inputs, attrs); + return { images: imagesDer }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const reverseGradConfig = { + kernelName: Reverse, + gradFunc: (dy, saved, attrs) => { + const { dims } = attrs; + const axes = parseAxisParam(dims, dy.shape); + return { x: () => reverse$2(dy, axes) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const roundGradConfig = { + kernelName: Round, + gradFunc: (dy) => { + // TODO(nsthorat): Let gradients be null for cases where we want to stop + // backpropgation. + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const rsqrtGradConfig = { + kernelName: Rsqrt, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => neg$2(div$1(dy, mul(pow$3(x, 1.5), 2))) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const selectGradConfig = { + kernelName: Select, + inputsToSave: ['condition'], + gradFunc: (dy, saved) => { + const [condition] = saved; + return { + // TODO(julianoks): Return null for condition gradient + // when backprop supports it. + condition: () => cast$3(zerosLike$3(condition), 'float32'), + t: () => mul(dy, cast$3(condition, dy.dtype)), + e: () => mul(dy, cast$3(logicalNot$2(condition), dy.dtype)) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const seluGradConfig = { + kernelName: Selu$1, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { + x: () => { + const mask = greater$3(x, scalar(0)); + const scaleAlpha = scalar(SELU_SCALEALPHA); + const scale = scalar(SELU_SCALE); + const greaterThanZeroDer = mul(dy, scale); + const lessEqualZeroDer = mul(mul(dy, scaleAlpha), exp$2(cast$3(x, 'float32'))); + return where(mask, greaterThanZeroDer, lessEqualZeroDer); + } + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sigmoidGradConfig = { + kernelName: Sigmoid$1, + outputsToSave: [true], + gradFunc: (dy, saved) => { + const [y] = saved; + return { x: () => mul(dy, mul(y, sub$2(scalar(1), y))) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const signGradConfig = { + kernelName: Sign, + gradFunc: (dy) => { + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sinGradConfig = { + kernelName: Sin, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => mul(cos$2(cast$3(x, 'float32')), dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sinhGradConfig = { + kernelName: Sinh, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => mul(cosh$2(cast$3(x, 'float32')), dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sliceGradConfig = { + kernelName: Slice, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const { begin, size } = attrs; + const inputShape = x.shape; + const [begin_, size_] = parseSliceParams(x, begin, size); + // Create an Nx2 padding where the first column represents how many + // zeros are prepended (at start) for each dimension, and the second + // column indicates how many zeros are appended (at end). + // The number of zeros to append is the shape of the input + // elementwise-subtracted by both the begin vector and sizes vector. + const paddings = []; + for (let i = 0; i < dy.rank; i++) { + paddings.push([begin_[i], inputShape[i] - begin_[i] - size_[i]]); + } + return { x: () => pad(dy, paddings) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const softmaxGradConfig = { + kernelName: Softmax$2, + outputsToSave: [true], + gradFunc: (dy, saved, attrs) => { + const [y] = saved; + const { dim } = attrs; + const keepDims = true; + const dyTimesY = mul(dy, y); + return { + logits: () => sub$2(dyTimesY, mul(sum$3(dyTimesY, [dim], keepDims), y)) + }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const softplusGradConfig = { + kernelName: Softplus$1, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => mul(dy, sigmoid$2(x)) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const spaceToBatchNDGradConfig = { + kernelName: SpaceToBatchND, + gradFunc: (dy, saved, attrs) => { + const { blockShape, paddings } = attrs; + return { x: () => batchToSpaceND$2(dy, blockShape, paddings) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const splitVGradConfig = { + kernelName: SplitV, + gradFunc: (dy, saved, attrs) => { + const { axis } = attrs; + return { x: () => concat$2(dy, axis) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sqrtGradConfig = { + kernelName: Sqrt, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => div$1(dy, mul(sqrt$2(cast$3(x, 'float32')), 2)) }; + } + }; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const squareGradConfig = { + kernelName: Square, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => mul(dy, mul(cast$3(x, 'float32'), 2)) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const squaredDifferenceGradConfig = { + kernelName: SquaredDifference, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const two = scalar(2); + const derA = () => mul(dy, mul(two, sub$2(a, b))); + const derB = () => mul(dy, mul(two, sub$2(b, a))); + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const stepGradConfig = { + kernelName: Step, + gradFunc: (dy) => { + // TODO(manrajgrover): Return null for gradients when backprop supports + // it. + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const subGradConfig = { + kernelName: Sub, + inputsToSave: ['a', 'b'], + gradFunc: (dy, saved) => { + const [a, b] = saved; + const outShape = assertAndGetBroadcastShape(a.shape, b.shape); + const derA = () => { + let res = dy; + const reduceAxes = getReductionAxes(a.shape, outShape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(res, a.shape); + }; + const derB = () => { + let res = dy; + const reduceAxes = getReductionAxes(b.shape, outShape); + if (reduceAxes.length > 0) { + res = sum$3(res, reduceAxes); + } + return reshape$3(neg$2(res), b.shape); + }; + return { a: derA, b: derB }; + } + }; + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sumGradConfig = { + kernelName: Sum, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const expandedDyShape = x.shape.slice(); + const { axis } = attrs; + const axes = parseAxisParam(axis, x.shape); + axes.forEach(axis => { + expandedDyShape[axis] = 1; + }); + const expandedDy = reshape$3(dy, expandedDyShape); + const derX = mul(expandedDy, ones$1(x.shape, 'float32')); + return { x: () => derX }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const tanGradConfig = { + kernelName: Tan, + inputsToSave: ['x'], + gradFunc: (dy, saved) => { + const [x] = saved; + return { x: () => div$1(dy, square$2(cos$2(x))) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const tanhGradConfig = { + kernelName: Tanh$1, + outputsToSave: [true], + gradFunc: (dy, saved) => { + const [y] = saved; + return { x: () => mul(sub$2(scalar(1), square$2(y)), dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const tileGradConfig = { + kernelName: Tile, + inputsToSave: ['x'], + gradFunc: (dy, saved, attrs) => { + const [x] = saved; + const { reps } = attrs; + const derX = () => { + let xGrad = zerosLike$3(x); + // TODO(cais): Maybe reduce memory footprint by avoiding repeated + // slicing. + if (x.rank === 1) { + for (let i = 0; i < reps[0]; ++i) { + xGrad = add$3(xGrad, slice$2(dy, [i * x.shape[0]], [x.shape[0]])); + } + } + else if (x.rank === 2) { + for (let i = 0; i < reps[0]; ++i) { + for (let j = 0; j < reps[1]; ++j) { + xGrad = add$3(xGrad, slice$2(dy, [i * x.shape[0], j * x.shape[1]], [ + x.shape[0], x.shape[1] + ])); + } + } + } + else if (x.rank === 3) { + for (let i = 0; i < reps[0]; ++i) { + for (let j = 0; j < reps[1]; ++j) { + for (let k = 0; k < reps[2]; ++k) { + xGrad = + add$3(xGrad, slice$2(dy, [i * x.shape[0], j * x.shape[1], k * x.shape[2]], [x.shape[0], x.shape[1], x.shape[2]])); + } + } + } + } + else if (x.rank === 4) { + for (let i = 0; i < reps[0]; ++i) { + for (let j = 0; j < reps[1]; ++j) { + for (let k = 0; k < reps[2]; ++k) { + for (let l = 0; l < reps[3]; ++l) { + xGrad = + add$3(xGrad, slice$2(dy, [ + i * x.shape[0], j * x.shape[1], k * x.shape[2], + l * x.shape[3] + ], [x.shape[0], x.shape[1], x.shape[2], x.shape[3]])); + } + } + } + } + } + else { + throw new Error(`Gradient for tile operation is not implemented for rank-` + + `${x.rank} tensors yet.`); + } + return xGrad; + }; + return { x: derX }; + }, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const transposeGradConfig = { + kernelName: Transpose, + gradFunc: (dy, saved, attrs) => { + const transposeAttrs = attrs; + const { perm } = transposeAttrs; + const undoPerm = getUndoAxesPermutation(perm); + return { x: () => transpose$2(dy, undoPerm) }; + } + }; + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const unpackGradConfig = { + kernelName: Unpack, + gradFunc: (dy, saved, attrs) => { + const unpackAttrs = attrs; + const { axis } = unpackAttrs; + return { value: () => stack(dy, axis) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const unsortedSegmentSumGradConfig = { + kernelName: UnsortedSegmentSum, + inputsToSave: ['segmentIds'], + gradFunc: (dy, saved) => { + const [segmentIds] = saved; + const derX = () => { + return gatherDropNegatives(dy, segmentIds); + }; + return { x: derX }; + } + }; + function gatherDropNegatives(x, indices) { + // Helper function for unsorted segment ops. Gathers params for + // positive segment ids and gathers 0 for inputs with negative segment id. + // Mirrors _GatherDropNegatives from tensorflow/python/ops/math_grad.py + const zeroClippedIndices = maximum$4(indices, zerosLike$3(indices)); + const gathered = gather$1(x, zeroClippedIndices); + let isPositive = greaterEqual$2(indices, scalar(0, 'int32')); + const numIters = gathered.rank - isPositive.rank; + for (let i = 0; i < numIters; ++i) { + isPositive = expandDims$3(isPositive, i + 1); + } + isPositive = logicalAnd$2(isPositive, ones$1(gathered.shape, 'bool')); + const zeroSlice = zerosLike$3(gathered); + return where(isPositive, gathered, zeroSlice); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const zerosLikeGradConfig = { + kernelName: ZerosLike, + gradFunc: (dy) => { + return { x: () => zerosLike$3(dy) }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Export all kernel configs here so that the package can auto register them + const gradConfigs = [ + absGradConfig, + acosGradConfig, + acoshGradConfig, + addGradConfig, + addNGradConfig, + argMaxGradConfig, + argMinGradConfig, + asinGradConfig, + asinhGradConfig, + atan2GradConfig, + atanGradConfig, + atanhGradConfig, + avgPool3DGradConfig$2, + avgPoolGradConfig$2, + batchMatMulGradConfig, + batchToSpaceNDGradConfig, + broadcastToGradConfig, + castGradConfig, + ceilGradConfig, + clipByValueGradConfig, + complexAbsGradConfig, + concatGradConfig, + conv2DBackpropInputGradConfig, + conv2DGradConfig, + conv3DGradConfig, + cosGradConfig, + coshGradConfig, + cumsumGradConfig, + depthwiseConv2dNativeGradConfig, + dilation2dGradConfig, + divGradConfig, + eluGradConfig$2, + erfGradConfig, + expGradConfig, + expandDimsGradConfig, + expm1GradConfig, + floorDivGradConfig, + floorGradConfig, + fusedBatchNormGradConfig, + gatherGradConfig, + greaterEqualGradConfig, + identityGradConfig, + isFiniteGradConfig, + isInfGradConfig, + isNanGradConfig, + leakyReluGradConfig, + log1pGradConfig, + logGradConfig, + logSoftmaxGradConfig, + lrnGradConfig, + maxGradConfig, + maxGradConfig, + maximumGradConfig, + maxPool3DGradConfig$2, + maxPoolGradConfig$2, + meanGradConfig, + minGradConfig, + minimumGradConfig, + mirrorPadGradConfig, + modGradConfig, + multiplyGradConfig, + negGradConfig, + oneHotGradConfig, + onesLikeGradConfig, + packGradConfig, + padV2GradConfig, + padV2GradConfig, + powGradConfig, + preluGradConfig, + prodGradConfig, + reciprocalGradConfig, + relu6GradConfig, + reluGradConfig, + reshapeGradConfig, + resizeBilinearGradConfig$2, + resizeNearestNeighborGradConfig$2, + reverseGradConfig, + roundGradConfig, + rsqrtGradConfig, + selectGradConfig, + seluGradConfig, + sigmoidGradConfig, + signGradConfig, + sinGradConfig, + sinhGradConfig, + sliceGradConfig, + softmaxGradConfig, + softplusGradConfig, + spaceToBatchNDGradConfig, + spaceToBatchNDGradConfig, + splitVGradConfig, + splitVGradConfig, + sqrtGradConfig, + squaredDifferenceGradConfig, + squareGradConfig, + stepGradConfig, + subGradConfig, + sumGradConfig, + tanGradConfig, + tanhGradConfig, + tileGradConfig, + transposeGradConfig, + unpackGradConfig, + unsortedSegmentSumGradConfig, + zerosLikeGradConfig + ]; + for (const gradientConfig of gradConfigs) { + registerGradient(gradientConfig); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.abs = function () { + this.throwIfDisposed(); + return abs$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.acos = function () { + this.throwIfDisposed(); + return acos$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.acosh = function () { + this.throwIfDisposed(); + return acosh$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.add = function (b) { + this.throwIfDisposed(); + return add$3(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.all = function (axis, keepDims) { + this.throwIfDisposed(); + return all$2(this, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.any = function (axis, keepDims) { + this.throwIfDisposed(); + return any$2(this, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.argMax = function (axis) { + this.throwIfDisposed(); + return argMax$2(this, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.argMin = function (axis) { + this.throwIfDisposed(); + return argMin$2(this, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts a size-1 `tf.Tensor` to a `tf.Scalar`. + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.asScalar = function () { + this.throwIfDisposed(); + assert$1(this.size === 1, () => 'The array must have only 1 element.'); + return reshape$3(this, []); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Casts a `tf.Tensor` to a specified dtype. + * + * @param dtype Data-type to cast the tensor to. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.asType = function (dtype) { + this.throwIfDisposed(); + return cast$3(this, dtype); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts a `tf.Tensor` to a `tf.Tensor1D`. + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.as1D = function () { + this.throwIfDisposed(); + return reshape$3(this, [this.size]); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts a `tf.Tensor` to a `tf.Tensor2D`. + * + * @param rows Number of rows in `tf.Tensor2D`. + * @param columns Number of columns in `tf.Tensor2D`. + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.as2D = function (rows, columns) { + this.throwIfDisposed(); + return reshape$3(this, [rows, columns]); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts a `tf.Tensor` to a `tf.Tensor3D`. + * + * @param rows Number of rows in `tf.Tensor3D`. + * @param columns Number of columns in `tf.Tensor3D`. + * @param depth Depth of `tf.Tensor3D`. + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.as3D = function (rows, columns, depth) { + this.throwIfDisposed(); + return reshape$3(this, [rows, columns, depth]); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts a `tf.Tensor` to a `tf.Tensor4D`. + * + * @param rows Number of rows in `tf.Tensor4D`. + * @param columns Number of columns in `tf.Tensor4D`. + * @param depth Depth of `tf.Tensor4D`. + * @param depth2 4th dimension of `tf.Tensor4D`. + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.as4D = function (rows, columns, depth, depth2) { + this.throwIfDisposed(); + return reshape$3(this, [rows, columns, depth, depth2]); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Converts a `tf.Tensor` to a `tf.Tensor5D`. + * + * @param rows Number of rows in `tf.Tensor5D`. + * @param columns Number of columns in `tf.Tensor5D`. + * @param depth Depth of `tf.Tensor5D`. + * @param depth2 4th dimension of `tf.Tensor5D`. + * @param depth3 5th dimension of 'tf.Tensor5D' + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.as5D = function (rows, columns, depth, depth2, depth3) { + this.throwIfDisposed(); + return reshape$3(this, [rows, columns, depth, depth2, depth3]); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.asin = function () { + this.throwIfDisposed(); + return asin$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.asinh = function () { + this.throwIfDisposed(); + return asinh$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.atan = function () { + this.throwIfDisposed(); + return atan$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.atan2 = function (b) { + this.throwIfDisposed(); + return atan2$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.atanh = function () { + this.throwIfDisposed(); + return atanh$2(this); + }; + + getGlobalTensorClass().prototype.avgPool = + function (filterSize, strides, pad, dimRoundingMode) { + this.throwIfDisposed(); + return avgPool$2(this, filterSize, strides, pad, dimRoundingMode); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.batchToSpaceND = function (blockShape, crops) { + this.throwIfDisposed(); + return batchToSpaceND$2(this, blockShape, crops); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.batchNorm = function (mean, variance, offset, scale, varianceEpsilon) { + this.throwIfDisposed(); + return batchNorm$2(this, mean, variance, offset, scale, varianceEpsilon); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.broadcastTo = function (shape) { + this.throwIfDisposed(); + return broadcastTo(this, shape); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.cast = function (dtype) { + this.throwIfDisposed(); + return cast$3(this, dtype); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.ceil = function () { + this.throwIfDisposed(); + return ceil$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.clipByValue = function (min, max) { + this.throwIfDisposed(); + return clipByValue$2(this, min, max); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.concat = function (x, axis) { + this.throwIfDisposed(); + if (x instanceof Tensor) { + x = [x]; + } + return concat$2([this, ...x], axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.conv1d = function (filter, stride, pad, dataFormat, dilation, dimRoundingMode) { + this.throwIfDisposed(); + return conv1d$2(this, filter, stride, pad, dataFormat, dilation, dimRoundingMode); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.conv2dTranspose = + function (filter, outputShape, strides, pad, dimRoundingMode) { + this.throwIfDisposed(); + return conv2dTranspose$1(this, filter, outputShape, strides, pad, dimRoundingMode); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.conv2d = function (filter, strides, pad, dataFormat, dilations, dimRoundingMode) { + this.throwIfDisposed(); + return conv2d$4(this, filter, strides, pad, dataFormat, dilations, dimRoundingMode); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.cos = function () { + this.throwIfDisposed(); + return cos$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.cosh = function () { + this.throwIfDisposed(); + return cosh$2(this); + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.cumprod = function (axis, exclusive, reverse) { + this.throwIfDisposed(); + return cumprod$2(this, axis, exclusive, reverse); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.cumsum = function (axis, exclusive, reverse) { + this.throwIfDisposed(); + return cumsum$2(this, axis, exclusive, reverse); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.depthToSpace = function (blockSize, dataFormat) { + this.throwIfDisposed(); + return depthToSpace$2(this, blockSize, dataFormat); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.depthwiseConv2d = + function (filter, strides, pad, dataFormat, dilations, dimRoundingMode) { + this.throwIfDisposed(); + return depthwiseConv2d$3(this, filter, strides, pad, dataFormat, dilations, dimRoundingMode); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.dilation2d = + function (filter, strides, pad, dilations, dataFormat) { + this.throwIfDisposed(); + return dilation2d(this, filter, strides, pad, dilations, dataFormat); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.divNoNan = function (b) { + this.throwIfDisposed(); + return divNoNan(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.div = function (b) { + this.throwIfDisposed(); + return div$1(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.dot = function (b) { + this.throwIfDisposed(); + return dot$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.elu = function () { + this.throwIfDisposed(); + return elu$4(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.equal = function (b) { + this.throwIfDisposed(); + return equal$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.erf = function () { + this.throwIfDisposed(); + return erf$2(this); + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.euclideanNorm = function (axis, keepDims) { + this.throwIfDisposed(); + return euclideanNorm(this, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.exp = function () { + this.throwIfDisposed(); + return exp$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.expandDims = function (axis) { + this.throwIfDisposed(); + return expandDims$3(this, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.expm1 = function () { + this.throwIfDisposed(); + return expm1$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.fft = function () { + this.throwIfDisposed(); + return fft$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Flatten a Tensor to a 1D array. + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.flatten = function () { + this.throwIfDisposed(); + return reshape$3(this, [this.size]); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.floor = function () { + this.throwIfDisposed(); + return floor$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.floorDiv = function (b) { + this.throwIfDisposed(); + return floorDiv$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.gather = function (indices, axis, batchDims) { + this.throwIfDisposed(); + return gather$1(this, indices, axis, batchDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.greaterEqual = function (b) { + this.throwIfDisposed(); + return greaterEqual$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.greater = function (b) { + this.throwIfDisposed(); + return greater$3(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.ifft = function () { + this.throwIfDisposed(); + return ifft$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.irfft = function () { + this.throwIfDisposed(); + return irfft(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.isFinite = function () { + this.throwIfDisposed(); + return isFinite$3(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.isInf = function () { + this.throwIfDisposed(); + return isInf$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.isNaN = function () { + this.throwIfDisposed(); + return isNaN$3(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.leakyRelu = function (alpha) { + this.throwIfDisposed(); + return leakyRelu$2(this, alpha); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.lessEqual = function (b) { + this.throwIfDisposed(); + return lessEqual$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.less = function (b) { + this.throwIfDisposed(); + return less$3(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.localResponseNormalization = + function (depthRadius, bias, alpha, beta) { + this.throwIfDisposed(); + return localResponseNormalization(this, depthRadius, bias, alpha, beta); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.logSigmoid = function () { + this.throwIfDisposed(); + return logSigmoid(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.logSoftmax = function (axis) { + this.throwIfDisposed(); + return logSoftmax(this, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.logSumExp = function (axis, keepDims) { + this.throwIfDisposed(); + return logSumExp(this, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.log = function () { + this.throwIfDisposed(); + return log$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.log1p = function () { + this.throwIfDisposed(); + return log1p$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.logicalAnd = function (b) { + this.throwIfDisposed(); + return logicalAnd$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.logicalNot = function () { + this.throwIfDisposed(); + return logicalNot$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.logicalOr = function (b) { + this.throwIfDisposed(); + return logicalOr$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.logicalXor = function (b) { + this.throwIfDisposed(); + return logicalXor(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.matMul = function (b, transposeA, transposeB) { + this.throwIfDisposed(); + return matMul$1(this, b, transposeA, transposeB); + }; + + getGlobalTensorClass().prototype.maxPool = + function (filterSize, strides, pad, dimRoundingMode) { + this.throwIfDisposed(); + return maxPool$2(this, filterSize, strides, pad, dimRoundingMode); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.max = function (axis, keepDims) { + this.throwIfDisposed(); + return max$3(this, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.maximum = function (b) { + this.throwIfDisposed(); + return maximum$4(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.mean = function (axis, keepDims) { + this.throwIfDisposed(); + return mean$3(this, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.min = function (axis, keepDims) { + this.throwIfDisposed(); + return min$3(this, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.minimum = function (b) { + this.throwIfDisposed(); + return minimum$4(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.mirrorPad = function (paddings, mode) { + this.throwIfDisposed(); + return mirrorPad$1(this, paddings, mode); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.mod = function (b) { + this.throwIfDisposed(); + return mod$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.mul = function (b) { + this.throwIfDisposed(); + return mul(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.neg = function () { + this.throwIfDisposed(); + return neg$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.norm = function (ord, axis, keepDims) { + this.throwIfDisposed(); + return norm(this, ord, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.notEqual = function (b) { + this.throwIfDisposed(); + return notEqual$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.oneHot = function (depth, onValue = 1, offValue = 0) { + this.throwIfDisposed(); + return oneHot$3(this, depth, onValue, offValue); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.onesLike = function () { + this.throwIfDisposed(); + return onesLike$3(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.pad = function (paddings, constantValue) { + this.throwIfDisposed(); + return pad(this, paddings, constantValue); + }; + + getGlobalTensorClass().prototype.pool = function (windowShape, poolingType, padding, dilationRate, strides, dimRoundingMode) { + this.throwIfDisposed(); + return pool$1(this, windowShape, poolingType, padding, dilationRate, strides, dimRoundingMode); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.pow = function (exp) { + this.throwIfDisposed(); + return pow$3(this, exp); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.prelu = function (alpha) { + this.throwIfDisposed(); + return prelu$3(this, alpha); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.prod = function (axis, keepDims) { + this.throwIfDisposed(); + return prod$2(this, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.reciprocal = function () { + this.throwIfDisposed(); + return reciprocal$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.relu = function () { + this.throwIfDisposed(); + return relu$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.relu6 = function () { + this.throwIfDisposed(); + return relu6$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Reshapes the tensor into the shape of the provided tensor. + * + * @param x The tensor of required shape. + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.reshapeAs = function (x) { + this.throwIfDisposed(); + return reshape$3(this, x.shape); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.reshape = function (shape) { + this.throwIfDisposed(); + return reshape$3(this, shape); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.resizeBilinear = + function (newShape2D, alignCorners, halfPixelCenters) { + this.throwIfDisposed(); + return resizeBilinear$3(this, newShape2D, alignCorners, halfPixelCenters); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.resizeNearestNeighbor = + function (newShape2D, alignCorners, halfFloatCenters) { + this.throwIfDisposed(); + return resizeNearestNeighbor$2(this, newShape2D, alignCorners, halfFloatCenters); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.reverse = function (axis) { + this.throwIfDisposed(); + return reverse$2(this, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.rfft = function () { + this.throwIfDisposed(); + return rfft(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.round = function () { + this.throwIfDisposed(); + return round$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.rsqrt = function () { + this.throwIfDisposed(); + return rsqrt$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.selu = function () { + this.throwIfDisposed(); + return selu$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.separableConv2d = + function (depthwiseFilter, pointwiseFilter, strides, pad, dilation, dataFormat) { + this.throwIfDisposed(); + return separableConv2d$1(this, depthwiseFilter, pointwiseFilter, strides, pad, dilation, dataFormat); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.sigmoid = function () { + this.throwIfDisposed(); + return sigmoid$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.sign = function () { + this.throwIfDisposed(); + return sign$3(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.sin = function () { + this.throwIfDisposed(); + return sin$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.sinh = function () { + this.throwIfDisposed(); + return sinh$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.slice = function (begin, size) { + this.throwIfDisposed(); + return slice$2(this, begin, size); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.softmax = function (dim) { + this.throwIfDisposed(); + return softmax$3(this, dim); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.softplus = function () { + this.throwIfDisposed(); + return softplus$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.spaceToBatchND = function (blockShape, paddings) { + this.throwIfDisposed(); + return spaceToBatchND$2(this, blockShape, paddings); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.split = function (numOrSizeSplits, axis) { + this.throwIfDisposed(); + return split$3(this, numOrSizeSplits, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.sqrt = function () { + this.throwIfDisposed(); + return sqrt$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.square = function () { + this.throwIfDisposed(); + return square$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.squaredDifference = function (b) { + this.throwIfDisposed(); + return squaredDifference$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.squeeze = function (axis) { + this.throwIfDisposed(); + return squeeze(this, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.stack = function (x, axis) { + this.throwIfDisposed(); + const tensorsToBeStacked = x instanceof Tensor ? [this, x] : [this, ...x]; + return stack(tensorsToBeStacked, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.step = function (alpha) { + this.throwIfDisposed(); + return step$2(this, alpha); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.stridedSlice = function (begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask) { + this.throwIfDisposed(); + return stridedSlice$2(this, begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.sub = function (b) { + this.throwIfDisposed(); + return sub$2(this, b); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.sum = function (axis, keepDims) { + this.throwIfDisposed(); + return sum$3(this, axis, keepDims); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.tan = function () { + this.throwIfDisposed(); + return tan$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.tanh = function () { + this.throwIfDisposed(); + return tanh$2(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.tile = function (reps) { + this.throwIfDisposed(); + return tile$3(this, reps); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Casts the array to type `bool` + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.toBool = function () { + this.throwIfDisposed(); + return cast$3(this, 'bool'); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Casts the array to type `float32` + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.toFloat = function () { + this.throwIfDisposed(); + return cast$3(this, 'float32'); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Casts the array to type `int32` + * + * @doc {heading: 'Tensors', subheading: 'Classes'} + */ + getGlobalTensorClass().prototype.toInt = function () { + this.throwIfDisposed(); + return cast$3(this, 'int32'); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.topk = function (k, sorted) { + this.throwIfDisposed(); + return topk(this, k, sorted); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.transpose = function (perm) { + this.throwIfDisposed(); + return transpose$2(this, perm); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.unique = function (axis) { + this.throwIfDisposed(); + return unique$3(this, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.unsortedSegmentSum = + function (segmentIds, numSegments) { + this.throwIfDisposed(); + return unsortedSegmentSum$2(this, segmentIds, numSegments); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.unstack = function (axis) { + this.throwIfDisposed(); + return unstack(this, axis); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.where = function (condition, x) { + this.throwIfDisposed(); + return where(condition, this, x); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + getGlobalTensorClass().prototype.zerosLike = function () { + this.throwIfDisposed(); + return zerosLike$3(this); + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Explicit error types. + * + * See the following link for more information about why the code includes + * calls to setPrototypeOf: + * + * https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work + */ + // tslint:enable + /** + * Equivalent of Python's AttributeError. + */ + class AttributeError extends Error { + constructor(message) { + super(message); + // Set the prototype explicitly. + Object.setPrototypeOf(this, AttributeError.prototype); + } + } + /** + * Equivalent of Python's RuntimeError. + */ + class RuntimeError extends Error { + constructor(message) { + super(message); + // Set the prototype explicitly. + Object.setPrototypeOf(this, RuntimeError.prototype); + } + } + /** + * Equivalent of Python's ValueError. + */ + class ValueError extends Error { + constructor(message) { + super(message); + // Set the prototype explicitly. + Object.setPrototypeOf(this, ValueError.prototype); + } + } + /** + * Equivalent of Python's NotImplementedError. + */ + class NotImplementedError extends Error { + constructor(message) { + super(message); + // Set the prototype explicitly. + Object.setPrototypeOf(this, NotImplementedError.prototype); + } + } + /** + * Equivalent of Python's AssertionError. + */ + class AssertionError extends Error { + constructor(message) { + super(message); + // Set the prototype explicitly. + Object.setPrototypeOf(this, AssertionError.prototype); + } + } + /** + * Equivalent of Python's IndexError. + */ + class IndexError extends Error { + constructor(message) { + super(message); + // Set the prototype explicitly. + Object.setPrototypeOf(this, IndexError.prototype); + } + } + + /** + * @license + * Copyright 2022 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * LruCache: A mapping from the String to T. If the number of the entries is + * exceeding the `maxEntries`, the LruCache will delete the least recently + * used entry. + */ + class LruCache { + constructor(maxEntries) { + this.maxEntries = maxEntries || 100; + this.cache = new Map(); + } + /** + * Get the entry for the key and mark it as used recently. + */ + get(key) { + let entry; + if (this.cache.has(key)) { + entry = this.cache.get(key); + this.cache.delete(key); + this.cache.set(key, entry); + } + return entry; + } + /** + * Put the entry into the cache. If the key already existed, mark the key as + * used recently. + */ + put(key, value) { + if (this.cache.has(key)) { + this.cache.delete(key); + } + else if (this.cache.size >= this.maxEntries) { + const keyToDelete = this.cache.keys().next().value; + this.cache.delete(keyToDelete); + } + this.cache.set(key, value); + } + /** + * Get the MaxEntries of the cache. + */ + getMaxEntries() { + return this.maxEntries; + } + /** + * Set the MaxEntries of the cache. If the maxEntries is decreased, reduce + * entries in the cache. + */ + setMaxEntries(maxEntries) { + if (maxEntries < 0) { + throw new Error(`The maxEntries of LRU caches must be at least 0, but got ${maxEntries}.`); + } + if (this.maxEntries > maxEntries) { + for (let i = 0; i < this.maxEntries - maxEntries; i++) { + const keyToDelete = this.cache.keys().next().value; + this.cache.delete(keyToDelete); + } + } + this.maxEntries = maxEntries; + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // tslint:enable + /** + * If `value` is an Array, equivalent to Python's `value * numValues`. + * If `value` is not an Array, equivalent to Python's `[value] * numValues` + */ + // tslint:disable-next-line:no-any + function pyListRepeat(value, numValues) { + if (Array.isArray(value)) { + // tslint:disable-next-line:no-any + let newArray = []; + for (let i = 0; i < numValues; i++) { + newArray = newArray.concat(value); + } + return newArray; + } + else { + const newArray = new Array(numValues); + newArray.fill(value); + return newArray; + } + } + function assert(val, message) { + if (!val) { + throw new AssertionError(message); + } + } + /** + * Count the number of elements of the `array` that are equal to `reference`. + */ + function count(array, refernce) { + let counter = 0; + for (const item of array) { + if (item === refernce) { + counter++; + } + } + return counter; + } + /** + * If an array is of length 1, just return the first element. Otherwise, return + * the full array. + * @param tensors + */ + function singletonOrArray(xs) { + if (xs.length === 1) { + return xs[0]; + } + return xs; + } + /** + * Normalizes a list/tensor into a list. + * + * If a tensor is passed, we return + * a list of size 1 containing the tensor. + * + * @param x target object to be normalized. + */ + // tslint:disable-next-line:no-any + function toList(x) { + if (Array.isArray(x)) { + return x; + } + return [x]; + } + /** + * Generate a UID for a list + */ + // tslint:disable-next-line:no-any + function objectListUid(objs) { + const objectList = toList(objs); + let retVal = ''; + for (const obj of objectList) { + if (obj.id == null) { + throw new ValueError(`Object ${obj} passed to objectListUid without an id`); + } + if (retVal !== '') { + retVal = retVal + ', '; + } + retVal = `${retVal}${Math.abs(obj.id)}`; + } + return retVal; + } + /** + * Converts string to snake-case. + * @param name + */ + function toSnakeCase(name) { + const intermediate = name.replace(/(.)([A-Z][a-z0-9]+)/g, '$1_$2'); + const insecure = intermediate.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase(); + /* + If the class is private the name starts with "_" which is not secure + for creating scopes. We prefix the name with "private" in this case. + */ + if (insecure[0] !== '_') { + return insecure; + } + return 'private' + insecure; + } + function toCamelCase(identifier) { + // quick return for empty string or single character strings + if (identifier.length <= 1) { + return identifier; + } + // Check for the underscore indicating snake_case + if (identifier.indexOf('_') === -1) { + return identifier; + } + return identifier.replace(/[_]+(\w|$)/g, (m, p1) => p1.toUpperCase()); + } + // tslint:disable-next-line:no-any + let _GLOBAL_CUSTOM_OBJECTS = {}; + function serializeKerasObject(instance) { + if (instance === null || instance === undefined) { + return null; + } + const dict = {}; + dict['className'] = instance.getClassName(); + dict['config'] = instance.getConfig(); + return dict; + } + /** + * Replace ndarray-style scalar objects in serialization objects with numbers. + * + * Background: In some versions of tf.keras, certain scalar values in the HDF5 + * model save file can be serialized as: `{'type': 'ndarray', 'value': num}`, + * where in `num` is a plain number. This method converts such serialization + * to a `number`. + * + * @param config The keras-format serialization object to be processed + * (in place). + */ + function convertNDArrayScalarsInConfig(config) { + if (config == null || typeof config !== 'object') { + return; + } + else if (Array.isArray(config)) { + config.forEach(configItem => convertNDArrayScalarsInConfig(configItem)); + } + else { + const fields = Object.keys(config); + for (const field of fields) { + const value = config[field]; + if (value != null && typeof value === 'object') { + if (!Array.isArray(value) && value['type'] === 'ndarray' && + typeof value['value'] === 'number') { + config[field] = value['value']; + } + else { + convertNDArrayScalarsInConfig(value); + } + } + } + } + } + /** + * Deserialize a saved Keras Object + * @param identifier either a string ID or a saved Keras dictionary + * @param moduleObjects a list of Python class names to object constructors + * @param customObjects a list of Python class names to object constructors + * @param printableModuleName debug text for the object being reconstituted + * @param fastWeightInit Optional flag to use fast weight initialization + * during deserialization. This is applicable to cases in which + * the initialization will be immediately overwritten by loaded weight + * values. Default: `false`. + * @returns a TensorFlow.js Layers object + */ + // tslint:disable:no-any + function deserializeKerasObject(identifier, moduleObjects = {}, customObjects = {}, printableModuleName = 'object', fastWeightInit = false) { + // tslint:enable + if (typeof identifier === 'string') { + const functionName = identifier; + let fn; + if (functionName in customObjects) { + fn = customObjects[functionName]; + } + else if (functionName in _GLOBAL_CUSTOM_OBJECTS) { + fn = _GLOBAL_CUSTOM_OBJECTS[functionName]; + } + else { + fn = moduleObjects[functionName]; + if (fn == null) { + throw new ValueError(`Unknown ${printableModuleName}: ${identifier}. ` + + `This may be due to one of the following reasons:\n` + + `1. The ${printableModuleName} is defined in Python, in which ` + + `case it needs to be ported to TensorFlow.js or your JavaScript ` + + `code.\n` + + `2. The custom ${printableModuleName} is defined in JavaScript, ` + + `but is not registered properly with ` + + `tf.serialization.registerClass().`); + // TODO(cais): Add link to tutorial page on custom layers. + } + } + return fn; + } + else { + // In this case we are dealing with a Keras config dictionary. + const config = identifier; + if (config['className'] == null || config['config'] == null) { + throw new ValueError(`${printableModuleName}: Improper config format: ` + + `${JSON.stringify(config)}.\n` + + `'className' and 'config' must set.`); + } + const className = config['className']; + let cls, fromConfig; + if (className in customObjects) { + [cls, fromConfig] = customObjects[className]; + } + else if (className in _GLOBAL_CUSTOM_OBJECTS) { + [cls, fromConfig] = _GLOBAL_CUSTOM_OBJECTS['className']; + } + else if (className in moduleObjects) { + [cls, fromConfig] = moduleObjects[className]; + } + if (cls == null) { + throw new ValueError(`Unknown ${printableModuleName}: ${className}. ` + + `This may be due to one of the following reasons:\n` + + `1. The ${printableModuleName} is defined in Python, in which ` + + `case it needs to be ported to TensorFlow.js or your JavaScript ` + + `code.\n` + + `2. The custom ${printableModuleName} is defined in JavaScript, ` + + `but is not registered properly with ` + + `tf.serialization.registerClass().`); + // TODO(cais): Add link to tutorial page on custom layers. + } + if (fromConfig != null) { + // Porting notes: Instead of checking to see whether fromConfig accepts + // customObjects, we create a customObjects dictionary and tack it on to + // config['config'] as config['config'].customObjects. Objects can use it, + // if they want. + // tslint:disable-next-line:no-any + const customObjectsCombined = {}; + for (const key of Object.keys(_GLOBAL_CUSTOM_OBJECTS)) { + customObjectsCombined[key] = _GLOBAL_CUSTOM_OBJECTS[key]; + } + for (const key of Object.keys(customObjects)) { + customObjectsCombined[key] = customObjects[key]; + } + // Add the customObjects to config + const nestedConfig = config['config']; + nestedConfig['customObjects'] = customObjectsCombined; + const backupCustomObjects = Object.assign({}, _GLOBAL_CUSTOM_OBJECTS); + for (const key of Object.keys(customObjects)) { + _GLOBAL_CUSTOM_OBJECTS[key] = customObjects[key]; + } + convertNDArrayScalarsInConfig(config['config']); + const returnObj = fromConfig(cls, config['config'], customObjects, fastWeightInit); + _GLOBAL_CUSTOM_OBJECTS = Object.assign({}, backupCustomObjects); + return returnObj; + } + else { + // Then `cls` may be a function returning a class. + // In this case by convention `config` holds + // the kwargs of the function. + const backupCustomObjects = Object.assign({}, _GLOBAL_CUSTOM_OBJECTS); + for (const key of Object.keys(customObjects)) { + _GLOBAL_CUSTOM_OBJECTS[key] = customObjects[key]; + } + // In python this is **config['config'], for tfjs-layers we require + // classes that use this fall-through construction method to take + // a config interface that mimics the expansion of named parameters. + const returnObj = new cls(config['config']); + _GLOBAL_CUSTOM_OBJECTS = Object.assign({}, backupCustomObjects); + return returnObj; + } + } + } + /** + * Compares two numbers for sorting. + * @param a + * @param b + */ + function numberCompare(a, b) { + return (a < b) ? -1 : ((a > b) ? 1 : 0); + } + /** + * Comparison of two numbers for reverse sorting. + * @param a + * @param b + */ + function reverseNumberCompare(a, b) { + return -1 * numberCompare(a, b); + } + /** + * Convert a string into the corresponding DType. + * @param dtype + * @returns An instance of DType. + */ + function stringToDType(dtype) { + switch (dtype) { + case 'float32': + return 'float32'; + default: + throw new ValueError(`Invalid dtype: ${dtype}`); + } + } + /** + * Test the element-by-element equality of two Arrays of strings. + * @param xs First array of strings. + * @param ys Second array of strings. + * @returns Wether the two arrays are all equal, element by element. + */ + function stringsEqual(xs, ys) { + if (xs == null || ys == null) { + return xs === ys; + } + if (xs.length !== ys.length) { + return false; + } + for (let i = 0; i < xs.length; ++i) { + if (xs[i] !== ys[i]) { + return false; + } + } + return true; + } + /** + * Get the unique elements of an array. + * @param xs Array. + * @returns An Array consisting of the unique elements in `xs`. + */ + function unique$2(xs) { + if (xs == null) { + return xs; + } + const out = []; + // TODO(cais): Maybe improve performance by sorting. + for (const x of xs) { + if (out.indexOf(x) === -1) { + out.push(x); + } + } + return out; + } + /** + * Determine if an Object is empty (i.e., does not have own properties). + * @param obj Object + * @returns Whether the Object is empty. + * @throws ValueError: If object is `null` or `undefined`. + */ + function isObjectEmpty(obj) { + if (obj == null) { + throw new ValueError(`Invalid value in obj: ${JSON.stringify(obj)}`); + } + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + return false; + } + } + return true; + } + /** + * Helper function used to build type union/enum run-time checkers. + * @param values The list of allowed values. + * @param label A string name for the type + * @param value The value to test. + * @throws ValueError: If the value is not in values nor `undefined`/`null`. + */ + function checkStringTypeUnionValue(values, label, value) { + if (value == null) { + return; + } + if (values.indexOf(value) < 0) { + throw new ValueError(`${value} is not a valid ${label}. Valid values are ${values} or null/undefined.`); + } + } + /** + * Helper function for verifying the types of inputs. + * + * Ensures that the elements of `x` are all of type `expectedType`. + * Also verifies that the length of `x` is within bounds. + * + * @param x Object to test. + * @param expectedType The string expected type of all of the elements in the + * Array. + * @param minLength Return false if x.length is less than this. + * @param maxLength Return false if x.length is greater than this. + * @returns true if and only if `x` is an `Array` with + * length >= `minLength` and <= `maxLength`. + */ + // tslint:disable:no-any + function checkArrayTypeAndLength(x, expectedType, minLength = 0, maxLength = Infinity) { + assert(minLength >= 0); + assert(maxLength >= minLength); + return (Array.isArray(x) && x.length >= minLength && x.length <= maxLength && + x.every(e => typeof e === expectedType)); + } + // tslint:enable:no-any + /** + * Assert that a value or an array of value are positive integer. + * + * @param value The value being asserted on. May be a single number or an array + * of numbers. + * @param name Name of the value, used to make the error message. + */ + function assertPositiveInteger(value, name) { + if (Array.isArray(value)) { + assert$1(value.length > 0, () => `${name} is unexpectedly an empty array.`); + value.forEach((v, i) => assertPositiveInteger(v, `element ${i + 1} of ${name}`)); + } + else { + assert$1(Number.isInteger(value) && value > 0, () => `Expected ${name} to be a positive integer, but got ` + + `${formatAsFriendlyString(value)}.`); + } + } + /** + * Format a value into a display-friendly, human-readable fashion. + * + * - `null` is formatted as `'null'` + * - Strings are formated with flanking pair of quotes. + * - Arrays are formatted with flanking pair of square brackets. + * + * @param value The value to display. + * @return Formatted string. + */ + // tslint:disable-next-line:no-any + function formatAsFriendlyString(value) { + if (value === null) { + return 'null'; + } + else if (Array.isArray(value)) { + return '[' + value.map(v => formatAsFriendlyString(v)).join(',') + ']'; + } + else if (typeof value === 'string') { + return `"${value}"`; + } + else { + return `${value}`; + } + } + /** + * Returns a function `f2` (decorator) which wraps the original function + * `f`. `f2` guarantees that `f` can be called at most once + * every `waitMs` ms. If `f2` is called more often, it will return + * the last returned result of `f`. + * + * @param f The original function `f` to wrap. + * @param waitMs The time between two consecutive calls to `f` in ms. + */ + function debounce(f, waitMs, nowFunc) { + let lastTime = nowFunc != null ? nowFunc() : now(); + let lastResult; + const f2 = (...args) => { + const now$1 = nowFunc != null ? nowFunc() : now(); + if (now$1 - lastTime < waitMs) { + return lastResult; + } + lastTime = now$1; + lastResult = f(...args); + return lastResult; + }; + return f2; + } + /** + * Returns the fusable activation given a layers identifier. + * + * @param activationName The layers identifier string. + * @return The name of the fusable activation. + */ + function mapActivationToFusedKernel(activationName) { + if (activationName === 'relu') { + return 'relu'; + } + if (activationName === 'linear') { + return 'linear'; + } + if (activationName === 'elu') { + return 'elu'; + } + return null; + } + /** + * Returns the cartesian product of sets of values. + * This works the same as itertools.product in Python. + * + * Example: + * + * filters = [128, 256, 512] + * paddings = ['same', 'valid'] + * + * product = [ [128, 'same'], [128, 'valid'], [256, 'same'], [256, 'valid'], + * [512, 'same'], [512, 'valid']] + * + * @param arrayOfValues List/array of values. + * @return The cartesian product. + */ + function getCartesianProductOfValues(...arrayOfValues) { + assert(arrayOfValues.length > 0, 'arrayOfValues is empty'); + for (const values of arrayOfValues) { + assert(Array.isArray(values), 'one of the values is not an array'); + assert(values.length > 0, 'one of the values is empty'); + } + return arrayOfValues.reduce((products, values) => { + if (products.length === 0) { + return values.map(value => [value]); + } + return values + .map(value => { + return products.map((prevValue) => [...prevValue, value]); + }) + .reduce((flattenedProduct, unflattenedProduct) => { + return flattenedProduct.concat(unflattenedProduct); + }, []); + }, []); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Utilities related to persistent state in the backend. + */ + /** + * An ID to track `tf.SymbolicTensor`s and derived classes. + * Required in different places in engine/topology.ts to identify unique + * tensors. + */ + let _nextUniqueTensorId = 0; + function getNextUniqueTensorId() { + return _nextUniqueTensorId++; + } + const _uidPrefixes = {}; + /** + * Provides a unique UID given a string prefix. + * + * @param prefix + */ + function getUid(prefix = '') { + if (!(prefix in _uidPrefixes)) { + _uidPrefixes[prefix] = 0; + } + _uidPrefixes[prefix] += 1; + return prefix + _uidPrefixes[prefix].toString(); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + const VALID_DATA_FORMAT_VALUES = ['channelsFirst', 'channelsLast']; + const VALID_INTERPOLATION_FORMAT_VALUES = ['nearest', 'bilinear']; + const VALID_PADDING_MODE_VALUES = ['valid', 'same', 'causal']; + const VALID_POOL_MODE_VALUES = ['max', 'avg']; + const VALID_BIDIRECTIONAL_MERGE_MODES = ['sum', 'mul', 'concat', 'ave']; + const VALID_SAMPLE_WEIGHT_MODES = ['temporal']; + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // A map from the requested scoped name of a Tensor to the number of Tensors + // wanting that name so far. This allows enforcing name uniqueness by appending + // an incrementing index, e.g. scope/name, scope/name_1, scope/name_2, etc. + const nameMap = new Map(); + function checkDataFormat(value) { + checkStringTypeUnionValue(VALID_DATA_FORMAT_VALUES, 'DataFormat', value); + } + function checkInterpolationFormat(value) { + checkStringTypeUnionValue(VALID_INTERPOLATION_FORMAT_VALUES, 'InterpolationFormat', value); + } + function checkPaddingMode(value) { + checkStringTypeUnionValue(VALID_PADDING_MODE_VALUES, 'PaddingMode', value); + } + function checkPoolMode(value) { + checkStringTypeUnionValue(VALID_POOL_MODE_VALUES, 'PoolMode', value); + } + const _nameScopeStack = []; + const _nameScopeDivider = '/'; + /** + * Enter namescope, which can be nested. + */ + function nameScope(name, fn) { + _nameScopeStack.push(name); + try { + const val = fn(); + _nameScopeStack.pop(); + return val; + } + catch (e) { + _nameScopeStack.pop(); + throw e; + } + } + /** + * Get the current namescope as a flat, concatenated string. + */ + function currentNameScopePrefix() { + if (_nameScopeStack.length === 0) { + return ''; + } + else { + return _nameScopeStack.join(_nameScopeDivider) + _nameScopeDivider; + } + } + /** + * Get the name a Tensor (or Variable) would have if not uniqueified. + * @param tensorName + * @return Scoped name string. + */ + function getScopedTensorName(tensorName) { + if (!isValidTensorName(tensorName)) { + throw new Error('Not a valid tensor name: \'' + tensorName + '\''); + } + return currentNameScopePrefix() + tensorName; + } + /** + * Get unique names for Tensors and Variables. + * @param scopedName The fully-qualified name of the Tensor, i.e. as produced by + * `getScopedTensorName()`. + * @return A unique version of the given fully scoped name. + * If this is the first time that the scoped name is seen in this session, + * then the given `scopedName` is returned unaltered. If the same name is + * seen again (producing a collision), an incrementing suffix is added to the + * end of the name, so it takes the form 'scope/name_1', 'scope/name_2', etc. + */ + function getUniqueTensorName(scopedName) { + if (!isValidTensorName(scopedName)) { + throw new Error('Not a valid tensor name: \'' + scopedName + '\''); + } + if (!nameMap.has(scopedName)) { + nameMap.set(scopedName, 0); + } + const index = nameMap.get(scopedName); + nameMap.set(scopedName, nameMap.get(scopedName) + 1); + if (index > 0) { + const result = `${scopedName}_${index}`; + // Mark the composed name as used in case someone wants + // to call getUniqueTensorName("name_1"). + nameMap.set(result, 1); + return result; + } + else { + return scopedName; + } + } + const tensorNameRegex = new RegExp(/^[A-Za-z0-9][-A-Za-z0-9\._\/]*$/); + /** + * Determine whether a string is a valid tensor name. + * @param name + * @returns A Boolean indicating whether `name` is a valid tensor name. + */ + function isValidTensorName(name) { + return !!name.match(tensorNameRegex); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Determine if a number is an integer. + */ + function isInteger(x) { + return x === parseInt(x.toString(), 10); + } + /** + * Calculate the product of an array of numbers. + * @param array The array to calculate the product over. + * @param begin Beginning index, inclusive. + * @param end Ending index, exclusive. + * @return The product. + */ + function arrayProd(array, begin, end) { + if (begin == null) { + begin = 0; + } + if (end == null) { + end = array.length; + } + let prod = 1; + for (let i = begin; i < end; ++i) { + prod *= array[i]; + } + return prod; + } + /** + * Compute minimum value. + * @param array + * @return minimum value. + */ + function min$2(array) { + // same behavior as tf.min() + if (array.length === 0) { + return Number.NaN; + } + let min = Number.POSITIVE_INFINITY; + for (let i = 0; i < array.length; i++) { + const value = array[i]; + if (value < min) { + min = value; + } + } + return min; + } + /** + * Compute maximum value. + * @param array + * @return maximum value + */ + function max$2(array) { + // same behavior as tf.max() + if (array.length === 0) { + return Number.NaN; + } + let max = Number.NEGATIVE_INFINITY; + for (let i = 0; i < array.length; i++) { + const value = array[i]; + if (value > max) { + max = value; + } + } + return max; + } + /** + * Compute sum of array. + * @param array + * @return The sum. + */ + function sum$2(array) { + let sum = 0; + for (let i = 0; i < array.length; i++) { + const value = array[i]; + sum += value; + } + return sum; + } + /** + * Compute mean of array. + * @param array + * @return The mean. + */ + function mean$1(array) { + return sum$2(array) / array.length; + } + /** + * Compute variance of array. + * @param array + * @return The variance. + */ + function variance(array) { + const meanValue = mean$1(array); + const demeaned = array.map((value) => value - meanValue); + let sumSquare = 0; + for (let i = 0; i < demeaned.length; i++) { + const value = demeaned[i]; + sumSquare += value * value; + } + return sumSquare / array.length; + } + /** + * Compute median of array. + * @param array + * @return The median value. + */ + function median(array) { + const arraySorted = array.slice().sort((a, b) => a - b); + const lowIdx = Math.floor((arraySorted.length - 1) / 2); + const highIdx = Math.ceil((arraySorted.length - 1) / 2); + if (lowIdx === highIdx) { + return arraySorted[lowIdx]; + } + return (arraySorted[lowIdx] + arraySorted[highIdx]) / 2; + } + /** + * Generate an array of integers in [begin, end). + * @param begin Beginning integer, inclusive. + * @param end Ending integer, exclusive. + * @returns Range array. + * @throws ValueError, iff `end` < `begin`. + */ + function range$2(begin, end) { + if (end < begin) { + throw new ValueError(`end (${end}) < begin (${begin}) is forbidden.`); + } + const out = []; + for (let i = begin; i < end; ++i) { + out.push(i); + } + return out; + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + let _epsilon; + /** + * Returns the value of the fuzz factor used in numeric expressions. + */ + function epsilon$1() { + if (_epsilon == null) { + _epsilon = backend$1().epsilon(); + } + return _epsilon; + } + /** + * Sets the value of the fuzz factor used in numeric expressions. + * @param e New value of epsilon. + */ + function setEpsilon(e) { + _epsilon = e; + } + /** + * Returns the default image data format convention. + */ + function imageDataFormat() { + return 'channelsLast'; + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // tslint:enable + /* Setting and getting backend from deeplearn.js. */ + // Default deeplearn.js backend is WebGL (GPU). + let backend = 'webgl'; + function setBackend(requestedBackend) { + setBackend$1(requestedBackend); + backend = requestedBackend; + } + function getBackend() { + return backend; + } + /** + * Indicates whether the backend is operating symbolically. + * + * This function will be used to determine how to interpret user code. If + * it returns true, calls to the backend construct a symbolic graph; if + * it returns false, calls to the backend execute immediately. + */ + function isBackendSymbolic() { + return false; + } + /** + * Get the number of elements in a Tensor. + * @param x The Tensor. + * @return Number of elements in `x`. + */ + function countParams(x) { + const shape = x.shape; + if (shape.length > 0) { + return shape.reduce((a, b) => a * b); + } + else { + // Scalar. + return 1; + } + } + /** + * Casts a tensor to a different dtype and returns it. + * @param x Input tensor. + * @param dtype String: 'float32'|'int32'|'bool'. + * @returns Tensor of the specified `dtype`. + */ + function cast$2(x, dtype) { + return cast$3(x, dtype); + } + /** + * Adds a 1-sized dimension at index "axis". + * @param x Input tensor. + * @param axis Position where to add the new axis. + * @returns Result of the dimension expansion. + */ + function expandDims$2(x, axis = -1) { + const outShape = x.shape.slice(); + if (axis < 0) { + axis = outShape.length + axis + 1; + } + outShape.splice(axis, 0, 1); + return reshape$3(x, outShape); + } + /** + * Repeats a 2D tensor. + * + * If `x` has shape `[samples, dim]` and `n` is 2, for example, the output + * will have shape `[samples, 2, dim]`. + * + * @param x Input tensor. + * @param n Integer, number of times to repeat. + * @returns The result of the repeat operation. + * @throws ValueError: If input tensor is not 2D. + */ + function repeat(x, n) { + return tidy(() => { + if (x.shape.length !== 2) { + throw new ValueError(`repeat() expects a rank-2 tensor, but received a ` + + `rank-${x.shape.length} tensor.`); + } + const y = expandDims$2(x, 1); + return tile$2(y, [1, n, 1]); + }); + } + /** + * Flatten a Tensor into 1D. + * @param x Input tensor. + * @return The result of the flattening `x`. + */ + function flatten$1(x) { + const newShape = [arrayProd(x.shape)]; + return reshape$3(x, newShape); + } + /** + * Turn a nD tensor into a 2D tensor with same 0th dimension. + * In other words, it flattens each data samples of a batch. + * + * @param x The tensor to flatten. The rank of this tensor is required to be 2 + * or higher. + * @return The result of the flattening. + */ + function batchFlatten(x) { + if (x.rank <= 1) { + throw new ValueError(`batchFlatten requires a minimum rank of 2. Got rank: ${x.rank}.`); + } + const newShape = [x.shape[0], arrayProd(x.shape, 1)]; + return reshape$3(x, newShape); + } + /** + * Do slicing along the first axis. + * @param array input `tf.Tensor`. + * @param start starting index, inclusive. + * @param size size of the slice along the first axis. + * @returns result of the slicing. + * @throws ValueError: If `array` is of an unsupported subtype of `tf.Tensor`. + */ + function sliceAlongFirstAxis(array, start, size) { + return tidy(() => { + switch (array.rank) { + case 1: + return slice1d(array, start, size); + case 2: + return slice2d(array, [start, 0], [size, array.shape[1]]); + case 3: + return slice3d(array, [start, 0, 0], [size, array.shape[1], array.shape[2]]); + case 4: + return slice4d(array, [start, 0, 0, 0], [size, array.shape[1], array.shape[2], array.shape[3]]); + case 5: + return slice$2(array, [start, 0, 0, 0, 0], [ + size, array.shape[1], array.shape[2], array.shape[3], array.shape[4] + ]); + case 6: + return slice$2(array, [start, 0, 0, 0, 0, 0], [ + size, array.shape[1], array.shape[2], array.shape[3], array.shape[4], + array.shape[5] + ]); + default: + throw new ValueError(`sliceAlongFirstAxis() received an unsupported tensor rank: ` + + `${array.rank}`); + } + }); + } + /** + * Do slicing along the last axis. + * @param array input `tf.Tensor`. + * @param start starting index, inclusive. + * @param size size of the slice along the last axis. + * @returns result of the slicing. + * @throws ValueError: If `array` is of an unsupported subtype of `tf.Tensor`. + */ + function sliceAlongLastAxis(array, start, size) { + return tidy(() => { + switch (array.rank) { + case 1: + return slice1d(array, start, size); + case 2: + return slice2d(array, [0, start], [array.shape[0], size]); + case 3: + return slice3d(array, [0, 0, start], [array.shape[0], array.shape[1], size]); + case 4: + return slice4d(array, [0, 0, 0, start], [array.shape[0], array.shape[1], array.shape[2], size]); + default: + throw new ValueError(`sliceAlongLastAxis() received an unsupported tensor rank: ` + + `${array.rank}`); + } + }); + } + /** + * Do slicing along the sepcified axis. + * @param array input `tf.Tensor`. + * @param start starting index, inclusive. + * @param size of the slice along the chosen axis. + * @param choose an axis. + * @returns result of the slicing. + * @throws ValueError: If `array` is of an unsupported subtype of `tf.Tensor`. + */ + function sliceAlongAxis(array, start, size, axis) { + return tidy(() => { + switch (array.rank) { + case 1: + return slice1d(array, start, size); + case 2: + switch (axis) { + case 1: + return sliceAlongFirstAxis(array, start, size); + case 2: + return sliceAlongLastAxis(array, start, size); + default: + throw new ValueError(`The axis is not within the rank of the tensor ` + + `${axis}`); + } + case 3: + switch (axis) { + case 1: + return sliceAlongFirstAxis(array, start, size); + case 2: + return slice3d(array, [0, start, 0], [array.shape[0], size, array.shape[2]]); + case 3: + return sliceAlongLastAxis(array, start, size); + default: + throw new ValueError(`The axis is not within the rank of the tensor ` + + `${axis}`); + } + case 4: + switch (axis) { + case 1: + return sliceAlongFirstAxis(array, start, size); + case 2: + return slice4d(array, [0, start, 0, 0], [array.shape[0], size, array.shape[2], array.shape[3]]); + case 3: + return slice4d(array, [0, 0, start, 0], [array.shape[0], array.shape[1], size, array.shape[3]]); + case 4: + return sliceAlongLastAxis(array, start, size); + default: + throw new ValueError(`The axis is not within the rank of the tensor ` + + `${axis}`); + } + default: + throw new ValueError(`sliceAlongLastAxis() received an unsupported tensor rank: ` + + `${array.rank}`); + } + }); + } + /** + * Concatenates a list of tensors alongside the specified axis. + * @param tensors `Array` of tensors to concatenate. + * @param axis Concatenation axis. + * @returns The result of the concatenation. + */ + function concatenate$2(tensors, axis = -1) { + let rank; + if (axis < 0) { + rank = tensors[0].rank; + if (rank !== 0) { + axis = rank; + } + else { + axis = 0; + } + } + if (axis === tensors[0].rank) { + // Porting Note: This is necessary because tfc.concat() requires axis to be + // in the interval [-rank, rank). + axis = -1; + } + // Porting Note: Sparse concat is not supported yet. + return concat$2(tensors, axis); + } + /** + * Concatenate two arrays along the first dimension. + * @param a The 1st `tf.Tensor` to concatenate. + * @param b The 2nd `tf.Tensor` to concatenate. + * @returns Result of the concatenation. + * @throws ValueError: If `a` is of an unsupported subtype of `tf.Tensor`. + */ + function concatAlongFirstAxis(a, b) { + switch (a.rank) { + case 1: + return concat1d([a, b]); + case 2: + return concat2d([a, b], 0); + case 3: + return concat3d([a, b], 0); + case 4: + return concat4d([a, b], 0); + default: + throw new ValueError(`concatAlongFirstAxis() received an unsupported ` + + `tensor rank: ${a.rank}`); + } + } + /** + * Creates a tensor by tiling `x` by `n`. + * @param x A tensor. + * @param n An Array of integers or a single integer. If an Array, the length + * must be the same as the number of dimensions in `x`. If a single integer, + * it will be treated as an Array of length 1. + */ + function tile$2(x, n) { + if (!Array.isArray(n)) { + n = [n]; + } + if (x.rank !== n.length) { + throw new ValueError(`The length of input n (${n.length}) does not match ` + + `the number of dimensions in input x (${x.rank})`); + } + return tile$3(x, n); + } + /* Creation of random tensors. */ + /** + * Get a tensor with normal distribution of values. + * + * @param shape Shape of the tensor. + * @param mean mean value of the normal distribution. + * @param stddev standard deviation of the normal distribution. + * @param dtype + * @param seed + * @return The normal tensor. + */ + function randomNormal$1(shape, mean = 0.0, stddev = 1.0, dtype, seed) { + return randomNormal$2(shape, mean, stddev, dtype, seed); + } + /* Linear Algebra */ + /** + * Multiply two tensors and returns the result as a tensor. + * + * For 2D tensors, this is equivalent to matrix multiplication (matMul). + * For tensors of higher ranks, it follows the Theano behavior, + * (e.g. `(2, 3) * (4, 3, 5) -> (2, 4, 5)`). From the Theano documentation: + * + * For N dimensions it is a sum product over the last axis of x and the + * second-to-last of y: + * + * @param a A tensor of at least rank 2. + * @param b A tensor of at least rank 2. + * @param activation (optional) A string identifying the activation + * function. + * @return Result of the dot operation. + */ + function dot$1(a, b, activation, bias) { + if ((a.rank < 2) || (b.rank < 2)) { + throw new NotImplementedError(`dot requires both inputs to be rank >= 2` + + ` but got x shape = ${a.shape} and y shape = ${b.shape}`); + } + if (b.rank >= 3) { + const xLastDim = a.shape.slice(-1)[0]; + const ySecondLastDim = b.shape.slice(-2)[0]; + if (xLastDim !== ySecondLastDim) { + throw new NotImplementedError(`If rank y >= 3, then the second last dim` + + ` of y must equal the last dim of x but got x shape = ${a.shape} and ` + + ` y shape = ${b.shape}`); + } + } + // Handle basic 2D x 2D case. + if ((a.rank === 2) && (b.rank === 2)) { + const transposeA = false; + const transposeB = false; + // tfc.fused.matMul only fuses certain activation functions. Unsupported + // activation functions are treated as 'linear' activations, which is + // equivalent to a no-op. + return matMul({ + a, + b: b, + transposeA, + transposeB, + bias: bias ? reshapeBias(a.rank, bias, imageDataFormat()) : null, + activation + }); + } + else { + // Reshape x into the analogous 2D Tensor. + const aFirstDims = a.shape.slice(); // Holds all but the last dim of x. + const aLastDim = aFirstDims.pop(); + a = reshape$3(a, [-1, aLastDim]); + // Reshape y into the analogous 2D Tensor, and keep track of the + // required dimensions to reproduce the output shape. + const bShape = b.shape.slice(); + const bLastDim = bShape.pop(); + const ySecondLastDim = bShape.pop(); + const yOtherDims = [...bShape, bLastDim]; + // permutation should be like [r-2, 0, 1, 2, ... r-4, r-3, r-1] + // where r is the rank of y. + const perm = Array.from({ length: b.rank }, (_, i) => { + if (i === 0) { + return b.rank - 2; + } + else if (i <= b.rank - 2) { + return i - 1; + } + return i; + }); + b = reshape$3(transpose$2(b, perm), [ySecondLastDim, -1]); + // Multiply x and y as 2D Tensors, and then reshape back to original. + const outputShape = [...aFirstDims, ...yOtherDims]; + const transposeA = false; + const transposeB = false; + return reshape$3(matMul({ + a, + b, + transposeA, + transposeB, + bias: bias ? reshapeBias(a.rank, bias, imageDataFormat()) : null, + activation + }), outputShape); + } + } + /** + * Compute the sign Tensor of an input Tensor. + * + * Elements of the input `tf.Tensor` that are === 0 are mapped to 0. + * Elements of the input `tf.Tensor` that are > 0 are mapped to 1. + * Elements of the input `tf.Tensor` that are < 0 are mapped to -1. + * + * @param x Input `tf.Tensor`. + * @return The sign `tf.Tensor`. + */ + function sign$2(x) { + // TODO(cais): Move to the core. + return tidy(() => { + const zerosLikeX = zerosLike$3(x); + const onesLikeX = onesLike$3(x); + return where(equal$2(x, zerosLikeX), zerosLikeX, where(greater$3(x, zerosLike$3(x)), onesLikeX, mul(-1, onesLikeX))); + }); + } + /** + * Computes the one-hot representation of an integer tensor. + * @param indices nD integer tensor of shape + * `(batch_size, dim1, dim2, ... dim(n-1))` + * @param numClasses Integer, number of classes to consider. + * @returns (n + 1)D one hot representation of the input + * with shape `(batch_size, dim1, dim2, ... dim(n-1), num_classes)` + */ + function oneHot$2(indices, numClasses) { + return tidy(() => { + if (indices.rank !== 1) { + throw new Error('Only 1D one-hot tensors are supported in the ' + + 'deeplearn backend, at present.'); + } + indices = cast$3(indices, 'int32'); + return cast$3(oneHot$3(indices, numClasses), 'float32'); + }); + } + /* Elementary math functions. */ + /** + * Retrieves the elements of indices `indices` in the tensor `reference`. + * @param reference A tensor. + * @param indices An integer tensor of indices or an `Array` of integers. + * @param axis Axis along which to perform the gather operation. + * @returns The result of the gathering as a tensor. + */ + function gather(reference, indices, axis) { + return tidy(() => { + if (Array.isArray(indices)) { + indices = tensor1d(indices, 'int32'); + } + else { + indices = cast$3(indices, 'int32'); + } + return gather$1(reference, indices, axis); + }); + } + /** + * Element-wise square. + * @param x Input tensor. + * @return element-wise x^2 + */ + function square$1(x) { + return mul(x, x); + } + /** + * Element-wise exponentiation. + * + * Porting Note: In PyKeras, `a` (the exponent) is a Python integer, which + * takes advatnage of the backend's (e.g., TensorFlow's) automatic + * conversion to tensor. Here we allow `a` to be either a number or a tensor. + * + * @param x The base tensor. + * @param a The exponent, tensor or number. If a number, it is rounded to the + * nearest integer and converted to a tensor. + * @returns A tensor of the same shape as `x`. + */ + function pow$2(x, a) { + return tidy(() => { + if (typeof (a) === 'number') { + a = scalar(Math.round(a), 'int32'); + } + if (a.dtype !== 'int32') { + throw new NotImplementedError(`Non-int32 dtype (${a.dtype}) is not supported by pow() yet`); + } + return pow$3(x, a); + }); + } + /** + * Reshapes bias tensor according to rank of x. + */ + function reshapeBias(xRank, bias, dataFormat) { + const biasShape = bias.shape; + if (bias.rank !== 1 && bias.rank !== xRank) { + throw new ValueError(`Unexpected bias dimensions: ${bias.rank}` + + `; expected it to be 1 or ${xRank}`); + } + if (xRank === 5) { + if (dataFormat === 'channelsFirst') { + if (biasShape.length === 1) { + return reshape$3(bias, [1, biasShape[0], 1, 1, 1]); + } + else { + return reshape$3(bias, [1, biasShape[3], biasShape[0], biasShape[1], biasShape[2]]); + } + } + else if (dataFormat === 'channelsLast') { + if (biasShape.length === 1) { + return reshape$3(bias, [1, 1, 1, 1, biasShape[0]]); + } + else { + return reshape$3(bias, [1].concat(biasShape)); + } + } + } + else if (xRank === 4) { + if (dataFormat === 'channelsFirst') { + if (biasShape.length === 1) { + return reshape$3(bias, [1, biasShape[0], 1, 1]); + } + else { + return reshape$3(bias, [1, biasShape[2], biasShape[0], biasShape[1]]); + } + } + else if (dataFormat === 'channelsLast') { + if (biasShape.length === 1) { + return reshape$3(bias, [1, 1, 1, biasShape[0]]); + } + else { + return reshape$3(bias, [1].concat(biasShape)); + } + } + } + else if (xRank === 3) { + if (dataFormat === 'channelsFirst') { + if (biasShape.length === 1) { + return reshape$3(bias, [1, biasShape[0], 1]); + } + else { + return reshape$3(bias, [1, biasShape[1], biasShape[0]]); + } + } + else if (dataFormat === 'channelsLast') { + if (biasShape.length === 1) { + return reshape$3(bias, [1, 1, biasShape[0]]); + } + else { + return reshape$3(bias, [1].concat(biasShape)); + } + } + } + else if (xRank < 3) { + return bias; + } + throw new ValueError(`Unsupported input rank by biasAdd: ${bias.rank}`); + } + /* Neural-network operations. */ + /** + * Add a bias to a tensor. + * + * @param x The tensor to add the bias to. + * @param bias The bias to add to `x`. Must be 1D or the same rank as `x`. + * @return Result of the bias adding. + * @throws ValueError: If the rank of `bias` is incorrect. + */ + function biasAdd(x, bias, dataFormat) { + return tidy(() => { + if (dataFormat == null) { + dataFormat = imageDataFormat(); + } + checkDataFormat(dataFormat); + return add$3(x, reshapeBias(x.rank, bias, dataFormat)); + }); + } + /** + * Exponential linear unit (ELU). + * @param x A tensor or variable to compute the activation function for. + * @param alpha: A scalar, a scaling factor for the negative section. + * @return Output of the ELU operation. + */ + function elu$3(x, alpha = 1) { + // TODO(cais): Add support for alpha values other than 1. + if (alpha !== 1) { + throw new NotImplementedError(`Support for alpha values other than 1 (${alpha}) is not implemented ` + + `yet.`); + } + return elu$4(x); + } + /** + * Softsign of a tensor. + * + * Defined as x / (abs(x) + 1), element-wise. + * + * @param x: Input. + * @returns Output. + */ + function softsign(x) { + return tidy(() => div$1(x, add$3(abs$2(x), 1))); + } + /** + * Sets entries in `x` to zero at random, while scaling the entire tensor. + * + * @param x input tensor. + * @param level fraction of the entries in the tensor that will be set to 0. + * @param noiseShape shape of randomly generated keep/drop flags, must be + * broadcastable to the shape of `x`. Optional. + * @param seed random seed to ensure determinism. Optional. + * @returns Result of the dropout operation. + */ + function dropout$1(x, level, noiseShape, seed) { + return tidy(() => dropout$2(x, level, noiseShape, seed)); + } + /** + * Element-wise, segment-wise linear approximation of sigmoid. + * + * Returns `0.` if `x < -2.5`, `1.` if `x > 2.5`. + * In `-2.5 <= x <= 2.5`, returns `0.2 * x + 0.5`. + * + * @param x Input tensor. + * @returns Output tensor. + */ + function hardSigmoid(x) { + return tidy(() => { + const y = add$3(.5, mul(.2, x)); + return clipByValue$2(y, 0, 1); + }); + } + /** + * Invoke `x` in the training phase, and `alt` otherwise. + * + * Porting Note: We do not create placeholder tensors for the `training` + * boolean flag here, because there is no such thing in the TF.js imperative + * backend. + * + * @param x The function to invoke iff `training` is `true`. + * @param alt The function to invoke iff `training` is `false`. + * @param training Boolean flag for whether training phase is active. + * @returns The return value of `x()` if `training` is `true`, or the return + * value of `alt()` if `training` is `false`. + */ + function inTrainPhase(x, alt, training = false) { + return training ? x() : alt(); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + const VALID_FAN_MODE_VALUES = ['fanIn', 'fanOut', 'fanAvg']; + const VALID_DISTRIBUTION_VALUES = ['normal', 'uniform', 'truncatedNormal']; + // We can't easily extract a string[] from the string union type, but we can + // recapitulate the list, enforcing at compile time that the values are valid + // and that we have the right number of them. + /** + * A string array of valid Initializer class names. + * + * This is guaranteed to match the `InitializerClassName` union type. + */ + const initializerClassNames = [ + 'Zeros', 'Ones', 'Constant', 'RandomNormal', 'RandomUniform', + 'TruncatedNormal', 'VarianceScaling', 'Orthogonal', 'Identity' + ]; + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + function checkFanMode(value) { + checkStringTypeUnionValue(VALID_FAN_MODE_VALUES, 'FanMode', value); + } + function checkDistribution(value) { + checkStringTypeUnionValue(VALID_DISTRIBUTION_VALUES, 'Distribution', value); + } + /** + * Initializer base class. + * + * @doc { + * heading: 'Initializers', subheading: 'Classes', namespace: 'initializers'} + */ + class Initializer extends Serializable { + fromConfigUsesCustomObjects() { + return false; + } + getConfig() { + return {}; + } + } + class Zeros extends Initializer { + apply(shape, dtype) { + return zeros$2(shape, dtype); + } + } + /** @nocollapse */ + Zeros.className = 'Zeros'; + registerClass(Zeros); + class Ones extends Initializer { + apply(shape, dtype) { + return ones$1(shape, dtype); + } + } + /** @nocollapse */ + Ones.className = 'Ones'; + registerClass(Ones); + class Constant extends Initializer { + constructor(args) { + super(); + if (typeof args !== 'object') { + throw new ValueError(`Expected argument of type ConstantConfig but got ${args}`); + } + if (args.value === undefined) { + throw new ValueError(`config must have value set but got ${args}`); + } + this.value = args.value; + } + apply(shape, dtype) { + return tidy(() => mul(scalar(this.value), ones$1(shape, dtype))); + } + getConfig() { + return { + value: this.value, + }; + } + } + /** @nocollapse */ + Constant.className = 'Constant'; + registerClass(Constant); + class RandomUniform extends Initializer { + constructor(args) { + super(); + this.DEFAULT_MINVAL = -0.05; + this.DEFAULT_MAXVAL = 0.05; + this.minval = args.minval || this.DEFAULT_MINVAL; + this.maxval = args.maxval || this.DEFAULT_MAXVAL; + this.seed = args.seed; + } + apply(shape, dtype) { + return randomUniform$1(shape, this.minval, this.maxval, dtype, this.seed); + } + getConfig() { + return { minval: this.minval, maxval: this.maxval, seed: this.seed }; + } + } + /** @nocollapse */ + RandomUniform.className = 'RandomUniform'; + registerClass(RandomUniform); + class RandomNormal extends Initializer { + constructor(args) { + super(); + this.DEFAULT_MEAN = 0.; + this.DEFAULT_STDDEV = 0.05; + this.mean = args.mean || this.DEFAULT_MEAN; + this.stddev = args.stddev || this.DEFAULT_STDDEV; + this.seed = args.seed; + } + apply(shape, dtype) { + dtype = dtype || 'float32'; + if (dtype !== 'float32' && dtype !== 'int32') { + throw new NotImplementedError(`randomNormal does not support dType ${dtype}.`); + } + return randomNormal$1(shape, this.mean, this.stddev, dtype, this.seed); + } + getConfig() { + return { mean: this.mean, stddev: this.stddev, seed: this.seed }; + } + } + /** @nocollapse */ + RandomNormal.className = 'RandomNormal'; + registerClass(RandomNormal); + class TruncatedNormal extends Initializer { + constructor(args) { + super(); + this.DEFAULT_MEAN = 0.; + this.DEFAULT_STDDEV = 0.05; + this.mean = args.mean || this.DEFAULT_MEAN; + this.stddev = args.stddev || this.DEFAULT_STDDEV; + this.seed = args.seed; + } + apply(shape, dtype) { + dtype = dtype || 'float32'; + if (dtype !== 'float32' && dtype !== 'int32') { + throw new NotImplementedError(`truncatedNormal does not support dType ${dtype}.`); + } + return truncatedNormal$1(shape, this.mean, this.stddev, dtype, this.seed); + } + getConfig() { + return { mean: this.mean, stddev: this.stddev, seed: this.seed }; + } + } + /** @nocollapse */ + TruncatedNormal.className = 'TruncatedNormal'; + registerClass(TruncatedNormal); + class Identity extends Initializer { + constructor(args) { + super(); + this.gain = args.gain != null ? args.gain : 1.0; + } + apply(shape, dtype) { + return tidy(() => { + if (shape.length !== 2 || shape[0] !== shape[1]) { + throw new ValueError('Identity matrix initializer can only be used for' + + ' 2D square matrices.'); + } + else { + return mul(this.gain, eye(shape[0])); + } + }); + } + getConfig() { + return { gain: this.gain }; + } + } + /** @nocollapse */ + Identity.className = 'Identity'; + registerClass(Identity); + /** + * Computes the number of input and output units for a weight shape. + * @param shape Shape of weight. + * @param dataFormat data format to use for convolution kernels. + * Note that all kernels in Keras are standardized on the + * CHANNEL_LAST ordering (even when inputs are set to CHANNEL_FIRST). + * @return An length-2 array: fanIn, fanOut. + */ + function computeFans(shape, dataFormat = 'channelsLast') { + let fanIn; + let fanOut; + checkDataFormat(dataFormat); + if (shape.length === 2) { + fanIn = shape[0]; + fanOut = shape[1]; + } + else if ([3, 4, 5].indexOf(shape.length) !== -1) { + if (dataFormat === 'channelsFirst') { + const receptiveFieldSize = arrayProd(shape, 2); + fanIn = shape[1] * receptiveFieldSize; + fanOut = shape[0] * receptiveFieldSize; + } + else if (dataFormat === 'channelsLast') { + const receptiveFieldSize = arrayProd(shape, 0, shape.length - 2); + fanIn = shape[shape.length - 2] * receptiveFieldSize; + fanOut = shape[shape.length - 1] * receptiveFieldSize; + } + } + else { + const shapeProd = arrayProd(shape); + fanIn = Math.sqrt(shapeProd); + fanOut = Math.sqrt(shapeProd); + } + return [fanIn, fanOut]; + } + class VarianceScaling extends Initializer { + /** + * Constructor of VarianceScaling. + * @throws ValueError for invalid value in scale. + */ + constructor(args) { + super(); + if (args.scale < 0.0) { + throw new ValueError(`scale must be a positive float. Got: ${args.scale}`); + } + this.scale = args.scale == null ? 1.0 : args.scale; + this.mode = args.mode == null ? 'fanIn' : args.mode; + checkFanMode(this.mode); + this.distribution = + args.distribution == null ? 'normal' : args.distribution; + checkDistribution(this.distribution); + this.seed = args.seed; + } + apply(shape, dtype) { + const fans = computeFans(shape); + const fanIn = fans[0]; + const fanOut = fans[1]; + let scale = this.scale; + if (this.mode === 'fanIn') { + scale /= Math.max(1, fanIn); + } + else if (this.mode === 'fanOut') { + scale /= Math.max(1, fanOut); + } + else { + scale /= Math.max(1, (fanIn + fanOut) / 2); + } + if (this.distribution === 'normal') { + const stddev = Math.sqrt(scale); + dtype = dtype || 'float32'; + if (dtype !== 'float32' && dtype !== 'int32') { + throw new NotImplementedError(`${this.getClassName()} does not support dType ${dtype}.`); + } + return truncatedNormal$1(shape, 0, stddev, dtype, this.seed); + } + else { + const limit = Math.sqrt(3 * scale); + return randomUniform$1(shape, -limit, limit, dtype, this.seed); + } + } + getConfig() { + return { + scale: this.scale, + mode: this.mode, + distribution: this.distribution, + seed: this.seed + }; + } + } + /** @nocollapse */ + VarianceScaling.className = 'VarianceScaling'; + registerClass(VarianceScaling); + class GlorotUniform extends VarianceScaling { + /** + * Constructor of GlorotUniform + * @param scale + * @param mode + * @param distribution + * @param seed + */ + constructor(args) { + super({ + scale: 1.0, + mode: 'fanAvg', + distribution: 'uniform', + seed: args == null ? null : args.seed + }); + } + getClassName() { + // In Python Keras, GlorotUniform is not a class, but a helper method + // that creates a VarianceScaling object. Use 'VarianceScaling' as + // class name to be compatible with that. + return VarianceScaling.className; + } + } + /** @nocollapse */ + GlorotUniform.className = 'GlorotUniform'; + registerClass(GlorotUniform); + class GlorotNormal extends VarianceScaling { + /** + * Constructor of GlorotNormal. + * @param scale + * @param mode + * @param distribution + * @param seed + */ + constructor(args) { + super({ + scale: 1.0, + mode: 'fanAvg', + distribution: 'normal', + seed: args == null ? null : args.seed + }); + } + getClassName() { + // In Python Keras, GlorotNormal is not a class, but a helper method + // that creates a VarianceScaling object. Use 'VarianceScaling' as + // class name to be compatible with that. + return VarianceScaling.className; + } + } + /** @nocollapse */ + GlorotNormal.className = 'GlorotNormal'; + registerClass(GlorotNormal); + class HeNormal extends VarianceScaling { + constructor(args) { + super({ + scale: 2.0, + mode: 'fanIn', + distribution: 'normal', + seed: args == null ? null : args.seed + }); + } + getClassName() { + // In Python Keras, HeNormal is not a class, but a helper method + // that creates a VarianceScaling object. Use 'VarianceScaling' as + // class name to be compatible with that. + return VarianceScaling.className; + } + } + /** @nocollapse */ + HeNormal.className = 'HeNormal'; + registerClass(HeNormal); + class HeUniform extends VarianceScaling { + constructor(args) { + super({ + scale: 2.0, + mode: 'fanIn', + distribution: 'uniform', + seed: args == null ? null : args.seed + }); + } + getClassName() { + // In Python Keras, HeUniform is not a class, but a helper method + // that creates a VarianceScaling object. Use 'VarianceScaling' as + // class name to be compatible with that. + return VarianceScaling.className; + } + } + /** @nocollapse */ + HeUniform.className = 'HeUniform'; + registerClass(HeUniform); + class LeCunNormal extends VarianceScaling { + constructor(args) { + super({ + scale: 1.0, + mode: 'fanIn', + distribution: 'normal', + seed: args == null ? null : args.seed + }); + } + getClassName() { + // In Python Keras, LeCunNormal is not a class, but a helper method + // that creates a VarianceScaling object. Use 'VarianceScaling' as + // class name to be compatible with that. + return VarianceScaling.className; + } + } + /** @nocollapse */ + LeCunNormal.className = 'LeCunNormal'; + registerClass(LeCunNormal); + class LeCunUniform extends VarianceScaling { + constructor(args) { + super({ + scale: 1.0, + mode: 'fanIn', + distribution: 'uniform', + seed: args == null ? null : args.seed + }); + } + getClassName() { + // In Python Keras, LeCunUniform is not a class, but a helper method + // that creates a VarianceScaling object. Use 'VarianceScaling' as + // class name to be compatible with that. + return VarianceScaling.className; + } + } + /** @nocollapse */ + LeCunUniform.className = 'LeCunUniform'; + registerClass(LeCunUniform); + class Orthogonal extends Initializer { + constructor(args) { + super(); + this.DEFAULT_GAIN = 1; + this.ELEMENTS_WARN_SLOW = 2000; + this.gain = args.gain == null ? this.DEFAULT_GAIN : args.gain; + this.seed = args.seed; + } + apply(shape, dtype) { + return tidy(() => { + if (shape.length < 2) { + throw new NotImplementedError('Shape must be at least 2D.'); + } + if (dtype !== 'int32' && dtype !== 'float32' && dtype !== undefined) { + throw new TypeError(`Unsupported data type ${dtype}.`); + } + dtype = dtype; + // flatten the input shape with the last dimension remaining its + // original shape so it works for conv2d + const numRows = sizeFromShape(shape.slice(0, -1)); + const numCols = shape[shape.length - 1]; + const numElements = numRows * numCols; + if (numElements > this.ELEMENTS_WARN_SLOW) { + console.warn(`Orthogonal initializer is being called on a matrix with more ` + + `than ${this.ELEMENTS_WARN_SLOW} (${numElements}) elements: ` + + `Slowness may result.`); + } + const flatShape = [Math.max(numCols, numRows), Math.min(numCols, numRows)]; + // Generate a random matrix + const randNormalMat = randomNormal$1(flatShape, 0, 1, dtype, this.seed); + // Compute QR factorization + const qr = linalg.qr(randNormalMat, false); + let qMat = qr[0]; + const rMat = qr[1]; + // Make Q uniform + const diag = rMat.flatten().stridedSlice([0], [Math.min(numCols, numRows) * Math.min(numCols, numRows)], [Math.min(numCols, numRows) + 1]); + qMat = mul(qMat, diag.sign()); + if (numRows < numCols) { + qMat = qMat.transpose(); + } + return mul(scalar(this.gain), qMat.reshape(shape)); + }); + } + getConfig() { + return { + gain: this.gain, + seed: this.seed, + }; + } + } + /** @nocollapse */ + Orthogonal.className = 'Orthogonal'; + registerClass(Orthogonal); + // Maps the JavaScript-like identifier keys to the corresponding registry + // symbols. + const INITIALIZER_IDENTIFIER_REGISTRY_SYMBOL_MAP = { + 'constant': 'Constant', + 'glorotNormal': 'GlorotNormal', + 'glorotUniform': 'GlorotUniform', + 'heNormal': 'HeNormal', + 'heUniform': 'HeUniform', + 'identity': 'Identity', + 'leCunNormal': 'LeCunNormal', + 'leCunUniform': 'LeCunUniform', + 'ones': 'Ones', + 'orthogonal': 'Orthogonal', + 'randomNormal': 'RandomNormal', + 'randomUniform': 'RandomUniform', + 'truncatedNormal': 'TruncatedNormal', + 'varianceScaling': 'VarianceScaling', + 'zeros': 'Zeros' + }; + function deserializeInitializer(config, customObjects = {}) { + return deserializeKerasObject(config, SerializationMap.getMap().classNameMap, customObjects, 'initializer'); + } + function serializeInitializer(initializer) { + return serializeKerasObject(initializer); + } + function getInitializer(identifier) { + if (typeof identifier === 'string') { + const className = identifier in INITIALIZER_IDENTIFIER_REGISTRY_SYMBOL_MAP ? + INITIALIZER_IDENTIFIER_REGISTRY_SYMBOL_MAP[identifier] : + identifier; + /* We have four 'helper' classes for common initializers that + all get serialized as 'VarianceScaling' and shouldn't go through + the deserializeInitializer pathway. */ + if (className === 'GlorotNormal') { + return new GlorotNormal(); + } + else if (className === 'GlorotUniform') { + return new GlorotUniform(); + } + else if (className === 'HeNormal') { + return new HeNormal(); + } + else if (className === 'HeUniform') { + return new HeUniform(); + } + else if (className === 'LeCunNormal') { + return new LeCunNormal(); + } + else if (className === 'LeCunUniform') { + return new LeCunUniform(); + } + else { + const config = {}; + config['className'] = className; + config['config'] = {}; + return deserializeInitializer(config); + } + } + else if (identifier instanceof Initializer) { + return identifier; + } + else { + return deserializeInitializer(identifier); + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // tslint:enable + /** + * Determine whether the input is an Array of Shapes. + */ + function isArrayOfShapes(x) { + return Array.isArray(x) && Array.isArray(x[0]); + } + /** + * Special case of normalizing shapes to lists. + * + * @param x A shape or list of shapes to normalize into a list of Shapes. + * @return A list of Shapes. + */ + function normalizeShapeList(x) { + if (x.length === 0) { + return []; + } + if (!Array.isArray(x[0])) { + return [x]; + } + return x; + } + /** + * Helper function to obtain exactly one Tensor. + * @param xs: A single `tf.Tensor` or an `Array` of `tf.Tensor`s. + * @return A single `tf.Tensor`. If `xs` is an `Array`, return the first one. + * @throws ValueError: If `xs` is an `Array` and its length is not 1. + */ + function getExactlyOneTensor(xs) { + let x; + if (Array.isArray(xs)) { + if (xs.length !== 1) { + throw new ValueError(`Expected Tensor length to be 1; got ${xs.length}`); + } + x = xs[0]; + } + else { + x = xs; + } + return x; + } + /** + * Helper function to obtain exactly on instance of Shape. + * + * @param shapes Input single `Shape` or Array of `Shape`s. + * @returns If input is a single `Shape`, return it unchanged. If the input is + * an `Array` containing exactly one instance of `Shape`, return the instance. + * Otherwise, throw a `ValueError`. + * @throws ValueError: If input is an `Array` of `Shape`s, and its length is not + * 1. + */ + function getExactlyOneShape(shapes) { + if (Array.isArray(shapes) && Array.isArray(shapes[0])) { + if (shapes.length === 1) { + shapes = shapes; + return shapes[0]; + } + else { + throw new ValueError(`Expected exactly 1 Shape; got ${shapes.length}`); + } + } + else { + return shapes; + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Count the elements in an Array of LayerVariables. + * + * @param weights: The LayerVariables of which the constituent numbers are to + * be counted. + * @returns A count of the elements in all the LayerVariables + */ + function countParamsInWeights(weights) { + let count = 0; + for (const weight of weights) { + if (weight.shape.length === 0) { + count += 1; + } + else { + count += weight.shape.reduce((a, b) => a * b); + } + } + return count; + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + const DEFAULT_VARIABLE_NAME_PREFIX = 'Variable'; + /** + * A `tf.layers.LayerVariable` is similar to a `tf.Tensor` in that it has a + * dtype and shape, but its value is mutable. The value is itself represented + * as a`tf.Tensor`, and can be read with the `read()` method and updated with + * the `write()` method. + */ + class LayerVariable { + /** + * Construct Variable from a `tf.Tensor`. + * + * If not explicitly named, the Variable will be given a name with the + * prefix 'Variable'. Variable names are unique. In the case of name + * collision, suffixies '_' will be added to the name. + * + * @param val Initial value of the Variable. + * @param name Name of the variable. If `null` or `undefined` is provided, it + * will default a name with the prefix 'Variable'. + * @param constraint Optional, projection function to be applied to the + * variable after optimize updates + * @throws ValueError if `name` is `null` or `undefined`. + */ + constructor(val, dtype = 'float32', name = DEFAULT_VARIABLE_NAME_PREFIX, trainable = true, constraint = null) { + this.dtype = dtype == null ? 'float32' : dtype; + this.shape = val.shape; + this.id = getNextUniqueTensorId(); + name = name == null ? DEFAULT_VARIABLE_NAME_PREFIX : name; + this.originalName = getScopedTensorName(name); + this.name = getUniqueTensorName(this.originalName); + this.trainable_ = trainable; + this.constraint = constraint; + this.val = variable$1(val, this.trainable_, this.name, this.dtype); + } + /** + * Get a snapshot of the Variable's value. + * + * The returned value is a snapshot of the Variable's value at the time of + * the invocation. Future mutations in the value of the tensor will only + * be reflected by future calls to this method. + */ + read() { + this.assertNotDisposed(); + return this.val; + } + /** + * Update the value of the Variable. + * + * @param newVal: The new value to update to. Must be consistent with the + * dtype and shape of the Variable. + * @return This Variable. + */ + write(newVal) { + // TODO(cais): Once TF.js Core supports Tensor.dtype, check dtype match. + this.assertNotDisposed(); + checkShapesMatch(this.val, newVal); + // Skip updating if this is the exact same tensor. + if (this.val.id !== newVal.id) { + this.val.assign(newVal); + if (this.constraint != null) { + this.val.assign(this.constraint.apply(this.val)); + } + } + return this; + } + /** + * Dispose this LayersVariable instance from memory. + */ + dispose() { + this.assertNotDisposed(); + this.val.dispose(); + } + assertNotDisposed() { + if (this.val.isDisposed) { + throw new Error(`LayersVariable ${this.name} is already disposed.`); + } + } + get trainable() { + return this.trainable_; + } + set trainable(trainable) { + this.trainable_ = trainable; + this.val.trainable = trainable; + } + } + function checkShapesMatch(x, y) { + if (x.shape.toString() !== y.shape.toString()) { + throw new Error('Shape mismatch: ' + JSON.stringify(x.shape) + ' vs. ' + + JSON.stringify(y.shape)); + } + } + /** + * Create a Variable. + * @param x The initial value of the `Variable`. + * @param dtype optional, the type of the variable. + * @param name optional, the name of the variable, default provided by + * Variable. + * @param constraint optional, a constraint to be applied after every update. + * @return The newly instantiated `Variable`. + */ + function variable(x, dtype, name, constraint) { + return new LayerVariable(x, dtype, name, true, constraint); + } + /** + * Instantiates an all-zeros Variable and returns it. + * + * @param shape Shape of the tensor. + * @param dtype DType of the tensor. + * @param name Name of the tensor. + * @return An all-zero Variable. + */ + function zerosVariable(shape, dtype, name) { + // TODO(cais): Implement logic for dtype. + return new LayerVariable(zeros$2(shape), dtype, name); + } + /** + * Instantiates an all-zeros tensor of the same shape as another tensor. + * + * @param x The other tensor. + * @param dtype DType of the tensor. + * @param name Name of the tensor. + * @return A newly instantiated Variable. + */ + function zerosLike$2(x, dtype, name) { + return new LayerVariable(zerosLike$3(x), dtype, name); + } + /** + * Instantiates an all-ones tensor and returns it. + * + * @param shape Shape of the tensor. + * @param dtype DType of the tensor. + * @param name Name of the tensor. + * @return An all-ones Variable. + */ + function onesVariable(shape, dtype, name) { + // TODO(cais): Implement logic for dtype. + const allocated = ones$1(shape); + return new LayerVariable(allocated, dtype, name); + } + /** + * Instantiates an all-ones tensor of the same shape as another tensor. + * + * @param x The other tensor. + * @param dtype DType of the tensor. + * @param name Name of the tensor. + * @return A newly instantiated Variable. + */ + function onesLike$2(x, dtype, name) { + const allocated = onesLike$3(x); + return new LayerVariable(allocated, dtype, name); + } + /** + * Instantiate an identity matrix and returns it, as a Variable + * + * @param size Number of rows/columns. + * @param dtype Data type of returned Variable. + * @param name Name of returned Variable. + * @return A Variable, an identity matrix. + */ + function eyeVariable(size, dtype, name) { + return new LayerVariable(eye(size), dtype, name); + } + /** + * Get a Variable with uniform distribution of values. + * @param shape Shape of the tensor. + * @param minval Lower bound of the uniform distribution. + * @param maxval Upper bound of the uniform distribution. + * @param dtype + * @param seed + * @param name Optional name. + * @return The uniform-random Variable. + */ + function randomUniformVariable(shape, minval, maxval, dtype, seed, name = 'randomUniform') { + return new LayerVariable(randomUniform$1(shape, minval, maxval, dtype), dtype, name); + } + /** + * Get a Variable with truncated-normal distribution of values. + * @param shape Shape of the tensor. + * @param mean mean value of the normal distribution. + * @param stddev standard deviation of the normal distribution. + * @param dtype + * @param seed + * @param name Optional name. + * @return The truncated-normal-random Variable. + */ + function truncatedNormalVariable(shape, mean = 0.0, stddev = 1.0, dtype, seed, name = 'truncatedNormal') { + // TODO(cais): Implement logic for dtype and seed once they are supported + // by deeplearn.js. + dtype = dtype || 'float32'; + if (dtype !== 'float32' && dtype !== 'int32') { + throw new NotImplementedError(`randomNormal does not support dType ${dtype}.`); + } + return new LayerVariable(truncatedNormal$1(shape, mean, stddev, dtype, seed), dtype, name); + } + /** + * Get a Variable with normal distribution of values. + * @param shape Shape of the tensor. + * @param mean mean value of the normal distribution. + * @param stddev standard deviation of the normal distribution. + * @param dtype + * @param seed + * @param name Optional name. + * @return The truncated-normal-random Variable. + */ + function randomNormalVariable(shape, mean = 0.0, stddev = 1.0, dtype, seed, name = 'randomNormal') { + dtype = dtype || 'float32'; + if (dtype !== 'float32' && dtype !== 'int32') { + throw new NotImplementedError(`randomNormalVariable does not support dType ${dtype}.`); + } + return new LayerVariable(randomNormal$2(shape, mean, stddev, dtype, seed), dtype, name); + } + /** + * Update the value of a Variable. + * @param x The Variable to be updated. + * @param xNew The new value to update to. + * @return The Variable updated. + */ + function update(x, xNew) { + return x.write(xNew); + } + /** + * Update the value of a Variable by adding an increment. + * @param x The Variable to be updated. + * @param increment The incrment to add to `x`. + * @return The Variable updated. + */ + function updateAdd(x, increment) { + return x.write(add$3(x.read(), increment)); + } + /** + * Update the value of a Variable by subtracting a decrement. + * @param x The Variable to be updated. + * @param decrement The decrement to subtract from `x`. + * @return The Variable updated. + */ + function updateSub(x, decrement) { + return x.write(sub$2(x.read(), decrement)); + } + /** + * Get the values of an array of Variables. + * + * @param tensors An `Array` of `Variable`s to get the values of. + * @return The values of the inputs, as an `Array` of`tf.Tensor`s. + */ + function batchGetValue(xs) { + return xs.map(x => x.read()); + } + /** + * Update the value of multiple Variables at once. + * + * @param variablesAndValues An `Array`, each element is of type + * [Variable, Tensor]. The first item is the + * `Variable` of which the value is to be updated. The second item + * carries the new value. + */ + function batchSetValue(variablesAndValues) { + variablesAndValues.forEach(variableAndValue => { + const variable = variableAndValue[0]; + variable.write(variableAndValue[1]); + }); + } + /** + * Returns the gradients of `variables` w.r.t. the return value of `lossFn`. + * @param lossFn A function which returns a Scalar to be used as the function + * value (i.e., numerator) for differentiation. + * @param variables List of variables to be used as the independent variables + * (i.e., denominator) for differentiation. + * @returns An Array of gradients tensors. + */ + function gradients(lossFn, variables) { + // TODO(cais): The return type signature can be simplified if deeplearn makes + // the corresponding type public. + const variableList = variables.map(variable => variable.read()); + const valudAndGrads = variableGrads(lossFn, variableList); + return variables.map(variable => valudAndGrads.grads[variable.name]); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Specifies the ndim, dtype and shape of every input to a layer. + * + * Every layer should expose (if appropriate) an `inputSpec` attribute: + * a list of instances of InputSpec (one per input tensor). + * + * A null entry in a shape is compatible with any dimension, + * a null shape is compatible with any shape. + */ + class InputSpec { + constructor(args) { + this.dtype = args.dtype; + this.shape = args.shape; + /* + TODO(michaelterry): Could throw error if ndim and shape are both defined + (then backport). + */ + if (args.shape != null) { + this.ndim = args.shape.length; + } + else { + this.ndim = args.ndim; + } + this.maxNDim = args.maxNDim; + this.minNDim = args.minNDim; + this.axes = args.axes || {}; + } + } + /** + * `tf.SymbolicTensor` is a placeholder for a Tensor without any concrete value. + * + * They are most often encountered when building a graph of `Layer`s for a + * `tf.LayersModel` and the input data's shape, but not values are known. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + class SymbolicTensor { + /** + * + * @param dtype + * @param shape + * @param sourceLayer The Layer that produced this symbolic tensor. + * @param inputs The inputs passed to sourceLayer's __call__() method. + * @param nodeIndex + * @param tensorIndex + * @param callArgs The keyword arguments passed to the __call__() method. + * @param name + * @param outputTensorIndex The index of this tensor in the list of outputs + * returned by apply(). + */ + constructor(dtype, shape, sourceLayer, inputs, callArgs, name, outputTensorIndex) { + this.dtype = dtype; + this.shape = shape; + this.sourceLayer = sourceLayer; + this.inputs = inputs; + this.callArgs = callArgs; + this.outputTensorIndex = outputTensorIndex; + this.id = getNextUniqueTensorId(); + if (name != null) { + this.originalName = getScopedTensorName(name); + this.name = getUniqueTensorName(this.originalName); + } + this.rank = shape.length; + } + } + let _nextNodeID = 0; + /** + * A `Node` describes the connectivity between two layers. + * + * Each time a layer is connected to some new input, + * a node is added to `layer.inboundNodes`. + * + * Each time the output of a layer is used by another layer, + * a node is added to `layer.outboundNodes`. + * + * `nodeIndices` and `tensorIndices` are basically fine-grained coordinates + * describing the origin of the `inputTensors`, verifying the following: + * + * `inputTensors[i] == + * inboundLayers[i].inboundNodes[nodeIndices[i]].outputTensors[ + * tensorIndices[i]]` + * + * A node from layer A to layer B is added to: + * A.outboundNodes + * B.inboundNodes + */ + class Node { + constructor(args, + // TODO(michaelterry): Define actual type for this. + callArgs) { + this.callArgs = callArgs; + this.id = _nextNodeID++; + /* + Layer instance (NOT a list). + this is the layer that takes a list of input tensors + and turns them into a list of output tensors. + the current node will be added to + the inboundNodes of outboundLayer. + */ + this.outboundLayer = args.outboundLayer; + /* + The following 3 properties describe where + the input tensors come from: which layers, + and for each layer, which node and which + tensor output of each node. + */ + // List of layer instances. + this.inboundLayers = args.inboundLayers; + // List of integers, 1:1 mapping with inboundLayers. + this.nodeIndices = args.nodeIndices; + // List of integers, 1:1 mapping with inboundLayers. + this.tensorIndices = args.tensorIndices; + /* + Following 2 properties: + tensor inputs and outputs of outboundLayer. + */ + // List of tensors. 1:1 mapping with inboundLayers. + this.inputTensors = args.inputTensors; + // List of tensors, created by outboundLayer.call(). + this.outputTensors = args.outputTensors; + /* + Following 2 properties: input and output masks. + List of tensors, 1:1 mapping with inputTensor. + */ + this.inputMasks = args.inputMasks; + // List of tensors, created by outboundLayer.computeMask(). + this.outputMasks = args.outputMasks; + // Following 2 properties: input and output shapes. + // List of shape tuples, shapes of inputTensors. + this.inputShapes = args.inputShapes; + // List of shape tuples, shapes of outputTensors. + this.outputShapes = args.outputShapes; + // Add nodes to all layers involved. + for (const layer of args.inboundLayers) { + if (layer != null) { + layer.outboundNodes.push(this); + } + } + args.outboundLayer.inboundNodes.push(this); + } + getConfig() { + const inboundNames = []; + for (const layer of this.inboundLayers) { + if (layer != null) { + inboundNames.push(layer.name); + } + else { + inboundNames.push(null); + } + } + return { + outboundLayer: this.outboundLayer ? this.outboundLayer.name : null, + inboundLayers: inboundNames, + nodeIndices: this.nodeIndices, + tensorIndices: this.tensorIndices + }; + } + } + let _nextLayerID = 0; + /** + * A layer is a grouping of operations and weights that can be composed to + * create a `tf.LayersModel`. + * + * Layers are constructed by using the functions under the + * [tf.layers](#Layers-Basic) namespace. + * + * @doc {heading: 'Layers', subheading: 'Classes', namespace: 'layers'} + */ + class Layer extends Serializable { + constructor(args = {}) { + super(); + this._callHook = null; + this._addedWeightNames = []; + // Porting Notes: PyKeras does not have this property in this base Layer + // class. Instead lets Layer subclass set it dynamically and checks the + // value with `hasattr`. In tfjs-layers, we let this be a member of this + // base class. + this._stateful = false; + this.id = _nextLayerID++; + this.activityRegularizer = null; + this.inputSpec = null; + this.supportsMasking = false; + // These properties will be set upon call of this.build() + this._trainableWeights = []; + this._nonTrainableWeights = []; + this._losses = []; + this._updates = []; + this._built = false; + /* + These lists will be filled via successive calls + to this.addInboundNode(). + */ + this.inboundNodes = []; + this.outboundNodes = []; + let name = args.name; + if (!name) { + const prefix = this.getClassName(); + name = toSnakeCase(prefix) + '_' + getUid(prefix); + } + this.name = name; + this.trainable_ = args.trainable == null ? true : args.trainable; + if (args.inputShape != null || args.batchInputShape != null) { + /* + In this case we will later create an input layer + to insert before the current layer + */ + let batchInputShape; + if (args.batchInputShape != null) { + batchInputShape = args.batchInputShape; + } + else if (args.inputShape != null) { + let batchSize = null; + if (args.batchSize != null) { + batchSize = args.batchSize; + } + batchInputShape = [batchSize].concat(args.inputShape); + } + this.batchInputShape = batchInputShape; + // Set dtype. + let dtype = args.dtype; + if (dtype == null) { + dtype = args.inputDType; + } + if (dtype == null) { + dtype = 'float32'; + } + this.dtype = dtype; + } + if (args.weights != null) { + this.initialWeights = args.weights; + } + else { + this.initialWeights = null; + } + // The value of `_refCount` is initialized to null. When the layer is used + // in a symbolic way for the first time, it will be set to 1. + this._refCount = null; + this.fastWeightInitDuringBuild = false; + } + /** + * Converts a layer and its index to a unique (immutable type) name. + * This function is used internally with `this.containerNodes`. + * @param layer The layer. + * @param nodeIndex The layer's position (e.g. via enumerate) in a list of + * nodes. + * + * @returns The unique name. + */ + static nodeKey(layer, nodeIndex) { + return layer.name + '_ib-' + nodeIndex.toString(); + } + /** + * Returns this.inboundNode at index nodeIndex. + * + * Porting note: This is a replacement for _get_node_attribute_at_index() + * @param nodeIndex + * @param attrName The name of the attribute related to request for this node. + */ + getNodeAtIndex(nodeIndex, attrName) { + if (this.inboundNodes.length === 0) { + throw new RuntimeError('The layer has never been called ' + + `and thus has no defined ${attrName}.`); + } + if (this.inboundNodes.length <= nodeIndex) { + throw new ValueError(`Asked to get ${attrName} at node ${nodeIndex}, ` + + `but the layer has only ${this.inboundNodes.length} inbound nodes.`); + } + return this.inboundNodes[nodeIndex]; + } + /** + * Retrieves the input tensor(s) of a layer at a given node. + * + * @param nodeIndex Integer, index of the node from which to retrieve the + * attribute. E.g. `nodeIndex=0` will correspond to the first time the layer + * was called. + * + * @return A tensor (or list of tensors if the layer has multiple inputs). + */ + getInputAt(nodeIndex) { + return singletonOrArray(this.getNodeAtIndex(nodeIndex, 'input').inputTensors); + } + /** + * Retrieves the output tensor(s) of a layer at a given node. + * + * @param nodeIndex Integer, index of the node from which to retrieve the + * attribute. E.g. `nodeIndex=0` will correspond to the first time the layer + * was called. + * + * @return A tensor (or list of tensors if the layer has multiple outputs). + */ + getOutputAt(nodeIndex) { + return singletonOrArray(this.getNodeAtIndex(nodeIndex, 'output').outputTensors); + } + // Properties + /** + * Retrieves the input tensor(s) of a layer. + * + * Only applicable if the layer has exactly one inbound node, + * i.e. if it is connected to one incoming layer. + * + * @return Input tensor or list of input tensors. + * + * @exception AttributeError if the layer is connected to more than one + * incoming layers. + */ + get input() { + if (this.inboundNodes.length > 1) { + throw new AttributeError(`Layer ${this.name}` + + ' has multiple inbound nodes, ' + + 'hence the notion of "layer input" ' + + 'is ill-defined. ' + + 'Use `getInputAt(nodeIndex)` instead.'); + } + else if (this.inboundNodes.length === 0) { + throw new AttributeError(`Layer ${this.name}` + + ' is not connected, no input to return.'); + } + return singletonOrArray(this.getNodeAtIndex(0, 'input').inputTensors); + } + /** + * Retrieves the output tensor(s) of a layer. + * + * Only applicable if the layer has exactly one inbound node, + * i.e. if it is connected to one incoming layer. + * + * @return Output tensor or list of output tensors. + * + * @exception AttributeError if the layer is connected to more than one + * incoming layers. + */ + get output() { + if (this.inboundNodes.length === 0) { + throw new AttributeError(`Layer ${this.name}` + + ' has no inbound nodes.'); + } + if (this.inboundNodes.length > 1) { + throw new AttributeError(`Layer ${this.name}` + + ' has multiple inbound nodes, ' + + 'hence the notion of "layer output" ' + + 'is ill-defined. ' + + 'Use `getOutputAt(nodeIndex)` instead.'); + } + return singletonOrArray(this.getNodeAtIndex(0, 'output').outputTensors); + } + get losses() { + return this._losses; + } + /** + * Retrieves the Layer's current loss values. + * + * Used for regularizers during training. + */ + calculateLosses() { + // Porting Node: This is an augmentation to Layer.loss in PyKeras. + // In PyKeras, Layer.loss returns symbolic tensors. Here a concrete + // Tensor (specifically Scalar) values are returned. This is due to the + // imperative backend. + return this.losses.map(lossFn => lossFn()); + } + get updates() { + return this._updates; + } + get built() { + return this._built; + } + set built(built) { + this._built = built; + } + get trainable() { + return this.trainable_; + } + set trainable(trainable) { + this._trainableWeights.forEach(w => w.trainable = trainable); + this.trainable_ = trainable; + } + get trainableWeights() { + if (this.trainable_) { + return this._trainableWeights.filter(w => w.trainable); + } + else { + return []; + } + } + set trainableWeights(weights) { + this._trainableWeights = weights; + } + get nonTrainableWeights() { + if (this.trainable) { + return this._trainableWeights.filter(w => !w.trainable) + .concat(this._nonTrainableWeights); + } + else { + return this._trainableWeights.concat(this._nonTrainableWeights); + } + } + set nonTrainableWeights(weights) { + this._nonTrainableWeights = weights; + } + /** + * The concatenation of the lists trainableWeights and nonTrainableWeights + * (in this order). + */ + get weights() { + return this.trainableWeights.concat(this.nonTrainableWeights); + } + get stateful() { + return this._stateful; + } + /** + * Reset the states of the layer. + * + * This method of the base Layer class is essentially a no-op. + * Subclasses that are stateful (e.g., stateful RNNs) should override this + * method. + */ + resetStates() { + if (!this.stateful) { + throw new Error('Cannot call the resetStates() method of a non-stateful Layer ' + + 'object.'); + } + } + /** + * Checks compatibility between the layer and provided inputs. + * + * This checks that the tensor(s) `input` + * verify the input assumptions of the layer + * (if any). If not, exceptions are raised. + * + * @param inputs Input tensor or list of input tensors. + * + * @exception ValueError in case of mismatch between + * the provided inputs and the expectations of the layer. + */ + assertInputCompatibility(inputs) { + const inputsList = toList(inputs); + if (this.inputSpec == null || this.inputSpec.length === 0) { + return; + } + const inputSpec = toList(this.inputSpec); + if (inputsList.length !== inputSpec.length) { + throw new ValueError(`Layer ${this.name} expects ${inputSpec.length} inputs, ` + + `but it received ${inputsList.length} input tensors. ` + + `Input received: ${inputs}`); + } + for (let inputIndex = 0; inputIndex < inputsList.length; inputIndex++) { + const x = inputsList[inputIndex]; + const spec = inputSpec[inputIndex]; + if (spec == null) { + continue; + } + // Check ndim. + const ndim = x.rank; + if (spec.ndim != null) { + if (ndim !== spec.ndim) { + throw new ValueError(`Input ${inputIndex} is incompatible with layer ${this.name}: ` + + `expected ndim=${spec.ndim}, found ndim=${ndim}`); + } + } + if (spec.maxNDim != null) { + if (ndim > spec.maxNDim) { + throw new ValueError(`Input ${inputIndex} is incompatible with layer ${this.name}` + + `: expected max_ndim=${spec.maxNDim}, found ndim=${ndim}`); + } + } + if (spec.minNDim != null) { + if (ndim < spec.minNDim) { + throw new ValueError(`Input ${inputIndex} is incompatible with layer ${this.name}` + + `: expected min_ndim=${spec.minNDim}, found ndim=${ndim}.`); + } + } + // Check dtype. + if (spec.dtype != null) { + if (x.dtype !== spec.dtype) { + throw new ValueError(`Input ${inputIndex} is incompatible with layer ${this.name} ` + + `: expected dtype=${spec.dtype}, found dtype=${x.dtype}.`); + } + } + // Check specific shape axes. + if (spec.axes) { + const xShape = x.shape; + for (const key in spec.axes) { + const axis = Number(key); + const value = spec.axes[key]; + // Perform Python-style slicing in case axis < 0; + // TODO(cais): Use https://github.com/alvivi/typescript-underscore to + // ensure type safety through Underscore calls. + const xShapeAtAxis = axis >= 0 ? xShape[axis] : xShape[xShape.length + axis]; + if (value != null && [value, null].indexOf(xShapeAtAxis) === -1) { + throw new ValueError(`Input ${inputIndex} is incompatible with layer ` + + `${this.name}: expected axis ${axis} of input shape to ` + + `have value ${value} but got shape ${xShape}.`); + } + } + } + // Check shape. + if (spec.shape != null) { + for (let i = 0; i < spec.shape.length; ++i) { + const specDim = spec.shape[i]; + const dim = x.shape[i]; + if (specDim != null && dim != null) { + if (specDim !== dim) { + throw new ValueError(`Input ${inputIndex} is incompatible with layer ` + + `${this.name}: expected shape=${spec.shape}, ` + + `found shape=${x.shape}.`); + } + } + } + } + } + } + /** + * This is where the layer's logic lives. + * + * @param inputs Input tensor, or list/tuple of input tensors. + * @param kwargs Additional keyword arguments. + * + * @return A tensor or list/tuple of tensors. + */ + call(inputs, kwargs) { + return inputs; + } + invokeCallHook(inputs, kwargs) { + if (this._callHook != null) { + this._callHook(inputs, kwargs); + } + } + /** + * Set call hook. + * This is currently used for testing only. + * @param callHook + */ + setCallHook(callHook) { + this._callHook = callHook; + } + /** + * Clear call hook. + * This is currently used for testing only. + */ + clearCallHook() { + this._callHook = null; + } + /** + * Builds or executes a `Layer`'s logic. + * + * When called with `tf.Tensor`(s), execute the `Layer`'s computation and + * return Tensor(s). For example: + * + * ```js + * const denseLayer = tf.layers.dense({ + * units: 1, + * kernelInitializer: 'zeros', + * useBias: false + * }); + * + * // Invoke the layer's apply() method with a `tf.Tensor` (with concrete + * // numeric values). + * const input = tf.ones([2, 2]); + * const output = denseLayer.apply(input); + * + * // The output's value is expected to be [[0], [0]], due to the fact that + * // the dense layer has a kernel initialized to all-zeros and does not have + * // a bias. + * output.print(); + * ``` + * + * When called with `tf.SymbolicTensor`(s), this will prepare the layer for + * future execution. This entails internal book-keeping on shapes of + * expected Tensors, wiring layers together, and initializing weights. + * + * Calling `apply` with `tf.SymbolicTensor`s are typically used during the + * building of non-`tf.Sequential` models. For example: + * + * ```js + * const flattenLayer = tf.layers.flatten(); + * const denseLayer = tf.layers.dense({units: 1}); + * + * // Use tf.layers.input() to obtain a SymbolicTensor as input to apply(). + * const input = tf.input({shape: [2, 2]}); + * const output1 = flattenLayer.apply(input); + * + * // output1.shape is [null, 4]. The first dimension is the undetermined + * // batch size. The second dimension comes from flattening the [2, 2] + * // shape. + * console.log(JSON.stringify(output1.shape)); + * + * // The output SymbolicTensor of the flatten layer can be used to call + * // the apply() of the dense layer: + * const output2 = denseLayer.apply(output1); + * + * // output2.shape is [null, 1]. The first dimension is the undetermined + * // batch size. The second dimension matches the number of units of the + * // dense layer. + * console.log(JSON.stringify(output2.shape)); + * + * // The input and output can be used to construct a model that consists + * // of the flatten and dense layers. + * const model = tf.model({inputs: input, outputs: output2}); + * ``` + * + * @param inputs a `tf.Tensor` or `tf.SymbolicTensor` or an Array of them. + * @param kwargs Additional keyword arguments to be passed to `call()`. + * + * @return Output of the layer's `call` method. + * + * @exception ValueError error in case the layer is missing shape information + * for its `build` call. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + // Porting Note: This is a replacement for __call__() in Python. + apply(inputs, kwargs) { + kwargs = kwargs || {}; + this.assertNotDisposed(); + // Ensure inputs are all the same type. + const inputsList = toList(inputs); + const allAreSymbolic = checkAllSymbolic(inputs); + const noneAreSymbolic = checkNoneSymbolic(inputs); + if (allAreSymbolic === noneAreSymbolic) { + throw new ValueError('Arguments to apply() must be all ' + + 'SymbolicTensors or all Tensors'); + } + // TODO(michaelterry): nameScope() may not be necessary. + return nameScope(this.name, () => { + // Handle laying building (weight creating, input spec locking). + if (!this.built) { + /* + Throw exceptions in case the input is not compatible + with the inputSpec specified in the layer constructor. + */ + this.assertInputCompatibility(inputs); + // Collect input shapes to build layer. + const inputShapes = []; + for (const xElem of toList(inputs)) { + inputShapes.push(xElem.shape); + } + this.build(singletonOrArray(inputShapes)); + this.built = true; + // Load weights that were specified at layer instantiation. + if (this.initialWeights) { + this.setWeights(this.initialWeights); + } + if (this._refCount === null && noneAreSymbolic) { + // The first use of this layer is a non-symbolic call, set ref count + // to 1 so the Layer can be properly disposed if its dispose() method + // is called. + this._refCount = 1; + } + } + /* + Throw exceptions in case the input is not compatible + with the inputSpec set at build time. + */ + this.assertInputCompatibility(inputs); + // Handle mask propagation. + // TODO(michaelterry): Mask propagation not currently implemented. + // Actually call the layer, collecting output(s), mask(s), and shape(s). + if (noneAreSymbolic) { + let output = this.call(inputs, kwargs); + // Apply masks to the output tensors if the layer supports it. + if (this.supportsMasking) { + // TODO(mattsoulanille): pass the input tensors' masks to computeMask + this.setMaskMetadata(inputs, output); + } + // If the layer returns tensors from its inputs, unmodified, + // we copy them to avoid loss of tensor metadata. + const outputList = toList(output); + const outputListCopy = []; + // TODO(michaelterry): This copying may not be necessary given our eager + // backend. + for (let x of outputList) { + if (inputsList.indexOf(x) !== -1) { + x = x.clone(); + } + outputListCopy.push(x); + } + output = singletonOrArray(outputListCopy); + if (this.activityRegularizer != null) { + throw new NotImplementedError('Layer invocation in the presence of activity ' + + 'regularizer(s) is not supported yet.'); + } + // TODO(michaelterry): Call addInboundNode()? + return output; + } + else { + const inputShape = collectInputShape(inputs); + const outputShape = this.computeOutputShape(inputShape); + let output; + const outputDType = guessOutputDType(inputs); + this.warnOnIncompatibleInputShape(Array.isArray(inputs) ? inputShape[0] : + inputShape); + if (outputShape != null && outputShape.length > 0 && + Array.isArray(outputShape[0])) { + // We have multiple output shapes. Create multiple output tensors. + output = outputShape + .map((shape, index) => new SymbolicTensor(outputDType, shape, this, toList(inputs), kwargs, this.name, index)); + } + else { + output = new SymbolicTensor(outputDType, outputShape, this, toList(inputs), kwargs, this.name); + } + /* + Add an inbound node to the layer, so that it keeps track + of the call and of all new variables created during the call. + This also updates the layer history of the output tensor(s). + If the input tensor(s) had no previous history, + this does nothing. + */ + this.addInboundNode(inputs, output, null, null, inputShape, outputShape, kwargs); + this._refCount++; + if (this.activityRegularizer != null) { + throw new NotImplementedError('Layer invocation in the presence of activity ' + + 'regularizer(s) is not supported yet.'); + } + return output; + } + }); + } + /** + * Check compatibility between input shape and this layer's batchInputShape. + * + * Print warning if any incompatibility is found. + * + * @param inputShape Input shape to be checked. + */ + warnOnIncompatibleInputShape(inputShape) { + if (this.batchInputShape == null) { + return; + } + else if (inputShape.length !== this.batchInputShape.length) { + console.warn(`The rank of the input tensor provided (shape: ` + + `${JSON.stringify(inputShape)}) does not match that of the ` + + `batchInputShape (${JSON.stringify(this.batchInputShape)}) ` + + `of the layer ${this.name}`); + } + else { + let dimMismatch = false; + this.batchInputShape.forEach((dimension, i) => { + if (dimension != null && inputShape[i] != null && + inputShape[i] !== dimension) { + dimMismatch = true; + } + }); + if (dimMismatch) { + console.warn(`The shape of the input tensor ` + + `(${JSON.stringify(inputShape)}) does not ` + + `match the expectation of layer ${this.name}: ` + + `${JSON.stringify(this.batchInputShape)}`); + } + } + } + /** + * Retrieves the output shape(s) of a layer. + * + * Only applicable if the layer has only one inbound node, or if all inbound + * nodes have the same output shape. + * + * @returns Output shape or shapes. + * @throws AttributeError: if the layer is connected to more than one incoming + * nodes. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + get outputShape() { + if (this.inboundNodes == null || this.inboundNodes.length === 0) { + throw new AttributeError(`The layer ${this.name} has never been called and thus has no ` + + `defined output shape.`); + } + const allOutputShapes = []; + for (const node of this.inboundNodes) { + const shapeString = JSON.stringify(node.outputShapes); + if (allOutputShapes.indexOf(shapeString) === -1) { + allOutputShapes.push(shapeString); + } + } + if (allOutputShapes.length === 1) { + const outputShapes = this.inboundNodes[0].outputShapes; + if (Array.isArray(outputShapes) && Array.isArray(outputShapes[0]) && + outputShapes.length === 1) { + return outputShapes[0]; + } + else { + return outputShapes; + } + } + else { + throw new AttributeError(`The layer ${this.name} has multiple inbound nodes with different ` + + `output shapes. Hence the notion of "output shape" is ill-defined ` + + `for the layer.`); + // TODO(cais): Implement getOutputShapeAt(). + } + } + /** + * Counts the total number of numbers (e.g., float32, int32) in the + * weights. + * + * @returns An integer count. + * @throws RuntimeError: If the layer is not built yet (in which case its + * weights are not defined yet.) + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + countParams() { + if (!this.built) { + throw new RuntimeError(`You tried to call countParams() on ${this.name}, ` + + `but the layer is not built yet. Build it first by calling ` + + `build(batchInputShape).`); + } + return countParamsInWeights(this.weights); + } + /** + * Creates the layer weights. + * + * Must be implemented on all layers that have weights. + * + * Called when apply() is called to construct the weights. + * + * @param inputShape A `Shape` or array of `Shape` (unused). + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + build(inputShape) { + this.built = true; + } + /** + * Returns the current values of the weights of the layer. + * + * @param trainableOnly Whether to get the values of only trainable weights. + * @returns Weight values as an `Array` of `tf.Tensor`s. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + getWeights(trainableOnly = false) { + return batchGetValue(trainableOnly ? this.trainableWeights : this.weights); + } + /** + * Sets the weights of the layer, from Tensors. + * + * @param weights a list of Tensors. The number of arrays and their shape + * must match number of the dimensions of the weights of the layer (i.e. + * it should match the output of `getWeights`). + * + * @exception ValueError If the provided weights list does not match the + * layer's specifications. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + setWeights(weights) { + tidy(() => { + const params = this.weights; + if (params.length !== weights.length) { + // TODO(cais): Restore the following and use `providedWeights`, instead + // of `weights` in the error message, once the deeplearn.js bug is + // fixed: https://github.com/PAIR-code/deeplearnjs/issues/498 const + // providedWeights = JSON.stringify(weights).slice(0, 50); + throw new ValueError(`You called setWeights(weights) on layer "${this.name}" ` + + `with a weight list of length ${weights.length}, ` + + `but the layer was expecting ${params.length} weights. ` + + `Provided weights: ${weights}...`); + } + if (params.length === 0) { + return; + } + const weightValueTuples = []; + const paramValues = batchGetValue(params); + for (let i = 0; i < paramValues.length; ++i) { + const pv = paramValues[i]; + const p = params[i]; + const w = weights[i]; + if (!arraysEqual(pv.shape, w.shape)) { + throw new ValueError(`Layer weight shape ${pv.shape} ` + + `not compatible with provided weight shape ${w.shape}`); + } + weightValueTuples.push([p, w]); + } + batchSetValue(weightValueTuples); + }); + } + /** + * Adds a weight variable to the layer. + * + * @param name Name of the new weight variable. + * @param shape The shape of the weight. + * @param dtype The dtype of the weight. + * @param initializer An initializer instance. + * @param regularizer A regularizer instance. + * @param trainable Whether the weight should be trained via backprop or not + * (assuming that the layer itself is also trainable). + * @param constraint An optional trainable. + * @return The created weight variable. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + addWeight(name, shape, dtype, initializer, regularizer, trainable, constraint, getInitializerFunc) { + // Reject duplicate weight names. + if (this._addedWeightNames.indexOf(name) !== -1) { + throw new ValueError(`Duplicate weight name ${name} for layer ${this.name}`); + } + this._addedWeightNames.push(name); + if (dtype == null) { + dtype = 'float32'; + } + if (this.fastWeightInitDuringBuild) { + initializer = getInitializerFunc != null ? getInitializerFunc() : + getInitializer('zeros'); + } + const initValue = initializer.apply(shape, dtype); + const weight = new LayerVariable(initValue, dtype, name, trainable, constraint); + initValue.dispose(); + // Request backend not to dispose the weights of the model on scope() exit. + if (regularizer != null) { + this.addLoss(() => regularizer.apply(weight.read())); + } + if (trainable == null) { + trainable = true; + } + if (trainable) { + this._trainableWeights.push(weight); + } + else { + this._nonTrainableWeights.push(weight); + } + return weight; + } + /** + * Set the fast-weight-initialization flag. + * + * In cases where the initialized weight values will be immediately + * overwritten by loaded weight values during model loading, setting + * the flag to `true` saves unnecessary calls to potentially expensive + * initializers and speeds up the loading process. + * + * @param value Target value of the flag. + */ + setFastWeightInitDuringBuild(value) { + this.fastWeightInitDuringBuild = value; + } + /** + * Add losses to the layer. + * + * The loss may potentially be conditional on some inputs tensors, + * for instance activity losses are conditional on the layer's inputs. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + addLoss(losses) { + if (losses == null || Array.isArray(losses) && losses.length === 0) { + return; + } + // Update this.losses + losses = toList(losses); + if (this._losses !== undefined && this._losses !== null) { + this.losses.push(...losses); + } + } + /** + * Computes the output shape of the layer. + * + * Assumes that the layer will be built to match that input shape provided. + * + * @param inputShape A shape (tuple of integers) or a list of shape tuples + * (one per output tensor of the layer). Shape tuples can include null for + * free dimensions, instead of an integer. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + computeOutputShape(inputShape) { + return inputShape; + } + /** + * Computes an output mask tensor. + * + * @param inputs Tensor or list of tensors. + * @param mask Tensor or list of tensors. + * + * @return null or a tensor (or list of tensors, one per output tensor of the + * layer). + */ + computeMask(inputs, mask) { + if (!this.supportsMasking) { + if (mask != null) { + if (Array.isArray(mask)) { + mask.forEach(maskElement => { + if (maskElement != null) { + throw new TypeError(`Layer ${this.name} does not support masking, ` + + 'but was passed an inputMask.'); + } + }); + } + else { + throw new TypeError(`Layer ${this.name} does not support masking, ` + + 'but was passed an inputMask.'); + } + } + // masking not explicitly supported: return null as mask + return null; + } + // if masking is explictly supported, by default + // carry over the input mask + return mask; + } + setMaskMetadata(inputs, outputs, previousMask) { + if (!this.supportsMasking) { + return; + } + const outputMasks = this.computeMask(inputs, previousMask); + const outputsList = toList(outputs); + const outputMasksList = toList(outputMasks); + if (outputsList.length !== outputMasksList.length) { + throw new Error(`${this.name} outputs ${outputsList.length} tensors ` + + `but ${outputsList.length} masks for those tensors`); + } + for (let i = 0; i < outputsList.length; i++) { + outputsList[i].kerasMask = outputMasksList[i]; + } + } + /** + * Internal method to create an inbound node for the layer. + * + * @param inputTensors List of input tensors. + * @param outputTensors List of output tensors. + * @param inputMasks List of input masks (a mask can be a tensor, or null). + * @param outputMasks List of output masks (a mask can be a tensor, or null). + * @param inputShapes List of input shape tuples. + * @param outputShapes List of output shape tuples. + * @param kwargs Dictionary of keyword arguments that were passed to the + * `call` method of the layer at the call that created the node. + */ + addInboundNode(inputTensors, outputTensors, inputMasks, outputMasks, inputShapes, outputShapes, kwargs = null) { + const inputTensorList = toList(inputTensors); + outputTensors = toList(outputTensors); + inputMasks = toList(inputMasks); + outputMasks = toList(outputMasks); + inputShapes = normalizeShapeList(inputShapes); + outputShapes = normalizeShapeList(outputShapes); + // Collect input tensor(s) coordinates. + const inboundLayers = []; + const nodeIndices = []; + const tensorIndices = []; + for (const x of inputTensorList) { + /* + * TODO(michaelterry): Keras adds this value to tensors; it's not + * clear whether we'll use this or not. + */ + inboundLayers.push(x.sourceLayer); + nodeIndices.push(x.nodeIndex); + tensorIndices.push(x.tensorIndex); + } + // Create node, add it to inbound nodes. + // (This call has side effects.) + // tslint:disable-next-line:no-unused-expression + new Node({ + outboundLayer: this, + inboundLayers, + nodeIndices, + tensorIndices, + inputTensors: inputTensorList, + outputTensors, + inputMasks, + outputMasks, + inputShapes, + outputShapes + }, kwargs); + // Update tensor history + for (let i = 0; i < outputTensors.length; i++) { + // TODO(michaelterry: _uses_learning_phase not tracked. + outputTensors[i].sourceLayer = this; + outputTensors[i].nodeIndex = this.inboundNodes.length - 1; + outputTensors[i].tensorIndex = i; + } + } + /** + * Returns the config of the layer. + * + * A layer config is a TS dictionary (serializable) + * containing the configuration of a layer. + * The same layer can be reinstantiated later + * (without its trained weights) from this configuration. + * + * The config of a layer does not include connectivity + * information, nor the layer class name. These are handled + * by 'Container' (one layer of abstraction above). + * + * Porting Note: The TS dictionary follows TS naming standards for + * keys, and uses tfjs-layers type-safe Enums. Serialization methods + * should use a helper function to convert to the pythonic storage + * standard. (see serialization_utils.convertTsToPythonic) + * + * @returns TS dictionary of configuration. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + getConfig() { + const config = { name: this.name, trainable: this.trainable }; + if (this.batchInputShape != null) { + config['batchInputShape'] = this.batchInputShape; + } + if (this.dtype != null) { + config['dtype'] = this.dtype; + } + return config; + } + /** + * Dispose the weight variables that this Layer instance holds. + * + * @returns {number} Number of disposed variables. + */ + disposeWeights() { + this.weights.forEach(weight => weight.dispose()); + return this.weights.length; + } + assertNotDisposed() { + if (this._refCount === 0) { + throw new Error(`Layer '${this.name}' is already disposed.`); + } + } + /** + * Attempt to dispose layer's weights. + * + * This method decreases the reference count of the Layer object by 1. + * + * A Layer is reference-counted. Its reference count is incremented by 1 + * the first item its `apply()` method is called and when it becomes a part + * of a new `Node` (through calling the `apply()` method on a + * `tf.SymbolicTensor`). + * + * If the reference count of a Layer becomes 0, all the weights will be + * disposed and the underlying memory (e.g., the textures allocated in WebGL) + * will be freed. + * + * Note: If the reference count is greater than 0 after the decrement, the + * weights of the Layer will *not* be disposed. + * + * After a Layer is disposed, it cannot be used in calls such as `apply()`, + * `getWeights()` or `setWeights()` anymore. + * + * @returns A DisposeResult Object with the following fields: + * - refCountAfterDispose: The reference count of the Container after this + * `dispose()` call. + * - numDisposedVariables: Number of `tf.Variable`s (i.e., weights) disposed + * during this `dispose()` call. + * @throws {Error} If the layer is not built yet, or if the layer has already + * been disposed. + * + * @doc {heading: 'Models', 'subheading': 'Classes'} + */ + dispose() { + if (!this.built) { + throw new Error(`Cannot dispose Layer ${this.name} because it has not been ` + + `built yet.`); + } + if (this._refCount === null) { + throw new Error(`Cannot dispose Layer ${this.name} because it has not been used ` + + `yet.`); + } + this.assertNotDisposed(); + let numDisposedVariables = 0; + if (--this._refCount === 0) { + numDisposedVariables = this.disposeWeights(); + } + return { refCountAfterDispose: this._refCount, numDisposedVariables }; + } + } + /** + * Collects the input shape(s) of a list of `tf.Tensor`s or + * `tf.SymbolicTensor`s. + * + * TODO(michaelterry): Update PyKeras docs (backport). + * + * @param inputTensors List of input tensors (or single input tensor). + * + * @return List of shape tuples (or single tuple), one tuple per input. + */ + function collectInputShape(inputTensors) { + inputTensors = + toList(inputTensors); + const shapes = []; + for (const x of inputTensors) { + shapes.push(x.shape); + } + return singletonOrArray(shapes); + } + /** + * Guesses output dtype based on inputs. + * + * At present, just returns 'float32' for any input. + * + * @param inputTensors List of input tensors (or single input tensor). + * + * @return The guessed DType. At present, always returns 'float32'. + */ + function guessOutputDType(inputTensors) { + return 'float32'; + } + /** + * Returns the list of input tensors necessary to compute `tensor`. + * + * Output will always be a list of tensors (potentially with 1 element). + * + * @param tensor The tensor to start from. + * @param layer Origin layer of the tensor. + * @param nodeIndex Origin node index of the tensor. + * + * @return Array of input tensors. + */ + function getSourceInputs(tensor, layer, nodeIndex) { + if (layer == null || (nodeIndex != null && nodeIndex > 0)) { + layer = tensor.sourceLayer; + nodeIndex = tensor.nodeIndex; + } + if (layer.inboundNodes.length === 0) { + return [tensor]; + } + else { + const node = layer.inboundNodes[nodeIndex]; + if (node.inboundLayers.length === 0) { + return node.inputTensors; + } + else { + const sourceTensors = []; + for (let i = 0; i < node.inboundLayers.length; i++) { + const x = node.inputTensors[i]; + const layer = node.inboundLayers[i]; + const nodeIndex = node.nodeIndices[i]; + const previousSources = getSourceInputs(x, layer, nodeIndex); + // Avoid input redundancy. + for (const x of previousSources) { + if (sourceTensors.indexOf(x) === -1) { + sourceTensors.push(x); + } + } + } + return sourceTensors; + } + } + } + function checkAllSymbolic(tensors) { + let allAreSymbolic = true; + for (const tensor of toList(tensors)) { + if (!(tensor instanceof SymbolicTensor)) { + allAreSymbolic = false; + break; + } + } + return allAreSymbolic; + } + function checkNoneSymbolic(tensors) { + let noneAreSymbolic = true; + for (const tensor of toList(tensors)) { + if (tensor instanceof SymbolicTensor) { + noneAreSymbolic = false; + break; + } + } + return noneAreSymbolic; + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + class InputLayer extends Layer { + constructor(args) { + super({ + dtype: args.dtype, + name: args.name != null ? args.name : getUid('input').toString() + }); + // Normalize config.batchSize and config.sparse + if (args.batchSize == null) { + args.batchSize = null; + } + if (args.sparse == null) { + args.sparse = false; + } + this.trainable = false; + this.built = true; + this.sparse = args.sparse; + if (args.inputShape != null && args.batchInputShape != null) { + throw new ValueError('Only provide the inputShape OR ' + + 'batchInputShape argument to inputLayer, not both at the same time.'); + } + let batchInputShape = args.batchInputShape; + if (batchInputShape == null) { + if (args.inputShape == null) { + throw new ValueError('An InputLayer should be passed either a ' + + '`batchInputShape` or an `inputShape`.'); + } + else { + batchInputShape = [args.batchSize].concat(args.inputShape); + } + } + else { + // TODO(michaelterry): Backport to PyKeras + if (args.batchSize != null) { + throw new ValueError('Cannot specify batchSize if batchInputShape is ' + + 'specified when creating an InputLayer.'); + } + } + const dtype = args.dtype || 'float32'; + this.batchInputShape = batchInputShape; + this.dtype = dtype; + // TODO(michaelterry): Backport this to PyKeras? + this.inputSpec = [{ shape: batchInputShape }]; + const inputTensor = new SymbolicTensor(this.dtype, this.batchInputShape, this, [], {}, this.name); + inputTensor.nodeIndex = 0; + inputTensor.tensorIndex = 0; + // Create an input node to add to this.outboundNode. + // (This call has side effects.) + // tslint:disable-next-line:no-unused-expression + new Node({ + outboundLayer: this, + inboundLayers: [], + nodeIndices: [], + tensorIndices: [], + inputTensors: [inputTensor], + outputTensors: [inputTensor], + inputMasks: [null], + outputMasks: [null], + inputShapes: [batchInputShape], + outputShapes: [batchInputShape] + }); + } + apply(inputs, kwargs) { + throw new ValueError('Cannot pass any input to an ' + + `InputLayer's apply() method. InputLayer name: ${this.name}`); + } + dispose() { + // dispose() for InputLayer is overridden as no-op. + return { refCountAfterDispose: this._refCount, numDisposedVariables: 0 }; + } + getConfig() { + return { + batchInputShape: this.batchInputShape, + dtype: this.dtype, + sparse: this.sparse, + name: this.name + }; + } + } + /** @nocollapse */ + InputLayer.className = 'InputLayer'; + registerClass(InputLayer); + function Input(config) { + if (config.batchShape == null && config.shape == null) { + throw new Error('Please provide to Input either a `shape`' + + ' or a `batchShape` argument. Note that ' + + '`shape` does not include the batch ' + + 'dimension.'); + } + if (config.batchShape != null && config.shape != null) { + // TODO(michaelterry): Backport to PyKeras. + throw new ValueError('Please provide either a `shape` or `batchShape` ' + + 'argument to Input, but not both.'); + } + let batchShape = config.batchShape; + if (config.shape != null && batchShape == null) { + batchShape = [null].concat(config.shape); + } + let dtype = config.dtype; + if (dtype == null) { + dtype = 'float32'; + } + const inputLayer = new InputLayer({ + batchInputShape: batchShape, + name: config.name, + dtype, + sparse: config.sparse + }); + const outputs = inputLayer.inboundNodes[0].outputTensors; + return outputs[0]; + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Helper function to check the dtype and shape compatibility of a feed value. + */ + function assertFeedCompatibility(key, val) { + // Check dtype compatibility. + if (key.dtype == null || key.dtype === val.dtype) { + // a. If types match, return val tensor as is. + return val; + } + try { + // b. Attempt to convert to expected type. + return cast$3(val, key.dtype); + } + catch (err) { + // c. If conversion fails, return helpful error. + throw new ValueError(`The dtype of the feed (${val.dtype}) can not be cast to the dtype ` + + `of the key '${key.name}' (${key.dtype}).`); + } + } + /** + * FeedDict: A mapping from unique SymbolicTensors to feed values for them. + * A feed value is a concrete value represented as an `Tensor`. + */ + class FeedDict { + /** + * Constructor, optionally does copy-construction. + * @param feeds An Array of `Feed`s, or another `FeedDict`, in which case + * copy-construction will be performed. + */ + constructor(feeds) { + this.id2Value = {}; + this.id2Mask = {}; + this.name2Id = {}; + if (feeds instanceof FeedDict) { + for (const id in feeds.id2Value) { + this.id2Value[id] = feeds.id2Value[id]; + if (id in feeds.id2Mask) { + this.id2Mask[id] = feeds.id2Mask[id]; + } + } + } + else { + if (feeds == null) { + return; + } + for (const feed of feeds) { + this.add(feed.key, feed.value); + } + } + } + /** + * Add a key-value pair to the FeedDict. + * + * @param key The key of the feed. + * @param value The value of the tensor feed. + * @param mask The value of the mask feed (optional). + * @returns This `FeedDict`. + * @throws ValueError: If the key `SymbolicTensor` already exists in the + * `FeedDict`. + */ + add(key, value, mask) { + if (this.id2Value[key.id] == null) { + this.id2Value[key.id] = assertFeedCompatibility(key, value); + this.name2Id[key.name] = key.id; + if (mask != null) { + this.id2Mask[key.id] = mask; + } + } + else { + throw new ValueError(`Duplicate key: name=${key.name}, id=${key.id}`); + } + return this; + } + /** + * Add a Feed to the FeedDict. + * @param feed The new `Feed` to add. + * @returns This `FeedDict`. + */ + addFeed(feed) { + this.add(feed.key, feed.value); + } + /** + * Probe whether a key already exists in the FeedDict. + * @param key + */ + hasKey(key) { + return this.id2Value[key.id] != null; + } + /** + * Get all the SymbolicTensor available in this FeedDict. + */ + names() { + return Object.keys(this.name2Id); + } + /** + * Get the feed value for given key. + * @param key The SymbolicTensor, or its name (as a string), of which the + * value is sought. + * @returns If `key` exists, the corresponding feed value. + * @throws ValueError: If `key` does not exist in this `FeedDict`. + */ + getValue(key) { + if (key instanceof SymbolicTensor) { + if (this.id2Value[key.id] == null) { + throw new ValueError(`Nonexistent key: ${key.name}`); + } + else { + return this.id2Value[key.id]; + } + } + else { + const id = this.name2Id[key]; + if (id == null) { + throw new ValueError(`Feed dict has no SymbolicTensor name: ${key}`); + } + return this.id2Value[id]; + } + } + /** + * Get the feed mask for given key. + * @param key The SymbolicTensor, or its name (as a string), of which the + * value is sought. + * @returns If `key` exists, the corresponding feed mask. + * @throws ValueError: If `key` does not exist in this `FeedDict`. + */ + getMask(key) { + if (key instanceof SymbolicTensor) { + if (this.id2Value[key.id] == null) { + throw new ValueError(`Nonexistent key: ${key.name}`); + } + else { + return this.id2Mask[key.id]; + } + } + else { + const id = this.name2Id[key]; + if (id == null) { + throw new ValueError(`Feed dict has no SymbolicTensor name: ${key}`); + } + return this.id2Mask[id]; + } + } + /** Dispose all mask Tensors held by this object. */ + disposeMasks() { + if (this.id2Mask != null) { + dispose(this.id2Mask); + } + } + } + // Cache for topologically sorted SymbolicTensors for given execution + // targets (i.e., fetches). + const cachedSorted = new LruCache(); + // Cache for recipient count maps for given execution targets (i.e., fetches). + const cachedRecipientCounts = new LruCache(); + function updateCacheMaxEntries(maxEntries) { + if (cachedSorted != null) { + cachedSorted.setMaxEntries(maxEntries); + } + if (cachedRecipientCounts != null) { + cachedRecipientCounts.setMaxEntries(maxEntries); + } + } + /** + * Execute a SymbolicTensor by using concrete feed values. + * + * A `SymbolicTensor` object is a node in a computation graph of TF.js + * Layers. The object is backed by a source layer and input + * `SymbolicTensor`s to the source layer. This method evaluates + * the `call()` method of the source layer, using concrete values of the + * inputs obtained from either + * * `feedDict`, if the input key exists in `feedDict`, or else, + * * a recursive call to `execute()` itself. + * + * @param x: The `SymbolicTensor` to execute. + * @param feedDict: The feed values, as base condition of the recursion. + * execution. + * @param kwargs: Optional keyword arguments. + * @param probe: A probe object (of interface `ExecutionProbe`) used for + * testing memory footprint of `execute` calls. + * @returns Result of the execution. + * @throws ValueError: If any `SymbolicTensor`s from `InputLayer`s + * encountered during the execution lacks a feed value in `feedDict`. + */ + function execute(fetches, feedDict, kwargs, probe) { + const training = kwargs == null ? false : kwargs['training']; + const arrayFetches = Array.isArray(fetches); + const fetchArray = arrayFetches ? fetches : [fetches]; + const outputNames = fetchArray.map(t => t.name); + const finalOutputs = []; + const feedNames = feedDict.names(); + for (const outputName of outputNames) { + if (feedNames.indexOf(outputName) !== -1) { + finalOutputs.push(feedDict.getValue(outputName)); + } + else { + finalOutputs.push(null); + } + } + if (probe != null) { + // For optional probing of memory footprint during execution. + probe.maxNumTensors = -Infinity; + probe.minNumTensors = Infinity; + } + // Check cache. + const fetchAndFeedKey = outputNames.join(',') + '|' + feedDict.names().sort().join(','); + let sorted = cachedSorted.get(fetchAndFeedKey); + let recipientCounts; + if (sorted == null) { + // Cache doesn't contain the desired combination of fetches. Compute + // topological sort for the combination for the first time. + const out = getTopologicalSortAndRecipientCounts(fetchArray, feedDict); + sorted = out.sorted; + recipientCounts = out.recipientCounts; + // Store results in cache for future use. + cachedSorted.put(fetchAndFeedKey, sorted); + cachedRecipientCounts.put(fetchAndFeedKey, recipientCounts); + } + recipientCounts = {}; + if (!training) { + Object.assign(recipientCounts, cachedRecipientCounts.get(fetchAndFeedKey)); + } + const internalFeedDict = new FeedDict(feedDict); + // Start iterative execution on the topologically-sorted SymbolicTensors. + for (let i = 0; i < sorted.length; ++i) { + if (probe != null) { + // For optional probing of memory usage during execution. + const numTensors = memory().numTensors; + if (numTensors > probe.maxNumTensors) { + probe.maxNumTensors = numTensors; + } + if (numTensors < probe.minNumTensors) { + probe.minNumTensors = numTensors; + } + } + const symbolic = sorted[i]; + const srcLayer = symbolic.sourceLayer; + if (srcLayer instanceof InputLayer) { + continue; + } + const inputValues = []; + const inputMasks = []; + const tensorsToDispose = []; + let maskExists = false; + for (const input of symbolic.inputs) { + const value = internalFeedDict.getValue(input); + const mask = internalFeedDict.getMask(input); + inputValues.push(value); + inputMasks.push(mask); + if (mask != null) { + maskExists = true; + } + if (!training) { + recipientCounts[input.name]--; + if (recipientCounts[input.name] === 0 && !feedDict.hasKey(input) && + outputNames.indexOf(input.name) === -1 && !value.isDisposed && + input.sourceLayer.stateful !== true) { + tensorsToDispose.push(value); + } + } + } + if (maskExists) { + kwargs = kwargs || {}; + kwargs['mask'] = inputMasks[0]; + } + const outputTensors = toList(srcLayer.apply(inputValues, kwargs)); + let outputMask = null; + if (srcLayer.supportsMasking) { + outputMask = srcLayer.computeMask(inputValues, inputMasks); + } + const layerOutputs = getNodeOutputs(symbolic); + const outputSymbolicTensors = Array.isArray(layerOutputs) ? layerOutputs : [layerOutputs]; + for (let i = 0; i < outputSymbolicTensors.length; ++i) { + if (!internalFeedDict.hasKey(outputSymbolicTensors[i])) { + internalFeedDict.add(outputSymbolicTensors[i], outputTensors[i], Array.isArray(outputMask) ? outputMask[0] : outputMask); + } + const index = outputNames.indexOf(outputSymbolicTensors[i].name); + if (index !== -1) { + finalOutputs[index] = outputTensors[i]; + } + } + if (!training) { + // Clean up Tensors that are no longer needed. + dispose(tensorsToDispose); + } + } + // NOTE(cais): Unlike intermediate tensors, we don't discard mask + // tensors as we go, because these tensors are sometimes passed over a + // series of mutliple layers, i.e., not obeying the immediate input + // relations in the graph. If this becomes a memory-usage concern, + // we can improve this in the future. + internalFeedDict.disposeMasks(); + return arrayFetches ? finalOutputs : finalOutputs[0]; + } + /** + * Sort the `SymbolicTensor`s topologically, for an array of fetches. + * + * This function calls getTopologicalSortAndRecipientCountsForOneFetch and + * merges their results. + * + * @param fetch The array of fetches requested. Must be a non-empty array. + * @param feedDict The dictionary of fed values. + * @returns sorted: Topologically-sorted array of SymbolicTensors. + * recipientCounts: Recipient counts for all SymbolicTensors in `sorted`. + */ + function getTopologicalSortAndRecipientCounts(fetches, feedDict) { + assert$1(fetches != null && fetches.length > 0, () => `Expected at least one fetch, got none`); + let finalSorted = []; + let finalRecipientMap = {}; + if (fetches.length === 1) { + // Special-casing 1 fetch for efficiency. + const out = getTopologicalSortAndRecipientCountsForOneFetch(fetches[0], feedDict); + finalSorted = out.sorted; + finalRecipientMap = out.recipientMap; + } + else { + const visited = new Set(); + for (const fetch of fetches) { + const { sorted, recipientMap } = getTopologicalSortAndRecipientCountsForOneFetch(fetch, feedDict); + // Merge sorted SymbolicTensor Arrays. + for (const symbolicTensor of sorted) { + if (!visited.has(symbolicTensor.name)) { + finalSorted.push(symbolicTensor); + visited.add(symbolicTensor.name); + } + } + // Merge recipient maps. + for (const name in recipientMap) { + if (finalRecipientMap[name] == null) { + finalRecipientMap[name] = new Set(); + } + recipientMap[name].forEach(recipient => finalRecipientMap[name].add(recipient)); + } + } + } + return { + sorted: finalSorted, + recipientCounts: recipientMap2Counts(finalRecipientMap) + }; + } + function recipientMap2Counts(recipientMap) { + const recipientCounts = {}; + for (const name in recipientMap) { + recipientCounts[name] = recipientMap[name].size; + } + return recipientCounts; + } + /** + * Sort the `SymbolicTensor`s topologically, for a single fetch. + * + * This helper function processes the upstream SymbolicTensors of a single + * fetch. + * + * @param fetch The single fetch requested. + * @param feedDict The dictionary of fed values. + * @returns sorted: Topologically-sorted array of SymbolicTensors. + * recipientMap: Recipient names for all SymbolicTensors in `sorted`. + */ + function getTopologicalSortAndRecipientCountsForOneFetch(fetch, feedDict) { + const visited = new Set(); + const sorted = []; + const recipientMap = {}; + // Put keys of the feedDict into visited first, so they don't have to be + // walked. This is needed in case where there are feeds for intermediate + // SymbolicTensors of the graph. + for (const key of feedDict.names()) { + visited.add(key); + } + const stack = []; + const marks = []; + // Initial population of stack and marks. + stack.push(fetch); + while (stack.length > 0) { + const top = stack[stack.length - 1]; + if (visited.has(top.name)) { + stack.pop(); + continue; + } + const topIsMarked = marks[marks.length - 1] === stack.length - 1; + if (top.inputs.length === 0 || topIsMarked) { + // Input SymbolicTensor or all children have been visited. + stack.pop(); + sorted.push(top); + visited.add(top.name); + if (topIsMarked) { + marks.pop(); + } + } + else { + // A non-input SymbolicTensor whose upstream SymbolicTensors haven't + // been visited yet. Push them onto the stack. + marks.push(stack.length - 1); + for (const input of top.inputs) { + // Increment the recipient count. Note that this needs to happen + // regardless of whether the SymbolicTensor has been visited before. + if (recipientMap[input.name] == null) { + recipientMap[input.name] = new Set(); + } + recipientMap[input.name].add(top.name); + if (visited.has(input.name)) { + continue; // Avoid repeated visits to the same SymbolicTensor. + } + stack.push(input); + } + } + } + return { sorted, recipientMap }; + } + /** + * Get the symbolic output tensors of the node to which a given fetch belongs. + * @param fetch The fetched symbolic tensor. + * @returns The Array of symbolic tensors output by the node to which `fetch` + * belongs. + */ + function getNodeOutputs(fetch) { + let layerOutputs; + if (fetch.sourceLayer.inboundNodes.length === 1) { + layerOutputs = fetch.sourceLayer.output; + } + else { + let nodeIndex = null; + for (let i = 0; i < fetch.sourceLayer.inboundNodes.length; ++i) { + for (const outputTensor of fetch.sourceLayer.inboundNodes[i] + .outputTensors) { + if (outputTensor.id === fetch.id) { + nodeIndex = i; + break; + } + } + } + layerOutputs = fetch.sourceLayer.getOutputAt(nodeIndex); + } + return layerOutputs; + } + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ENV$2 = env(); + /** The max number of entries for the caches of layers' topological sort. */ + ENV$2.registerFlag('TOPOLOGICAL_SORT_CACHE_MAX_ENTRIES', () => 100, updateCacheMaxEntries); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Helper function used by many of the Constraints to find the L2Norms. + */ + function calcL2Norms(w, axis) { + return tidy(() => sqrt$2(sum$3(mul(w, w), axis, true))); + } + /** + * Base class for functions that impose constraints on weight values + * + * @doc { + * heading: 'Constraints', + * subheading: 'Classes', + * namespace: 'constraints' + * } + */ + class Constraint extends Serializable { + getConfig() { + return {}; + } + } + class MaxNorm extends Constraint { + constructor(args) { + super(); + this.defaultMaxValue = 2; + this.defaultAxis = 0; + this.maxValue = + args.maxValue != null ? args.maxValue : this.defaultMaxValue; + this.axis = args.axis != null ? args.axis : this.defaultAxis; + } + apply(w) { + return tidy(() => { + const norms = calcL2Norms(w, this.axis); + const desired = clipByValue$2(norms, 0, this.maxValue); + return mul(w, div$1(desired, add$3(epsilon$1(), norms))); + }); + } + getConfig() { + return { maxValue: this.maxValue, axis: this.axis }; + } + } + /** @nocollapse */ + MaxNorm.className = 'MaxNorm'; + registerClass(MaxNorm); + class UnitNorm extends Constraint { + constructor(args) { + super(); + this.defaultAxis = 0; + this.axis = args.axis != null ? args.axis : this.defaultAxis; + } + apply(w) { + return tidy(() => div$1(w, add$3(epsilon$1(), calcL2Norms(w, this.axis)))); + } + getConfig() { + return { axis: this.axis }; + } + } + /** @nocollapse */ + UnitNorm.className = 'UnitNorm'; + registerClass(UnitNorm); + class NonNeg extends Constraint { + apply(w) { + return relu$2(w); + } + } + /** @nocollapse */ + NonNeg.className = 'NonNeg'; + registerClass(NonNeg); + class MinMaxNorm extends Constraint { + constructor(args) { + super(); + this.defaultMinValue = 0.0; + this.defaultMaxValue = 1.0; + this.defaultRate = 1.0; + this.defaultAxis = 0; + this.minValue = + args.minValue != null ? args.minValue : this.defaultMinValue; + this.maxValue = + args.maxValue != null ? args.maxValue : this.defaultMaxValue; + this.rate = args.rate != null ? args.rate : this.defaultRate; + this.axis = args.axis != null ? args.axis : this.defaultAxis; + } + apply(w) { + return tidy(() => { + const norms = calcL2Norms(w, this.axis); + const desired = add$3(mul(this.rate, clipByValue$2(norms, this.minValue, this.maxValue)), mul(1.0 - this.rate, norms)); + return mul(w, div$1(desired, add$3(epsilon$1(), norms))); + }); + } + getConfig() { + return { + minValue: this.minValue, + maxValue: this.maxValue, + rate: this.rate, + axis: this.axis + }; + } + } + /** @nocollapse */ + MinMaxNorm.className = 'MinMaxNorm'; + registerClass(MinMaxNorm); + // Maps the JavaScript-like identifier keys to the corresponding registry + // symbols. + const CONSTRAINT_IDENTIFIER_REGISTRY_SYMBOL_MAP = { + 'maxNorm': 'MaxNorm', + 'minMaxNorm': 'MinMaxNorm', + 'nonNeg': 'NonNeg', + 'unitNorm': 'UnitNorm' + }; + function serializeConstraint(constraint) { + return serializeKerasObject(constraint); + } + function deserializeConstraint(config, customObjects = {}) { + return deserializeKerasObject(config, SerializationMap.getMap().classNameMap, customObjects, 'constraint'); + } + function getConstraint(identifier) { + if (identifier == null) { + return null; + } + if (typeof identifier === 'string') { + const className = identifier in CONSTRAINT_IDENTIFIER_REGISTRY_SYMBOL_MAP ? + CONSTRAINT_IDENTIFIER_REGISTRY_SYMBOL_MAP[identifier] : + identifier; + const config = { className, config: {} }; + return deserializeConstraint(config); + } + else if (identifier instanceof Constraint) { + return identifier; + } + else { + return deserializeConstraint(identifier); + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * MaxNorm weight constraint. + * + * Constrains the weights incident to each hidden unit + * to have a norm less than or equal to a desired value. + * + * References + * - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting + * Srivastava, Hinton, et al. + * 2014](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) + * + * @doc {heading: 'Constraints',namespace: 'constraints'} + */ + function maxNorm(args) { + return new MaxNorm(args); + } + /** + * Constrains the weights incident to each hidden unit to have unit norm. + * + * @doc {heading: 'Constraints', namespace: 'constraints'} + */ + function unitNorm(args) { + return new UnitNorm(args); + } + /** + * Constrains the weight to be non-negative. + * + * @doc {heading: 'Constraints', namespace: 'constraints'} + */ + function nonNeg() { + return new NonNeg(); + } + /** @doc {heading: 'Constraints', namespace: 'constraints'} */ + function minMaxNorm(config) { + return new MinMaxNorm(config); + } + + var exports_constraints = /*#__PURE__*/Object.freeze({ + __proto__: null, + maxNorm: maxNorm, + minMaxNorm: minMaxNorm, + nonNeg: nonNeg, + unitNorm: unitNorm + }); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Initializer that generates tensors initialized to 0. + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function zeros$1() { + return new Zeros(); + } + /** + * Initializer that generates tensors initialized to 1. + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function ones() { + return new Ones(); + } + /** + * Initializer that generates values initialized to some constant. + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function constant(args) { + return new Constant(args); + } + /** + * Initializer that generates random values initialized to a uniform + * distribution. + * + * Values will be distributed uniformly between the configured minval and + * maxval. + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function randomUniform(args) { + return new RandomUniform(args); + } + /** + * Initializer that generates random values initialized to a normal + * distribution. + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function randomNormal(args) { + return new RandomNormal(args); + } + /** + * Initializer that generates random values initialized to a truncated normal + * distribution. + * + * These values are similar to values from a `RandomNormal` except that values + * more than two standard deviations from the mean are discarded and re-drawn. + * This is the recommended initializer for neural network weights and filters. + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function truncatedNormal(args) { + return new TruncatedNormal(args); + } + /** + * Initializer that generates the identity matrix. + * Only use for square 2D matrices. + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function identity$2(args) { + return new Identity(args); + } + /** + * Initializer capable of adapting its scale to the shape of weights. + * With distribution=NORMAL, samples are drawn from a truncated normal + * distribution centered on zero, with `stddev = sqrt(scale / n)` where n is: + * - number of input units in the weight tensor, if mode = FAN_IN. + * - number of output units, if mode = FAN_OUT. + * - average of the numbers of input and output units, if mode = FAN_AVG. + * With distribution=UNIFORM, + * samples are drawn from a uniform distribution + * within [-limit, limit], with `limit = sqrt(3 * scale / n)`. + * + * @doc {heading: 'Initializers',namespace: 'initializers'} + */ + function varianceScaling(config) { + return new VarianceScaling(config); + } + /** + * Glorot uniform initializer, also called Xavier uniform initializer. + * It draws samples from a uniform distribution within [-limit, limit] + * where `limit` is `sqrt(6 / (fan_in + fan_out))` + * where `fan_in` is the number of input units in the weight tensor + * and `fan_out` is the number of output units in the weight tensor + * + * Reference: + * Glorot & Bengio, AISTATS 2010 + * http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf. + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function glorotUniform(args) { + return new GlorotUniform(args); + } + /** + * Glorot normal initializer, also called Xavier normal initializer. + * It draws samples from a truncated normal distribution centered on 0 + * with `stddev = sqrt(2 / (fan_in + fan_out))` + * where `fan_in` is the number of input units in the weight tensor + * and `fan_out` is the number of output units in the weight tensor. + * + * Reference: + * Glorot & Bengio, AISTATS 2010 + * http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function glorotNormal(args) { + return new GlorotNormal(args); + } + /** + * He normal initializer. + * + * It draws samples from a truncated normal distribution centered on 0 + * with `stddev = sqrt(2 / fanIn)` + * where `fanIn` is the number of input units in the weight tensor. + * + * Reference: + * He et al., http://arxiv.org/abs/1502.01852 + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function heNormal(args) { + return new HeNormal(args); + } + /** + * He uniform initializer. + * + * It draws samples from a uniform distribution within [-limit, limit] + * where `limit` is `sqrt(6 / fan_in)` + * where `fanIn` is the number of input units in the weight tensor. + * + * Reference: + * He et al., http://arxiv.org/abs/1502.01852 + * + * @doc {heading: 'Initializers',namespace: 'initializers'} + */ + function heUniform(args) { + return new HeUniform(args); + } + /** + * LeCun normal initializer. + * + * It draws samples from a truncated normal distribution centered on 0 + * with `stddev = sqrt(1 / fanIn)` + * where `fanIn` is the number of input units in the weight tensor. + * + * References: + * [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515) + * [Efficient Backprop](http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf) + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function leCunNormal(args) { + return new LeCunNormal(args); + } + /** + * LeCun uniform initializer. + * + * It draws samples from a uniform distribution in the interval + * `[-limit, limit]` with `limit = sqrt(3 / fanIn)`, + * where `fanIn` is the number of input units in the weight tensor. + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function leCunUniform(args) { + return new LeCunUniform(args); + } + /** + * Initializer that generates a random orthogonal matrix. + * + * Reference: + * [Saxe et al., http://arxiv.org/abs/1312.6120](http://arxiv.org/abs/1312.6120) + * + * @doc {heading: 'Initializers', namespace: 'initializers'} + */ + function orthogonal(args) { + return new Orthogonal(args); + } + + var exports_initializers = /*#__PURE__*/Object.freeze({ + __proto__: null, + constant: constant, + glorotNormal: glorotNormal, + glorotUniform: glorotUniform, + heNormal: heNormal, + heUniform: heUniform, + identity: identity$2, + leCunNormal: leCunNormal, + leCunUniform: leCunUniform, + ones: ones, + orthogonal: orthogonal, + randomNormal: randomNormal, + randomUniform: randomUniform, + truncatedNormal: truncatedNormal, + varianceScaling: varianceScaling, + zeros: zeros$1 + }); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Turn any Scalar values in a Logs object into actual number values. + * + * @param logs The `Logs` object to be resolved in place. + */ + async function resolveScalarsInLogs(logs) { + if (logs == null) { + return; + } + const promises = []; + const keys = []; + const scalarsToDispose = []; + for (const key in logs) { + const value = logs[key]; + if (typeof value !== 'number') { + const valueScalar = value; + promises.push(valueScalar.data()); + keys.push(key); + scalarsToDispose.push(valueScalar); + } + } + if (promises.length > 0) { + const values = await Promise.all(promises); + for (let i = 0; i < values.length; ++i) { + logs[keys[i]] = values[i][0]; + } + // Dispose the original scalar tensors. + dispose(scalarsToDispose); + } + } + /** + * Dispose all Tensors in an UnresolvedLogs object. + * + * @param logs An `UnresolvedLogs` object potentially containing `tf.Tensor`s in + * places where the values can be `tf.Tensor` or `number`. + */ + function disposeTensorsInLogs(logs) { + if (logs == null) { + return; + } + for (const key in logs) { + const value = logs[key]; + if (typeof value !== 'number') { + value.dispose(); + } + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** Verbosity logging level when fitting a model. */ + var ModelLoggingVerbosity; + (function (ModelLoggingVerbosity) { + ModelLoggingVerbosity[ModelLoggingVerbosity["SILENT"] = 0] = "SILENT"; + ModelLoggingVerbosity[ModelLoggingVerbosity["VERBOSE"] = 1] = "VERBOSE"; + })(ModelLoggingVerbosity || (ModelLoggingVerbosity = {})); + /** How often to yield to the main thread when training (in ms). */ + const DEFAULT_YIELD_EVERY_MS = 125; + /** + * Abstract base class used to build new callbacks. + * + * The `logs` dictionary that callback methods take as argument will contain + * keys for quantities relevant to the current batch or epoch. + * + * Currently, the `.fit()` method of the `Sequential` model class + * will include the following quantities in the `logs` that + * it passes to its callbacks: + * + * onEpochEnd: Logs include `acc` and `loss`, and optionally include `valLoss` + * (if validation is enabled in `fit`), and `valAcc` (if validation and + * accuracy monitoring are enabled). + * onBatchBegin: Logs include `size`, the number of samples in the current + * batch. + * onBatchEnd: Logs include `loss`, and optionally `acc` (if accuracy monitoring + * is enabled). + */ + class BaseCallback { + constructor() { + // TODO(michaelterry): This type is a best guess. + this.validationData = null; + } + setParams(params) { + this.params = params; + } + async onEpochBegin(epoch, logs) { } + async onEpochEnd(epoch, logs) { } + async onBatchBegin(batch, logs) { } + async onBatchEnd(batch, logs) { } + async onTrainBegin(logs) { } + async onTrainEnd(logs) { } + // LayersModel needs to call Callback.setModel(), but cannot actually depend + // on Callback because that creates a cyclic dependency. Providing this no-op + // method on BaseCallback breaks the cycle: this way LayersModel can depend on + // BaseCallback but not on Callback. The argument is typed as `Container` + // (the superclass of LayersModel) to avoid recapitulating the cycle. Callback + // overrides this method and enforces that the argument is really a + // LayersModel. + setModel(model) { + // Do nothing. Use Callback instead of BaseCallback to track the model. + } + } + /** + * Container abstracting a list of callbacks. + */ + class CallbackList { + // TODO(cais): When the need arises, uncomment the following lines and + // implement the queue for time values. + // private deltaTBatch: number; + // private deltaTsBatchBegin: Array; + // private deltaTsBatchEnd: Array; + /** + * Constructor of CallbackList. + * @param callbacks Array of `Callback` instances. + * @param queueLength Queue length for keeping running statistics over + * callback execution time. + */ + constructor(callbacks, queueLength = 10) { + // TODO(cais): Make use of queueLength when implementing the queue for time + // values. + if (callbacks == null) { + callbacks = []; + } + this.callbacks = callbacks; + this.queueLength = queueLength; + } + append(callback) { + this.callbacks.push(callback); + } + setParams(params) { + for (const callback of this.callbacks) { + callback.setParams(params); + } + } + setModel(model) { + for (const callback of this.callbacks) { + callback.setModel(model); + } + } + /** + * Called at the start of an epoch. + * @param epoch Index of epoch. + * @param logs Dictionary of logs. + */ + async onEpochBegin(epoch, logs) { + if (logs == null) { + logs = {}; + } + for (const callback of this.callbacks) { + await callback.onEpochBegin(epoch, logs); + } + } + /** + * Called at the end of an epoch. + * @param epoch Index of epoch. + * @param logs Dictionary of logs. + */ + async onEpochEnd(epoch, logs) { + if (logs == null) { + logs = {}; + } + for (const callback of this.callbacks) { + await callback.onEpochEnd(epoch, logs); + } + } + /** + * Called right before processing a batch. + * @param batch Index of batch within the current epoch. + * @param logs Dictionary of logs. + */ + async onBatchBegin(batch, logs) { + if (logs == null) { + logs = {}; + } + for (const callback of this.callbacks) { + await callback.onBatchBegin(batch, logs); + } + } + /** + * Called at the end of a batch. + * @param batch Index of batch within the current epoch. + * @param logs Dictionary of logs. + */ + async onBatchEnd(batch, logs) { + if (logs == null) { + logs = {}; + } + for (const callback of this.callbacks) { + await callback.onBatchEnd(batch, logs); + } + } + /** + * Called at the beginning of training. + * @param logs Dictionary of logs. + */ + async onTrainBegin(logs) { + if (logs == null) { + logs = {}; + } + for (const callback of this.callbacks) { + await callback.onTrainBegin(logs); + } + } + /** + * Called at the end of training. + * @param logs Dictionary of logs. + */ + async onTrainEnd(logs) { + if (logs == null) { + logs = {}; + } + for (const callback of this.callbacks) { + await callback.onTrainEnd(logs); + } + } + } + /** + * Callback that accumulates epoch averages of metrics. + * + * This callback is automatically applied to every LayersModel. + */ + class BaseLogger extends BaseCallback { + constructor() { + super(); + } + async onEpochBegin(epoch) { + this.seen = 0; + this.totals = {}; + } + async onBatchEnd(batch, logs) { + if (logs == null) { + logs = {}; + } + const batchSize = logs['size'] == null ? 0 : logs['size']; + this.seen += batchSize; + for (const key in logs) { + const value = logs[key]; + if (typeof value === 'number') { + if (!this.totals.hasOwnProperty(key)) { + this.totals[key] = 0; + } + this.totals[key] = this.totals[key] + value * batchSize; + } + else { + let oldTotalsToDispose; + if (key in this.totals) { + oldTotalsToDispose = this.totals[key]; + } + else { + this.totals[key] = 0; + } + const total = tidy(() => add$3((this.totals[key]), mul(value, batchSize))); + this.totals[key] = total; + if (oldTotalsToDispose != null) { + oldTotalsToDispose.dispose(); + } + } + } + } + async onEpochEnd(epoch, logs) { + if (logs != null) { + for (const key of this.params['metrics']) { + if (this.totals[key] == null) { + continue; + } + if (typeof this.totals[key] === 'number') { + logs[key] = this.totals[key] / this.seen; + } + else { + tidy(() => { + const log = mul(div$1(1, this.seen), this.totals[key]); + logs[key] = log; + this.totals[key].dispose(); + keep(logs[key]); + }); + } + } + } + } + } + /** + * Callback that records events into a `History` object. This callback is + * automatically applied to every TF.js Layers model. The `History` object + * gets returned by the `fit` method of models. + */ + class History extends BaseCallback { + async onTrainBegin(logs) { + this.epoch = []; + this.history = {}; + } + async onEpochEnd(epoch, logs) { + if (logs == null) { + logs = {}; + } + this.epoch.push(epoch); + for (const key in logs) { + if (this.history[key] == null) { + this.history[key] = []; + } + this.history[key].push(logs[key]); + } + } + /** + * Await the values of all losses and metrics. + */ + async syncData() { + const promises = []; + const keys = []; + const indices = []; + for (const key in this.history) { + const valueArray = this.history[key]; + for (let i = 0; i < valueArray.length; ++i) { + if (typeof valueArray[i] !== 'number') { + const valueScalar = valueArray[i]; + promises.push(valueScalar.data()); + keys.push(key); + indices.push(i); + } + } + } + const values = await Promise.all(promises); + for (let n = 0; n < values.length; ++n) { + const tensorToDispose = this.history[keys[n]][indices[n]]; + tensorToDispose.dispose(); + this.history[keys[n]][indices[n]] = values[n][0]; + } + } + } + /** + * Custom callback for training. + */ + class CustomCallback extends BaseCallback { + constructor(args, yieldEvery) { + super(); + this.currentEpoch = 0; + this.nowFunc = args.nowFunc; + this.nextFrameFunc = args.nextFrameFunc || nextFrame; + this.yieldEvery = yieldEvery || 'auto'; + if (this.yieldEvery === 'auto') { + this.yieldEvery = DEFAULT_YIELD_EVERY_MS; + } + if (this.yieldEvery === 'never' && args.onYield != null) { + throw new Error('yieldEvery is `never` but you provided an `onYield` callback. ' + + 'Either change `yieldEvery` or remove the callback'); + } + if (isNumber(this.yieldEvery)) { + // Decorate `maybeWait` so it will be called at most once every + // `yieldEvery` ms. + this.maybeWait = debounce(this.maybeWait.bind(this), this.yieldEvery, this.nowFunc); + } + this.trainBegin = args.onTrainBegin; + this.trainEnd = args.onTrainEnd; + this.epochBegin = args.onEpochBegin; + this.epochEnd = args.onEpochEnd; + this.batchBegin = args.onBatchBegin; + this.batchEnd = args.onBatchEnd; + this.yield = args.onYield; + } + async maybeWait(epoch, batch, logs) { + const ps = []; + if (this.yield != null) { + await resolveScalarsInLogs(logs); + ps.push(this.yield(epoch, batch, logs)); + } + ps.push(this.nextFrameFunc()); + await Promise.all(ps); + } + async onEpochBegin(epoch, logs) { + this.currentEpoch = epoch; + if (this.epochBegin != null) { + await resolveScalarsInLogs(logs); + await this.epochBegin(epoch, logs); + } + } + async onEpochEnd(epoch, logs) { + const ps = []; + if (this.epochEnd != null) { + await resolveScalarsInLogs(logs); + ps.push(this.epochEnd(epoch, logs)); + } + if (this.yieldEvery === 'epoch') { + ps.push(this.nextFrameFunc()); + } + await Promise.all(ps); + } + async onBatchBegin(batch, logs) { + if (this.batchBegin != null) { + await resolveScalarsInLogs(logs); + await this.batchBegin(batch, logs); + } + } + async onBatchEnd(batch, logs) { + const ps = []; + if (this.batchEnd != null) { + await resolveScalarsInLogs(logs); + ps.push(this.batchEnd(batch, logs)); + } + if (this.yieldEvery === 'batch') { + ps.push(this.nextFrameFunc()); + } + else if (isNumber(this.yieldEvery)) { + ps.push(this.maybeWait(this.currentEpoch, batch, logs)); + } + await Promise.all(ps); + } + async onTrainBegin(logs) { + if (this.trainBegin != null) { + await resolveScalarsInLogs(logs); + await this.trainBegin(logs); + } + } + async onTrainEnd(logs) { + if (this.trainEnd != null) { + await resolveScalarsInLogs(logs); + await this.trainEnd(logs); + } + } + } + /** + * Standardize callbacks or configurations of them to an Array of callbacks. + */ + function standardizeCallbacks(callbacks, yieldEvery) { + if (callbacks == null) { + callbacks = {}; + } + if (callbacks instanceof BaseCallback) { + return [callbacks]; + } + if (Array.isArray(callbacks) && callbacks[0] instanceof BaseCallback) { + return callbacks; + } + // Convert custom callback configs to custom callback objects. + const callbackConfigs = toList(callbacks); + return callbackConfigs.map(callbackConfig => new CustomCallback(callbackConfig, yieldEvery)); + } + /** + * A global registry for callback constructors to be used during + * LayersModel.fit(). + */ + class CallbackConstructorRegistry { + /** + * Blocks public access to constructor. + */ + constructor() { } + /** + * Register a tf.LayersModel.fit() callback constructor. + * + * The registered callback constructor will be used to instantiate + * callbacks for every tf.LayersModel.fit() call afterwards. + * + * @param verbosityLevel Level of verbosity at which the `callbackConstructor` + * is to be reigstered. + * @param callbackConstructor A no-arg constructor for `tf.Callback`. + * @throws Error, if the same callbackConstructor has been registered before, + * either at the same or a different `verbosityLevel`. + */ + static registerCallbackConstructor(verbosityLevel, callbackConstructor) { + assert$1(verbosityLevel >= 0 && Number.isInteger(verbosityLevel), () => `Verbosity level is expected to be an integer >= 0, ` + + `but got ${verbosityLevel}`); + CallbackConstructorRegistry.checkForDuplicate(callbackConstructor); + if (CallbackConstructorRegistry.constructors[verbosityLevel] == null) { + CallbackConstructorRegistry.constructors[verbosityLevel] = []; + } + CallbackConstructorRegistry.constructors[verbosityLevel].push(callbackConstructor); + } + static checkForDuplicate(callbackConstructor) { + for (const levelName in CallbackConstructorRegistry.constructors) { + const constructors = CallbackConstructorRegistry.constructors[+levelName]; + constructors.forEach(ctor => { + if (ctor === callbackConstructor) { + throw new ValueError('Duplicate callback constructor.'); + } + }); + } + } + /** + * Clear all registered callback constructors. + */ + static clear() { + CallbackConstructorRegistry.constructors = {}; + } + /** + * Create callbacks using the registered callback constructors. + * + * Given `verbosityLevel`, all constructors registered at that level or above + * will be called and the instantiated callbacks will be used. + * + * @param verbosityLevel: Level of verbosity. + */ + static createCallbacks(verbosityLevel) { + const constructors = []; + for (const levelName in CallbackConstructorRegistry.constructors) { + const level = +levelName; + if (verbosityLevel >= level) { + constructors.push(...CallbackConstructorRegistry.constructors[level]); + } + } + return constructors.map(ctor => new ctor()); + } + } + CallbackConstructorRegistry.constructors = {}; + function configureCallbacks(callbacks, verbose, epochs, initialEpoch, numTrainSamples, stepsPerEpoch, batchSize, doValidation, callbackMetrics) { + const history = new History(); + const actualCallbacks = [ + new BaseLogger(), ...CallbackConstructorRegistry.createCallbacks(verbose) + ]; + if (callbacks != null) { + actualCallbacks.push(...callbacks); + } + actualCallbacks.push(history); + const callbackList = new CallbackList(actualCallbacks); + // TODO(cais): Figure out when this LayersModel instance can have a + // dynamically + // set property called 'callback_model' as in PyKeras. + callbackList.setParams({ + epochs, + initialEpoch, + samples: numTrainSamples, + steps: stepsPerEpoch, + batchSize, + verbose, + doValidation, + metrics: callbackMetrics, + }); + return { callbackList, history }; + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Instantiate a layer from a config dictionary. + * @param config dict of the form {class_name: str, config: dict} + * @param customObjects dict mapping class names (or function names) + * of custom (non-Keras) objects to class/functions + * @param fastWeightInit Optional flag to use fast weight initialization + * during deserialization. This is applicable to cases in which + * the initialization will be immediately overwritten by loaded weight + * values. Default: `false`. + * @returns Layer instance (may be LayersModel, Sequential, Layer...) + */ + function deserialize(config, customObjects = {}, fastWeightInit = false) { + return deserializeKerasObject(config, SerializationMap.getMap().classNameMap, customObjects, 'layer', fastWeightInit); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Normalizes a tensor wrt the L2 norm alongside the specified axis. + * @param x + * @param axis Axis along which to perform normalization. + */ + function l2Normalize(x, axis) { + return tidy(() => { + if (x.dtype !== 'float32') { + x = cast$3(x, 'float32'); + } + const squareSum = sum$3(square$1(x), axis, true); + const epsilonTensor = fill$2(squareSum.shape, epsilon$1()); + const norm = sqrt$2(maximum$4(squareSum, epsilonTensor)); + return div$1(x, norm); + }); + } + function meanSquaredError$1(yTrue, yPred) { + return tidy(() => mean$3(square$1(sub$2(yPred, yTrue)), -1)); + } + function meanAbsoluteError$1(yTrue, yPred) { + return tidy(() => mean$3(abs$2(sub$2(yPred, yTrue)), -1)); + } + function meanAbsolutePercentageError$1(yTrue, yPred) { + return tidy(() => { + const diff = sub$2(yTrue, yPred); + const clippedTrue = clipByValue$2(abs$2(yTrue), epsilon$1(), Number.MAX_VALUE); + const absResult = abs$2(div$1(diff, clippedTrue)); + return mul(100, mean$3(absResult, -1)); + }); + } + function meanSquaredLogarithmicError(yTrue, yPred) { + return tidy(() => { + const clippedPred = clipByValue$2(yPred, epsilon$1(), Number.MAX_VALUE); + const firstLog = log$2(add$3(1, clippedPred)); + const clippedTrue = clipByValue$2(yTrue, epsilon$1(), Number.MAX_VALUE); + const secondLog = log$2(add$3(1, clippedTrue)); + return mean$3(square$1(sub$2(firstLog, secondLog)), -1); + }); + } + function squaredHinge(yTrue, yPred) { + return tidy(() => { + const maxResult = maximum$4(0, sub$2(1, mul(yTrue, yPred))); + return mean$3(square$1(maxResult), -1); + }); + } + function hinge(yTrue, yPred) { + return tidy(() => { + const maxResult = maximum$4(0, sub$2(1, mul(yTrue, yPred))); + return mean$3(maxResult, -1); + }); + } + function categoricalHinge(yTrue, yPred) { + return tidy(() => { + const pos = sum$3(mul(yTrue, yPred), -1); + const neg = max$3(mul(sub$2(1, yTrue), yPred), -1); + return maximum$4(0, add$3(1, sub$2(neg, pos))); + }); + } + /** + * Logarithm of the hyperbolic cosine of the prediction error. + * + * `log(cosh(x))` is approximately equal to `(x ** 2) / 2` for small `x` and + * to `abs(x) - log(2)` for large `x`. This means that 'logcosh' works mostly + * like the mean squared error, but will not be so strongly affected by the + * occasional wildly incorrect prediction. + */ + function logcosh(yTrue, yPred) { + return tidy(() => { + const log2 = Math.log(2); + const predictionDiff = sub$2(yPred, yTrue); + const logcoshResult = sub$2(add$3(predictionDiff, softplus$2(mul(-2, predictionDiff))), log2); + return mean$3(logcoshResult, -1); + }); + } + function categoricalCrossentropy$2(target, output, fromLogits = false) { + return tidy(() => { + if (fromLogits) { + output = softmax$3(output); + } + else { + // scale preds so that the class probabilities of each sample sum to 1. + const outputSum = sum$3(output, output.shape.length - 1, true); + output = div$1(output, outputSum); + } + output = clipByValue$2(output, epsilon$1(), 1 - epsilon$1()); + return neg$2(sum$3(mul(cast$3(target, 'float32'), log$2(output)), output.shape.length - 1)); + }); + } + /** + * Categorical crossentropy with integer targets. + * + * @param target An integer tensor. + * @param output A tensor resulting from a softmax (unless `fromLogits` is + * `true`, in which case `output` is expected to be the logits). + * @param fromLogits Boolean, whether `output` is the result of a softmax, or is + * a tensor of logits. + */ + function sparseCategoricalCrossentropy$1(target, output, fromLogits = false) { + return tidy(() => { + const flatTarget = cast$3(floor$2(flatten$1(target)), 'int32'); + output = clipByValue$2(output, epsilon$1(), 1 - epsilon$1()); + const outputShape = output.shape; + const oneHotTarget = reshape$3(oneHot$3(flatTarget, outputShape[outputShape.length - 1]), outputShape); + return categoricalCrossentropy$2(oneHotTarget, output, fromLogits); + }); + } + /** + * From TensorFlow's implementation in nn_impl.py: + * + * For brevity, let `x = logits`, `z = labels`. The logistic loss is + * z * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x)) + * = z * -log(1 / (1 + exp(-x))) + (1 - z) * -log(exp(-x) / (1 + exp(-x))) + * = z * log(1 + exp(-x)) + (1 - z) * (-log(exp(-x)) + log(1 + exp(-x))) + * = z * log(1 + exp(-x)) + (1 - z) * (x + log(1 + exp(-x)) + * = (1 - z) * x + log(1 + exp(-x)) + * = x - x * z + log(1 + exp(-x)) + * For x < 0, to avoid overflow in exp(-x), we reformulate the above + * x - x * z + log(1 + exp(-x)) + * = log(exp(x)) - x * z + log(1 + exp(-x)) + * = - x * z + log(1 + exp(x)) + * Hence, to ensure stability and avoid overflow, the implementation uses this + * equivalent formulation + * max(x, 0) - x * z + log(1 + exp(-abs(x))) + * + * @param labels The labels. + * @param logits The logits. + */ + function sigmoidCrossEntropyWithLogits(labels, logits) { + if (!arraysEqual(labels.shape, logits.shape)) { + throw new ValueError(`logits and labels must have the same shape, but got shapes ` + + `${JSON.stringify(labels.shape)} and ${JSON.stringify(logits.shape)}`); + } + return tidy(() => { + // The logistic loss formula from above is + // x - x * z + log(1 + exp(-x)) + // For x < 0, a more numerically stable formula is + // -x * z + log(1 + exp(x)) + // Note that these two expressions can be combined into the following: + // max(x, 0) - x * z + log(1 + exp(-abs(x))) + const reluLogits = relu$2(logits); + const negAbsLogits = neg$2(abs$2(logits)); + return add$3(sub$2(reluLogits, mul(logits, labels)), log1p$2(exp$2(negAbsLogits))); + }); + } + function binaryCrossentropy$2(yTrue, yPred) { + return tidy(() => { + let y; + y = clipByValue$2(yPred, epsilon$1(), 1 - epsilon$1()); + y = log$2(div$1(y, sub$2(1, y))); + return mean$3(sigmoidCrossEntropyWithLogits(yTrue, y), -1); + }); + } + function kullbackLeiblerDivergence(yTrue, yPred) { + return tidy(() => { + const clippedTrue = clipByValue$2(yTrue, epsilon$1(), 1); + const clippedPred = clipByValue$2(yPred, epsilon$1(), 1); + return sum$3(mul(yTrue, log$2(div$1(clippedTrue, clippedPred))), -1); + }); + } + function poisson(yTrue, yPred) { + return tidy(() => { + const logPred = log$2(add$3(epsilon$1(), yPred)); + return mean$3(sub$2(yPred, mul(yTrue, logPred)), -1); + }); + } + function cosineProximity$1(yTrue, yPred) { + return tidy(() => { + const trueNormalized = l2Normalize(yTrue, -1); + const predNormalized = l2Normalize(yPred, -1); + const trueXPred = mul(trueNormalized, predNormalized); + return neg$2(sum$3(trueXPred, -1)); + }); + } + const mse$2 = meanSquaredError$1; + const MSE$2 = meanSquaredError$1; + const mae$1 = meanAbsoluteError$1; + const MAE$1 = meanAbsoluteError$1; + const mape$2 = meanAbsolutePercentageError$1; + const MAPE$2 = meanAbsolutePercentageError$1; + const msle = meanSquaredLogarithmicError; + const MSLE = meanSquaredLogarithmicError; + const kld = kullbackLeiblerDivergence; + const KLD = kullbackLeiblerDivergence; + const cosine$1 = cosineProximity$1; + // TODO(michaelterry): Add deserialize() function. + const lossesMap = { + meanSquaredError: meanSquaredError$1, + meanAbsoluteError: meanAbsoluteError$1, + meanAbsolutePercentageError: meanAbsolutePercentageError$1, + meanSquaredLogarithmicError, + squaredHinge, + hinge, + categoricalHinge, + logcosh, + categoricalCrossentropy: categoricalCrossentropy$2, + sparseCategoricalCrossentropy: sparseCategoricalCrossentropy$1, + binaryCrossentropy: binaryCrossentropy$2, + kullbackLeiblerDivergence, + poisson, + cosineProximity: cosineProximity$1 + }; + // Porting note: This diverges from the PyKeras implementation and may need to + // change based on (de)serialization requirements. + function get$1(identifierOrFn) { + if (typeof identifierOrFn === 'string') { + if (identifierOrFn in lossesMap) { + return lossesMap[identifierOrFn]; + } + let errMsg = `Unknown loss ${identifierOrFn}`; + if (identifierOrFn.toLowerCase().includes('softmaxcrossentropy')) { + errMsg = `Unknown loss ${identifierOrFn}. ` + + 'Use "categoricalCrossentropy" as the string name for ' + + 'tf.losses.softmaxCrossEntropy'; + } + throw new ValueError(errMsg); + } + else { + return identifierOrFn; + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + function binaryAccuracy$1(yTrue, yPred) { + return tidy(() => { + const threshold = mul(.5, onesLike$3(yPred)); + const yPredThresholded = cast$2(greater$3(yPred, threshold), yTrue.dtype); + return mean$3(equal$2(yTrue, yPredThresholded), -1); + }); + } + function categoricalAccuracy$1(yTrue, yPred) { + return tidy(() => cast$2(equal$2(argMax$2(yTrue, -1), argMax$2(yPred, -1)), 'float32')); + } + function truePositives(yTrue, yPred) { + return tidy(() => { + return cast$3(sum$3(logicalAnd$2(equal$2(yTrue, 1), equal$2(yPred, 1))), 'float32'); + }); + } + function falseNegatives(yTrue, yPred) { + return tidy(() => { + return cast$3(sum$3(logicalAnd$2(equal$2(yTrue, 1), equal$2(yPred, 0))), 'float32'); + }); + } + function falsePositives(yTrue, yPred) { + return tidy(() => { + return cast$3(sum$3(logicalAnd$2(equal$2(yTrue, 0), equal$2(yPred, 1))), 'float32'); + }); + } + function precision$1(yTrue, yPred) { + return tidy(() => { + const tp = truePositives(yTrue, yPred); + const fp = falsePositives(yTrue, yPred); + const denominator = add$3(tp, fp); + return cast$3(where(greater$3(denominator, 0), div$1(tp, denominator), 0), 'float32'); + }); + } + function recall$1(yTrue, yPred) { + return tidy(() => { + const tp = truePositives(yTrue, yPred); + const fn = falseNegatives(yTrue, yPred); + const denominator = add$3(tp, fn); + return cast$3(where(greater$3(denominator, 0), div$1(tp, denominator), 0), 'float32'); + }); + } + function binaryCrossentropy$1(yTrue, yPred) { + return binaryCrossentropy$2(yTrue, yPred); + } + function sparseCategoricalAccuracy$1(yTrue, yPred) { + if (yTrue.rank === yPred.rank) { + yTrue = squeeze(yTrue, [yTrue.rank - 1]); + } + yPred = argMax$2(yPred, -1); + if (yPred.dtype !== yTrue.dtype) { + yPred = cast$3(yPred, yTrue.dtype); + } + return cast$3(equal$2(yTrue, yPred), 'float32'); + } + function topKCategoricalAccuracy(yTrue, yPred) { + throw new NotImplementedError(); + } + function sparseTopKCategoricalAccuracy(yTrue, yPred) { + throw new NotImplementedError(); + } + function r2Score$1(yTrue, yPred) { + return tidy(() => { + const sumSquaresResiduals = yTrue.sub(yPred).square().sum(); + const sumSquares = yTrue.sub(yTrue.mean()).square().sum(); + return scalar(1).sub(sumSquaresResiduals.div(sumSquares)); + }); + } + // Aliases. + const mse$1 = meanSquaredError$1; + const MSE$1 = meanSquaredError$1; + const mae = meanAbsoluteError$1; + const MAE = meanAbsoluteError$1; + const mape$1 = meanAbsolutePercentageError$1; + const MAPE$1 = meanAbsolutePercentageError$1; + const categoricalCrossentropy$1 = categoricalCrossentropy$2; + const cosine = cosineProximity$1; + const sparseCategoricalCrossentropy = sparseCategoricalCrossentropy$1; + // TODO(cais, nielsene): Add serialize(). + const metricsMap = { + binaryAccuracy: binaryAccuracy$1, + categoricalAccuracy: categoricalAccuracy$1, + precision: precision$1, + categoricalCrossentropy: categoricalCrossentropy$1, + sparseCategoricalCrossentropy, + mse: mse$1, + MSE: MSE$1, + mae, + MAE, + mape: mape$1, + MAPE: MAPE$1, + cosine + }; + function get(identifier) { + if (typeof identifier === 'string' && identifier in metricsMap) { + return metricsMap[identifier]; + } + else if (typeof identifier !== 'string' && identifier != null) { + return identifier; + } + else { + throw new ValueError(`Unknown metric ${identifier}`); + } + } + /** + * Get the shortcut function name. + * + * If the fn name is a string, + * directly return the string name. + * If the function is included in metricsMap or lossesMap, + * return key of the map. + * - If the function relative to multiple keys, + * return the first found key as the function name. + * - If the function exists in both lossesMap and metricsMap, + * search lossesMap first. + * If the function is not included in metricsMap or lossesMap, + * return the function name. + * + * @param fn loss function, metric function, or short cut name. + * @returns Loss or Metric name in string. + */ + function getLossOrMetricName(fn) { + assert(fn !== null, `Unknown LossOrMetricFn ${fn}`); + if (typeof fn === 'string') { + return fn; + } + else { + let fnName; + for (const key of Object.keys(lossesMap)) { + if (lossesMap[key] === fn) { + fnName = key; + break; + } + } + if (fnName !== undefined) { + return fnName; + } + for (const key of Object.keys(metricsMap)) { + if (metricsMap[key] === fn) { + fnName = key; + break; + } + } + if (fnName !== undefined) { + return fnName; + } + return fn.name; + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // Add (de)serialize() + // Porting note: This diverges from the PyKeras implementation and may need to + // change based on (de)serialization requirements. + function getOptimizer(identifier) { + const optimizerMap = { + 'Adagrad': () => train.adagrad(0.01), + 'Adadelta': () => train.adadelta(1, 0.95, epsilon$1()), + 'Adam': () => train.adam(0.001, 0.9, 0.999, epsilon$1()), + 'Adamax': () => train.adamax(0.002, 0.9, 0.999, epsilon$1(), 0), + 'RMSProp': () => train.rmsprop(0.001, 0.9, 0, epsilon$1()), + 'SGD': () => train.sgd(0.01) + }; + optimizerMap['adagrad'] = optimizerMap['Adagrad']; + optimizerMap['adadelta'] = optimizerMap['Adadelta']; + optimizerMap['adam'] = optimizerMap['Adam']; + optimizerMap['adamax'] = optimizerMap['Adamax']; + optimizerMap['rmsprop'] = optimizerMap['RMSProp']; + optimizerMap['sgd'] = optimizerMap['SGD']; + if (identifier in optimizerMap) { + return optimizerMap[identifier](); + } + throw new ValueError(`Unknown Optimizer ${identifier}`); + } + + /** + * @license + * Copyright 2019 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** Utility functions related to user-defined metadata. */ + // Maximum recommended serialized size for user-defined metadata. + // Beyond this limit, a warning message will be printed during model loading and + // saving. + const MAX_USER_DEFINED_METADATA_SERIALIZED_LENGTH = 1 * 1024 * 1024; + /** + * Check validity of user-defined metadata. + * + * @param userDefinedMetadata + * @param modelName Name of the model that the user-defined metadata belongs to. + * Used during construction of error messages. + * @param checkSize Whether to check the size of the metadata is under + * recommended limit. Default: `false`. If `true`, will try stringify the + * JSON object and print a console warning if the serialzied size is above the + * limit. + * @throws Error if `userDefinedMetadata` is not a plain JSON object. + */ + function checkUserDefinedMetadata(userDefinedMetadata, modelName, checkSize = false) { + if (userDefinedMetadata == null || + typeof userDefinedMetadata !== 'object' || + Object.getPrototypeOf(userDefinedMetadata) !== Object.prototype || + !plainObjectCheck(userDefinedMetadata)) { + throw new Error('User-defined metadata is expected to be a JSON object, but is not.'); + } + if (checkSize) { + const out = JSON.stringify(userDefinedMetadata); + if (out.length > MAX_USER_DEFINED_METADATA_SERIALIZED_LENGTH) { + console.warn(`User-defined metadata of model "${modelName}" is too large in ` + + `size (length=${out.length} when serialized). It is not ` + + `recommended to store such large objects in user-defined metadata. ` + + `Please make sure its serialized length is <= ` + + `${MAX_USER_DEFINED_METADATA_SERIALIZED_LENGTH}.`); + } + } + } + /** + * Check if an input is plain JSON object or any valid subfield of it. + * + * @param x The input to be checked. + * @param assertObject Whether to assert `x` is a JSON object, i.e., reject + * cases of arrays and primitives. + * @return Returns `true` if and only if `x` is a plain JSON object, + * a JSON-valid primitive including string, number, boolean and null, + * or an array of the said types. + */ + // tslint:disable-next-line:no-any + function plainObjectCheck(x) { + if (x === null) { + // Note: typeof `null` is 'object', and `null` is valid in JSON. + return true; + } + else if (typeof x === 'object') { + if (Object.getPrototypeOf(x) === Object.prototype) { + // `x` is a JavaScript object and its prototype is Object. + const keys = Object.keys(x); + for (const key of keys) { + if (typeof key !== 'string') { + // JSON keys must be strings. + return false; + } + if (!plainObjectCheck(x[key])) { // Recursive call. + return false; + } + } + return true; + } + else { + // `x` is a JavaScript object but its prototype is not Object. + if (Array.isArray(x)) { + // `x` is a JavaScript array. + for (const item of x) { + if (!plainObjectCheck(item)) { // Recursive call. + return false; + } + } + return true; + } + else { + // `x` is a JavaScript object and its prototype is not Object, + // and it's not an Array. I.e., it's a complex object such as + // `Error` and `Date`. + return false; + } + } + } + else { + // `x` is not a JavaScript object or `null`. + const xType = typeof x; + return xType === 'string' || xType === 'number' || xType === 'boolean'; + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Print the summary of a LayersModel object. + * + * @param model tf.LayersModel instance. + * @param lineLength Total length of printed lines. Set this to adapt to the + * display to different terminal or console sizes. + * @param positions Relative or absolute positions of log elements in each + * line. Each number corresponds to right-most (i.e., ending) position of a + * column. + * If not provided, defaults to `[0.45, 0.85, 1]` for sequential-like + * models and `[0.33, 0.55, 0.67, 1]` for non-sequential like models. + * @param printFn Print function to use. + * It will be called on each line of the summary. You can provide a custom + * function in order to capture the string summary. Defaults to `console.log`. + */ + function printSummary(model, lineLength, positions, + // tslint:disable-next-line:no-any + printFn = console.log) { + const sequentialLike = isModelSequentialLike(model); + // Header names for different log elements. + const toDisplay = ['Layer (type)', 'Input Shape', 'Output shape', 'Param #']; + if (sequentialLike) { + lineLength = lineLength || 90; + positions = positions || [0.32, 0.61, 0.89, 1]; + } + else { + lineLength = lineLength || 115; + positions = positions || [0.24, 0.48, 0.70, 0.80, 1]; + // Header names for different log elements. + } + if (positions[positions.length - 1] <= 1) { + // `positions` is relative. Convert it to absolute positioning. + positions = positions.map(p => Math.floor(lineLength * p)); + } + let relevantNodes; + if (!sequentialLike) { + toDisplay.push('Receives inputs'); + relevantNodes = []; + for (const depth in model.nodesByDepth) { + relevantNodes.push(...model.nodesByDepth[depth]); + } + } + printFn('_'.repeat(lineLength)); + printRow(toDisplay, positions, printFn); + printFn('='.repeat(lineLength)); + const layers = model.layers; + for (let i = 0; i < layers.length; ++i) { + if (sequentialLike) { + printLayerSummary(layers[i], positions, printFn); + } + else { + printLayerSummaryWithConnections(layers[i], positions, relevantNodes, printFn); + } + printFn((i === layers.length - 1 ? '=' : '_').repeat(lineLength)); + } + // tslint:disable-next-line:no-any + model.checkTrainableWeightsConsistency(); + const trainableCount = countTrainableParams(model); + const nonTrainableCount = countParamsInWeights(model.nonTrainableWeights); + printFn(`Total params: ${trainableCount + nonTrainableCount}`); + printFn(`Trainable params: ${trainableCount}`); + printFn(`Non-trainable params: ${nonTrainableCount}`); + printFn('_'.repeat(lineLength)); + } + function countTrainableParams(model) { + let trainableCount; + // tslint:disable:no-any + if (model.collectedTrainableWeights != null) { + trainableCount = + countParamsInWeights(model.collectedTrainableWeights); + } + else { + trainableCount = countParamsInWeights(model.trainableWeights); + } + // tslint:enable:no-any + return trainableCount; + } + function isModelSequentialLike(model) { + let sequentialLike = true; + const nodesByDepth = []; + const nodes = []; + for (const depth in model.nodesByDepth) { + nodesByDepth.push(model.nodesByDepth[depth]); + } + for (const depthNodes of nodesByDepth) { + if (depthNodes.length > 1 || + depthNodes.length === 1 && depthNodes[0].inboundLayers.length > 1) { + sequentialLike = false; + break; + } + nodes.push(...depthNodes); + } + if (sequentialLike) { + // Search for shared layers. + for (const layer of model.layers) { + let flag = false; + for (const node of layer.inboundNodes) { + if (nodes.indexOf(node) !== -1) { + if (flag) { + sequentialLike = false; + break; + } + else { + flag = true; + } + } + } + if (!sequentialLike) { + break; + } + } + } + return sequentialLike; + } + function printRow(fields, positions, + // tslint:disable-next-line:no-any + printFn = console.log) { + let line = ''; + for (let i = 0; i < fields.length; ++i) { + if (i > 0) { + line = line.slice(0, line.length - 1) + ' '; + } + line += fields[i]; + line = line.slice(0, positions[i]); + line += ' '.repeat(positions[i] - line.length); + } + printFn(line); + } + /** + * Prints a summary for a single Layer, without connectivity information. + * + * @param layer: Layer instance to print. + */ + function printLayerSummary(layer, positions, + // tslint:disable-next-line:no-any + printFn) { + let outputShape; + let inputShape; + try { + inputShape = (layer.inboundNodes.map(x => JSON.stringify(x.inputShapes))).join(','); + } + catch (err) { + inputShape = 'multiple'; + } + try { + outputShape = JSON.stringify(layer.outputShape); + } + catch (err) { + outputShape = 'multiple'; + } + const name = layer.name; + const className = layer.getClassName(); + const fields = [`${name} (${className})`, inputShape, + outputShape, layer.countParams().toString()]; + printRow(fields, positions, printFn); + } + /** + * Prints a summary for a single Layer, with connectivity information. + */ + function printLayerSummaryWithConnections(layer, positions, relevantNodes, + // tslint:disable-next-line:no-any + printFn) { + let outputShape; + let inputShape; + try { + inputShape = (layer.inboundNodes.map(x => JSON.stringify(x.inputShapes))).join(','); + } + catch (err) { + inputShape = 'multiple'; + } + try { + outputShape = JSON.stringify(layer.outputShape); + } + catch (err) { + outputShape = 'multiple'; + } + const connections = []; + for (const node of layer.inboundNodes) { + if (relevantNodes != null && relevantNodes.length > 0 && + relevantNodes.indexOf(node) === -1) { + continue; + } + for (let i = 0; i < node.inboundLayers.length; ++i) { + const inboundLayer = node.inboundLayers[i].name; + const inboundLayerIndex = node.nodeIndices[i]; + const inboundTensorIndex = node.tensorIndices[i]; + connections.push(`${inboundLayer}[${inboundLayerIndex}][${inboundTensorIndex}]`); + } + } + const name = layer.name; + const className = layer.getClassName(); + const firstConnection = connections.length === 0 ? '' : connections[0]; + const fields = [ + `${name} (${className})`, inputShape, + outputShape, layer.countParams().toString(), + firstConnection + ]; + printRow(fields, positions, printFn); + for (let i = 1; i < connections.length; ++i) { + printRow(['', '', '', '', connections[i]], positions, printFn); + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // tslint:enable + /** + * Test whether a value in an array is the name of a LayersModel or Layer. + * @param key The key name that the value is found under. Note that the key + * may not be at the level immediately above the value, if the value is in a + * nested array. + * @param index Index of the value in the Array that it is found in. + * @param value The value object. + * @returns A boolean indicating whether value is a name. + */ + function isArrayItemInputOrOutputName(key, index, value) { + return (key === 'inboundNodes' || key === 'outputLayers' || + key === 'inputLayers') && + index === 0 && typeof value === 'string'; + } + /** + * Convert a Pythonic config object to TypeScript config object. + * @param pythonicConfig The config object to convert. + * @param key Optional key name of the object being converted. + * @returns Result of the conversion. + */ + function convertPythonicToTs(pythonicConfig, key) { + if (pythonicConfig === null) { + return null; + } + else if (typeof pythonicConfig === 'string') { + return toCamelCase(pythonicConfig); + } + else if ((typeof pythonicConfig === 'number') || + (typeof pythonicConfig === 'boolean')) { + return pythonicConfig; + } + else if (pythonicConfig instanceof Array) { + const tsArray = []; + const arrayLength = pythonicConfig.length; + for (let i = 0; i < arrayLength; ++i) { + const item = pythonicConfig[i]; + if (isArrayItemInputOrOutputName(key, i, item)) { + tsArray.push(item); + } + else { + tsArray.push(convertPythonicToTs(item, key)); + } + } + return tsArray; + } + else { + const tsDict = {}; + for (const pythonicKey of Object.keys(pythonicConfig)) { + const pythonicValue = pythonicConfig[pythonicKey]; + if (pythonicKey === 'name' && typeof pythonicValue === 'string') { + // Special case the 'name' key with a string value. Name values, such as + // the names of LayersModel and Layer instances, should not undergo the + // camel-case conversion. + tsDict[pythonicKey] = pythonicValue; + } + else { + const tsKey = toCamelCase(pythonicKey); + tsDict[tsKey] = convertPythonicToTs(pythonicValue, tsKey); + } + } + return tsDict; + } + } + /** + * Convert a TypeScript config object to Python config object. + * @param tsConfig The config object to convert. + * @param key Optional key name of the object being converted. + * @returns Result of the conversion. + */ + function convertTsToPythonic(tsConfig, key) { + if (tsConfig === null || tsConfig === undefined) { + return null; + } + else if (typeof tsConfig === 'string') { + return toSnakeCase(tsConfig); + } + else if ((typeof tsConfig === 'number') || (typeof tsConfig === 'boolean')) { + return tsConfig; + } + else if (tsConfig instanceof Array) { + const pyArray = []; + const arrayLength = tsConfig.length; + for (let i = 0; i < arrayLength; ++i) { + const item = tsConfig[i]; + if (isArrayItemInputOrOutputName(key, i, item)) { + pyArray.push(item); + } + else { + pyArray.push(convertTsToPythonic(item, key)); + } + } + return pyArray; + } + else { + const pyDict = {}; + for (const tsKey of Object.keys(tsConfig)) { + const tsValue = tsConfig[tsKey]; + const pyKey = toSnakeCase(tsKey); + if ((tsKey === 'name' || tsKey === 'className') && + typeof tsValue === 'string') { + // Special case the 'name' key with a string value. Name values, such as + // the names of LayersModel and Layer instances, should not undergo the + // snake-case conversion. + pyDict[pyKey] = tsValue; + } + else { + pyDict[pyKey] = convertTsToPythonic(tsValue, tsKey); + } + } + return pyDict; + } + } + + /** @license See the LICENSE file. */ + // This code is auto-generated, do not modify this file! + const version$6 = '4.22.0'; + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // get weights key from tensor map in order to check if it is from keras v3. + // e.g. dense/0 + const isKerasSavedModelFormat = (weights) => { + const keys = Object.keys(weights); + if (keys.length === 0) { + return false; + } + const key = keys[0].split('/'); + return !isNaN(parseInt(key[key.length - 1], 10)); + }; + /** + * A Container is a directed acyclic graph of layers. + * + * It is the topological form of a "model". A LayersModel + * is simply a Container with added training routines. + * + */ + class Container extends Layer { + constructor(args) { + // No args passed to super's constructor. + super({}); + this.containerNodes = new Set(); + this.name = args.name; + if (this.name == null) { + const prefix = this.getClassName().toLowerCase(); + this.name = getUid(prefix); + } + this.supportsMasking = false; + this.trainable_ = true; + // TODO(michaelterry): Initialize perInputLosses/Updates here. + // Container-specific properties. + if (Array.isArray(args.inputs)) { + this.inputs = args.inputs.slice(); + } + else { + this.inputs = [args.inputs]; + } + if (Array.isArray(args.outputs)) { + this.outputs = args.outputs.slice(); + } + else { + this.outputs = [args.outputs]; + } + // Check for redundancy in inputs. + if (unique$2(this.inputs).length !== this.inputs.length) { + throw new ValueError('The list of inputs passed to the model is ' + + 'redundant. All inputs should only appear once. Found: ' + + `${this.inputs.map(x => x.name)}`); + } + // Check for redundancy in outputs. + if (unique$2(this.outputs).length !== this.outputs.length) { + console.warn('The list of outputs passed to the model is redundant. ' + + 'All outputs should only appear once. Found: ' + + `${this.outputs.map(x => x.name)}`); + } + /* + List of initial layers (1 to 1 mapping with this.inputs, hence the same + layer might appear twice) + */ + this.inputLayers = []; + this.inputLayersNodeIndices = []; + this.inputLayersTensorIndices = []; + /* + List of layers (1 to 1 mapping with this.outputs, hence the same layer + might appear twice) + */ + this.outputLayers = []; + this.outputLayersNodeIndices = []; + this.outputLayersTensorIndices = []; + /* + All layers in order of horizontal graph traversal. Entries are unique. + Includes input and output layers. + */ + this.layers = []; + /* + References to container layers that were constructed internally. We need + these to properly dispose of tensors from nested containers. + */ + this.internalContainerRefs = []; + // TODO(michaelterry): Determine if caching still needed with eager + // backend. + /* + This is for performance optimization when calling the Container on new + inputs. Every time the Container is called on a set on input tensors, + we compute the output tensors, output masks and output shapes in one pass, + then cache them here. When one of these outputs is queried later, + we retrieve it from there instead of recomputing it. + */ + // this.outputTensorCache = {}; + // this.outputShapeCache = {}; + // Build this.outputLayers: + for (const x of this.outputs) { + const layer = x.sourceLayer; + const nodeIndex = x.nodeIndex; + const tensorIndex = x.tensorIndex; + this.outputLayers.push(layer); + this.outputLayersNodeIndices.push(nodeIndex); + this.outputLayersTensorIndices.push(tensorIndex); + } + // TODO(michaelterry): Add output mask cache code. + // Build this.inputLayers: + for (const x of this.inputs) { + const layer = x.sourceLayer; + const nodeIndex = x.nodeIndex; + const tensorIndex = x.tensorIndex; + /* + It's supposed to be an input layer, so only one node + and one tensor output. + */ + assert(nodeIndex === 0, 'input layer has >1 nodes'); + assert(tensorIndex === 0, 'input layer has >1 tensors'); + this.inputLayers.push(layer); + this.inputLayersNodeIndices.push(nodeIndex); + this.inputLayersTensorIndices.push(tensorIndex); + } + // Build this.inputNames and this.outputNames. + this.inputNames = []; + this.outputNames = []; + this.feedInputShapes = []; + this.feedInputNames = []; + this.feedOutputNames = []; + for (let i = 0; i < this.inputLayers.length; i++) { + const layer = this.inputLayers[i]; + // Check that layer is an InputLayer. + if (!(layer instanceof InputLayer)) { + throw new TypeError('Input layers to a LayersModel must be InputLayer objects. ' + + `Received inputs: ${args.inputs}. ` + + `Input ${i} (0-based) originates ` + + `from layer type ${layer.getClassName()}.`); + } + this.inputNames.push(layer.name); + this.feedInputShapes.push(layer.batchInputShape); + this.feedInputNames.push(layer.name); + } + for (const layer of this.outputLayers) { + this.outputNames.push(layer.name); + } + this.internalInputShapes = this.inputs.map(x => x.shape); + this.internalOutputShapes = this.outputs.map(x => x.shape); + /* + Container_nodes: set of nodes included in the graph (not all nodes + included in the layers are relevant to the current graph). + */ + // ids of all nodes relevant to the Container: + const nodesDepths = {}; + // To recover nodes from their ID. + const nodeIDToNode = {}; + const layersDepths = {}; + // To layers from their ID. + const layerIDToLayer = {}; + const layerIndices = {}; + const nodesInDecreasingDepth = []; + /** + * Builds a map of the graph of layers. + * + * This recursively updates the map `layerIndices`, + * the list `nodesInDecreasingDepth` and the set `containerNodes`. + * + * @param tensor Some tensor in a graph. + * @param finishedNodes Set of nodes whose subgraphs have been traversed + * completely. Useful to prevent duplicated work. + * @param nodesInProgress Set of nodes that are currently active on the + * recursion stack. Useful to detect cycles. + * @param layer Layer from which `tensor` comes from. If not provided, + * will be obtained from tensor.sourceLayer. + * @param nodeIndex Node index from which `tensor` comes from. + * @param tensorIndex TensorIndex from which `tensor` comes from. + * + * @exception RuntimeError if a cycle is detected. + */ + const buildMapOfGraph = (tensor, finishedNodes, nodesInProgress, layer, nodeIndex, tensorIndex) => { + if (layer == null || nodeIndex == null || tensorIndex == null) { + layer = tensor.sourceLayer; + nodeIndex = tensor.nodeIndex; + tensorIndex = tensor.tensorIndex; + } + const node = layer.inboundNodes[nodeIndex]; + // Prevent cycles. + if (nodesInProgress.indexOf(node) !== -1) { + throw new RuntimeError(`The tensor ${tensor.name} at layer "${layer.name}" ` + + 'is part of a cycle.'); + } + // Don't repeat work for shared subgraphs + if (finishedNodes.indexOf(node) !== -1) { + return; + } + // Update containerNodes. + this.containerNodes.add(Container.nodeKey(layer, nodeIndex)); + // Store the traversal order for layer sorting. + if (!(layer.id in layerIndices)) { + layerIndices[layer.id] = Object.keys(layerIndices).length; + } + if (nodesInProgress.indexOf(node) === -1) { + nodesInProgress.push(node); + } + // Propagate to all previous tensors connected to this node. + const numInboundLayers = node.inboundLayers.length; + for (let i = 0; i < numInboundLayers; i++) { + const x = node.inputTensors[i]; + const layer = node.inboundLayers[i]; + const nodeIndex = node.nodeIndices[i]; + const tensorIndex = node.tensorIndices[i]; + buildMapOfGraph(x, finishedNodes, nodesInProgress, layer, nodeIndex, tensorIndex); + } + finishedNodes.push(node); + while (nodesInProgress.indexOf(node) >= 0) { + nodesInProgress.splice(nodesInProgress.indexOf(node), 1); + } + nodesInDecreasingDepth.push(node); + }; + const finishedNodes = []; + const nodesInProgress = []; + for (const x of this.outputs) { + buildMapOfGraph(x, finishedNodes, nodesInProgress); + } + const reversedNodesInDecreasingDepth = nodesInDecreasingDepth.slice().reverse(); + for (const node of reversedNodesInDecreasingDepth) { + nodeIDToNode[node.id] = node; + // If the depth is not set, the node has no outbound nodes (depth 0). + if (!(node.id in nodesDepths)) { + nodesDepths[node.id] = 0; + } + let depth = nodesDepths[node.id]; + // Update the depth of the corresponding layer + const previousDepth = (layersDepths[node.outboundLayer.id] == null ? + 0 : + layersDepths[node.outboundLayer.id]); + /* + If we've seen this layer before at a higher depth, we should use that + depth instead of the node depth. This is necessary for shared layers + that have inputs at different depth levels in the graph. + */ + depth = Math.max(depth, previousDepth); + layersDepths[node.outboundLayer.id] = depth; + layerIDToLayer[node.outboundLayer.id] = node.outboundLayer; + nodesDepths[node.id] = depth; + // Update the depth of inbound nodes. + for (let i = 0; i < node.inboundLayers.length; i++) { + const inboundLayer = node.inboundLayers[i]; + const nodeIndex = node.nodeIndices[i]; + const inboundNode = inboundLayer.inboundNodes[nodeIndex]; + const previousDepth = (nodesDepths[inboundNode.id] == null ? 0 : + nodesDepths[inboundNode.id]); + nodesDepths[inboundNode.id] = Math.max(depth + 1, previousDepth); + nodeIDToNode[inboundNode.id] = inboundNode; + } + } + // Build a dict {depth: list of nodes with this depth} + const nodesByDepth = {}; + for (const nodeID in nodesDepths) { + const depth = nodesDepths[nodeID]; + if (!(depth in nodesByDepth)) { + nodesByDepth[depth] = []; + } + nodesByDepth[depth].push(nodeIDToNode[nodeID]); + } + // Build a dict {depth: list of layers with this depth} + const layersByDepth = {}; + for (const layerID in layersDepths) { + const depth = layersDepths[layerID]; + if (!(depth in layersByDepth)) { + layersByDepth[depth] = []; + } + layersByDepth[depth].push(layerIDToLayer[layerID]); + } + // Get sorted list of layer depths. + let depthKeys = Object.keys(layersByDepth) + .map(x => parseInt(x, 10)) + .sort(reverseNumberCompare); + // Set this.layers and this.layersByDepth. + this.layers = []; + for (const depth of depthKeys) { + const layersForDepth = layersByDepth[depth]; + // Container.layers needs to have a deterministic order: + // here we order them by traversal order. + layersForDepth.sort((a, b) => { + const aIndex = layerIndices[a.id]; + const bIndex = layerIndices[b.id]; + if (aIndex < bIndex) { + return -1; + } + if (aIndex > bIndex) { + return 1; + } + return 0; + }); + for (const layer of layersForDepth) { + if (layer instanceof Container) { + this.internalContainerRefs.push(layer); + } + this.layers.push(layer); + } + } + this.layersByDepth = layersByDepth; + // Get sorted list of node depths; + depthKeys = Object.keys(nodesByDepth) + .map(x => parseInt(x, 10)) + .sort(reverseNumberCompare); + // Check that all tensors required are computable. + // computable_tensors: all tensors in the graph + // that can be computed from the inputs provided. + const computableTensors = this.inputs.slice(); + // To provide a better error msg. + const layersWithCompleteInput = []; + for (const depth of depthKeys) { + for (const node of nodesByDepth[depth]) { + const layer = node.outboundLayer; + if (layer != null) { + for (const x of node.inputTensors) { + if (computableTensors.indexOf(x) === -1) { + throw new RuntimeError(`Graph disconnected: cannot obtain value for tensor ${x}` + + ` at layer "${layer.name}". ` + + 'The following previous layers were accessed without ' + + `issue: ${layersWithCompleteInput}`); + } + } + for (const x of node.outputTensors) { + computableTensors.push(x); + } + layersWithCompleteInput.push(layer.name); + } + } + } + // Set this.containerNodes and this.nodesByDepth. + this.nodesByDepth = nodesByDepth; + // Ensure name unicity, which will be crucial for serialization + // (since serialized nodes refer to layers by their name). + const allNames = this.layers.map(x => x.name); + for (const name of allNames) { + const numOccurrences = allNames.filter(x => x === name).length; + if (numOccurrences !== 1) { + throw new RuntimeError(`The name "${name}" is used ${numOccurrences} times ` + + 'in the model. All layer names should be unique. Layer names: ' + + JSON.stringify(allNames)); + } + } + // Layer parameters. + // The new container starts with a single inbound node + // for its inputs, and no outbound nodes. + // Will be appended to by future calls to apply(). + this.outboundNodes = []; + // Will be appended to below, and by future calls to apply(). + this.inboundNodes = []; + // Create the node linking internal inputs to internal outputs. + // (This call has side effects.) + // tslint:disable-next-line:no-unused-expression + new Node({ + outboundLayer: this, + inboundLayers: [], + nodeIndices: [], + tensorIndices: [], + inputTensors: this.inputs, + outputTensors: this.outputs, + inputMasks: this.inputs.map(x => null), + outputMasks: this.outputs.map(x => null), + inputShapes: this.inputs.map(x => x.shape), + outputShapes: this.outputs.map(x => x.shape) + }); + this.built = true; + this._refCount = 1; // The ref count of a container always start at 1. + } + assertNotDisposed() { + if (this._refCount === 0) { + throw new Error(`Container '${this.name}' is already disposed.`); + } + } + /** + * Attempt to dispose a LayersModel's weights. + * + * This method decrease the reference count of the LayersModel object by 1. + * + * A LayersModel is reference-counted. Its reference count is incremented by 1 + * when it is first constructed and when it is used as a Layer of another + * LayersModel. + * + * If the reference count of a LayersModel becomes 0, the `dispose` method of + * all its constituent `Layer`s will be called. + * + * Note: If the reference count is greater than 0 after the decrement, the + * `dispose` method of its constituent `Layer`s will *not* be called. + * + * After a LayersModel is disposed, it cannot be used in calls such as + * 'predict`, `evaluate` or `fit` anymore. + * + * @returns A DisposeResult Object with the following fields: + * - refCountAfterDispose: The reference count of the LayersModel after this + * `dispose()` call. + * - numDisposedVariables: Number of `tf.Variable`s (i.e., weights) disposed + * during this `dispose()` call. + * @throws {Error} If the layer is not built yet, or if the LayersModel has + * already been disposed. + */ + dispose() { + this.assertNotDisposed(); + const result = { refCountAfterDispose: null, numDisposedVariables: 0 }; + if (--this._refCount === 0) { + for (const layer of this.layers) { + result.numDisposedVariables += layer.dispose().numDisposedVariables; + } + // Call dispose on each internally created container layer again to ensure + // their refCounts hit zero and their tensors are subsequently deleted. + for (const container of this.internalContainerRefs) { + result.numDisposedVariables += container.dispose().numDisposedVariables; + } + } + result.refCountAfterDispose = this._refCount; + return result; + } + get trainable() { + return this.trainable_; + } + set trainable(trainable) { + this.layers.forEach(layer => { + // tslint:disable-next-line:no-any + layer._trainableWeights + .forEach(w => w.trainable = trainable); + }); + this.trainable_ = trainable; + } + get trainableWeights() { + // Porting Note: This check below is to prevent errors where the + // _trainableWeights inherited from the parent class (Layer) gets + // inadvertently used. + if (this._trainableWeights.length > 0) { + throw new ValueError('Container instance unexpectedly contains _trainableWeights.' + + 'The trainable weights of a Container are a union of the ' + + 'trainable weights of its consituent Layers. Its own ' + + '_trainableWeights must remain an empty Array.'); + } + if (!this.trainable) { + return []; + } + let weights = []; + for (const layer of this.layers) { + weights = weights.concat(layer.trainableWeights); + } + return weights; + } + get nonTrainableWeights() { + const weights = []; + for (const layer of this.layers) { + weights.push(...layer.nonTrainableWeights); + } + if (!this.trainable) { + const trainableWeights = []; + for (const layer of this.layers) { + trainableWeights.push(...layer.trainableWeights); + } + return trainableWeights.concat(weights); + } + return weights; + } + get weights() { + return this.trainableWeights.concat(this.nonTrainableWeights); + } + /** + * Loads all layer weights from a JSON object. + * + * Porting Note: HDF5 weight files cannot be directly loaded in JavaScript / + * TypeScript. The utility script at `scripts/pykeras.py` offers means + * to convert them into JSON strings compatible with this method. + * Porting Note: TensorFlow.js Layers supports only loading by name currently. + * + * @param weights A JSON mapping weight names to weight values as nested + * arrays of numbers, or a `NamedTensorMap`, i.e., a JSON mapping weight + * names to `tf.Tensor` objects. + * @param strict Require that the provided weights exactly match those + * required by the container. Default: `true`. Passing `false` means that + * extra weights and missing weights will be silently ignored. + */ + loadWeights(weights, strict = true) { + const nameToWeight = {}; + let totalWeightsCount = 0; + const modelIsKerasSavedModelFormat = isKerasSavedModelFormat(weights); + if (modelIsKerasSavedModelFormat) { + this.parseWeights(weights); + } + // Check if weights from keras v3. + for (const layer of this.layers) { + for (const [index, weight] of layer.weights.entries()) { + // Parse the name to layerName/index. + // e.g. dense/0, dense/1, dense_1/0, dense_1/1 + const parsedName = modelIsKerasSavedModelFormat ? + `${weight.name.split('/').slice(0, -1).join('/') + '/'}${index}` : + weight.originalName; + if (nameToWeight[parsedName] != null) { + throw new ValueError(`Duplicate weight name: ${parsedName}`); + } + nameToWeight[parsedName] = weight; + totalWeightsCount++; + } + } + const weightValueTuples = []; + for (const name in weights) { + // TF 2.2.0 added cell name to the weight name in the format of + // layer_name/cell_name/weight_name, we need to remove + // the inner cell name. + let validatedName = name; + if (nameToWeight[name] == null) { + const tokens = name.split('/'); + const shortenNameArray = tokens.slice(0, -2).concat([tokens[tokens.length - 1]]); + validatedName = shortenNameArray.join('/'); + } + if (nameToWeight[validatedName] != null) { + weightValueTuples.push([nameToWeight[validatedName], weights[name]]); + } + else if (strict) { + throw new ValueError(`Provided weight data has no target variable: ${name}`); + } + delete nameToWeight[validatedName]; + } + if (strict) { + // Check that all weights are set. + const unsetNames = []; + for (const name in nameToWeight) { + unsetNames.push(name); + } + if (unsetNames.length > 0) { + throw new ValueError(`${unsetNames.length} of ${totalWeightsCount} weights are not set: ` + + `${unsetNames}`); + } + } + batchSetValue(weightValueTuples); + } + parseWeights(weights) { + for (const key in Object.keys(weights)) { + const listParts = key.split('/'); + const list = ['vars', 'layer_checkpoint_dependencies']; + // For keras v3, the weights name are saved based on the folder structure. + // e.g. _backbone/_layer_checkpoint_dependencies/transformer/_self../ + // _output_dense/vars/0 + // Therefore we discard the `vars` and `layer_checkpoint_depencies` within + // the saved name and only keeps the layer name and weights. + // This can help to mapping the actual name of the layers and load each + // weight accordingly. + const newKey = listParts + .map(str => { + if (str.startsWith('_')) { + return str.slice(1); + } + return str; + }) + .filter(str => !list.includes(str)) + .join('/'); + if (newKey !== key) { + weights[newKey] = weights[key]; + delete weights[key]; + } + } + } + /** + * Util shared between different serialization methods. + * @returns LayersModel config with Keras version information added. + */ + updatedConfig() { + const theConfig = this.getConfig(); + const modelConfig = {}; + modelConfig['className'] = this.getClassName(); + modelConfig['config'] = theConfig; + modelConfig['kerasVersion'] = `tfjs-layers ${version$6}`; + // TODO(nielsene): Replace something like K.backend() once + // possible. + modelConfig['backend'] = 'TensorFlow.js'; + return modelConfig; + } + /** + * Returns a JSON string containing the network configuration. + * + * To load a network from a JSON save file, use + * models.modelFromJSON(jsonString); + * @param extraJsonArgs Unused in tfjs-layers, maintained for PyKeras + * @param returnString Whether the return value should be stringified + * (default: `true`). + * @returns a JSON string if `returnString` (default), or a JSON object if + * `!returnString`. + */ + // tslint:disable-next-line:no-any + toJSON(unused, returnString = true) { + const modelConfig = convertTsToPythonic(this.updatedConfig()); + return returnString ? JSON.stringify(modelConfig) : modelConfig; + } + /** + * Call the model on new inputs. + * + * In this case `call` just reapplies all ops in the graph to the new inputs + * (e.g. build a new computational graph from the provided inputs). + * + * @param inputs A tensor or list of tensors. + * @param mask A mask or list of masks. A mask can be either a tensor or null + * (no mask). + * + * @return A tensor if there is a single output, or a list of tensors if there + * are more than one outputs. + */ + call(inputs, kwargs) { + return tidy(() => { + inputs = toList(inputs); + const feedDict = new FeedDict(); + for (let i = 0; i < this.inputs.length; ++i) { + feedDict.add(this.inputs[i], inputs[i]); + } + return execute(this.outputs, feedDict, kwargs); + }); + } + /** + * Computes an output mask tensor. + * + * @param inputs Tensor or list of tensors. + * @param mask Tensor or list of tensors. + * + * @return null or a tensor (or list of tensors, one per output tensor of the + * layer). + */ + computeMask(inputs, mask) { + return tidy(() => { + inputs = toList(inputs); + let masks; + if (mask == null) { + masks = pyListRepeat(null, inputs.length); + } + else { + masks = toList(mask); + } + // TODO(michaelterry): Add support for mask caching. + return this.runInternalGraph(inputs, masks)[1]; + }); + } + /** + * Computes the output shape of the layer. + * + * Assumes that the layer will be built to match that input shape provided. + * + * @param inputShape A shape (tuple of integers) or a list of shape tuples + * (one per output tensor of the layer). Shape tuples can include null for + * free dimensions, instead of an integer. + */ + computeOutputShape(inputShape) { + const inputShapes = normalizeShapeList(inputShape); + if (inputShapes.length !== this.inputLayers.length) { + throw new ValueError(`Invalid inputShape argument ${inputShape}: ` + + `model has ${this.inputLayers.length} tensor inputs.`); + } + // TODO(michaelterry): Add caching + const layersToOutputShapes = {}; + for (let i = 0; i < inputShapes.length; i++) { + const layer = this.inputLayers[i]; + const inputShape = inputShapes[i]; + // It's an input layer: computeOutputShape is identity, + // and there is only one node and one tensor output. + const shapeKey = layer.name + '_0_0'; + layersToOutputShapes[shapeKey] = inputShape; + } + const depthKeys = Object.keys(this.nodesByDepth) + .map(x => parseInt(x, 10)) + .sort(reverseNumberCompare); + // Iterate over nodes, by depth level. + if (depthKeys.length > 1) { + for (const depth of depthKeys) { + const nodes = this.nodesByDepth[depth]; + for (const node of nodes) { + // This is always a single layer, never a list. + const layer = node.outboundLayer; + if (this.inputLayers.map(x => x.id).indexOf(layer.id) !== -1) { + // We've already covered the input layers a few lines above. + continue; + } + // Potentially redundant list, same size of node.inputTensors. + const inputShapes = []; + for (let j = 0; j < node.inboundLayers.length; j++) { + const inboundLayer = node.inboundLayers[j]; + const nodeIndex = node.nodeIndices[j]; + const tensorIndex = node.tensorIndices[j]; + const shapeKey = `${inboundLayer.name}_${nodeIndex}_${tensorIndex}`; + const inputShape = layersToOutputShapes[shapeKey]; + inputShapes.push(inputShape); + } + const outputShape = layer.computeOutputShape(singletonOrArray(inputShapes)); + const outputShapes = normalizeShapeList(outputShape); + const nodeIndex = layer.inboundNodes.indexOf(node); + for (let j = 0; j < outputShapes.length; j++) { + const shapeKey = `${layer.name}_${nodeIndex}_${j}`; + layersToOutputShapes[shapeKey] = outputShapes[j]; + } + } + } + } + // Read final output shapes from layersToOutputShapes. + const outputShapes = []; + const outputShapeKeys = []; + for (let i = 0; i < this.outputLayers.length; i++) { + const layer = this.outputLayers[i]; + const nodeIndex = this.outputLayersNodeIndices[i]; + const tensorIndex = this.outputLayersTensorIndices[i]; + const shapeKey = `${layer.name}_${nodeIndex}_${tensorIndex}`; + outputShapeKeys.push(shapeKey); + } + for (let i = 0; i < outputShapeKeys.length; i++) { + const key = outputShapeKeys[i]; + assert(key in layersToOutputShapes); + outputShapes.push(layersToOutputShapes[key]); + } + // TODO(michaelterry): Update cache + return singletonOrArray(outputShapes); + } + /** + * Computes output tensors for new inputs. + * + * Note: + * - Expects `inputs` to be a list (potentially with 1 element). + * + * @param inputs List of tensors + * @param masks List of masks (tensors or null). + * @return Three lists: outputTensors, outputMasks, outputShapes + */ + runInternalGraph(inputs, masks) { + if (masks == null) { + masks = pyListRepeat(null, inputs.length); + } + // Dictionary mapping reference tensors to tuples + // (computed tensor, compute mask) + // we assume a 1:1 mapping from tensor to mask + // TODO: raise exception when a `.computeMask()` call + // does not return a list the same size as `call` + const tensorMap = {}; + for (let i = 0; i < this.inputs.length; ++i) { + const x = this.inputs[i]; + const y = inputs[i]; + const mask = masks[i]; + tensorMap[x.id] = [y, mask]; + } + const depthKeys = Object.keys(this.nodesByDepth) + .map(x => parseInt(x, 10)) + .sort(reverseNumberCompare); + for (const depth of depthKeys) { + const nodes = this.nodesByDepth[depth]; + for (const node of nodes) { + // This is always a single layer, never a list. + const layer = node.outboundLayer; + const referenceInputTensors = node.inputTensors; + const referenceOutputTensors = node.outputTensors; + // If all previous input tensors are available in tensorMap, + // then call node.inboundLayer on them. + // List of tuples [input, mask]: + const computedData = new Array(); + for (const x of referenceInputTensors) { + if (x.id in tensorMap) { + computedData.push(tensorMap[x.id]); + } + } + if (computedData.length === referenceInputTensors.length) { + // TODO(michaelterry): Add K.name_scope here, if we need it. + let kwargs = {}; + let computedTensors; + let computedMasks; + let outputTensors; + let outputMasks; + // call layer + if (node.callArgs != null) { + kwargs = node.callArgs; + } + if (computedData.length === 1) { + const [computedTensor, computedMask] = computedData[0]; + if (kwargs['mask'] == null) { + kwargs['mask'] = computedMask; + } + outputTensors = + toList(layer.call(computedTensor, kwargs)); + outputMasks = toList(layer.computeMask(computedTensor, computedMask)); + computedTensors = [computedTensor]; + computedMasks = [computedMask]; + } + else { + computedTensors = computedData.map(x => x[0]); + computedMasks = computedData.map(x => x[1]); + if (kwargs['mask'] == null) { + kwargs['mask'] = computedMasks; + } + outputTensors = + toList(layer.call(computedTensors, kwargs)); + outputMasks = toList(layer.computeMask(computedTensors, computedMasks)); + } + if (layer.activityRegularizer) { + throw new NotImplementedError('LayersModel invocation with concrete Tensor value(s) in the ' + + 'presence of activity regularizer(s) is not supported yet.'); + } + // TODO(michaelterry): Add model updates and losses + // Update tensor map. + for (let i = 0; i < referenceOutputTensors.length; ++i) { + const x = referenceOutputTensors[i]; + const y = outputTensors[i]; + const mask = outputMasks[i]; + tensorMap[x.id] = [y, mask]; + } + } + } + } + const outputTensors = []; + const outputMasks = []; + const outputShapes = []; + for (const x of this.outputs) { + assert(x.id in tensorMap, `Could not compute output ${x.name} : ${x.id}`); + const [tensor, mask] = tensorMap[x.id]; + outputShapes.push(tensor.shape); + outputTensors.push(tensor); + outputMasks.push(mask); + } + // TODO(michaelterry): Add support for caches. + return [outputTensors, outputMasks, outputShapes]; + } + /** + * Builds a map of internal node keys to node ordering. + * Used in serializaion a node orderings may change as unused nodes are + * dropped. Porting Note: This helper method was pulled out of getConfig to + * improve readability. + * @param layers An array of Layers in the model. + * @returns Map of Node Keys to index order within the layer. + */ + buildNodeConversionMap(layers) { + const nodeConversionMap = {}; + let keptNodes; + for (const layer of this.layers) { + keptNodes = layer instanceof Container ? 1 : 0; + for (let originalNodeIndex = 0; originalNodeIndex < layer.inboundNodes.length; originalNodeIndex++) { + const nodeKey = Container.nodeKey(layer, originalNodeIndex); + if (this.containerNodes.has(nodeKey)) { + // i.e. we mark it to be saved + nodeConversionMap[nodeKey] = keptNodes; + keptNodes += 1; + } + } + } + return nodeConversionMap; + } + getLayer(nameOrIndex, index) { + if (index != null) { + return this.findLayer(index); + } + else { + if (nameOrIndex == null) { + throw new ValueError('Provide either a layer name or layer index'); + } + if (typeof nameOrIndex === 'number') { + return this.findLayer(nameOrIndex); + } + } + for (const layer of this.layers) { + if (layer.name === nameOrIndex) { + return layer; + } + } + throw new ValueError(`No such layer: ${nameOrIndex}`); + } + findLayer(index) { + if (this.layers.length <= index) { + throw new ValueError(`Was asked to retrieve layer at index ${index}, but model only ` + + `has ${this.layers.length} layer(s).`); + } + else { + return this.layers[index]; + } + } + /** + * Retrieves the Container's current loss values. + * + * Used for regularizers during training. + */ + calculateLosses() { + // Porting Node: This is an augmentation to Container.loss in PyKeras. + // In PyKeras, Container.loss returns symbolic tensors. Here a concrete + // Tensor (specifically Scalar) values are returned. This is due to the + // imperative backend. + return tidy(() => { + const losses = []; + for (const layer of this.layers) { + for (let nodeIndex = 0; nodeIndex < layer.inboundNodes.length; ++nodeIndex) { + const nodeKey = Container.nodeKey(layer, nodeIndex); + if (this.containerNodes.has(nodeKey)) { + losses.push(...layer.calculateLosses()); + } + } + } + // TODO(cais): Add any unconditional model-level losses? + return losses; + }); + } + getConfig() { + const config = { name: this.name }; + // Build a map from layer unique name (self._node_key) + // to the index of the nodes that are saved in the config. + // Only nodes in container_nodes are saved. + const nodeConversionMap = this.buildNodeConversionMap(this.layers); + // Serialize and save the layers in layerConfigs + const layerConfigs = []; + for (const layer of this.layers) { + const layerClassName = layer.getClassName(); + const layerConfig = layer.getConfig(); + const filteredInboundNodes = []; + for (let originalNodeIndex = 0; originalNodeIndex < layer.inboundNodes.length; originalNodeIndex++) { + const node = layer.inboundNodes[originalNodeIndex]; + const nodeKey = Container.nodeKey(layer, originalNodeIndex); + let kwargs = {}; + if (this.containerNodes.has(nodeKey)) { + // The node is relevant to the model: + // add to filteredInboundNodes. + if (node.callArgs) { + try { + JSON.stringify(node.callArgs); + kwargs = node.callArgs; + } + catch (err) { + console.warn(`Layer ${layer.name} was passed ` + + `non-serializable keyword arguments: ` + + `${node.callArgs}. They will not be included ` + + `in the serialized model (and thus will be ` + + `missing at deserialization time).`); + kwargs = {}; + } + } + if (node.inboundLayers.length > 0) { + const nodeData = []; + for (let i = 0; i < node.inboundLayers.length; i++) { + const inboundLayer = node.inboundLayers[i]; + const nodeIndex = node.nodeIndices[i]; + const tensorIndex = node.tensorIndices[i]; + const nodeKey = Container.nodeKey(inboundLayer, nodeIndex); + let newNodeIndex = nodeConversionMap[nodeKey]; + if (newNodeIndex == null) { + newNodeIndex = 0; + } + nodeData.push([inboundLayer.name, newNodeIndex, tensorIndex, kwargs]); + } + filteredInboundNodes.push(nodeData); + } + } + } + const dict = {}; + dict['name'] = layer.name; + dict['className'] = layerClassName; + dict['config'] = layerConfig; + dict['inboundNodes'] = filteredInboundNodes; + layerConfigs.push(dict); + } + config['layers'] = layerConfigs; + // Gather info about inputs and outputs + const modelInputs = []; + for (let i = 0; i < this.inputLayers.length; i++) { + const layer = this.inputLayers[i]; + const nodeIndex = this.inputLayersNodeIndices[i]; + const nodeKey = Container.nodeKey(layer, nodeIndex); + if (!this.containerNodes.has(nodeKey)) { + continue; + } + let newNodeIndex = nodeConversionMap[nodeKey]; + if (newNodeIndex === null || newNodeIndex === undefined) { + newNodeIndex = 0; + } + const tensorIndex = this.inputLayersTensorIndices[i]; + modelInputs.push([layer.name, newNodeIndex, tensorIndex]); + } + config['inputLayers'] = modelInputs; + const modelOutputs = []; + for (let i = 0; i < this.outputLayers.length; i++) { + const layer = this.outputLayers[i]; + const nodeIndex = this.outputLayersNodeIndices[i]; + const nodeKey = Container.nodeKey(layer, nodeIndex); + if (!this.containerNodes.has(nodeKey)) { + continue; + } + let newNodeIndex = nodeConversionMap[nodeKey]; + if (newNodeIndex === null || newNodeIndex === undefined) { + newNodeIndex = 0; + } + const tensorIndex = this.outputLayersTensorIndices[i]; + modelOutputs.push([layer.name, newNodeIndex, tensorIndex]); + } + config['outputLayers'] = modelOutputs; + return config; + } + /** + * Instantiates a LayersModel from its config (output of `get_config()`). + * @param cls the class to create + * @param config LayersModel config dictionary. + * @param customObjects An optional dictionary of custom objects. + * @param fastWeightInit Optional flag to use fast weight initialization + * during deserialization. This is applicable to cases in which + * the initialization will be immediately overwritten by loaded weight + * values. Default: `false`. + * @returns A LayersModel instance. + * @throws ValueError: In case of improperly formatted config dict. + */ + /** @nocollapse */ + static fromConfig(cls, config, customObjects = {}, fastWeightInit = false) { + // Layer instances created during + // the graph reconstruction process + const createdLayers = {}; + // Dictionary mapping layer instances to + // node data that specifies a layer call. + // It acts as a queue that maintains any unprocessed + // layer call until it becomes possible to process it + // (i.e. until the input tensors to the call all exist). + const unprocessedNodes = {}; + function addUnprocessedNode(layer, nodeData) { + if (!(layer.name in unprocessedNodes)) { + unprocessedNodes[layer.name] = [nodeData]; + } + else { + unprocessedNodes[layer.name].push(nodeData); + } + } + function processNode(layer, nodeData) { + const inputTensors = []; + let kwargs; + for (const inputData of nodeData) { + const inboundLayerName = inputData[0]; + const inboundNodeIndex = inputData[1]; + const inboundTensorIndex = inputData[2]; + kwargs = inputData[3] == null ? + {} : + inputData[3]; + if (!(inboundLayerName in createdLayers)) { + addUnprocessedNode(layer, nodeData); + return; + } + const inboundLayer = createdLayers[inboundLayerName]; + if (inboundLayer.inboundNodes.length <= inboundNodeIndex) { + addUnprocessedNode(layer, nodeData); + return; + } + const inboundNode = inboundLayer.inboundNodes[inboundNodeIndex]; + inputTensors.push(inboundNode.outputTensors[inboundTensorIndex]); + } + // Call layer on its inputs, thus creating the node + // and building the layer if needed. + // Note: This has Eager vs Graph Implications. + if (inputTensors.length > 0) { + layer.apply(singletonOrArray(inputTensors), kwargs); // was ** kwargs + } + } + /** + * Deserialize a layer, then call it on appropriate inputs. + * @param layerData: layer config dict. + * @throws ValueError: In case of improperly formatted `layer_data` + * dict. + */ + function processLayer(layerData) { + const layerName = layerData['name']; + // Instantiate layer. + const layer = deserialize(layerData, config['customObjects'] != null ? + config['customObjects'] : + {}); + layer.setFastWeightInitDuringBuild(fastWeightInit); + createdLayers[layerName] = layer; + // Gather layer inputs. + const inboundNodesData = layerData['inboundNodes']; + inboundNodesData.forEach(nodeData => { + if (!(nodeData instanceof Array)) { + throw new ValueError(`Corrupted configuration, expected array for nodeData: ${nodeData}`); + } + // We don't process nodes (i.e. make layer calls) + // on the fly because the inbound node may not yet exist, + // in case of layer shared at different topological depths + // (e.g.a model such as A(B(A(B(x))))) + addUnprocessedNode(layer, nodeData); + }); + } + // First, we create all layers and enqueue nodes to be processed. + const name = config['name']; + const layersFromConfig = config['layers']; + for (const layerData of layersFromConfig) { + processLayer(layerData); + } + // Then we process nodes in order of layer depth. + // Nodes that cannot yet be processed(if the inbound node + // does not yet exist) are re - enqueued, and the process + // is repeated until all nodes are processed. + while (!isObjectEmpty(unprocessedNodes)) { + for (const layerData of layersFromConfig) { + const layer = createdLayers[layerData['name']]; + if (layer.name in unprocessedNodes) { + const currentUnprocessedNodesForLayer = unprocessedNodes[layer.name]; + delete unprocessedNodes[layer.name]; + for (const nodeData of currentUnprocessedNodesForLayer) { + processNode(layer, nodeData); + } + } + } + } + const inputTensors = []; + const outputTensors = []; + const inputLayersFromConfig = config['inputLayers']; + for (const layerData of inputLayersFromConfig) { + const layerName = layerData[0]; + const nodeIndex = layerData[1]; + const tensorIndex = layerData[2]; + assert(layerName in createdLayers); + const layer = createdLayers[layerName]; + const layerOutputTensors = layer.inboundNodes[nodeIndex].outputTensors; + inputTensors.push(layerOutputTensors[tensorIndex]); + } + const outputLayersFromConfig = config['outputLayers']; + for (const layerData of outputLayersFromConfig) { + const layerName = layerData[0]; + const nodeIndex = layerData[1]; + const tensorIndex = layerData[2]; + assert(layerName in createdLayers); + const layer = createdLayers[layerName]; + const layerOutputTensors = layer.inboundNodes[nodeIndex].outputTensors; + outputTensors.push(layerOutputTensors[tensorIndex]); + } + return new cls({ inputs: inputTensors, outputs: outputTensors, name }); + } + /** + * Determine whether the container is stateful. + * + * Porting Note: this is the equivalent of the stateful @property of + * the Container class in PyKeras. + */ + get stateful() { + // Porting Note: This check is to prevent inadvertent setting of the + // _stateful property of the Container instance. + if (this._stateful) { + throw new ValueError('Container instance unexpectedly has _stateful = true. The ' + + 'statefulness of a Container is determined by the Layers it ' + + 'contains. Its _stateful property must remain the default false.'); + } + for (const layer of this.layers) { + if (layer.stateful) { + return true; + } + } + return false; + } + /** + * Reset the state of all stateful constituent layers (if any). + * + * Examples of stateful layers include RNN layers whose `stateful` property + * is set as `true`. + */ + resetStates() { + tidy(() => { + this.layers.forEach(layer => { + // tslint:disable:no-any + if (layer.stateful) { + layer.resetStates(); + } + // tslint:enable:no-any + }); + }); + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + function standardizeSampleOrClassWeights(xWeight, outputNames, weightType) { + const numOutputs = outputNames.length; + if (xWeight == null || (Array.isArray(xWeight) && xWeight.length === 0)) { + return outputNames.map(name => null); + } + if (numOutputs === 1) { + if (Array.isArray(xWeight) && xWeight.length === 1) { + return xWeight; + } + else if (typeof xWeight === 'object' && outputNames[0] in xWeight) { + return [xWeight[outputNames[0]]]; + } + else { + return [xWeight]; + } + } + if (Array.isArray(xWeight)) { + if (xWeight.length !== numOutputs) { + throw new Error(`Provided ${weightType} is an array of ${xWeight.length} ` + + `element(s), but the model has ${numOutputs} outputs. ` + + `Make sure a set of weights is provided for each model output.`); + } + return xWeight; + } + else if (typeof xWeight === 'object' && Object.keys(xWeight).length > 0 && + typeof xWeight[Object.keys(xWeight)[0]] === + 'object') { + const output = []; + outputNames.forEach(outputName => { + if (outputName in xWeight) { + output.push(xWeight[outputName]); + } + else { + output.push(null); + } + }); + return output; + } + else { + throw new Error(`The model has multiple (${numOutputs}) outputs, ` + + `so ${weightType} must be either an array with ` + + `${numOutputs} elements or an object with ${outputNames} keys. ` + + `Provided ${weightType} not understood: ${JSON.stringify(xWeight)}`); + } + } + /** + * Standardize class weighting objects. + * + * This function takes a single class-weighting object, an array of them, + * or a map from output name to class-weighting object. It compares it to the + * output name(s) of the model, base on which it outputs an array of + * class-weighting objects of which the length matches the number of outputs. + * + * @param classWeight Input class-weighting object(s). + * @param outputNames All output name(s) of the model. + * @return An array of class-weighting objects. The length of the array matches + * the model's number of outputs. + */ + function standardizeClassWeights(classWeight, outputNames) { + return standardizeSampleOrClassWeights(classWeight, outputNames, 'classWeight'); + } + function standardizeSampleWeights(classWeight, outputNames) { + return standardizeSampleOrClassWeights(classWeight, outputNames, 'sampleWeight'); + } + /** + * Standardize by-sample and/or by-class weights for training. + * + * Note that this function operates on one model output at a time. For a model + * with multiple outputs, you must call this function multiple times. + * + * @param y The target tensor that the by-sample and/or by-class weight is for. + * The values of y are assumed to encode the classes, either directly + * as an integer index, or as one-hot encoding. + * @param sampleWeight By-sample weights. + * @param classWeight By-class weights: an object mapping class indices + * (integers) to a weight (float) to apply to the model's loss for the + * samples from this class during training. This can be useful to tell the + * model to "pay more attention" to samples from an under-represented class. + * @param sampleWeightMode The mode for the sample weights. + * @return A Promise of weight tensor, of which the size of the first dimension + * matches that of `y`. + */ + async function standardizeWeights(y, sampleWeight, classWeight, sampleWeightMode) { + if (sampleWeight != null || sampleWeightMode != null) { + // TODO(cais): Once 'temporal' mode is implemented, document it in the doc + // string. + throw new Error('Support sampleWeight is not implemented yet'); + } + if (classWeight != null) { + // Apply class weights per sample. + const yClasses = tidy(() => { + if (y.shape.length === 1) { + // Assume class indices. + return clone(y); + } + else if (y.shape.length === 2) { + if (y.shape[1] > 1) { + // Assume one-hot encoding of classes. + const axis = 1; + return argMax$2(y, axis); + } + else if (y.shape[1] === 1) { + // Class index. + return reshape$3(y, [y.shape[0]]); + } + else { + throw new Error(`Encountered unexpected last-dimension size (${y.shape[1]}) ` + + `during handling of class weights. The size is expected to be ` + + `>= 1.`); + } + } + else { + throw new Error(`Unexpected rank of target (y) tensor (${y.rank}) during ` + + `handling of class weights. The rank is expected to be 1 or 2.`); + } + }); + const yClassIndices = Array.from(await yClasses.data()); + dispose(yClasses); + const classSampleWeight = []; + yClassIndices.forEach(classIndex => { + if (classWeight[classIndex] == null) { + throw new Error(`classWeight must contain all classes in the training data. ` + + `The class ${classIndex} exists in the data but not in ` + + `classWeight`); + } + else { + classSampleWeight.push(classWeight[classIndex]); + } + }); + return tensor1d(classSampleWeight, 'float32'); + } + else { + return null; + } + } + /** + * Apply per-sample weights on the loss values from a number of samples. + * + * @param losses Loss tensor of shape `[batchSize]`. + * @param sampleWeights Per-sample weight tensor of shape `[batchSize]`. + * @returns Tensor of the same shape as`losses`. + */ + function computeWeightedLoss(losses, sampleWeights) { + return mul(losses, sampleWeights); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // Default batch size used during tensor-based validation. + const DEFAULT_VALIDATION_BATCH_SIZE = 32; + /** + * Standardize the output of a dataset iterator for use by + * LayersModel.fitDataset(). + * + * @param model: A `tf.LayersModel` object. + * @param iteratorOut The output of a dataset iterator. It is required to be + * an object of the form `{xs: TensorOrArrayOrMap, ys: + * TensorOrArrayOrMap}`, where `TensorOrArrayOrMap` is a single `tf.Tensor`, + * a `tf.Tensor[]`, or a flat map from string names to `tf.Tensor`s. + * @returns A flat array of `tf.Tensor` objects: the input `tf.Tensor`s + * followed by the target `tf.Tensor`s. When `tf.Tensor`s are provided + * as a map, the order in the resulting array is taken from the `inputNames` + * and `outputNames` of the model. + */ + function standardizeDataIteratorOutput( + // Type `model` as `any` here to avoid circular dependency w/ + // training.ts. + // tslint:disable-next-line:no-any + model, iteratorOut) { + let xs; + let ys; + const iteratorOutObj = iteratorOut; + xs = iteratorOutObj['xs']; + ys = iteratorOutObj['ys']; + assert$1(xs != null && ys != null, () => 'A Dataset iterator for fitDataset() is expected to generate ' + + 'objects of the form `{xs: xVal, ys: yVal}`, where the two ' + + 'values may be `tf.Tensor`, an array of Tensors, or a map of ' + + 'string to Tensor. The provided Dataset instead generates ' + + `${iteratorOut}`); + const flattenedXs = flattenTensorOrArrayOrMap('input', model.inputNames, xs); + const flattenedYs = flattenTensorOrArrayOrMap('output', model.outputNames, ys); + const batchSize = flattenedXs[0].shape[0]; + assert$1(flattenedXs.length === model.inputs.length, () => `LayersModel has ${model.inputs.length} inputs, but the dataset ` + + `provides ${flattenedXs.length} inputs. (Expected input keys: ` + + `${JSON.stringify(model.inputNames)})`); + assert$1(flattenedYs.length === model.outputs.length, () => `LayersModel has ${model.outputs.length} outputs, but the dataset ` + + `provides ${flattenedYs.length} outputs. (Expected output keys: ` + + `${JSON.stringify(model.outputNames)})`); + for (let xIndex = 0; xIndex < flattenedXs.length; xIndex++) { + assert$1(flattenedXs[xIndex].shape[0] === batchSize, () => `Batch size mismatch: input ` + + `${model.inputNames[xIndex]} has ${flattenedXs[xIndex].shape[0]}; ` + + `expected ${batchSize} based on input ${model.inputNames[0]}.`); + } + for (let yIndex = 0; yIndex < flattenedYs.length; yIndex++) { + assert$1(flattenedYs[yIndex].shape[0] === batchSize, () => `Batch size mismatch: output ` + + `${model.outputNames[yIndex]} has ${flattenedYs[yIndex].shape[0]}; ` + + `expected ${batchSize} based on input ${model.inputNames[0]}.`); + } + return { xs: flattenedXs, ys: flattenedYs }; + } + function flattenTensorOrArrayOrMap(inputOrOutput, names, values) { + if (values instanceof Tensor) { + return [values]; + } + else if (Array.isArray(values)) { + assert$1(values.length === names.length, () => `Received an array of ${values.length} Tensors, but expected ${names.length} to match the ${inputOrOutput} keys ${names}.`); + return values; + } + else { + const result = []; + // Check that all the required keys are available. + for (const name of names) { + if (values[name] == null) { + throw new ValueError(`The feature data generated by the dataset lacks the required ` + + `${inputOrOutput} key '${name}'.`); + } + result.push(values[name]); + } + return result; + } + } + function standardizeTensorValidationData(data) { + if (data.length === 3) { + throw new NotImplementedError('Validation with sample weights is not implemented yet.'); + } + return { xs: data[0], ys: data[1] }; + } + async function fitDataset( + // Type `model` as `any` here to avoid circular dependency w/ + // training.ts. + // tslint:disable-next-line:no-any + model, dataset, args) { + const hasBatchesPerEpoch = args.batchesPerEpoch != null; + assert$1(model.optimizer != null, () => 'You must compile a model before training/testing. Use ' + + 'LayersModel.compile(modelCompileConfig).'); + assert$1(args != null, () => `For fitDataset(), the 2nd argument (config) is required, ` + + `but it is not provided in this call.`); + assert$1(args.epochs != null && args.epochs > 0 && Number.isInteger(args.epochs), () => `For fitDataset(), config.epochs is expected to be a positive ` + + `integer, but got ${args.epochs}`); + assert$1(!hasBatchesPerEpoch || + (args.batchesPerEpoch > 0 && Number.isInteger(args.batchesPerEpoch)), () => `For fitDataset(), config.batchesPerEpoch is expected to be a ` + + `positive integer if specified, but got ${args.batchesPerEpoch}`); + assert$1( + // tslint:disable-next-line:no-any + args['validationSplit'] == null, () => '`validationSplit` is not supported by `fitDataset()`. ' + + 'Use validationData instead.'); + if (model.isTraining) { + throw new Error('Cannot start training because another fit() call is ongoing.'); + } + model.isTraining = true; + try { + const doValidation = args.validationData != null; + let valXs; + let valYs; + if (doValidation) { + if (isDatasetObject(args.validationData)) { + assert$1(args.validationBatches == null || + (args.validationBatches > 0 && + Number.isInteger(args.validationBatches)), () => `For fitDataset() with dataset-based validation, ` + + `config.validationBatches is expected not to be provided, ` + + `or to be a positive integer, ` + + `but got ${args.validationBatches}`); + } + else { + const validationData = standardizeTensorValidationData(args.validationData); + valXs = validationData.xs; + valYs = validationData.ys; + } + } + const trainFunction = model.makeTrainFunction(); + const outLabels = model.getDedupedMetricsNames(); + let callbackMetrics; + if (doValidation) { + callbackMetrics = + outLabels.slice().concat(outLabels.map(n => 'val_' + n)); + } + else { + callbackMetrics = outLabels.slice(); + } + const callbacks = standardizeCallbacks(args.callbacks, args.yieldEvery); + const verbose = args.verbose == null ? 1 : args.verbose; + const { callbackList, history } = configureCallbacks(callbacks, verbose, args.epochs, null, null, getStepsPerEpoch(dataset, args), null, // Batch size determined by the dataset itself. + doValidation, callbackMetrics); + callbackList.setModel(model); + model.history = history; + await callbackList.onTrainBegin(); + model.stopTraining_ = false; + let epoch = args.initialEpoch == null ? 0 : args.initialEpoch; + let dataIterator = await dataset.iterator(); + while (epoch < args.epochs) { + const epochLogs = {}; + await callbackList.onEpochBegin(epoch); + let stepsDone = 0; + let batchIndex = 0; + if (!hasBatchesPerEpoch) { + dataIterator = await dataset.iterator(); + } + while (hasBatchesPerEpoch ? stepsDone < args.batchesPerEpoch : true) { + const iteratorOut = await dataIterator.next(); + // If `batchesPerEpoch` is specified, the dataset should not be + // exhausted until all epoches are done. + if (hasBatchesPerEpoch && iteratorOut.done) { + console.warn('You provided `batchesPerEpoch` as ' + + `${args.batchesPerEpoch}, ` + + 'but your dataset iterator ran out of data after ' + + `${stepsDone} batches; ` + + 'interrupting training. Make sure that your ' + + 'dataset can generate at least `batchesPerEpoch * epochs` ' + + 'batches (in this case, ' + + `${args.batchesPerEpoch * args.epochs} batches). ` + + 'You may need to use the repeat() function when building ' + + 'your dataset.'); + break; + } + if (iteratorOut.value != null) { + const { xs, ys } = standardizeDataIteratorOutput(model, iteratorOut.value); + const batchLogs = {}; + batchLogs['batch'] = batchIndex; + batchLogs['size'] = xs[0].shape[0]; + await callbackList.onBatchBegin(batchIndex, batchLogs); + const sampleWeights = []; + if (args.classWeight != null) { + const standardClassWeights = standardizeClassWeights(args.classWeight, model.outputNames); + for (let i = 0; i < standardClassWeights.length; ++i) { + sampleWeights.push(await standardizeWeights(ys[i], null, standardClassWeights[i])); + } + } + // Train on batch. + const ins = xs.concat(ys).concat(sampleWeights); + const outs = trainFunction(ins); + dispose(ins); + for (let i = 0; i < outLabels.length; ++i) { + const label = outLabels[i]; + const out = outs[i]; + batchLogs[label] = out; + keep(out); + } + await callbackList.onBatchEnd(batchIndex, batchLogs); + disposeTensorsInLogs(batchLogs); + batchIndex++; + stepsDone++; + } + if (hasBatchesPerEpoch ? stepsDone >= args.batchesPerEpoch : + iteratorOut.done) { + // Epoch finished. Perform validation. + if (doValidation) { + let valOuts; + if (isDatasetObject(args.validationData)) { + valOuts = toList(await model.evaluateDataset(args.validationData, { batches: args.validationBatches })); + } + else { + valOuts = toList(model.evaluate(valXs, valYs, { + batchSize: args.validationBatchSize == null ? + DEFAULT_VALIDATION_BATCH_SIZE : + args.validationBatchSize, + verbose: 0 + })); + } + for (let i = 0; i < model.metricsNames.length; ++i) { + epochLogs[`val_${model.metricsNames[i]}`] = valOuts[i]; + } + } + // Call `break` to exit one epoch lopp after validation is done. If + // config.batchesPerEpoch is specified, an epoch while loop will + // stop when `stepsDone >= config.batchesPerEpoch`. When + // config.batchesPerEpoch is not provided, the following `break` is + // required to exit the while lopp after dataset is exhausted. + break; + } + if (model.stopTraining_) { + break; + } + } + await callbackList.onEpochEnd(epoch, epochLogs); + epoch++; + if (model.stopTraining_) { + break; + } + } + await callbackList.onTrainEnd(); + await model.history.syncData(); + return model.history; + } + finally { + model.isTraining = false; + } + } + /** Helper function that determines number of steps (batches) per epoch. */ + function getStepsPerEpoch(dataset, args) { + // Attempt to determine # of batches in an epoch. + let stepsPerEpoch = null; + if (args.batchesPerEpoch != null) { + stepsPerEpoch = args.batchesPerEpoch; + } + else if (Number.isFinite(dataset.size)) { + stepsPerEpoch = dataset.size; + } + return stepsPerEpoch; + } + // Check if provided object is a Dataset object by checking its .iterator + // element. + function isDatasetObject(dataset) { + return (typeof dataset.iterator === 'function'); + } + // Check if provided object is a LazyIterator object by checking it's .next + // element. + function isLazyIteratorObject(iterator) { + return (typeof iterator.next === 'function'); + } + async function evaluateDataset( + // Type `model` as `any` here to avoid circular dependency w/ + // training.ts. + // tslint:disable-next-line:no-any + model, dataset, args) { + args = args || {}; + const hasBatches = args.batches != null; + const f = model.testFunction; + let outs = []; + if (args.verbose > 0) { + throw new NotImplementedError('Verbose mode is not implemented yet.'); + } + assert$1(!hasBatches || (args.batches > 0 && Number.isInteger(args.batches)), () => 'Test loop expects `batches` to be a positive integer, but ' + + `received ${JSON.stringify(args.batches)}`); + const dataIterator = isLazyIteratorObject(dataset) ? + dataset : + await dataset.iterator(); + // Keeps track of number of examples used in this evaluation. + let numExamples = 0; + let batch = 0; + while (hasBatches ? batch < args.batches : true) { + const iteratorOut = await dataIterator.next(); + outs = tidy(() => { + if (iteratorOut.value) { + // TODO(cais): Once real dataset is available, use + // `map(x => standardizeDataIteratorOutput(model, x).map(f)`. + const { xs, ys } = standardizeDataIteratorOutput(model, iteratorOut.value); + const xsAndYs = xs.concat(ys); + const batchOuts = tidy(() => f(xsAndYs)); + dispose(xsAndYs); + if (batch === 0) { + for (let i = 0; i < batchOuts.length; ++i) { + outs.push(scalar(0)); + } + } + const batchSize = xsAndYs[0].shape[0]; + for (let i = 0; i < batchOuts.length; ++i) { + const batchOut = batchOuts[i]; + const oldScalar = outs[i]; + outs[i] = + tidy(() => add$3(outs[i], mul(batchSize, batchOut))); + if (batch > 0) { + dispose(oldScalar); + } + } + dispose(batchOuts); + numExamples += batchSize; + ++batch; + } + return outs; + }); + if (iteratorOut.done) { + if (hasBatches) { + console.warn('Your dataset iterator ran out of data during evaluateDataset(). ' + + 'Interrupting evalution. Make sure that your ' + + 'dataset can generate at least `batches` ' + + `batches (in this case, ${args.batches} batches). ` + + 'You may need to use the repeat() function when building ' + + 'your dataset.'); + } + break; + } + } + for (let i = 0; i < outs.length; ++i) { + const oldScalar = outs[i]; + outs[i] = div$1(outs[i], numExamples); + dispose(oldScalar); + } + return singletonOrArray(outs); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + function checkBatchSize(batchSize) { + assert$1(batchSize > 0 && Number.isInteger(batchSize), () => `batchSize is required to be a positive integer, but got ${batchSize}`); + } + /** + * Slice a Tensor or an Array of Tensors, by start and stop indices. + * + * Porting Note: The `_slice_arrays` function in PyKeras is covered by this + * function and `sliceArraysByIndices()` together. + * + * @param arrays: the input. + * @param start: the starting index (inclusive). + * @param stop: the stopping index (exclusive). + * @returns The result of the slicing. If `arrays` is an `Array` of + * `tf.Tensor`s, the slicing will be applied to all elements of the `Array` + * in the same way. + */ + function sliceArrays(arrays, start, stop) { + if (arrays == null) { + return [null]; + } + else if (Array.isArray(arrays)) { + return arrays.map(array => sliceAlongFirstAxis(array, start, stop - start)); + } + else { // Tensor. + return sliceAlongFirstAxis(arrays, start, stop - start); + } + } + /** + * Slice a Tensor or an Array of Tensors, by random-order indices. + * + * Porting Note: The `_slice_arrays` function in PyKeras is covered by this + * function and `sliceArrays()` together. + * + * @param arrays The input `tf.Tensor` or `Array` of `tf.Tensor`s to slice. + * If an `Array` of `tf.Tensor`s, all `tf.Tensor`s will be sliced in the + * same fashion. + * @param indices The indices to use for slicing along the first (batch) + * dimension. + * @returns Result(s) of the slicing. + */ + function sliceArraysByIndices(arrays, indices) { + return tidy(() => { + if (arrays == null) { + return null; + } + else if (Array.isArray(arrays)) { + return arrays.map(array => sliceArraysByIndices(array, indices)); + } + else { + // TODO(cais): indices should be a pre-constructed Tensor1D to avoid + // tensor1d() calls. + return gather(arrays, indices.dtype === 'int32' ? indices : cast$3(indices, 'int32')); + } + }); + } + /** + * Returns a list of batch indices (tuples of indices). + * @param size: Integer, total size of the data to slice into batches. + * @param batchSize: Integer, batch size. + * @returns An Array of [batchStart, batchEnd] tuples. batchStart is + * inclusive; batchEnd is exclusive. I.e., each batch consists of indices x + * that satisfy batchStart <= x < batchEnd. + */ + function makeBatches(size, batchSize) { + const output = []; + let batchStart = 0; + let batchEnd = null; + while (batchStart < size) { + batchEnd = batchStart + batchSize; + if (batchEnd >= size) { + batchEnd = size; + } + output.push([batchStart, batchEnd]); + batchStart = batchEnd; + } + return output; + } + /** + * Ensure tensors all have a rank of at least 2. + * + * If a tensor has a rank of 1, it is dimension-expanded to rank 2. + * If any tensor has a rank of 0 (i.e., is a scalar), an error will be thrown. + */ + function ensureTensorsRank2OrHigher(tensors) { + const outs = []; + if (tensors instanceof Tensor) { + tensors = [tensors]; + } + // Make Tensors at least 2D. + for (let i = 0; i < tensors.length; ++i) { + const tensor = tensors[i]; + if (tensor.rank === 1) { + outs.push(expandDims$2(tensor, 1)); + } + else if (tensor.rank === 0) { + throw new Error('Expected tensor to be at least 1D, but received a 0D tensor ' + + '(scalar).'); + } + else { + outs.push(tensor); + } + } + return outs; + } + /** + * Compare a set of tensors with a reference (old) set, discard the ones + * in the new set that are not present in the reference set. + * + * This method is used for memory clenaup during calls such as + * LayersModel.fit(). + * + * @param tensors New set which may contain Tensors not present in + * `refTensors`. + * @param refTensors Reference Tensor set. + */ + // TODO(cais, kangyizhang): Deduplicate with tfjs-data. + function disposeNewTensors(tensors, refTensors) { + if (tensors == null) { + return; + } + const oldTensorIds = []; + if (refTensors instanceof Tensor) { + oldTensorIds.push(refTensors.id); + } + else if (Array.isArray(refTensors)) { + refTensors.forEach(t => oldTensorIds.push(t.id)); + } + else if (refTensors != null) { + // `oldTensors` is a map from string name to Tensor. + for (const name in refTensors) { + const oldTensor = refTensors[name]; + oldTensorIds.push(oldTensor.id); + } + } + const tensorsToDispose = []; + if (tensors instanceof Tensor) { + if (oldTensorIds.indexOf(tensors.id) === -1) { + tensorsToDispose.push(tensors); + } + } + else if (Array.isArray(tensors)) { + tensors.forEach(t => { + if (oldTensorIds.indexOf(t.id) === -1) { + tensorsToDispose.push(t); + } + }); + } + else if (tensors != null) { + // `oldTensors` is a map from string name to Tensor. + for (const name in tensors) { + const tensor = tensors[name]; + if (oldTensorIds.indexOf(tensor.id) === -1) { + tensorsToDispose.push(tensor); + } + } + } + tensorsToDispose.forEach(t => { + if (!t.isDisposed) { + t.dispose(); + } + }); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Helper function for polymorphic input data: 1. singleton Tensor. + */ + function isDataTensor(x) { + return x instanceof Tensor; + } + /** + * Helper function for polymorphic input data: 2. Array of Tensor. + */ + function isDataArray(x) { + return Array.isArray(x); + } + /** + * Helper function for polymorphic input data: 3. "dict" of Tensor. + */ + function isDataDict(x) { + return !isDataTensor(x) && !isDataArray(x); + } + /** + * Normalizes inputs and targets provided by users. + * @param data User-provided input data (polymorphic). + * @param names An Array of expected Tensor names. + * @param shapes Optional Array of expected Tensor shapes. + * @param checkBatchAxis Whether to check that the batch axis of the arrays + * match the expected value found in `shapes`. + * @param exceptionPrefix String prefix used for exception formatting. + * @returns List of standardized input Tensors (one Tensor per model input). + * @throws ValueError: in case of improperly formatted user data. + */ + function standardizeInputData(data, names, shapes, checkBatchAxis = true, exceptionPrefix = '') { + if (names == null || names.length === 0) { + // Check for the case where the model expected no data, but some data got + // sent. + if (data != null) { + let gotUnexpectedData = false; + if (isDataArray(data) && data.length > 0) { + gotUnexpectedData = true; + } + else if (isDataDict(data)) { + for (const key in data) { + if (data.hasOwnProperty(key)) { + gotUnexpectedData = true; + break; + } + } + } + else { + // `data` is a singleton Tensor in this case. + gotUnexpectedData = true; + } + if (gotUnexpectedData) { + throw new ValueError(`Error when checking model ${exceptionPrefix} expected no data, ` + + `but got ${data}`); + } + } + return []; + } + if (data == null) { + return names.map(name => null); + } + let arrays; + if (isDataDict(data)) { + data = data; + arrays = []; + for (const name of names) { + if (data[name] == null) { + throw new ValueError(`No data provided for "${name}". Need data for each key in: ` + + `${names}`); + } + arrays.push(data[name]); + } + } + else if (isDataArray(data)) { + data = data; + if (data.length !== names.length) { + throw new ValueError(`Error when checking model ${exceptionPrefix}: the Array of ` + + `Tensors that you are passing to your model is not the size the ` + + `model expected. Expected to see ${names.length} Tensor(s), but ` + + `instead got the following list of Tensor(s): ${data}`); + } + arrays = data; + } + else { + data = data; + if (names.length > 1) { + throw new ValueError(`The model ${exceptionPrefix} expects ${names.length} Tensor(s), ` + + `but only received one Tensor. Found: Tensor with shape ${data.shape}`); + } + arrays = [data]; + } + arrays = ensureTensorsRank2OrHigher(arrays); + // Check shape compatibility. + if (shapes != null) { + for (let i = 0; i < names.length; ++i) { + if (shapes[i] == null) { + continue; + } + const array = arrays[i]; + if (array.shape.length !== shapes[i].length) { + throw new ValueError(`Error when checking ${exceptionPrefix}: expected ${names[i]} ` + + `to have ${shapes[i].length} dimension(s). but got array with ` + + `shape ${array.shape}`); + } + for (let j = 0; j < shapes[i].length; ++j) { + if (j === 0 && !checkBatchAxis) { + // Skip the first (batch) axis. + continue; + } + const dim = array.shape[j]; + const refDim = shapes[i][j]; + if (refDim != null && refDim >= 0 && dim !== refDim) { + throw new ValueError(`${exceptionPrefix} expected a batch of elements where each ` + + `example has shape [${shapes[i].slice(1, shapes[i].length)}] ` + + `(i.e.,tensor shape [*,${shapes[i].slice(1, shapes[i].length)}])` + + ` but the ${exceptionPrefix} received an input with ${array.shape[0]}` + + ` examples, each with shape [${array.shape.slice(1, array.shape.length)}]` + + ` (tensor shape [${array.shape}])`); + } + } + } + } + return arrays; + } + /** + * User input validation for Tensors. + * @param inputs `Array` of `tf.Tensor`s for inputs. + * @param targets `Array` of `tf.Tensor`s for targets. + * @param weights Optional `Array` of `tf.Tensor`s for sample weights. + * @throws ValueError: in case of incorrectly formatted data. + */ + function checkArrayLengths(inputs, targets, weights) { + const setX = unique$2(inputs.map(input => input.shape[0])); + setX.sort(); + const setY = unique$2(targets.map(target => target.shape[0])); + setY.sort(); + // TODO(cais): Check `weights` as well. + if (setX.length > 1) { + throw new ValueError(`All input Tensors (x) should have the same number of samples. ` + + `Got array shapes: ` + + `${JSON.stringify(inputs.map(input => input.shape))}`); + } + if (setY.length > 1) { + throw new ValueError(`All target Tensors (y) should have the same number of samples. ` + + `Got array shapes: ` + + `${JSON.stringify(targets.map(target => target.shape))}`); + } + if (setX.length > 0 && setY.length > 0 && !arraysEqual(setX, setY)) { + throw new ValueError(`Input Tensors should have the same number of samples as target ` + + `Tensors. Found ${setX[0]} input sample(s) and ${setY[0]} target ` + + `sample(s).`); + } + } + /** + * Validation on the compatibility of targes and loss functions. + * + * This helps prevent users from using loss functions incorrectly. + * + * @param targets `Array` of `tf.Tensor`s of targets. + * @param lossFns `Array` of loss functions. + * @param outputShapes `Array` of shapes of model outputs. + */ + function checkLossAndTargetCompatibility(targets, lossFns, outputShapes) { + // TODO(cais): Dedicated test coverage? + const keyLosses = [ + meanSquaredError$1, binaryCrossentropy$2, + categoricalCrossentropy$2 + ]; + for (let i = 0; i < targets.length; ++i) { + const y = targets[i]; + const loss = lossFns[i]; + const shape = outputShapes[i]; + if (loss == null) { + continue; + } + if (loss === categoricalCrossentropy$2) { + if (y.shape[y.shape.length - 1] === 1) { + throw new ValueError(`You are passing a target array of shape ${y.shape} while using ` + + `a loss 'categorical_crossentropy'. 'categorical_crossentropy'` + + `expects targets to be binary matrices (1s and 0s) of shape ` + + `[samples, classes].`); + // TODO(cais): Example code in error message. + } + } + if (keyLosses.indexOf(loss) !== -1) { + const slicedYShape = y.shape.slice(1); + const slicedShape = shape.slice(1); + for (let j = 0; j < slicedYShape.length; ++j) { + const targetDim = slicedYShape[j]; + const outDim = slicedShape[j]; + if (outDim != null && targetDim !== outDim) { + throw new ValueError(`A target Tensor with shape ${y.shape} was passed for an ` + + `output of shape ${shape}, while using a loss function that ` + + `expects targets to have the same shape as the output.`); + } + } + } + } + } + /** + * Check inputs provided by the user. + * + * Porting Note: This corresponds to _standardize_input_data() in Python + * Keras. Because of the strong typing in TF.js, we do not need to convert + * the data. Specifically: + * 1) in PyKeras, `data` can be `DataFrame` instances from pandas, for + * example. We don't need to worry about that here because there is no + * widely popular javascript/typesdcript equivalent of pandas (so far). + * If one becomes available in the future, we can add support. + * 2) in PyKeras, inputs can be Python dict. But here we are stipulating + * that the data is either a single `tf.Tensor` or an Array of `tf.Tensor`s. We + * may add support for `Object` data inputs in the future when the need + * arises. + * + * Instead, we perform basic checks for number of parameters and shapes. + * + * @param data: The input data. + * @param names: Name for the inputs, from the model. + * @param shapes: Expected shapes for the input data, from the model. + * @param checkBatchAxis: Whether the size along the batch axis (i.e., the + * first dimension) will be checked for matching. + * @param exceptionPrefix: Execption prefix message, used in generating error + * messages. + * @throws ValueError: on incorrect number of inputs or mismatches in shapes. + */ + function checkInputData(data, names, shapes, checkBatchAxis = true, exceptionPrefix = '') { + let arrays; + if (Array.isArray(data)) { + if (data.length !== names.length) { + throw new ValueError(`Error when checking model ${exceptionPrefix}: the Array of ` + + `Tensors that you are passing to your model is not the size the ` + + `the model expected. Expected to see ${names.length} Tensor(s),` + + ` but instead got ${data.length} Tensors(s).`); + } + arrays = data; + } + else { + if (names.length > 1) { + throw new ValueError(`The model expects ${names.length} ${exceptionPrefix} Tensors, ` + + `but only received one Tensor. Found: array with shape ` + + `${JSON.stringify(data.shape)}.`); + } + arrays = [data]; + } + if (shapes != null) { + for (let i = 0; i < names.length; ++i) { + if (shapes[i] == null) { + continue; + } + const array = arrays[i]; + if (array.shape.length !== shapes[i].length) { + throw new ValueError(`Error when checking ${exceptionPrefix}: expected ${names[i]} ` + + `to have ${shapes[i].length} dimension(s), but got array with ` + + `shape ${JSON.stringify(array.shape)}`); + } + for (let j = 0; j < shapes[i].length; ++j) { + if (j === 0 && !checkBatchAxis) { + continue; + } + const dim = array.shape[j]; + const refDim = shapes[i][j]; + if (refDim != null) { + if (refDim !== dim) { + throw new ValueError(`Error when checking ${exceptionPrefix}: expected ` + + `${names[i]} to have shape ${JSON.stringify(shapes[i])} but ` + + `got array with shape ${JSON.stringify(array.shape)}.`); + } + } + } + } + } + } + /** + * Maps metric functions to model outputs. + * @param metrics An shortcut strings name, metric function, `Array` or dict + * (`Object`) of metric functions. + * @param outputNames An `Array` of the names of model outputs. + * @returns An `Array` (one entry per model output) of `Array` of metric + * functions. For instance, if the model has 2 outputs, and for the first + * output we want to compute `binaryAccuracy` and `binaryCrossentropy`, + * and just `binaryAccuracy` for the second output, the `Array` would look + * like: + * `[[binaryAccuracy, binaryCrossentropy], [binaryAccuracy]]` + * @throws TypeError: incompatible metrics format. + */ + function collectMetrics(metrics, outputNames) { + if (metrics == null || Array.isArray(metrics) && metrics.length === 0) { + return outputNames.map(name => []); + } + let wrappedMetrics; + if (typeof metrics === 'string' || typeof metrics === 'function') { + wrappedMetrics = [metrics]; + } + else if (Array.isArray(metrics) || typeof metrics === 'object') { + wrappedMetrics = metrics; + } + else { + throw new TypeError('Type of metrics argument not understood. Expected an string,' + + `function, Array, or Object, found: ${metrics}`); + } + if (Array.isArray(wrappedMetrics)) { + // We then apply all metrics to all outputs. + return outputNames.map(name => wrappedMetrics); + } + else { + // In this case, metrics is a dict. + const nestedMetrics = []; + for (const name of outputNames) { + let outputMetrics = wrappedMetrics.hasOwnProperty(name) ? wrappedMetrics[name] : []; + if (!Array.isArray(outputMetrics)) { + outputMetrics = [outputMetrics]; + } + nestedMetrics.push(outputMetrics); + } + return nestedMetrics; + } + } + const LAYERS_MODEL_FORMAT_NAME = 'layers-model'; + /** + * A `tf.LayersModel` is a directed, acyclic graph of `tf.Layer`s plus methods + * for training, evaluation, prediction and saving. + * + * `tf.LayersModel` is the basic unit of training, inference and evaluation in + * TensorFlow.js. To create a `tf.LayersModel`, use `tf.LayersModel`. + * + * See also: + * `tf.Sequential`, `tf.loadLayersModel`. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + class LayersModel extends Container { + constructor(args) { + super(args); + this.isTraining = false; + } + /** + * Print a text summary of the model's layers. + * + * The summary includes + * - Name and type of all layers that comprise the model. + * - Output shape(s) of the layers + * - Number of weight parameters of each layer + * - If the model has non-sequential-like topology, the inputs each layer + * receives + * - The total number of trainable and non-trainable parameters of the model. + * + * ```js + * const input1 = tf.input({shape: [10]}); + * const input2 = tf.input({shape: [20]}); + * const dense1 = tf.layers.dense({units: 4}).apply(input1); + * const dense2 = tf.layers.dense({units: 8}).apply(input2); + * const concat = tf.layers.concatenate().apply([dense1, dense2]); + * const output = + * tf.layers.dense({units: 3, activation: 'softmax'}).apply(concat); + * + * const model = tf.model({inputs: [input1, input2], outputs: output}); + * model.summary(); + * ``` + * + * @param lineLength Custom line length, in number of characters. + * @param positions Custom widths of each of the columns, as either + * fractions of `lineLength` (e.g., `[0.5, 0.75, 1]`) or absolute number + * of characters (e.g., `[30, 50, 65]`). Each number corresponds to + * right-most (i.e., ending) position of a column. + * @param printFn Custom print function. Can be used to replace the default + * `console.log`. For example, you can use `x => {}` to mute the printed + * messages in the console. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + summary(lineLength, positions, printFn = console.log) { + if (!this.built) { + throw new ValueError(`This model has never been called, thus its weights have not been ` + + `created yet. So no summary can be displayed. Build the model ` + + `first (e.g., by calling it on some test data).`); + } + printSummary(this, lineLength, positions, printFn); + } + /** + * Configures and prepares the model for training and evaluation. Compiling + * outfits the model with an optimizer, loss, and/or metrics. Calling `fit` + * or `evaluate` on an un-compiled model will throw an error. + * + * @param args a `ModelCompileArgs` specifying the loss, optimizer, and + * metrics to be used for fitting and evaluating this model. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + compile(args) { + if (args.loss == null) { + args.loss = []; + } + this.loss = args.loss; + if (typeof args.optimizer === 'string') { + this.optimizer_ = getOptimizer(args.optimizer); + this.isOptimizerOwned = true; + } + else { + if (!(args.optimizer instanceof Optimizer)) { + throw new ValueError(`User-defined optimizer must be an instance of tf.Optimizer.`); + } + this.optimizer_ = args.optimizer; + this.isOptimizerOwned = false; + } + // TODO(cais): Add lossWeights. + // TODO(cais): Add sampleWeightMode. + // Prepare loss functions. + let lossFunctions = []; + if (!Array.isArray(args.loss) && typeof args.loss !== 'string' && + typeof args.loss !== 'function') { + args.loss = args.loss; + for (const name in args.loss) { + if (this.outputNames.indexOf(name) === -1) { + throw new ValueError(`Unknown entry in loss dictionary: "${name}". ` + + `Only expected the following keys: ${this.outputNames}`); + } + } + for (const name of this.outputNames) { + if (args.loss[name] == null) { + console.warn(`Output "${name}" is missing from loss dictionary. We assume ` + + `this was done on purpose, and we will not be expecting data ` + + `to be passed to ${name} during training`); + } + lossFunctions.push(get$1(args.loss[name])); + } + } + else if (Array.isArray(args.loss)) { + if (args.loss.length !== this.outputs.length) { + throw new ValueError(`When passing an Array as loss, it should have one entry per ` + + `model output. The model has ${this.outputs.length} output(s), ` + + `but you passed loss=${args.loss}.`); + } + const theLosses = args.loss; + lossFunctions = theLosses.map(l => get$1(l)); + } + else { + const lossFunction = get$1(args.loss); + this.outputs.forEach(_ => { + lossFunctions.push(lossFunction); + }); + } + this.lossFunctions = lossFunctions; + this.feedOutputNames = []; + this.feedOutputShapes = []; + this.feedLossFns = []; + for (let i = 0; i < this.outputs.length; ++i) { + // TODO(cais): Logic for skipping target(s). + const shape = this.internalOutputShapes[i]; + const name = this.outputNames[i]; + this.feedOutputNames.push(name); + this.feedOutputShapes.push(shape); + this.feedLossFns.push(this.lossFunctions[i]); + } + // TODO(cais): Add logic for output masks. + // TODO(cais): Add logic for sample weights. + const skipTargetIndices = []; + // Prepare metrics. + this.metrics = args.metrics; + // TODO(cais): Add weightedMetrics. + this.metricsNames = ['loss']; + this.metricsTensors = []; + // Compute total loss. + // Porting Note: In PyKeras, metrics_tensors are symbolic tensor objects. + // Here, metricsTensors are TypeScript functions. This difference is due + // to the difference in symbolic/imperative property of the backends. + nameScope('loss', () => { + for (let i = 0; i < this.outputs.length; ++i) { + if (skipTargetIndices.indexOf(i) !== -1) { + continue; + } + // TODO(cais): Add weightedLoss, sampleWeight and mask. + // The following line should be weightedLoss + const weightedLoss = this.lossFunctions[i]; + if (this.outputs.length > 1) { + this.metricsTensors.push([weightedLoss, i]); + this.metricsNames.push(this.outputNames[i] + '_loss'); + } + } + // Porting Note: Due to the imperative nature of the backend, we calculate + // the regularizer penalties in the totalLossFunction, instead of here. + }); + const nestedMetrics = collectMetrics(args.metrics, this.outputNames); + // TODO(cais): Add nestedWeightedMetrics. + /** + * Helper function used in loop below. + */ + const appendMetric = (outputIndex, metricName, metricTensor) => { + if (this.outputNames.length > 1) { + metricName = this.outputNames[outputIndex] + '_' + metricName; + } + this.metricsNames.push(metricName); + this.metricsTensors.push([metricTensor, outputIndex]); + }; + nameScope('metric', () => { + for (let i = 0; i < this.outputs.length; ++i) { + if (skipTargetIndices.indexOf(i) !== -1) { + continue; + } + const outputMetrics = nestedMetrics[i]; + // TODO(cais): Add weights and outputWeightedMetrics. + // TODO(cais): Add optional arg `weights` to the following function. + const handleMetrics = (metrics) => { + const metricNamePrefix = ''; + let metricName; + let accFn; + let weightedMetricFn; + // TODO(cais): Use 'weights_' for weighted metrics. + for (const metric of metrics) { + if (typeof metric === 'string' && + ['accuracy', 'acc', 'crossentropy', 'ce'].indexOf(metric) !== + -1) { + const outputShape = this.internalOutputShapes[i]; + if (outputShape[outputShape.length - 1] === 1 || + this.lossFunctions[i] === binaryCrossentropy$2) { + // case: binary accuracy/crossentropy. + if (['accuracy', 'acc'].indexOf(metric) !== -1) { + accFn = binaryAccuracy$1; + } + else if (['crossentropy', 'ce'].indexOf(metric) !== -1) { + accFn = binaryCrossentropy$1; + } + } + else if (this.lossFunctions[i] === + sparseCategoricalCrossentropy$1) { + // case: categorical accuracy / crossentropy with sparse + // targets. + if (['accuracy', 'acc'].indexOf(metric) !== -1) { + accFn = sparseCategoricalAccuracy$1; + } + else if (['crossentropy', 'ce'].indexOf(metric) !== -1) { + accFn = sparseCategoricalCrossentropy; + } + } + else { + // case: categorical accuracy / crossentropy. + if (['accuracy', 'acc'].indexOf(metric) !== -1) { + accFn = categoricalAccuracy$1; + } + else if (['crossentropy', 'ce'].indexOf(metric) !== -1) { + accFn = categoricalCrossentropy$1; + } + } + let suffix; + if (['accuracy', 'acc'].indexOf(metric) !== -1) { + suffix = 'acc'; + } + else if (['crossentropy', 'ce'].indexOf(metric) !== -1) { + suffix = 'ce'; + } + // TODO(cais): Add weighting actually. + weightedMetricFn = accFn; + metricName = metricNamePrefix + suffix; + } + else { + const metricFn = get(metric); + // TODO(cais): Add weighting actually. + weightedMetricFn = metricFn; + metricName = + metricNamePrefix + getLossOrMetricName(metric); + } + // TODO(cais): Add weighting and masking to metricResult. + let metricResult; + nameScope(metricName, () => { + metricResult = weightedMetricFn; + }); + appendMetric(i, metricName, metricResult); + } + }; + handleMetrics(outputMetrics); + // TODO(cais): Call handleMetrics with weights. + } + }); + // Porting Notes: Given the imperative backend of tfjs-core, + // there is no need for constructing the symbolic graph and placeholders. + this.collectedTrainableWeights = this.trainableWeights; + } + /** + * Check trainable weights count consistency. + * + * This will raise a warning if `this.trainableWeights` and + * `this.collectedTrainableWeights` are inconsistent (i.e., have different + * numbers of parameters). + * Inconsistency will typically arise when one modifies `model.trainable` + * without calling `model.compile()` again. + */ + checkTrainableWeightsConsistency() { + if (this.collectedTrainableWeights == null) { + return; + } + if (this.trainableWeights.length !== + this.collectedTrainableWeights.length) { + console.warn('Discrepancy between trainableweights and collected trainable ' + + 'weights. Did you set `model.trainable` without calling ' + + '`model.compile()` afterwards?'); + } + } + /** + * Returns the loss value & metrics values for the model in test mode. + * + * Loss and metrics are specified during `compile()`, which needs to happen + * before calls to `evaluate()`. + * + * Computation is done in batches. + * + * ```js + * const model = tf.sequential({ + * layers: [tf.layers.dense({units: 1, inputShape: [10]})] + * }); + * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'}); + * const result = model.evaluate( + * tf.ones([8, 10]), tf.ones([8, 1]), {batchSize: 4}); + * result.print(); + * ``` + * + * @param x `tf.Tensor` of test data, or an `Array` of `tf.Tensor`s if the + * model has multiple inputs. + * @param y `tf.Tensor` of target data, or an `Array` of `tf.Tensor`s if the + * model has multiple outputs. + * @param args A `ModelEvaluateArgs`, containing optional fields. + * + * @return `Scalar` test loss (if the model has a single output and no + * metrics) or `Array` of `Scalar`s (if the model has multiple outputs + * and/or metrics). The attribute `model.metricsNames` + * will give you the display labels for the scalar outputs. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + evaluate(x, y, args = {}) { + const batchSize = args.batchSize == null ? 32 : args.batchSize; + checkBatchSize(batchSize); + // TODO(cais): Standardize `config.sampleWeights` as well. + // Validate user data. + const checkBatchAxis = true; + const standardizedOuts = this.standardizeUserDataXY(x, y, checkBatchAxis, batchSize); + try { + // TODO(cais): If uses `useLearningPhase`, set the corresponding element + // of the input to 0. + const ins = standardizedOuts[0].concat(standardizedOuts[1]); + this.makeTestFunction(); + const f = this.testFunction; + const testOuts = this.testLoop(f, ins, batchSize, args.verbose, args.steps); + return singletonOrArray(testOuts); + } + finally { + disposeNewTensors(standardizedOuts[0], x); + disposeNewTensors(standardizedOuts[1], y); + } + } + // TODO(cais): Add code snippet below once real dataset objects are + // available. + /** + * Evaluate model using a dataset object. + * + * Note: Unlike `evaluate()`, this method is asynchronous (`async`). + * + * @param dataset A dataset object. Its `iterator()` method is expected + * to generate a dataset iterator object, the `next()` method of which + * is expected to produce data batches for evaluation. The return value + * of the `next()` call ought to contain a boolean `done` field and a + * `value` field. The `value` field is expected to be an array of two + * `tf.Tensor`s or an array of two nested `tf.Tensor` structures. The former + * case is for models with exactly one input and one output (e.g. + * a sequential model). The latter case is for models with multiple + * inputs and/or multiple outputs. Of the two items in the array, the + * first is the input feature(s) and the second is the output target(s). + * @param args A configuration object for the dataset-based evaluation. + * @returns Loss and metric values as an Array of `Scalar` objects. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + async evaluateDataset(dataset, args) { + this.makeTestFunction(); + return evaluateDataset(this, dataset, args); + } + /** + * Get number of samples provided for training, evaluation or prediction. + * + * @param ins Input `tf.Tensor`. + * @param batchSize Integer batch size, optional. + * @param steps Total number of steps (batches of samples) before + * declaring loop finished. Optional. + * @param stepsName The public API's parameter name for `steps`. + * @returns Number of samples provided. + */ + checkNumSamples(ins, batchSize, steps, stepsName = 'steps') { + let numSamples; + if (steps != null) { + numSamples = null; + if (batchSize != null) { + throw new ValueError(`If ${stepsName} is set, batchSize must be null or undefined.` + + `Got batchSize = ${batchSize}`); + } + } + else if (ins != null) { + if (Array.isArray(ins)) { + numSamples = ins[0].shape[0]; + } + else { + numSamples = ins.shape[0]; + } + } + else { + throw new ValueError(`Either the input data should have a defined shape, or ` + + `${stepsName} shoud be specified.`); + } + return numSamples; + } + /** + * Execute internal tensors of the model with input data feed. + * @param inputs Input data feed. Must match the inputs of the model. + * @param outputs Names of the output tensors to be fetched. Must match + * names of the SymbolicTensors that belong to the graph. + * @returns Fetched values for `outputs`. + */ + execute(inputs, outputs) { + if (Array.isArray(outputs) && outputs.length === 0) { + throw new ValueError('`outputs` is an empty Array, which is not allowed.'); + } + const outputsIsArray = Array.isArray(outputs); + const outputNames = (outputsIsArray ? outputs : [outputs]); + const outputSymbolicTensors = this.retrieveSymbolicTensors(outputNames); + // Format the input into a FeedDict. + const feedDict = new FeedDict(); + if (inputs instanceof Tensor) { + inputs = [inputs]; + } + if (Array.isArray(inputs)) { + if (inputs.length !== this.inputs.length) { + throw new ValueError(`The number of inputs provided (${inputs.length}) ` + + `does not match the number of inputs of this model ` + + `(${this.inputs.length}).`); + } + for (let i = 0; i < this.inputs.length; ++i) { + feedDict.add(this.inputs[i], inputs[i]); + } + } + else { + for (const input of this.inputs) { + const tensorValue = inputs[input.name]; + if (tensorValue == null) { + throw new ValueError(`No value is provided for the model's input ${input.name}`); + } + feedDict.add(input, tensorValue); + } + } + // Run execution. + const executeOutputs = execute(outputSymbolicTensors, feedDict); + return outputsIsArray ? executeOutputs : executeOutputs[0]; + } + /** + * Retrieve the model's internal symbolic tensors from symbolic-tensor names. + */ + retrieveSymbolicTensors(symbolicTensorNames) { + const outputSymbolicTensors = pyListRepeat(null, symbolicTensorNames.length); + let outputsRemaining = symbolicTensorNames.length; + for (const layer of this.layers) { + const layerOutputs = Array.isArray(layer.output) ? layer.output : [layer.output]; + const layerOutputNames = layerOutputs.map(output => output.name); + for (let i = 0; i < symbolicTensorNames.length; ++i) { + const index = layerOutputNames.indexOf(symbolicTensorNames[i]); + if (index !== -1) { + outputSymbolicTensors[i] = layerOutputs[index]; + outputsRemaining--; + } + if (outputsRemaining === 0) { + break; + } + } + if (outputsRemaining === 0) { + break; + } + } + if (outputsRemaining > 0) { + const remainingNames = []; + outputSymbolicTensors.forEach((tensor, i) => { + if (tensor == null) { + remainingNames.push(symbolicTensorNames[i]); + } + }); + throw new ValueError(`Cannot find SymbolicTensors for output name(s): ` + + `${JSON.stringify(remainingNames)}`); + } + return outputSymbolicTensors; + } + /** + * Helper method to loop over some data in batches. + * + * Porting Note: Not using the functional approach in the Python equivalent + * due to the imperative backend. + * Porting Note: Does not support step mode currently. + * + * @param ins: input data + * @param batchSize: integer batch size. + * @param verbose: verbosity model + * @returns: Predictions as `tf.Tensor` (if a single output) or an `Array` of + * `tf.Tensor` (if multipe outputs). + */ + predictLoop(ins, batchSize = 32, verbose = false) { + return tidy(() => { + const numSamples = this.checkNumSamples(ins); + if (verbose) { + throw new NotImplementedError('Verbose predictLoop() is not implemented yet.'); + } + // Sample-based predictions. + // Porting Note: Tensor currently does not support sliced assignments as + // in numpy, e.g., x[1:3] = y. Therefore we use concatenation while + // iterating over the batches. + const batches = makeBatches(numSamples, batchSize); + const outsBatches = this.outputs.map(output => []); + // TODO(cais): Can the scope() be pushed down inside the for loop? + for (let batchIndex = 0; batchIndex < batches.length; ++batchIndex) { + const batchOuts = tidy(() => { + const batchStart = batches[batchIndex][0]; + const batchEnd = batches[batchIndex][1]; + // TODO(cais): Take care of the case of the last element is a flag for + // training/test. + const insBatch = sliceArrays(ins, batchStart, batchEnd); + // Construct the feeds for execute(); + const feeds = []; + if (Array.isArray(insBatch)) { + for (let i = 0; i < insBatch.length; ++i) { + feeds.push({ key: this.inputs[i], value: insBatch[i] }); + } + } + else { + feeds.push({ key: this.inputs[0], value: insBatch }); + } + const feedDict = new FeedDict(feeds); + return execute(this.outputs, feedDict); + }); + batchOuts.forEach((batchOut, i) => outsBatches[i].push(batchOut)); + } + return singletonOrArray(outsBatches.map(batches => concat$2(batches, 0))); + }); + } + /** + * Generates output predictions for the input samples. + * + * Computation is done in batches. + * + * Note: the "step" mode of predict() is currently not supported. + * This is because the TensorFlow.js core backend is imperative only. + * + * ```js + * const model = tf.sequential({ + * layers: [tf.layers.dense({units: 1, inputShape: [10]})] + * }); + * model.predict(tf.ones([8, 10]), {batchSize: 4}).print(); + * ``` + * + * @param x The input data, as a Tensor, or an `Array` of `tf.Tensor`s if + * the model has multiple inputs. + * @param args A `ModelPredictArgs` object containing optional fields. + * + * @return Prediction results as a `tf.Tensor`(s). + * + * @exception ValueError In case of mismatch between the provided input data + * and the model's expectations, or in case a stateful model receives a + * number of samples that is not a multiple of the batch size. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + predict(x, args = {}) { + const xsRank2OrHigher = ensureTensorsRank2OrHigher(x); + checkInputData(xsRank2OrHigher, this.inputNames, this.feedInputShapes, false); + try { + // TODO(cais): Take care of stateful models. + // if (this.stateful) ... + // TODO(cais): Take care of the learning_phase boolean flag. + // if (this.useLearningPhase) ... + const batchSize = args.batchSize == null ? 32 : args.batchSize; + checkBatchSize(batchSize); + return this.predictLoop(xsRank2OrHigher, batchSize); + } + finally { + disposeNewTensors(xsRank2OrHigher, x); + } + } + /** + * Returns predictions for a single batch of samples. + * + * ```js + * const model = tf.sequential({ + * layers: [tf.layers.dense({units: 1, inputShape: [10]})] + * }); + * model.predictOnBatch(tf.ones([8, 10])).print(); + * ``` + * @param x: Input samples, as a Tensor (for models with exactly one + * input) or an array of Tensors (for models with more than one input). + * @return Tensor(s) of predictions + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + predictOnBatch(x) { + checkInputData(x, this.inputNames, this.feedInputShapes, true); + // TODO(cais): Take care of the learning_phase boolean flag. + // if (this.useLearningPhase) ... + const batchSize = (Array.isArray(x) ? x[0] : x).shape[0]; + return this.predictLoop(x, batchSize); + } + standardizeUserDataXY(x, y, checkBatchAxis = true, batchSize) { + // TODO(cais): Add sampleWeight, classWeight + if (this.optimizer_ == null) { + throw new RuntimeError('You must compile a model before training/testing. Use ' + + 'LayersModel.compile(modelCompileArgs).'); + } + const outputShapes = []; + for (let i = 0; i < this.feedOutputShapes.length; ++i) { + const outputShape = this.feedOutputShapes[i]; + const lossFn = this.feedLossFns[i]; + if (lossFn === sparseCategoricalCrossentropy$1) { + outputShapes.push(outputShape.slice(0, outputShape.length - 1).concat([1])); + } + else { + // Porting Note: Because of strong typing `lossFn` must be a function. + outputShapes.push(outputShape); + } + } + x = standardizeInputData(x, this.feedInputNames, this.feedInputShapes, false, 'input'); + y = standardizeInputData(y, this.feedOutputNames, outputShapes, false, 'target'); + // TODO(cais): Standardize sampleWeights & classWeights. + checkArrayLengths(x, y, null); + // TODO(cais): Check sampleWeights as well. + checkLossAndTargetCompatibility(y, this.feedLossFns, this.feedOutputShapes); + if (this.stateful && batchSize != null && batchSize > 0) { + if (x[0].shape[0] % batchSize !== 0) { + throw new ValueError(`In a stateful network, you should only pass inputs with a ` + + `number of samples that is divisible by the batch size ` + + `${batchSize}. Found: ${x[0].shape[0]} sample(s).`); + } + } + return [x, y]; + } + async standardizeUserData(x, y, sampleWeight, classWeight, checkBatchAxis = true, batchSize) { + const [standardXs, standardYs] = this.standardizeUserDataXY(x, y, checkBatchAxis, batchSize); + // TODO(cais): Handle sampleWeights. + if (sampleWeight != null) { + throw new Error('sample weight is not supported yet.'); + } + let standardSampleWeights = null; + if (classWeight != null) { + const classWeights = standardizeClassWeights(classWeight, this.outputNames); + standardSampleWeights = []; + for (let i = 0; i < classWeights.length; ++i) { + standardSampleWeights.push(await standardizeWeights(standardYs[i], null, classWeights[i])); + } + } + // TODO(cais): Deal with the case of model.stateful == true. + return [standardXs, standardYs, standardSampleWeights]; + } + /** + * Loop over some test data in batches. + * @param f A Function returning a list of tensors. + * @param ins Array of tensors to be fed to `f`. + * @param batchSize Integer batch size or `null` / `undefined`. + * @param verbose verbosity mode. + * @param steps Total number of steps (batches of samples) before + * declaring test finished. Ignored with the default value of `null` / + * `undefined`. + * @returns Array of Scalars. + */ + testLoop(f, ins, batchSize, verbose = 0, steps) { + return tidy(() => { + const numSamples = this.checkNumSamples(ins, batchSize, steps, 'steps'); + const outs = []; + if (verbose > 0) { + throw new NotImplementedError('Verbose mode is not implemented yet.'); + } + // TODO(cais): Use `indicesForConversionToDense' to prevent slow down. + if (steps != null) { + throw new NotImplementedError('steps mode in testLoop() is not implemented yet'); + } + else { + const batches = makeBatches(numSamples, batchSize); + const indexArray = tensor1d(range$2(0, numSamples)); + for (let batchIndex = 0; batchIndex < batches.length; ++batchIndex) { + const batchStart = batches[batchIndex][0]; + const batchEnd = batches[batchIndex][1]; + const batchIds = sliceAlongFirstAxis(indexArray, batchStart, batchEnd - batchStart); + // TODO(cais): In ins, train flag can be a number, instead of an + // Tensor? Do we need to handle this in tfjs-layers? + const insBatch = sliceArraysByIndices(ins, batchIds); + const batchOuts = f(insBatch); + if (batchIndex === 0) { + for (let i = 0; i < batchOuts.length; ++i) { + outs.push(scalar(0)); + } + } + for (let i = 0; i < batchOuts.length; ++i) { + const batchOut = batchOuts[i]; + outs[i] = + add$3(outs[i], mul(batchEnd - batchStart, batchOut)); + } + } + for (let i = 0; i < outs.length; ++i) { + outs[i] = div$1(outs[i], numSamples); + } + } + return outs; + }); + } + getDedupedMetricsNames() { + const outLabels = this.metricsNames; + // Rename duplicated metrics names (can happen with an output layer + // shared among multiple dataflows). + const dedupedOutLabels = []; + for (let i = 0; i < outLabels.length; ++i) { + const label = outLabels[i]; + let newLabel = label; + if (count(outLabels, label) > 1) { + const dupIndex = count(outLabels.slice(0, i), label); + newLabel += `_${dupIndex}`; + } + dedupedOutLabels.push(newLabel); + } + return dedupedOutLabels; + } + /** + * Creates a function that performs the following actions: + * + * 1. computes the losses + * 2. sums them to get the total loss + * 3. call the optimizer computes the gradients of the LayersModel's + * trainable weights w.r.t. the total loss and update the variables + * 4. calculates the metrics + * 5. returns the values of the losses and metrics. + */ + makeTrainFunction() { + return (data) => { + const lossValues = []; + const inputs = data.slice(0, this.inputs.length); + const targets = data.slice(this.inputs.length, this.inputs.length + this.outputs.length); + const sampleWeights = data.slice(this.inputs.length + this.outputs.length, this.inputs.length + this.outputs.length * 2); + const metricsValues = []; + // Create a function that computes the total loss based on the + // inputs. This function is used for obtaining gradients through + // backprop. + const totalLossFunction = () => { + const feeds = []; + for (let i = 0; i < this.inputs.length; ++i) { + feeds.push({ key: this.inputs[i], value: inputs[i] }); + } + const feedDict = new FeedDict(feeds); + const outputs = execute(this.outputs, feedDict, { 'training': true }); + // TODO(cais): Take care of the case of multiple outputs from a + // single layer? + let totalLoss; + for (let i = 0; i < this.lossFunctions.length; ++i) { + const lossFunction = this.lossFunctions[i]; + let loss = lossFunction(targets[i], outputs[i]); + if (sampleWeights[i] != null) { + loss = computeWeightedLoss(loss, sampleWeights[i]); + } + // TODO(cais): push Scalar instead. + const meanLoss = mean$3(loss); + // TODO(cais): Use a scope() instead, to avoid ownership. + lossValues.push(meanLoss); + if (i === 0) { + totalLoss = loss; + } + else { + totalLoss = add$3(totalLoss, loss); + } + } + // Compute the metrics. + // TODO(cais): These should probably be calculated outside + // totalLossFunction to benefit speed? + for (let i = 0; i < this.metricsTensors.length; ++i) { + let weightedMetric; + if (this.outputs.length > 1 && i < this.outputs.length) { + weightedMetric = lossValues[i]; + } + else { + const metric = this.metricsTensors[i][0]; + const outputIndex = this.metricsTensors[i][1]; + weightedMetric = + mean$3(metric(targets[outputIndex], outputs[outputIndex])); + } + keep(weightedMetric); + // TODO(cais): Use a scope() instead, to avoid ownership. + metricsValues.push(weightedMetric); + } + totalLoss = mean$3(totalLoss); + // Add regularizer penalties. + this.calculateLosses().forEach(regularizerLoss => { + totalLoss = add$3(totalLoss, regularizerLoss); + }); + return totalLoss; + }; + const variables = this.collectedTrainableWeights.map(param => param.read()); + const returnCost = true; + const totalLossValue = this.optimizer_.minimize(totalLossFunction, returnCost, variables); + return [totalLossValue].concat(metricsValues); + }; + } + /** + * Create a function which, when invoked with an array of `tf.Tensor`s as a + * batch of inputs, returns the prespecified loss and metrics of the model + * under the batch of input data. + */ + makeTestFunction() { + this.testFunction = (data) => { + return tidy(() => { + const valOutputs = []; + let totalLoss; + const inputs = data.slice(0, this.inputs.length); + const targets = data.slice(this.inputs.length, this.inputs.length + this.outputs.length); + const feeds = []; + for (let i = 0; i < this.inputs.length; ++i) { + feeds.push({ key: this.inputs[i], value: inputs[i] }); + } + const feedDict = new FeedDict(feeds); + const outputs = execute(this.outputs, feedDict); + // Compute total loss. + for (let i = 0; i < this.lossFunctions.length; ++i) { + const lossFunction = this.lossFunctions[i]; + // TODO(cais): Add sample weighting and replace the simple + // averaging. + const loss = mean$3(lossFunction(targets[i], outputs[i])); + if (i === 0) { + totalLoss = loss; + } + else { + totalLoss = add$3(totalLoss, loss); + } + valOutputs.push(totalLoss); + } + // Compute the metrics. + for (let i = 0; i < this.metricsTensors.length; ++i) { + const metric = this.metricsTensors[i][0]; + const outputIndex = this.metricsTensors[i][1]; + // TODO(cais): Replace K.mean() with a proper weighting function. + const meanMetric = mean$3(metric(targets[outputIndex], outputs[outputIndex])); + valOutputs.push(meanMetric); + } + return valOutputs; + }); + }; + } + /** + * Trains the model for a fixed number of epochs (iterations on a + * dataset). + * + * ```js + * const model = tf.sequential({ + * layers: [tf.layers.dense({units: 1, inputShape: [10]})] + * }); + * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'}); + * for (let i = 1; i < 5 ; ++i) { + * const h = await model.fit(tf.ones([8, 10]), tf.ones([8, 1]), { + * batchSize: 4, + * epochs: 3 + * }); + * console.log("Loss after Epoch " + i + " : " + h.history.loss[0]); + * } + * ``` + * + * @param x `tf.Tensor` of training data, or an array of `tf.Tensor`s if the + * model has multiple inputs. If all inputs in the model are named, you + * can also pass a dictionary mapping input names to `tf.Tensor`s. + * @param y `tf.Tensor` of target (label) data, or an array of `tf.Tensor`s if + * the model has multiple outputs. If all outputs in the model are named, + * you can also pass a dictionary mapping output names to `tf.Tensor`s. + * @param args A `ModelFitArgs`, containing optional fields. + * + * @return A `History` instance. Its `history` attribute contains all + * information collected during training. + * + * @exception ValueError In case of mismatch between the provided input + * data and what the model expects. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + async fit(x, y, args = {}) { + if (this.isTraining) { + throw new Error('Cannot start training because another fit() call is ongoing.'); + } + this.isTraining = true; + let inputs; + let targets; + let originalInputs; + let originalTargets; + let inputValX; + let inputValY; + let valX; + let valY; + let sampleWeights; + try { + const batchSize = args.batchSize == null ? 32 : args.batchSize; + checkBatchSize(batchSize); + // Validate user data. + // TODO(cais): Support sampleWeight. + const checkBatchAxis = false; + const standardizedOuts = await this.standardizeUserData(x, y, args.sampleWeight, args.classWeight, checkBatchAxis, batchSize); + inputs = standardizedOuts[0]; + targets = standardizedOuts[1]; + sampleWeights = standardizedOuts[2]; + // Prepare validation data. + let doValidation = false; + let valIns; + if (args.validationData != null && args.validationData.length > 0) { + doValidation = true; + if (args.validationData.length === 2) { + // config.validationData consists of valX and valY. + inputValX = args.validationData[0]; + inputValY = args.validationData[1]; + } + else if (args.validationData.length === 3) { + throw new NotImplementedError('validationData including sample weights is not supported yet.'); + } + else { + throw new ValueError(`When passing validation data, it must contain 2 (valX, valY) ` + + `or 3 (valX, valY, valSampleWeight) items; ` + + `${args.validationData} is invalid.`); + } + const checkBatchAxis = true; + const valStandardized = await this.standardizeUserData(inputValX, inputValY, null, /** Unused sample weights. */ null, /** Unused class weights. */ checkBatchAxis, batchSize); + valX = valStandardized[0]; + valY = valStandardized[1]; + valIns = valX.concat(valY); + // TODO(cais): Add useLearningPhase data properly. + } + else if (args.validationSplit != null && args.validationSplit > 0 && + args.validationSplit < 1) { + doValidation = true; + // Porting Note: In tfjs-layers, inputs[0] is always a Tensor. + const splitAt = Math.floor(inputs[0].shape[0] * (1 - args.validationSplit)); + const originalBatchSize = inputs[0].shape[0]; + valX = sliceArrays(inputs, splitAt, originalBatchSize); + originalInputs = inputs; + inputs = sliceArrays(inputs, 0, splitAt); + valY = sliceArrays(targets, splitAt, originalBatchSize); + originalTargets = targets; + targets = sliceArrays(targets, 0, splitAt); + // TODO(cais): Once sampleWeights becomes available, slice it to get + // valSampleWeights. + valIns = valX.concat(valY); + // TODO(cais): Add useLearningPhase data properly. + } + else if (args.validationSteps != null) { + doValidation = true; + // TODO(cais): Add useLearningPhase. + } + const ins = inputs.concat(targets).concat(sampleWeights); + this.checkTrainableWeightsConsistency(); + // TODO(cais): Handle use_learning_phase and learning_phase? + // Porting Note: Here we see a key deviation of tfjs-layers from + // Keras. + // Due to the imperative nature of tfjs-layers' backend (tfjs-core), + // we do not construct symbolic computation graphs to embody the + // training process. Instead, we define a function that performs the + // training action. In PyKeras, the data (inputs and targets) are fed + // through graph placeholders. In tfjs-layers, the data are fed as + // function arguments. Since the function are defined below in the + // scope, we don't have equivalents of PyKeras's + // `_make_train_funciton`. + const trainFunction = this.makeTrainFunction(); + const outLabels = this.getDedupedMetricsNames(); + let valFunction; + let callbackMetrics; + if (doValidation) { + this.makeTestFunction(); + valFunction = this.testFunction; + callbackMetrics = + outLabels.slice().concat(outLabels.map(n => 'val_' + n)); + } + else { + valFunction = null; + valIns = []; + callbackMetrics = outLabels.slice(); + } + const callbacks = standardizeCallbacks(args.callbacks, args.yieldEvery); + const out = await this.fitLoop(trainFunction, ins, outLabels, batchSize, args.epochs, args.verbose, callbacks, valFunction, valIns, args.shuffle, callbackMetrics, args.initialEpoch, null, null); + return out; + } + finally { + this.isTraining = false; + // Memory clean up. + disposeNewTensors(inputs, x); + disposeNewTensors(targets, y); + disposeNewTensors(originalInputs, x); + disposeNewTensors(originalTargets, y); + disposeNewTensors(valX, inputValX); + disposeNewTensors(valY, inputValY); + if (sampleWeights != null) { + dispose(sampleWeights); + } + } + // TODO(cais): Add value to outLabels. + } + /** + * Abstract fit function for `f(ins)`. + * @param f A Function returning a list of tensors. For training, this + * function is expected to perform the updates to the variables. + * @param ins List of tensors to be fed to `f`. + * @param outLabels List of strings, display names of the outputs of `f`. + * @param batchSize Integer batch size or `== null` if unknown. Default : 32. + * @param epochs Number of times to iterate over the data. Default : 1. + * @param verbose Verbosity mode: 0, 1, or 2. Default: 1. + * @param callbacks List of callbacks to be called during training. + * @param valF Function to call for validation. + * @param valIns List of tensors to be fed to `valF`. + * @param shuffle Whether to shuffle the data at the beginning of every + * epoch. Default : true. + * @param callbackMetrics List of strings, the display names of the metrics + * passed to the callbacks. They should be the concatenation of the + * display names of the outputs of `f` and the list of display names + * of the outputs of `valF`. + * @param initialEpoch Epoch at which to start training (useful for + * resuming a previous training run). Default : 0. + * @param stepsPerEpoch Total number of steps (batches on samples) before + * declaring one epoch finished and starting the next epoch. Ignored with + * the default value of `undefined` or `null`. + * @param validationSteps Number of steps to run validation for (only if + * doing validation from data tensors). Not applicable for tfjs-layers. + * @returns A `History` object. + */ + async fitLoop(f, ins, outLabels, batchSize, epochs, verbose, callbacks, valF, valIns, shuffle$1, callbackMetrics, initialEpoch, stepsPerEpoch, validationSteps) { + if (batchSize == null) { + batchSize = 32; + } + if (epochs == null) { + epochs = 1; + } + if (shuffle$1 == null) { + shuffle$1 = true; + } + if (initialEpoch == null) { + initialEpoch = 0; + } + // TODO(cais): Change const to let below when implementing validation. + let doValidation = false; + if (valF != null && valIns != null) { + doValidation = true; + // TODO(cais): verbose message. + } + if (validationSteps != null) { + doValidation = true; + if (stepsPerEpoch == null) { + throw new ValueError('Can only use `validationSteps` when doing step-wise training, ' + + 'i.e., `stepsPerEpoch` must be set.'); + } + } + const numTrainSamples = this.checkNumSamples(ins, batchSize, stepsPerEpoch, 'steps_per_epoch'); + let indexArray; + if (numTrainSamples != null) { + indexArray = range$2(0, numTrainSamples); + } + if (verbose == null) { + verbose = 1; + } + const { callbackList, history } = configureCallbacks(callbacks, verbose, epochs, initialEpoch, numTrainSamples, stepsPerEpoch, batchSize, doValidation, callbackMetrics); + callbackList.setModel(this); + this.history = history; + await callbackList.onTrainBegin(); + this.stopTraining_ = false; + // TODO(cais): Take care of callbacks.validation_data as in PyKeras. + // TODO(cais): Pre-convert feeds for performance as in PyKeras. + for (let epoch = initialEpoch; epoch < epochs; ++epoch) { + await callbackList.onEpochBegin(epoch); + const epochLogs = {}; + if (stepsPerEpoch != null) { + throw new NotImplementedError('stepsPerEpoch mode is not implemented yet.'); + } + else { + if (shuffle$1 === 'batch') { + throw new NotImplementedError('batch shuffling is not implemneted' + + ' yet'); + } + else if (shuffle$1) { + shuffle(indexArray); + } + // Convert the potentially shuffled indices to Tensor1D, to avoid the + // cost of repeated creation of Array1Ds later on. + const epochIndexArray1D = tensor1d(indexArray); + const batches = makeBatches(numTrainSamples, batchSize); + for (let batchIndex = 0; batchIndex < batches.length; ++batchIndex) { + const batchLogs = {}; + await callbackList.onBatchBegin(batchIndex, batchLogs); + tidy(() => { + const batchStart = batches[batchIndex][0]; + const batchEnd = batches[batchIndex][1]; + const batchIds = sliceAlongFirstAxis(epochIndexArray1D, batchStart, batchEnd - batchStart); + batchLogs['batch'] = batchIndex; + batchLogs['size'] = batchEnd - batchStart; + // TODO(cais): In ins, train flag can be a number, instead of an + // Tensor? Do we need to handle this in tfjs-layers? + const insBatch = sliceArraysByIndices(ins, batchIds); + const outs = f(insBatch); + for (let i = 0; i < outLabels.length; ++i) { + const label = outLabels[i]; + const out = outs[i]; + batchLogs[label] = out; + keep(out); + // TODO(cais): Use scope() to avoid ownership. + } + if (batchIndex === batches.length - 1) { // Last batch. + if (doValidation) { + const valOuts = this.testLoop(valF, valIns, batchSize); + // Porting Notes: In tfjs-layers, valOuts is always an Array. + for (let i = 0; i < outLabels.length; ++i) { + const label = outLabels[i]; + const out = valOuts[i]; + keep(out); + // TODO(cais): Use scope() to avoid ownership. + epochLogs['val_' + label] = out; + } + } + } + }); + await callbackList.onBatchEnd(batchIndex, batchLogs); + disposeTensorsInLogs(batchLogs); + if (this.stopTraining_) { + break; + } + // TODO(cais): return outs as list of Tensor. + } + epochIndexArray1D.dispose(); + } + // TODO(cais): Run validation at the end of the epoch. + await callbackList.onEpochEnd(epoch, epochLogs); + if (this.stopTraining_) { + break; + } + } + await callbackList.onTrainEnd(); + await this.history.syncData(); + return this.history; + } + // TODO(cais): Add code snippet below when it's possible to instantiate + // actual dataset objects. + /** + * Trains the model using a dataset object. + * + * @param dataset A dataset object. Its `iterator()` method is expected + * to generate a dataset iterator object, the `next()` method of which + * is expected to produce data batches for training. The return value + * of the `next()` call ought to contain a boolean `done` field and a + * `value` field. The `value` field is expected to be an array of two + * `tf.Tensor`s or an array of two nested `tf.Tensor` structures. The former + * case is for models with exactly one input and one output (e.g. + * a sequential model). The latter case is for models with multiple + * inputs and/or multiple outputs. + * Of the two items in the array, the first is the input feature(s) and + * the second is the output target(s). + * @param args A `ModelFitDatasetArgs`, containing optional fields. + * + * @return A `History` instance. Its `history` attribute contains all + * information collected during training. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + async fitDataset(dataset, args) { + return fitDataset(this, dataset, args); + } + /** + * Runs a single gradient update on a single batch of data. + * + * This method differs from `fit()` and `fitDataset()` in the following + * regards: + * - It operates on exactly one batch of data. + * - It returns only the loss and metric values, instead of + * returning the batch-by-batch loss and metric values. + * - It doesn't support fine-grained options such as verbosity and + * callbacks. + * + * @param x Input data. It could be one of the following: + * - A `tf.Tensor`, or an Array of `tf.Tensor`s (in case the model has + * multiple inputs). + * - An Object mapping input names to corresponding `tf.Tensor` (if the + * model has named inputs). + * @param y Target data. It could be either a `tf.Tensor` or multiple + * `tf.Tensor`s. It should be consistent with `x`. + * @returns Training loss or losses (in case the model has + * multiple outputs), along with metrics (if any), as numbers. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + async trainOnBatch(x, y) { + // TODO(cais): Support sampleWeight and classWeight. + // TODO(cais): Support Dataset objects. + const standardizeOut = await this.standardizeUserData(x, y); + const inputs = standardizeOut[0]; + const targets = standardizeOut[1]; + const trainFunction = this.makeTrainFunction(); + const losses = trainFunction(inputs.concat(targets)); + const lossValues = []; + for (const loss of losses) { + const v = await loss.data(); + lossValues.push(v[0]); + } + dispose(losses); + disposeNewTensors(standardizeOut[0], x); + disposeNewTensors(standardizeOut[1], y); + return singletonOrArray(lossValues); + } + /** + * Extract weight values of the model. + * + * @param config: An instance of `io.SaveConfig`, which specifies + * model-saving options such as whether only trainable weights are to be + * saved. + * @returns A `NamedTensorMap` mapping original weight names (i.e., + * non-uniqueified weight names) to their values. + */ + getNamedWeights(config) { + const namedWeights = []; + const trainableOnly = config != null && config.trainableOnly; + const weights = trainableOnly ? this.trainableWeights : this.weights; + const weightValues = this.getWeights(trainableOnly); + for (let i = 0; i < weights.length; ++i) { + if (trainableOnly && !weights[i].trainable) { + // Optionally skip non-trainable weights. + continue; + } + namedWeights.push({ name: weights[i].originalName, tensor: weightValues[i] }); + } + return namedWeights; + } + /** + * Setter used for force stopping of LayersModel.fit() (i.e., training). + * + * Example: + * + * ```js + * const input = tf.input({shape: [10]}); + * const output = tf.layers.dense({units: 1}).apply(input); + * const model = tf.model({inputs: [input], outputs: [output]}); + * model.compile({loss: 'meanSquaredError', optimizer: 'sgd'}); + * const xs = tf.ones([8, 10]); + * const ys = tf.zeros([8, 1]); + * + * const history = await model.fit(xs, ys, { + * epochs: 10, + * callbacks: { + * onEpochEnd: async (epoch, logs) => { + * if (epoch === 2) { + * model.stopTraining = true; + * } + * } + * } + * }); + * + * // There should be only 3 values in the loss array, instead of 10 + * values, + * // due to the stopping after 3 epochs. + * console.log(history.history.loss); + * ``` + */ + set stopTraining(stop) { + this.stopTraining_ = stop; + } + get stopTraining() { + return this.stopTraining_; + } + get optimizer() { + return this.optimizer_; + } + set optimizer(optimizer) { + if (this.optimizer_ !== optimizer) { + this.optimizer_ = optimizer; + this.isOptimizerOwned = false; + } + } + dispose() { + const result = super.dispose(); + if (result.refCountAfterDispose === 0 && this.optimizer != null && + this.isOptimizerOwned) { + const numTensorsBeforeOptmizerDisposal = memory().numTensors; + this.optimizer_.dispose(); + result.numDisposedVariables += + numTensorsBeforeOptmizerDisposal - memory().numTensors; + } + return result; + } + getLossIdentifiers() { + let lossNames; + if (typeof this.loss === 'string') { + lossNames = toSnakeCase(this.loss); + } + else if (Array.isArray(this.loss)) { + for (const loss of this.loss) { + if (typeof loss !== 'string') { + throw new Error('Serialization of non-string loss is not supported.'); + } + } + lossNames = this.loss.map(name => toSnakeCase(name)); + } + else { + const outputNames = Object.keys(this.loss); + lossNames = {}; + const losses = this.loss; + for (const outputName of outputNames) { + if (typeof losses[outputName] === 'string') { + lossNames[outputName] = + toSnakeCase(losses[outputName]); + } + else { + throw new Error('Serialization of non-string loss is not supported.'); + } + } + } + return lossNames; + } + getMetricIdentifiers() { + if (typeof this.metrics === 'string' || + typeof this.metrics === 'function') { + return [toSnakeCase(getLossOrMetricName(this.metrics))]; + } + else if (Array.isArray(this.metrics)) { + return this.metrics.map(metric => toSnakeCase(getLossOrMetricName(metric))); + } + else { + const metricsIdentifiers = {}; + for (const key in this.metrics) { + metricsIdentifiers[key] = + toSnakeCase(getLossOrMetricName(this.metrics[key])); + } + return metricsIdentifiers; + } + } + getTrainingConfig() { + return { + loss: this.getLossIdentifiers(), + metrics: this.getMetricIdentifiers(), + optimizer_config: { + class_name: this.optimizer.getClassName(), + config: this.optimizer.getConfig() + } + }; + // TODO(cais): Add weight_metrics when they are supported. + // TODO(cais): Add sample_weight_mode when it's supported. + // TODO(cais): Add loss_weights when it's supported. + } + loadTrainingConfig(trainingConfig) { + if (trainingConfig.weighted_metrics != null) { + throw new Error('Loading weight_metrics is not supported yet.'); + } + if (trainingConfig.loss_weights != null) { + throw new Error('Loading loss_weights is not supported yet.'); + } + if (trainingConfig.sample_weight_mode != null) { + throw new Error('Loading sample_weight_mode is not supported yet.'); + } + const tsConfig = convertPythonicToTs(trainingConfig.optimizer_config); + const optimizer = deserialize(tsConfig); + let loss; + if (typeof trainingConfig.loss === 'string') { + loss = toCamelCase(trainingConfig.loss); + } + else if (Array.isArray(trainingConfig.loss)) { + loss = trainingConfig.loss.map(lossEntry => toCamelCase(lossEntry)); + } + else if (trainingConfig.loss != null) { + loss = {}; + for (const key in trainingConfig.loss) { + loss[key] = toCamelCase(trainingConfig.loss[key]); + } + } + let metrics; + if (Array.isArray(trainingConfig.metrics)) { + metrics = trainingConfig.metrics.map(metric => toCamelCase(metric)); + } + else if (trainingConfig.metrics != null) { + metrics = {}; + for (const key in trainingConfig.metrics) { + metrics[key] = toCamelCase(trainingConfig.metrics[key]); + } + } + this.compile({ loss, metrics, optimizer }); + } + /** + * Save the configuration and/or weights of the LayersModel. + * + * An `IOHandler` is an object that has a `save` method of the proper + * signature defined. The `save` method manages the storing or + * transmission of serialized data ("artifacts") that represent the + * model's topology and weights onto or via a specific medium, such as + * file downloads, local storage, IndexedDB in the web browser and HTTP + * requests to a server. TensorFlow.js provides `IOHandler` + * implementations for a number of frequently used saving mediums, such as + * `tf.io.browserDownloads` and `tf.io.browserLocalStorage`. See `tf.io` + * for more details. + * + * This method also allows you to refer to certain types of `IOHandler`s + * as URL-like string shortcuts, such as 'localstorage://' and + * 'indexeddb://'. + * + * Example 1: Save `model`'s topology and weights to browser [local + * storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage); + * then load it back. + * + * ```js + * const model = tf.sequential( + * {layers: [tf.layers.dense({units: 1, inputShape: [3]})]}); + * console.log('Prediction from original model:'); + * model.predict(tf.ones([1, 3])).print(); + * + * const saveResults = await model.save('localstorage://my-model-1'); + * + * const loadedModel = await tf.loadLayersModel('localstorage://my-model-1'); + * console.log('Prediction from loaded model:'); + * loadedModel.predict(tf.ones([1, 3])).print(); + * ``` + * + * Example 2. Saving `model`'s topology and weights to browser + * [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API); + * then load it back. + * + * ```js + * const model = tf.sequential( + * {layers: [tf.layers.dense({units: 1, inputShape: [3]})]}); + * console.log('Prediction from original model:'); + * model.predict(tf.ones([1, 3])).print(); + * + * const saveResults = await model.save('indexeddb://my-model-1'); + * + * const loadedModel = await tf.loadLayersModel('indexeddb://my-model-1'); + * console.log('Prediction from loaded model:'); + * loadedModel.predict(tf.ones([1, 3])).print(); + * ``` + * + * Example 3. Saving `model`'s topology and weights as two files + * (`my-model-1.json` and `my-model-1.weights.bin`) downloaded from + * browser. + * + * ```js + * const model = tf.sequential( + * {layers: [tf.layers.dense({units: 1, inputShape: [3]})]}); + * const saveResults = await model.save('downloads://my-model-1'); + * ``` + * + * Example 4. Send `model`'s topology and weights to an HTTP server. + * See the documentation of `tf.io.http` for more details + * including specifying request parameters and implementation of the + * server. + * + * ```js + * const model = tf.sequential( + * {layers: [tf.layers.dense({units: 1, inputShape: [3]})]}); + * const saveResults = await model.save('http://my-server/model/upload'); + * ``` + * + * @param handlerOrURL An instance of `IOHandler` or a URL-like, + * scheme-based string shortcut for `IOHandler`. + * @param config Options for saving the model. + * @returns A `Promise` of `SaveResult`, which summarizes the result of + * the saving, such as byte sizes of the saved artifacts for the model's + * topology and weight values. + * + * @doc {heading: 'Models', subheading: 'Classes', ignoreCI: true} + */ + async save(handlerOrURL, config) { + if (typeof handlerOrURL === 'string') { + const handlers = getSaveHandlers(handlerOrURL); + if (handlers.length === 0) { + throw new ValueError(`Cannot find any save handlers for URL '${handlerOrURL}'`); + } + else if (handlers.length > 1) { + throw new ValueError(`Found more than one (${handlers.length}) save handlers for ` + + `URL '${handlerOrURL}'`); + } + handlerOrURL = handlers[0]; + } + if (handlerOrURL.save == null) { + throw new ValueError('LayersModel.save() cannot proceed because the IOHandler ' + + 'provided does not have the `save` attribute defined.'); + } + const weightDataAndSpecs = await encodeWeights(this.getNamedWeights(config)); + const returnString = false; + const unusedArg = null; + const modelConfig = this.toJSON(unusedArg, returnString); + const modelArtifacts = { + modelTopology: modelConfig, + format: LAYERS_MODEL_FORMAT_NAME, + generatedBy: `TensorFlow.js tfjs-layers v${version$6}`, + convertedBy: null, + }; + const includeOptimizer = config == null ? false : config.includeOptimizer; + if (includeOptimizer && this.optimizer != null) { + modelArtifacts.trainingConfig = this.getTrainingConfig(); + const weightType = 'optimizer'; + const { data: optimizerWeightData, specs: optimizerWeightSpecs } = await encodeWeights(await this.optimizer.getWeights(), weightType); + weightDataAndSpecs.specs.push(...optimizerWeightSpecs); + weightDataAndSpecs.data = concatenateArrayBuffers([weightDataAndSpecs.data, optimizerWeightData]); + } + if (this.userDefinedMetadata != null) { + // Check serialized size of user-defined metadata. + const checkSize = true; + checkUserDefinedMetadata(this.userDefinedMetadata, this.name, checkSize); + modelArtifacts.userDefinedMetadata = this.userDefinedMetadata; + } + modelArtifacts.weightData = weightDataAndSpecs.data; + modelArtifacts.weightSpecs = weightDataAndSpecs.specs; + return handlerOrURL.save(modelArtifacts); + } + /** + * Set user-defined metadata. + * + * The set metadata will be serialized together with the topology + * and weights of the model during `save()` calls. + * + * @param setUserDefinedMetadata + */ + setUserDefinedMetadata(userDefinedMetadata) { + checkUserDefinedMetadata(userDefinedMetadata, this.name); + this.userDefinedMetadata = userDefinedMetadata; + } + /** + * Get user-defined metadata. + * + * The metadata is supplied via one of the two routes: + * 1. By calling `setUserDefinedMetadata()`. + * 2. Loaded during model loading (if the model is constructed + * via `tf.loadLayersModel()`.) + * + * If no user-defined metadata is available from either of the + * two routes, this function will return `undefined`. + */ + getUserDefinedMetadata() { + return this.userDefinedMetadata; + } + } + // The class name is 'Model' rather than 'LayersModel' for backwards + // compatibility since this class name shows up in the serialization format. + /** @nocollapse */ + LayersModel.className = 'Model'; + registerClass(LayersModel); + /** + * A `tf.Functional` is an alias to `tf.LayersModel`. + * + * See also: + * `tf.LayersModel`, `tf.Sequential`, `tf.loadLayersModel`. + */ + /** @doc {heading: 'Models', subheading: 'Classes'} */ + class Functional extends LayersModel { + } + Functional.className = 'Functional'; + registerClass(Functional); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Parses a JSON model configuration file and returns a model instance. + * + * ```js + * // This example shows how to serialize a model using `toJSON()` and + * // deserialize it as another model using `tf.models.modelFromJSON()`. + * // Note: this example serializes and deserializes only the topology + * // of the model; the weights of the loaded model will be different + * // from those of the the original model, due to random weight + * // initialization. + * // To load the topology and weights of a model, use `tf.loadLayersModel()`. + * const model1 = tf.sequential(); + * model1.add(tf.layers.repeatVector({inputShape: [2], n: 4})); + * // Serialize `model1` as a JSON object. + * const model1JSON = model1.toJSON(null, false); + * model1.summary(); + * + * const model2 = await tf.models.modelFromJSON(model1JSON); + * model2.summary(); + * ``` + * + * @param modelAndWeightsConfig JSON object or string encoding a model and + * weights configuration. It can also be only the topology JSON of the + * model, in which case the weights will not be loaded. + * @param custom_objects Optional dictionary mapping names + * (strings) to custom classes or functions to be + * considered during deserialization. + * @returns A TensorFlow.js Layers `tf.LayersModel` instance (uncompiled). + */ + async function modelFromJSON(modelAndWeightsConfig, customObjects) { + if (!('modelTopology' in modelAndWeightsConfig)) { + modelAndWeightsConfig = { modelTopology: modelAndWeightsConfig }; + } + modelAndWeightsConfig = modelAndWeightsConfig; + let modelTopology = modelAndWeightsConfig.modelTopology; + if (modelTopology['model_config'] != null) { + // If the model-topology JSON contains a 'model_config' field, then it is + // a full model JSON (e.g., from `keras.Model.save()`), which contains + // not only the model's architecture in its 'model_config' field, but + // additional information such as the model's optimizer. We use only the + // 'model_config' field currently. + modelTopology = modelTopology['model_config']; + } + const tsConfig = convertPythonicToTs(modelTopology); + const model = deserialize(tsConfig, customObjects); + if (modelAndWeightsConfig.weightsManifest != null) { + // Load the weight values keyed by the original tensor names in the model + // file that was loaded. These should match the keys of the weight + // manifest. + const weightValues = await loadWeights(modelAndWeightsConfig.weightsManifest, modelAndWeightsConfig.pathPrefix, model.weights.map(weight => weight.originalName)); + // Map the weights to the unique tensor names generated during model loading + const uniqueWeightValues = {}; + for (const weight of model.weights) { + uniqueWeightValues[weight.originalName] = + weightValues[weight.originalName]; + } + model.loadWeights(uniqueWeightValues); + // Dispose temporary weight values. + dispose(weightValues); + } + return model; + } + /** + * Load a model composed of Layer objects, including its topology and optionally + * weights. See the Tutorial named "How to import a Keras Model" for usage + * examples. + * + * This method is applicable to: + * + * 1. Models created with the `tf.layers.*`, `tf.sequential`, and + * `tf.model` APIs of TensorFlow.js and later saved with the + * `tf.LayersModel.save` method. + * 2. Models converted from Keras or TensorFlow tf.keras using the + * [tensorflowjs_converter](https://github.com/tensorflow/tfjs/tree/master/tfjs-converter). + * + * This mode is *not* applicable to TensorFlow `SavedModel`s or their converted + * forms. For those models, use `tf.loadGraphModel`. + * + * Example 1. Load a model from an HTTP server. + * + * ```js + * const model = await tf.loadLayersModel( + * 'https://storage.googleapis.com/tfjs-models/tfjs/iris_v1/model.json'); + * model.summary(); + * ``` + * + * Example 2: Save `model`'s topology and weights to browser [local + * storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage); + * then load it back. + * + * ```js + * const model = tf.sequential( + * {layers: [tf.layers.dense({units: 1, inputShape: [3]})]}); + * console.log('Prediction from original model:'); + * model.predict(tf.ones([1, 3])).print(); + * + * const saveResults = await model.save('localstorage://my-model-1'); + * + * const loadedModel = await tf.loadLayersModel('localstorage://my-model-1'); + * console.log('Prediction from loaded model:'); + * loadedModel.predict(tf.ones([1, 3])).print(); + * ``` + * + * Example 3. Saving `model`'s topology and weights to browser + * [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API); + * then load it back. + * + * ```js + * const model = tf.sequential( + * {layers: [tf.layers.dense({units: 1, inputShape: [3]})]}); + * console.log('Prediction from original model:'); + * model.predict(tf.ones([1, 3])).print(); + * + * const saveResults = await model.save('indexeddb://my-model-1'); + * + * const loadedModel = await tf.loadLayersModel('indexeddb://my-model-1'); + * console.log('Prediction from loaded model:'); + * loadedModel.predict(tf.ones([1, 3])).print(); + * ``` + * + * Example 4. Load a model from user-selected files from HTML + * [file input + * elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file). + * + * ```js + * // Note: this code snippet will not work without the HTML elements in the + * // page + * const jsonUpload = document.getElementById('json-upload'); + * const weightsUpload = document.getElementById('weights-upload'); + * + * const model = await tf.loadLayersModel( + * tf.io.browserFiles([jsonUpload.files[0], weightsUpload.files[0]])); + * ``` + * + * @param pathOrIOHandler Can be either of the two formats + * 1. A string path to the `ModelAndWeightsConfig` JSON describing + * the model in the canonical TensorFlow.js format. For file:// + * (tfjs-node-only), http:// and https:// schemas, the path can be + * either absolute or relative. The content of the JSON file is assumed to + * be a JSON object with the following fields and values: + * - 'modelTopology': A JSON object that can be either of: + * 1. a model architecture JSON consistent with the format of the return + * value of `keras.Model.to_json()` + * 2. a full model JSON in the format of `keras.models.save_model()`. + * - 'weightsManifest': A TensorFlow.js weights manifest. + * See the Python converter function `save_model()` for more details. + * It is also assumed that model weights can be accessed from relative + * paths described by the `paths` fields in weights manifest. + * 2. A `tf.io.IOHandler` object that loads model artifacts with its `load` + * method. + * @param options Optional configuration arguments for the model loading, + * including: + * - `strict`: Require that the provided weights exactly match those required + * by the layers. Default true. Passing false means that both extra + * weights and missing weights will be silently ignored. + * - `onProgress`: A progress callback of the form: + * `(fraction: number) => void`. This callback can be used to monitor the + * model-loading process. + * @returns A `Promise` of `tf.LayersModel`, with the topology and weights + * loaded. + * + * @doc {heading: 'Models', subheading: 'Loading'} + */ + async function loadLayersModel(pathOrIOHandler, options) { + if (options == null) { + options = {}; + } + if (typeof pathOrIOHandler === 'string') { + const handlers = getLoadHandlers(pathOrIOHandler, options); + if (handlers.length === 0) { + // For backward compatibility: if no load handler can be found, + // assume it is a relative http path. + // TODO(cais): Reformat the args into a single `LoadOptions` once the core + // is refactored. + handlers.push(browserHTTPRequest(pathOrIOHandler, options)); + } + else if (handlers.length > 1) { + throw new ValueError(`Found more than one (${handlers.length}) load handlers for ` + + `URL '${pathOrIOHandler}'`); + } + pathOrIOHandler = handlers[0]; + } + return loadLayersModelFromIOHandler(pathOrIOHandler, undefined, options); + } + /** + * Load a model and optionally its weights, using an IOHandler object. + * + * @param handler The instance of `IOHandler` to be used during the model + * loading. + * @param customObjects Any optional custom objects to be used during model + * loading. + * @param strict Whether the weight loading will be done in strict mode. + * Default: `true`. + */ + async function loadLayersModelFromIOHandler(handler, customObjects, options) { + if (options == null) { + options = {}; + } + if (handler.load == null) { + throw new ValueError('Cannot proceed with model loading because the IOHandler provided ' + + 'does not have the `load` method implemented.'); + } + const artifacts = await handler.load(); + let modelTopology = artifacts.modelTopology; + if (modelTopology['model_config'] != null) { + modelTopology = modelTopology['model_config']; + } + const strict = options.strict == null ? true : options.strict; + // If weights are provided and the weight-loading mode is strict, use + // fast weight initialization. This skips costly initializers such as + // 'orthogonal' and saves unnecessary computation in cases where + // the initialized weight values will immediately be overwritten by + // loaded weight values. + const fastWeightInit = artifacts.weightData != null && artifacts.weightSpecs != null && strict; + const model = deserialize(convertPythonicToTs(modelTopology), customObjects, fastWeightInit); + const trainingConfig = artifacts.trainingConfig; + if (trainingConfig != null) { + model.loadTrainingConfig(trainingConfig); + } + if (artifacts.userDefinedMetadata != null) { + model.setUserDefinedMetadata(artifacts.userDefinedMetadata); + } + // If weightData is present, load the weights into the model. + if (artifacts.weightData != null) { + // Loading weights requires weightSpecs. + if (artifacts.weightSpecs == null) { + throw new ValueError('LayersModel artifacts contains weight data, but not weight specs. ' + + 'Therefore loading of weights cannot proceed.'); + } + const { modelWeights, optimizerWeights } = decodeModelAndOptimizerWeights(artifacts.weightData, artifacts.weightSpecs); + model.loadWeights(modelWeights, strict); + if (model.optimizer != null && optimizerWeights.length > 0) { + await model.optimizer.setWeights(optimizerWeights); + } + // Dispose temporary weight values. + dispose(modelWeights); + dispose(optimizerWeights.map(w => w.tensor)); + } + return model; + } + function decodeModelAndOptimizerWeights(weightData, specs) { + const name2Tensor = decodeWeights(weightData, specs); + const modelWeights = {}; + const optimizerWeights = []; + specs.forEach(spec => { + if (spec.group === 'optimizer') { + optimizerWeights.push({ name: spec.name, tensor: name2Tensor[spec.name] }); + } + else { + modelWeights[spec.name] = name2Tensor[spec.name]; + } + }); + return { modelWeights, optimizerWeights }; + } + /** + * A model with a stack of layers, feeding linearly from one to the next. + * + * `tf.sequential` is a factory function that creates an instance of + * `tf.Sequential`. + * + * ```js + * // Define a model for linear regression. + * const model = tf.sequential(); + * model.add(tf.layers.dense({units: 1, inputShape: [1]})); + * + * // Prepare the model for training: Specify the loss and the optimizer. + * model.compile({loss: 'meanSquaredError', optimizer: 'sgd'}); + * + * // Generate some synthetic data for training. + * const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]); + * const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]); + * + * // Train the model using the data then do inference on a data point the + * // model hasn't seen: + * await model.fit(xs, ys); + * model.predict(tf.tensor2d([5], [1, 1])).print(); + * ``` + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + class Sequential extends LayersModel { + constructor(args) { + super({ inputs: [], outputs: [] }); + args = args || {}; + this.trainable = true; + this.built = false; + // Set model name. + this.name = (args.name != null) ? args.name : getUid('sequential_'); + // Add to the model any layers passed to the constructor. + if (args.layers != null) { + for (const layer of args.layers) { + this.add(layer); + } + } + } + // Helper function to Sequential.add Throws if the new output shape will be + // invalid. + checkShape(layer) { + const shape = layer.inboundNodes[0].outputTensors[0].shape; + if (shape.some(x => x < 0)) { + throw new ValueError('Negative dimension size caused by adding layer ' + + `${layer.name} with input shape [` + + `${layer.inboundNodes[0].inputTensors[0].shape}]`); + } + } + /** + * Adds a layer instance on top of the layer stack. + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.dense({units: 8, inputShape: [1]})); + * model.add(tf.layers.dense({units: 4, activation: 'relu6'})); + * model.add(tf.layers.dense({units: 1, activation: 'relu6'})); + * // Note that the untrained model is random at this point. + * model.predict(tf.randomNormal([10, 1])).print(); + * ``` + * @param layer Layer instance. + * + * @exception ValueError In case the `layer` argument does not know its + * input shape. + * @exception ValueError In case the `layer` argument has multiple output + * tensors, or is already connected somewhere else (forbidden in + * `Sequential` models). + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + add(layer) { + const isLayerModelInstance = layer instanceof Sequential || layer instanceof LayersModel; + let modelLayer; + if (isLayerModelInstance) { + modelLayer = layer; + if (modelLayer.outputs.length !== 1) { + throw new ValueError('All layers in a Sequential model ' + + 'should have a single output tensor. ' + + 'For multi-output layers, ' + + 'use the functional API.'); + } + if (modelLayer.inputs.length !== 1) { + throw new ValueError('All layers in a Sequential model ' + + 'should have a single input tensor. ' + + 'For multi-input layers, ' + + 'use the functional API.'); + } + } + if (this.outputs.length === 0) { + // first layer in model: check that it is an input layer + if (layer.inboundNodes.length === 0) { + // create an input layer + if (layer.batchInputShape == null) { + throw new ValueError('The first layer in a Sequential model must ' + + 'get an `inputShape` or `batchInputShape` argument.'); + } + // Instantiate the input layer. + const x = Input({ + batchShape: layer.batchInputShape, + dtype: layer.dtype, + name: layer.name + '_input' + }); + // This will build the current layer and create the node connecting + // the current layer to the input layer we just created. + layer.apply(x); + } + if (isLayerModelInstance) { + this.outputs = modelLayer.outputs; + this.inputs = modelLayer.inputs; + } + else { + if (layer.inboundNodes.length !== 1) { + throw new ValueError('A layer added to a Sequential model must not already be ' + + `connected somewhere else. LayersModel received layer ${layer.name} ` + + `which has ${layer.inboundNodes.length} pre-existing inbound ` + + 'connections.'); + } + if (layer.inboundNodes[0].outputTensors.length !== 1) { + throw new ValueError('All layers in a Sequential model ' + + 'should have a single output tensor. ' + + 'For multi-output layers, ' + + 'use the functional API.'); + } + this.checkShape(layer); + this.outputs = [layer.inboundNodes[0].outputTensors[0]]; + this.inputs = getSourceInputs(this.outputs[0]); + } + this.inboundNodes = []; + // We create an input node, which we will keep updated + // as we add more layers. + // (This call has side effects.) + // tslint:disable-next-line:no-unused-expression + new Node({ + outboundLayer: this, + inboundLayers: [], + nodeIndices: [], + tensorIndices: [], + inputTensors: this.inputs, + outputTensors: this.outputs, + // no model-level masking for now + inputMasks: pyListRepeat(null, this.inputs.length), + outputMasks: [null], + inputShapes: this.inputs.map(x => x.shape), + outputShapes: this.outputs[0].shape + }); + } + else { + const outputTensor = layer.apply(this.outputs[0]); + if (Array.isArray(outputTensor)) { + throw new TypeError('All layers in a Sequential model ' + + 'should have a single output tensor. ' + + 'For multi-output layers, ' + + 'use the functional API.'); + } + this.checkShape(layer); + this.outputs = [outputTensor]; + // update self.inbound_nodes + this.inboundNodes[0].outputTensors = this.outputs; + this.inboundNodes[0].outputShapes = [this.outputs[0].shape]; + } + this.layers.push(layer); + this.built = false; + } + /** + * Removes the last layer in the model. + * + * @exception TypeError if there are no layers in the model. + */ + pop() { + if (this.layers.length === 0) { + throw new TypeError('There are no layers in the model.'); + } + this.layers.pop(); + if (this.layers.length === 0) { + this.outputs = []; + this.inboundNodes = []; + this.outboundNodes = []; + } + else { + const lastLayerIndex = this.layers.length - 1; + this.layers[lastLayerIndex].outboundNodes = []; + this.outputs = [this.layers[lastLayerIndex].output]; + // update self.inbound_nodes + this.inboundNodes[0].outputTensors = this.outputs; + this.inboundNodes[0].outputShapes = [this.outputs[0].shape]; + } + } + call(inputs, kwargs) { + if (this.model == null) { + this.build(); + } + return this.model.call(inputs, kwargs); + } + build(inputShape) { + // Call `getExactlyOneShape` without using its return value, + // to verify that exactly one input shape is provided. + getExactlyOneShape(inputShape); + if (this.inputs.length === 0 || this.outputs.length === 0) { + throw new TypeError('Sequential model cannot be built: model is empty.' + + ' Add some layers first.'); + } + // actually create the model + this.model = new LayersModel({ + inputs: this.inputs, + outputs: this.outputs[0], + name: this.name + '_model' + }); + this.model.trainable = this.trainable; + // mirror model attributes + this.supportsMasking = this.model.supportsMasking; + // TODO(michaelterry): Add caches + this.inputLayers = this.model.inputLayers; + this.inputLayersNodeIndices = this.model.inputLayersNodeIndices; + this.inputLayersTensorIndices = this.model.inputLayersTensorIndices; + this.outputLayers = this.model.outputLayers; + this.outputLayersNodeIndices = this.model.outputLayersNodeIndices; + this.outputLayersTensorIndices = this.model.outputLayersTensorIndices; + this.nodesByDepth = this.model.nodesByDepth; + this.containerNodes = this.model.containerNodes; + this.outputNames = this.model.outputNames; + this.inputNames = this.model.inputNames; + // TODO(michaelterry): Add feedInputNames, feedInputs, if needed. + // TODO(michaelterry): Add callbackModel if needed. + this.built = true; + } + countParams() { + if (!this.built) { + this.build(); + } + return super.countParams(); + } + /** + * Print a text summary of the Sequential model's layers. + * + * The summary includes + * - Name and type of all layers that comprise the model. + * - Output shape(s) of the layers + * - Number of weight parameters of each layer + * - The total number of trainable and non-trainable parameters of the + * model. + * + * ```js + * const model = tf.sequential(); + * model.add( + * tf.layers.dense({units: 100, inputShape: [10], activation: 'relu'})); + * model.add(tf.layers.dense({units: 1, activation: 'sigmoid'})); + * + * model.summary(); + * ``` + * + * @param lineLength Custom line length, in number of characters. + * @param positions Custom widths of each of the columns, as either + * fractions of `lineLength` (e.g., `[0.5, 0.75, 1]`) or absolute number + * of characters (e.g., `[30, 50, 65]`). Each number corresponds to + * right-most (i.e., ending) position of a column. + * @param printFn Custom print function. Can be used to replace the default + * `console.log`. For example, you can use `x => {}` to mute the printed + * messages in the console. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + summary(lineLength, positions, printFn = console.log) { + if (!this.built) { + this.build(); + } + super.summary(lineLength, positions, printFn); + } + /** + * Sets the weights of the model. + * + * @param weights Should be a list of Tensors with shapes and types matching + * the output of `model.getWeights()`. + */ + setWeights(weights) { + if (this.model == null) { + this.build(); + } + this.model.setWeights(weights); + } + /** + * Returns the loss value & metrics values for the model in test mode. + * + * Loss and metrics are specified during `compile()`, which needs to happen + * before calls to `evaluate()`. + * + * Computation is done in batches. + * + * ```js + * const model = tf.sequential({ + * layers: [tf.layers.dense({units: 1, inputShape: [10]})] + * }); + * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'}); + * const result = model.evaluate(tf.ones([8, 10]), tf.ones([8, 1]), { + * batchSize: 4, + * }); + * result.print(); + * ``` + * + * @param x `tf.Tensor` of test data, or an `Array` of `tf.Tensor`s if the + * model has multiple inputs. + * @param y `tf.Tensor` of target data, or an `Array` of `tf.Tensor`s if the + * model has multiple outputs. + * @param args A `ModelEvaluateConfig`, containing optional fields. + * + * @return `Scalar` test loss (if the model has a single output and no + * metrics) or `Array` of `Scalar`s (if the model has multiple outputs + * and/or metrics). The attribute `model.metricsNames` + * will give you the display labels for the scalar outputs. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + evaluate(x, y, args = {}) { + if (!this.built) { + throw new RuntimeError('The model needs to be compiled before being used.'); + } + return this.model.evaluate(x, y, args); + } + // TODO(cais): Add code snippet below once real dataset objects are + // available. + /** + * Evaluate model using a dataset object. + * + * Note: Unlike `evaluate()`, this method is asynchronous (`async`). + * + * @param dataset A dataset object. Its `iterator()` method is expected + * to generate a dataset iterator object, the `next()` method of which + * is expected to produce data batches for evaluation. The return value + * of the `next()` call ought to contain a boolean `done` field and a + * `value` field. The `value` field is expected to be an array of two + * `tf.Tensor`s or an array of two nested `tf.Tensor` structures. The former + * case is for models with exactly one input and one output (e.g. + * a sequential model). The latter case is for models with multiple + * inputs and/or multiple outputs. Of the two items in the array, the + * first is the input feature(s) and the second is the output target(s). + * @param args A configuration object for the dataset-based evaluation. + * @returns Loss and metric values as an Array of `Scalar` objects. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + async evaluateDataset(dataset, args) { + if (!this.built) { + throw new RuntimeError('The model needs to be compiled before being used.'); + } + return this.model.evaluateDataset(dataset, args); + } + /** + * Generates output predictions for the input samples. + * + * Computation is done in batches. + * + * Note: the "step" mode of predict() is currently not supported. + * This is because the TensorFlow.js core backend is imperative only. + * + * ```js + * const model = tf.sequential({ + * layers: [tf.layers.dense({units: 1, inputShape: [10]})] + * }); + * model.predict(tf.ones([2, 10])).print(); + * ``` + * + * @param x The input data, as a Tensor, or an `Array` of `tf.Tensor`s if + * the model has multiple inputs. + * @param conifg A `ModelPredictConfig` object containing optional fields. + * + * @return `tf.Tensor`(s) of predictions. + * + * @exception ValueError In case of mismatch between the provided input data + * and the model's expectations, or in case a stateful model receives a + * number of samples that is not a multiple of the batch size. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + predict(x, args = {}) { + if (this.model == null) { + this.build(); + } + return this.model.predict(x, args); + } + /** + * Returns predictions for a single batch of samples. + * + * @param x: Input samples, as a Tensor, or list of Tensors (if the model + * has multiple inputs). + * @return Tensor(s) of predictions + */ + predictOnBatch(x) { + if (this.model == null) { + this.build(); + } + return this.model.predictOnBatch(x); + } + /** + * See `LayersModel.compile`. + * + * @param args + */ + compile(args) { + this.build(); + this.model.compile(args); + this.optimizer_ = this.model.optimizer; + // tslint:disable-next-line:no-any + this.isOptimizerOwned = this.model.isOptimizerOwned; + this.loss = this.model.loss; + this.metrics = this.model.metrics; + // TODO(cais): Add this.lossWeights, this.sampleWeightMode, + // this.weightedMetrics, this.targets. + this.metricsTensors = this.model.metricsTensors; + this.metricsNames = this.model.metricsNames; + // TODO(cais): Add sampleWeights. + } + get optimizer() { + return this.model == null ? undefined : this.model.optimizer; + } + set optimizer(optimizer) { + this.model.optimizer = optimizer; + } + /** + * Trains the model for a fixed number of epochs (iterations on a dataset). + * + * ```js + * const model = tf.sequential({ + * layers: [tf.layers.dense({units: 1, inputShape: [10]})] + * }); + * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'}); + * const history = await model.fit(tf.ones([8, 10]), tf.ones([8, 1]), { + * batchSize: 4, + * epochs: 3 + * }); + * console.log(history.history.loss[0]); + * ``` + * + * @param x `tf.Tensor` of training data, or an array of `tf.Tensor`s if the + * model has multiple inputs. If all inputs in the model are named, you can + * also pass a dictionary mapping input names to `tf.Tensor`s. + * @param y `tf.Tensor` of target (label) data, or an array of `tf.Tensor`s if + * the model has multiple outputs. If all outputs in the model are named, you + * can also pass a dictionary mapping output names to `tf.Tensor`s. + * @param args A `ModelFitConfig`, containing optional fields. + * + * @return A `History` instance. Its `history` attribute contains all + * information collected during training. + * + * @exception ValueError In case of mismatch between the provided input data + * and what the model expects. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + async fit(x, y, args = {}) { + if (!this.built) { + throw new RuntimeError('The model needs to be compiled before ' + + 'being used.'); + } + return this.model.fit(x, y, args); + } + /** + * Trains the model using a dataset object. + * + * ```js + * const xArray = [ + * [1, 1, 1, 1, 1, 1, 1, 1, 1], + * [1, 1, 1, 1, 1, 1, 1, 1, 1], + * [1, 1, 1, 1, 1, 1, 1, 1, 1], + * [1, 1, 1, 1, 1, 1, 1, 1, 1], + * ]; + * const yArray = [1, 1, 1, 1]; + * // Create a dataset from the JavaScript array. + * const xDataset = tf.data.array(xArray); + * const yDataset = tf.data.array(yArray); + * // Zip combines the `x` and `y` Datasets into a single Dataset, the + * // iterator of which will return an object containing of two tensors, + * // corresponding to `x` and `y`. The call to `batch(4)` will bundle + * // four such samples into a single object, with the same keys now pointing + * // to tensors that hold 4 examples, organized along the batch dimension. + * // The call to `shuffle(4)` causes each iteration through the dataset to + * // happen in a different order. The size of the shuffle window is 4. + * const xyDataset = tf.data.zip({xs: xDataset, ys: yDataset}) + * .batch(4) + * .shuffle(4); + * const model = tf.sequential({ + * layers: [tf.layers.dense({units: 1, inputShape: [9]})] + * }); + * model.compile({optimizer: 'sgd', loss: 'meanSquaredError'}); + * const history = await model.fitDataset(xyDataset, { + * epochs: 4, + * callbacks: {onEpochEnd: (epoch, logs) => console.log(logs.loss)} + * }); + * ``` + * + * @param dataset A dataset object. Its `iterator()` method is expected to + * generate a dataset iterator object, the `next()` method of which is + * expected to produce data batches for evaluation. The return value of the + * `next()` call ought to contain a boolean `done` field and a `value` + * field. + * + * The `value` field is expected to be an object of with fields + * `xs` and `ys`, which point to the feature tensor and the target tensor, + * respectively. This case is for models with exactly one input and one + * output (e.g. a sequential model). For example: + * ```js + * {value: {xs: xsTensor, ys: ysTensor}, done: false} + * ``` + * + * If the model has multiple inputs, the `xs` field of `value` should + * be an object mapping input names to their respective feature tensors. + * For example: + * ```js + * { + * value: { + * xs: { + * input_1: xsTensor1, + * input_2: xsTensor2 + * }, + * ys: ysTensor + * }, + * done: false + * } + * ``` + * If the model has multiple outputs, the `ys` field of `value` should + * be an object mapping output names to their respective target tensors. + * For example: + * ```js + * { + * value: { + * xs: xsTensor, + * ys: { + * output_1: ysTensor1, + * output_2: ysTensor2 + * }, + * }, + * done: false + * } + * ``` + * @param args A `ModelFitDatasetArgs`, containing optional fields. + * + * @return A `History` instance. Its `history` attribute contains all + * information collected during training. + * + * @doc {heading: 'Models', subheading: 'Classes', ignoreCI: true} + */ + async fitDataset(dataset, args) { + if (!this.built) { + throw new RuntimeError('The model needs to be compiled before ' + + 'being used.'); + } + return this.model.fitDataset(dataset, args); + } + /** + * Runs a single gradient update on a single batch of data. + * + * This method differs from `fit()` and `fitDataset()` in the following + * regards: + * - It operates on exactly one batch of data. + * - It returns only the loss and metric values, instead of + * returning the batch-by-batch loss and metric values. + * - It doesn't support fine-grained options such as verbosity and + * callbacks. + * + * @param x Input data. It could be one of the following: + * - A `tf.Tensor`, or an Array of `tf.Tensor`s (in case the model has + * multiple inputs). + * - An Object mapping input names to corresponding `tf.Tensor` (if the + * model has named inputs). + * @param y Target data. It could be either a `tf.Tensor` or multiple + * `tf.Tensor`s. It should be consistent with `x`. + * @returns Training loss or losses (in case the model has + * multiple outputs), along with metrics (if any), as numbers. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + async trainOnBatch(x, y) { + return this.model.trainOnBatch(x, y); + } + /* See parent class for JsDoc */ + /** @nocollapse */ + static fromConfig(cls, config, customObjects = {}, fastWeightInit = false) { + let configArray; + let extraModelConfig = {}; + if (config instanceof Array) { + if (!(config[0].className != null) || + config[0]['className'] === 'Merge') { + throw new ValueError('Legacy serialization format not supported yet.'); + } + configArray = config; + } + else { + assert$1(config['layers'] != null, () => `When the config data for a Sequential model is not an Array, ` + + `it must be an Object that contains the 'layers' field.`); + configArray = config['layers']; + delete config['layers']; + extraModelConfig = config; + } + const model = new cls(extraModelConfig); + if (!(model instanceof Sequential)) { + throw new NotImplementedError(`Sequential.fromConfig called on non-Sequential input: ${model}`); + } + for (const conf of configArray) { + const customObjects = undefined; + const layer = deserialize(conf, customObjects, fastWeightInit); + if (fastWeightInit) { + layer.setFastWeightInitDuringBuild(true); + } + model.add(layer); + } + return model; + } + /** + * Setter used for force stopping of LayersModel.fit() (i.e., training). + * + * Example: + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.dense({units: 1, inputShape: [10]})); + * model.compile({loss: 'meanSquaredError', optimizer: 'sgd'}); + * const xs = tf.ones([8, 10]); + * const ys = tf.zeros([8, 1]); + * + * const history = await model.fit(xs, ys, { + * epochs: 10, + * callbacks: { + * onEpochEnd: async (epoch, logs) => { + * if (epoch === 2) { + * model.stopTraining = true; + * } + * } + * } + * }); + * + * // There should be only 3 values in the loss array, instead of 10 values, + * // due to the stopping after 3 epochs. + * console.log(history.history.loss); + * ``` + */ + set stopTraining(stop) { + // TODO(cais): When refactoring to remove the composition pattern happens, + // remove this method overriding. + if (this.model == null) { + throw new ValueError('Cannot set the stopTraining property of a sequential model before ' + + 'it is compiled.'); + } + this.model.stopTraining = stop; + } + get stopTraining() { + if (this.model == null) { + throw new ValueError('Cannot get the stopTraining property of a sequential model before ' + + 'it is compiled.'); + } + return this.model.stopTraining; + } + // TODO(cais): Override get trainableWeights() here + // tslint:disable-next-line:no-any + getConfig() { + // NOTE(cais): We override the return type of getConfig() to `any` here, + // because the `Sequential` class is a special case among `Container` + // subtypes in that its getConfig() method returns an Array (not a + // dict). + const layers = []; + for (const layer of this.layers) { + const dict = {}; + dict['className'] = layer.getClassName(); + dict['config'] = layer.getConfig(); + layers.push(dict); + } + return { name: this.name, layers }; + } + } + /** @nocollapse */ + Sequential.className = 'Sequential'; + registerClass(Sequential); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // TODO(cais): Add doc string to all the public static functions in this + // class; include exectuable JavaScript code snippets where applicable + // (b/74074458). + // LayersModel and related factory methods. + /** + * A model is a data structure that consists of `Layers` and defines inputs + * and outputs. + * + * The key difference between `tf.model` and `tf.sequential` is that + * `tf.model` is more generic, supporting an arbitrary graph (without + * cycles) of layers. `tf.sequential` is less generic and supports only a linear + * stack of layers. + * + * When creating a `tf.LayersModel`, specify its input(s) and output(s). Layers + * are used to wire input(s) to output(s). + * + * For example, the following code snippet defines a model consisting of + * two `dense` layers, with 10 and 4 units, respectively. + * + * ```js + * // Define input, which has a size of 5 (not including batch dimension). + * const input = tf.input({shape: [5]}); + * + * // First dense layer uses relu activation. + * const denseLayer1 = tf.layers.dense({units: 10, activation: 'relu'}); + * // Second dense layer uses softmax activation. + * const denseLayer2 = tf.layers.dense({units: 4, activation: 'softmax'}); + * + * // Obtain the output symbolic tensor by applying the layers on the input. + * const output = denseLayer2.apply(denseLayer1.apply(input)); + * + * // Create the model based on the inputs. + * const model = tf.model({inputs: input, outputs: output}); + * + * // The model can be used for training, evaluation and prediction. + * // For example, the following line runs prediction with the model on + * // some fake data. + * model.predict(tf.ones([2, 5])).print(); + * ``` + * See also: + * `tf.sequential`, `tf.loadLayersModel`. + * + * @doc {heading: 'Models', subheading: 'Creation'} + */ + function model(args) { + return new LayersModel(args); + } + /** + * Creates a `tf.Sequential` model. A sequential model is any model where the + * outputs of one layer are the inputs to the next layer, i.e. the model + * topology is a simple 'stack' of layers, with no branching or skipping. + * + * This means that the first layer passed to a `tf.Sequential` model should have + * a defined input shape. What that means is that it should have received an + * `inputShape` or `batchInputShape` argument, or for some type of layers + * (recurrent, Dense...) an `inputDim` argument. + * + * The key difference between `tf.model` and `tf.sequential` is that + * `tf.sequential` is less generic, supporting only a linear stack of layers. + * `tf.model` is more generic and supports an arbitrary graph (without + * cycles) of layers. + * + * Examples: + * + * ```js + * const model = tf.sequential(); + * + * // First layer must have an input shape defined. + * model.add(tf.layers.dense({units: 32, inputShape: [50]})); + * // Afterwards, TF.js does automatic shape inference. + * model.add(tf.layers.dense({units: 4})); + * + * // Inspect the inferred shape of the model's output, which equals + * // `[null, 4]`. The 1st dimension is the undetermined batch dimension; the + * // 2nd is the output size of the model's last layer. + * console.log(JSON.stringify(model.outputs[0].shape)); + * ``` + * + * It is also possible to specify a batch size (with potentially undetermined + * batch dimension, denoted by "null") for the first layer using the + * `batchInputShape` key. The following example is equivalent to the above: + * + * ```js + * const model = tf.sequential(); + * + * // First layer must have a defined input shape + * model.add(tf.layers.dense({units: 32, batchInputShape: [null, 50]})); + * // Afterwards, TF.js does automatic shape inference. + * model.add(tf.layers.dense({units: 4})); + * + * // Inspect the inferred shape of the model's output. + * console.log(JSON.stringify(model.outputs[0].shape)); + * ``` + * + * You can also use an `Array` of already-constructed `Layer`s to create + * a `tf.Sequential` model: + * + * ```js + * const model = tf.sequential({ + * layers: [tf.layers.dense({units: 32, inputShape: [50]}), + * tf.layers.dense({units: 4})] + * }); + * console.log(JSON.stringify(model.outputs[0].shape)); + * ``` + * + * @doc {heading: 'Models', subheading: 'Creation'} + */ + function sequential(config) { + return new Sequential(config); + } + /** + * Used to instantiate an input to a model as a `tf.SymbolicTensor`. + * + * Users should call the `input` factory function for + * consistency with other generator functions. + * + * Example: + * + * ```js + * // Defines a simple logistic regression model with 32 dimensional input + * // and 3 dimensional output. + * const x = tf.input({shape: [32]}); + * const y = tf.layers.dense({units: 3, activation: 'softmax'}).apply(x); + * const model = tf.model({inputs: x, outputs: y}); + * model.predict(tf.ones([2, 32])).print(); + * ``` + * + * Note: `input` is only necessary when using `model`. When using + * `sequential`, specify `inputShape` for the first layer or use `inputLayer` + * as the first layer. + * + * @doc {heading: 'Models', subheading: 'Inputs'} + */ + function input(config) { + return Input(config); + } + function registerCallbackConstructor(verbosityLevel, callbackConstructor) { + CallbackConstructorRegistry.registerCallbackConstructor(verbosityLevel, callbackConstructor); + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Base class for Activations. + * + * Special note: due to cross-language compatibility reasons, the + * static readonly className field in this family of classes must be set to + * the initialLowerCamelCase name of the activation. + */ + let Activation$1 = class Activation extends Serializable { + getConfig() { + return {}; + } + }; + /** + * Exponential linear unit (ELU). + * Reference: https://arxiv.org/abs/1511.07289 + */ + class Elu extends Activation$1 { + /** + * Calculate the activation function. + * + * @param x: Input. + * @param alpha: Scaling factor the negative section. + * @return Output of the ELU activation. + */ + apply(x, alpha = 1) { + return elu$3(x, alpha); + } + } + /** @nocollapse */ + Elu.className = 'elu'; + registerClass(Elu); + /** + * Scaled Exponential Linear Unit. (Klambauer et al., 2017). + * Reference: Self-Normalizing Neural Networks, https://arxiv.org/abs/1706.02515 + * Notes: + * - To be used together with the initialization "lecunNormal". + * - To be used together with the dropout variant "AlphaDropout". + */ + class Selu extends Activation$1 { + apply(x) { + return selu$2(x); + } + } + /** @nocollapse */ + Selu.className = 'selu'; + registerClass(Selu); + /** + * Rectified linear unit + */ + class Relu extends Activation$1 { + apply(x) { + return relu$2(x); + } + } + /** @nocollapse */ + Relu.className = 'relu'; + registerClass(Relu); + /** + * Rectified linear unit activation maxing out at 6.0. + */ + class Relu6 extends Activation$1 { + apply(x) { + return tidy(() => minimum$4(6.0, relu$2(x))); + } + } + /** @nocollapse */ + Relu6.className = 'relu6'; + registerClass(Relu6); + //* Linear activation (no-op) */ + class Linear extends Activation$1 { + apply(x) { + return x; + } + } + /** @nocollapse */ + Linear.className = 'linear'; + registerClass(Linear); + /** + * Sigmoid activation function. + */ + class Sigmoid extends Activation$1 { + apply(x) { + return sigmoid$2(x); + } + } + /** @nocollapse */ + Sigmoid.className = 'sigmoid'; + registerClass(Sigmoid); + /** + * Segment-wise linear approximation of sigmoid. + */ + class HardSigmoid extends Activation$1 { + apply(x) { + return hardSigmoid(x); + } + } + /** @nocollapse */ + HardSigmoid.className = 'hardSigmoid'; + registerClass(HardSigmoid); + /** + * Softplus activation function. + */ + class Softplus extends Activation$1 { + apply(x) { + return softplus$2(x); + } + } + /** @nocollapse */ + Softplus.className = 'softplus'; + registerClass(Softplus); + /** + * Softsign activation function. + */ + class Softsign extends Activation$1 { + apply(x) { + return softsign(x); + } + } + /** @nocollapse */ + Softsign.className = 'softsign'; + registerClass(Softsign); + /** + * Hyperbolic tangent function. + */ + class Tanh extends Activation$1 { + apply(x) { + return tanh$2(x); + } + } + /** @nocollapse */ + Tanh.className = 'tanh'; + registerClass(Tanh); + /** + * Softmax activation function + */ + let Softmax$1 = class Softmax extends Activation$1 { + /** + * Calculate the activation function. + * + * @param x Tensor. + * @param axis Integer, axis along which the softmax normalization is applied. + * Invalid if < 2, as softmax across 1 (the batch dimension) is assumed to be + * an error. + * + * @returns a Tensor of the same shape as x + * + * @throws ValueError: In case `dim(x) < 2`. + */ + apply(x, axis = (-1)) { + return softmax$3(x, axis); + } + }; + /** @nocollapse */ + Softmax$1.className = 'softmax'; + registerClass(Softmax$1); + /** + * Log softmax activation function + */ + class LogSoftmax extends Activation$1 { + /** + * Calculate the activation function of log softmax: + * log( exp(x_i) / sum(exp(x)) ) + * + * @param x Tensor. + * @param axis Integer, axis along which the softmax normalization is applied. + * Invalid if < 2, as softmax across 1 (the batch dimension) is assumed to be + * an error. + * + * @returns a Tensor of the same shape as x + * + * @throws ValueError: In case `dim(x) < 2`. + */ + apply(x, axis = (-1)) { + return logSoftmax(x, axis); + } + } + /** @nocollapse */ + LogSoftmax.className = 'logSoftmax'; + registerClass(LogSoftmax); + /** + * Gelu activation function + */ + class Gelu extends Activation$1 { + /** + * Calculate the activation function. + * + * @param x Tensor. + * @returns a Tensor of the same shape as x + */ + apply(x) { + return tidy(() => { + return tidy(() => { + const sqrtTwo = Math.sqrt(2); + // Compute Φ(x) using the erf function + const cdf = mul(0.5, add$3(1, erf$2(div$1(x, sqrtTwo)))); + // Compute GELU(x) = x * Φ(x) + return mul(x, cdf); + }); + }); + } + } + /** @nocollapse */ + Gelu.className = 'gelu'; + registerClass(Gelu); + /** + * GeluNew activation function + */ + class GeluNew extends Activation$1 { + /** + * Calculate the activation function. + * + * @param x Tensor. + * @returns a Tensor of the same shape as x + */ + apply(x) { + return tidy(() => { + return mul(0.5, mul(x, add$3(1, tanh$2(mul(sqrt$2(div$1(2, Math.PI)), add$3(x, mul(0.044715, pow$3(x, 3)))))))); + }); + } + } + /** @nocollapse */ + GeluNew.className = 'gelu_new'; + registerClass(GeluNew); + /** + * Mish activation function + */ + class Mish extends Activation$1 { + /** + * Calculate the activation function. + * + * @param x Tensor. + * @returns a Tensor of the same shape as x + */ + apply(x) { + return tidy(() => mul(x, tanh$2(softplus$2(x)))); + } + } + /** @nocollapse */ + Mish.className = 'mish'; + registerClass(Mish); + /** + * Swish activation function + */ + class Swish extends Activation$1 { + /** + * Calculate the activation function. + * + * @param x Tensor. + * @param alpha Scaling factor for the sigmoid function. + * @returns a Tensor of the same shape as x + */ + apply(x, alpha = 1) { + return tidy(() => mul(sigmoid$2(mul(x, alpha)), x)); + } + } + /** @nocollapse */ + Swish.className = 'swish'; + registerClass(Swish); + function serializeActivation(activation) { + return activation.getClassName(); + } + function deserializeActivation(config, customObjects = {}) { + return deserializeKerasObject(config, SerializationMap.getMap().classNameMap, customObjects, 'activation'); + } + function getActivation(identifier) { + if (identifier == null) { + const config = {}; + config['className'] = 'linear'; + config['config'] = {}; + return deserializeActivation(config); + } + if (typeof identifier === 'string') { + const config = {}; + config['className'] = identifier; + config['config'] = {}; + return deserializeActivation(config); + } + else if (identifier instanceof Activation$1) { + return identifier; + } + else { + return deserializeActivation(identifier); + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + function assertObjectArgs(args) { + if (args != null && typeof args !== 'object') { + throw new Error(`Argument to L1L2 regularizer's constructor is expected to be an ` + + `object, but received: ${args}`); + } + } + /** + * Regularizer base class. + */ + class Regularizer extends Serializable { + } + class L1L2 extends Regularizer { + constructor(args) { + super(); + assertObjectArgs(args); + this.l1 = args == null || args.l1 == null ? 0.01 : args.l1; + this.l2 = args == null || args.l2 == null ? 0.01 : args.l2; + this.hasL1 = this.l1 !== 0; + this.hasL2 = this.l2 !== 0; + } + /** + * Porting note: Renamed from __call__. + * @param x Variable of which to calculate the regularization score. + */ + apply(x) { + return tidy(() => { + let regularization = zeros$2([1]); + if (this.hasL1) { + regularization = add$3(regularization, sum$3(mul(this.l1, abs$2(x)))); + } + if (this.hasL2) { + regularization = + add$3(regularization, sum$3(mul(this.l2, square$1(x)))); + } + return reshape$3(regularization, []); + }); + } + getConfig() { + return { 'l1': this.l1, 'l2': this.l2 }; + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls({ l1: config['l1'], l2: config['l2'] }); + } + } + /** @nocollapse */ + L1L2.className = 'L1L2'; + registerClass(L1L2); + function l1$1(args) { + assertObjectArgs(args); + return new L1L2({ l1: args != null ? args.l1 : null, l2: 0 }); + } + function l2$1(args) { + assertObjectArgs(args); + return new L1L2({ l2: args != null ? args.l2 : null, l1: 0 }); + } + // Maps the JavaScript-like identifier keys to the corresponding keras symbols. + const REGULARIZER_IDENTIFIER_REGISTRY_SYMBOL_MAP = { + 'l1l2': 'L1L2' + }; + function serializeRegularizer(constraint) { + return serializeKerasObject(constraint); + } + function deserializeRegularizer(config, customObjects = {}) { + return deserializeKerasObject(config, SerializationMap.getMap().classNameMap, customObjects, 'regularizer'); + } + function getRegularizer(identifier) { + if (identifier == null) { + return null; + } + if (typeof identifier === 'string') { + const className = identifier in REGULARIZER_IDENTIFIER_REGISTRY_SYMBOL_MAP ? + REGULARIZER_IDENTIFIER_REGISTRY_SYMBOL_MAP[identifier] : + identifier; + const config = { className, config: {} }; + return deserializeRegularizer(config); + } + else if (identifier instanceof Regularizer) { + return identifier; + } + else { + return deserializeRegularizer(identifier); + } + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + class ReLU extends Layer { + constructor(args) { + super(args == null ? {} : args); + this.supportsMasking = true; + if (args != null) { + this.maxValue = args.maxValue; + } + } + call(inputs, kwargs) { + inputs = getExactlyOneTensor(inputs); + let output = relu$2(inputs); + if (this.maxValue != null) { + output = clipByValue$2(output, 0, this.maxValue); + } + return output; + } + computeOutputShape(inputShape) { + return inputShape; + } + getConfig() { + const config = { maxValue: this.maxValue }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + ReLU.className = 'ReLU'; + registerClass(ReLU); + class LeakyReLU extends Layer { + constructor(args) { + super(args == null ? {} : args); + this.DEFAULT_ALPHA = 0.3; + if (args == null) { + args = {}; + } + this.alpha = args.alpha == null ? this.DEFAULT_ALPHA : args.alpha; + } + call(inputs, kwargs) { + const x = getExactlyOneTensor(inputs); + return leakyRelu$2(x, this.alpha); + } + computeOutputShape(inputShape) { + return inputShape; + } + getConfig() { + const config = { alpha: this.alpha }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + LeakyReLU.className = 'LeakyReLU'; + registerClass(LeakyReLU); + class PReLU extends Layer { + constructor(args) { + super(args == null ? {} : args); + this.DEFAULT_ALPHA_INITIALIZER = 'zeros'; + if (args == null) { + args = {}; + } + this.supportsMasking = true; + this.alphaInitializer = + getInitializer(args.alphaInitializer || this.DEFAULT_ALPHA_INITIALIZER); + this.alphaRegularizer = getRegularizer(args.alphaRegularizer); + this.alphaConstraint = getConstraint(args.alphaConstraint); + if (args.sharedAxes == null) { + this.sharedAxes = null; + } + else if (Array.isArray(args.sharedAxes)) { + this.sharedAxes = args.sharedAxes; + } + else if (typeof args.sharedAxes === 'number') { + this.sharedAxes = [args.sharedAxes]; + } + else { + throw new ValueError(`Expected sharedAxes to be a number or an array of numbers, ` + + `but got ${args.sharedAxes}`); + } + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const paramShape = inputShape.slice(1); + if (this.sharedAxes != null) { + for (const i of this.sharedAxes) { + paramShape[i - 1] = 1; + } + } + this.alpha = this.addWeight('alpha', paramShape, 'float32', this.alphaInitializer, this.alphaRegularizer, true, this.alphaConstraint); + // Set input spec. + const axes = {}; + if (this.sharedAxes != null) { + for (let i = 1; i < inputShape.length; ++i) { + axes[i] = inputShape[i]; + } + } + this.inputSpec = [new InputSpec({ + ndim: inputShape.length, + axes, + })]; + this.built = true; + } + call(inputs, kwargs) { + inputs = getExactlyOneTensor(inputs); + return prelu$3(inputs, this.alpha.read()); + } + getConfig() { + const config = { + alphaInitializer: serializeInitializer(this.alphaInitializer), + alphaRegularizer: serializeRegularizer(this.alphaRegularizer), + alphaConstraint: serializeConstraint(this.alphaConstraint), + sharedAxes: this.sharedAxes + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + PReLU.className = 'PReLU'; + registerClass(PReLU); + let ELU$3 = class ELU extends Layer { + constructor(args) { + super(args == null ? {} : args); + this.DEFAULT_ALPHA = 1.0; + if (args == null) { + args = {}; + } + if (args.alpha != null && args.alpha !== this.DEFAULT_ALPHA) { + throw new NotImplementedError(`Non-default alpha value (${args.alpha}) is not supported by the ` + + `ELU layer yet.`); + } + this.alpha = args.alpha == null ? this.DEFAULT_ALPHA : args.alpha; + } + call(inputs, kwargs) { + const x = getExactlyOneTensor(inputs); + return elu$4(x); + } + computeOutputShape(inputShape) { + return inputShape; + } + getConfig() { + const config = { alpha: this.alpha }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + }; + /** @nocollapse */ + ELU$3.className = 'ELU'; + registerClass(ELU$3); + class ThresholdedReLU extends Layer { + constructor(args) { + super(args == null ? {} : args); + this.DEFAULT_THETA = 1.0; + if (args == null) { + args = {}; + } + this.theta = args.theta == null ? this.DEFAULT_THETA : args.theta; + } + call(inputs, kwargs) { + const x = getExactlyOneTensor(inputs); + return mul(x, cast$3(greater$3(x, this.theta), 'float32')); + } + computeOutputShape(inputShape) { + return inputShape; + } + getConfig() { + const config = { theta: this.theta }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + ThresholdedReLU.className = 'ThresholdedReLU'; + registerClass(ThresholdedReLU); + class Softmax extends Layer { + constructor(args) { + super(args == null ? {} : args); + this.DEFAULT_AXIS = 1.0; + if (args == null) { + args = {}; + } + this.softmax = new Softmax$1().apply; + this.axis = args.axis == null ? this.DEFAULT_AXIS : args.axis; + } + call(inputs, kwargs) { + // TODO(pforderique): Add tests for when `this.axis` is a number[]. + return tidy(() => { + let x = getExactlyOneTensor(inputs); + const mask = kwargs['mask']; + if (mask != null) { + // Since mask is 1.0 for positions we want to keep and 0.0 for masked + // positions, this operation will create a tensor which is 0.0 for + // positions we want to attend and -1e.9 for masked positions. + const adder = mul(sub$2(ones$1(x.shape), cast$3(mask, x.dtype)), scalar(-1e9)); + // Since we are adding it to the raw scores before the softmax, this + // is effectively the same as removing these entirely. + x = add$3(x, adder); + } + if (this.axis instanceof Array) { + if (this.axis.length > 1) { + return exp$2(sub$2(x, logSumExp(x, this.axis, true))); + } + else { + return this.softmax(x, this.axis[0]); + } + } + return this.softmax(x, this.axis); + }); + } + computeOutputShape(inputShape) { + return inputShape; + } + getConfig() { + const config = { axis: this.axis }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Softmax.className = 'Softmax'; + registerClass(Softmax); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Transforms a single number of array of numbers into an array of numbers. + * @param value + * @param n: The size of the tuple to be returned. + * @param name: Name of the parameter, used for generating error messages. + * @returns An array of numbers. + */ + function normalizeArray(value, n, name) { + if (typeof value === 'number') { + return pyListRepeat(value, n); + } + else { + if (value.length !== n) { + throw new ValueError(`The ${name} argument must be an integer or tuple of ${n} integers.` + + ` Received: ${value.length} elements.`); + } + for (let i = 0; i < n; ++i) { + const singleValue = value[i]; + if (!isInteger(singleValue)) { + throw new ValueError(`The ${name} argument must be an integer or tuple of ${n}` + + ` integers. Received: ${JSON.stringify(value)} including a` + + ` non-integer number ${singleValue}`); + } + } + return value; + } + } + /** + * Determines output length of a convolution given input length. + * @param inputLength + * @param filterSize + * @param padding + * @param stride + * @param dilation: dilation rate. + */ + function convOutputLength(inputLength, filterSize, padding, stride, dilation = 1) { + if (inputLength == null) { + return inputLength; + } + const dilatedFilterSize = filterSize + (filterSize - 1) * (dilation - 1); + let outputLength; + if (padding === 'same') { + outputLength = inputLength; + } + else { // VALID + outputLength = inputLength - dilatedFilterSize + 1; + } + return Math.floor((outputLength + stride - 1) / stride); + } + function deconvLength(dimSize, strideSize, kernelSize, padding) { + if (dimSize == null) { + return null; + } + if (padding === 'valid') { + dimSize = dimSize * strideSize + max$2([kernelSize - strideSize, 0]); + } + else if (padding === 'same') { + dimSize = dimSize * strideSize; + } + else { + throw new ValueError(`Unsupport padding mode: ${padding}.`); + } + return dimSize; + } + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Transpose and cast the input before the conv2d. + * @param x Input image tensor. + * @param dataFormat + */ + function preprocessConv2DInput(x, dataFormat) { + // TODO(cais): Cast type to float32 if not. + return tidy(() => { + checkDataFormat(dataFormat); + if (dataFormat === 'channelsFirst') { + return transpose$2(x, [0, 2, 3, 1]); // NCHW -> NHWC. + } + else { + return x; + } + }); + } + /** + * Transpose and cast the input before the conv3d. + * @param x Input image tensor. + * @param dataFormat + */ + function preprocessConv3DInput(x, dataFormat) { + return tidy(() => { + checkDataFormat(dataFormat); + if (dataFormat === 'channelsFirst') { + return transpose$2(x, [0, 2, 3, 4, 1]); // NCDHW -> NDHWC. + } + else { + return x; + } + }); + } + /** + * 1D-convolution with bias added. + * + * Porting Note: This function does not exist in the Python Keras backend. + * It is exactly the same as `conv2d`, except the added `bias`. + * + * @param x Input tensor, rank-3, of shape `[batchSize, width, inChannels]`. + * @param kernel Kernel, rank-3, of shape `[filterWidth, inDepth, outDepth]`. + * @param bias Bias, rank-3, of shape `[outDepth]`. + * @param strides + * @param padding Padding mode. + * @param dataFormat Data format. + * @param dilationRate + * @returns The result of the 1D convolution. + * @throws ValueError, if `x`, `kernel` or `bias` is not of the correct rank. + */ + function conv1dWithBias(x, kernel, bias, strides = 1, padding = 'valid', dataFormat, dilationRate = 1) { + return tidy(() => { + if (dataFormat == null) { + dataFormat = imageDataFormat(); + } + checkDataFormat(dataFormat); + // Check the ranks of x, kernel and bias. + if (x.shape.length !== 3) { + throw new ValueError(`The input of a conv1dWithBias operation should be 3, but is ` + + `${x.shape.length} instead.`); + } + if (kernel.shape.length !== 3) { + throw new ValueError(`The kernel for a conv1dWithBias operation should be 3, but is ` + + `${kernel.shape.length} instead`); + } + if (bias != null && bias.shape.length !== 1) { + throw new ValueError(`The bias for a conv1dWithBias operation should be 1, but is ` + + `${bias.shape.length} instead`); + } + // TODO(cais): Support CAUSAL padding mode. + if (dataFormat === 'channelsFirst') { + x = transpose$2(x, [0, 2, 1]); // NCW -> NWC. + } + if (padding === 'causal') { + throw new NotImplementedError('The support for CAUSAL padding mode in conv1dWithBias is not ' + + 'implemented yet.'); + } + let y = conv1d$2(x, kernel, strides, padding === 'same' ? 'same' : 'valid', 'NWC', dilationRate); + if (bias != null) { + y = biasAdd(y, bias); + } + return y; + }); + } + /** + * 1D-convolution. + * + * @param x Input tensor, rank-3, of shape `[batchSize, width, inChannels]`. + * @param kernel Kernel, rank-3, of shape `[filterWidth, inDepth, outDepth]`.s + * @param strides + * @param padding Padding mode. + * @param dataFormat Data format. + * @param dilationRate + * @returns The result of the 1D convolution. + * @throws ValueError, if `x`, `kernel` or `bias` is not of the correct rank. + */ + function conv1d$1(x, kernel, strides = 1, padding = 'valid', dataFormat, dilationRate = 1) { + return tidy(() => { + checkDataFormat(dataFormat); + return conv1dWithBias(x, kernel, null, strides, padding, dataFormat, dilationRate); + }); + } + /** + * 2D Convolution + * @param x + * @param kernel kernel of the convolution. + * @param strides strides array. + * @param padding padding mode. Default to 'valid'. + * @param dataFormat data format. Defaults to 'channelsLast'. + * @param dilationRate dilation rate array. + * @returns Result of the 2D pooling. + */ + function conv2d$2(x, kernel, strides = [1, 1], padding = 'valid', dataFormat, dilationRate) { + return tidy(() => { + checkDataFormat(dataFormat); + return conv2dWithBiasActivation(x, kernel, null, strides, padding, dataFormat, dilationRate); + }); + } + /** + * 2D Convolution with an added bias and optional activation. + * Note: This function does not exist in the Python Keras Backend. This function + * is exactly the same as `conv2d`, except the added `bias`. + */ + function conv2dWithBiasActivation(x, kernel, bias, strides = [1, 1], padding = 'valid', dataFormat, dilationRate, activation = null) { + return tidy(() => { + if (dataFormat == null) { + dataFormat = imageDataFormat(); + } + checkDataFormat(dataFormat); + if (x.rank !== 3 && x.rank !== 4) { + throw new ValueError(`conv2dWithBiasActivation expects input to be of rank 3 or 4, ` + + `but received ${x.rank}.`); + } + if (kernel.rank !== 3 && kernel.rank !== 4) { + throw new ValueError(`conv2dWithBiasActivation expects kernel to be of rank 3 or 4, ` + + `but received ${x.rank}.`); + } + let y = preprocessConv2DInput(x, dataFormat); + if (padding === 'causal') { + throw new NotImplementedError('The support for CAUSAL padding mode in conv1dWithBias is not ' + + 'implemented yet.'); + } + y = conv2d$3({ + x: y, + filter: kernel, + strides: strides, + pad: padding === 'same' ? 'same' : 'valid', + dilations: dilationRate, + dataFormat: 'NHWC', + bias, + activation + }); + if (dataFormat === 'channelsFirst') { + y = transpose$2(y, [0, 3, 1, 2]); + } + return y; + }); + } + /** + * 3D Convolution. + * @param x + * @param kernel kernel of the convolution. + * @param strides strides array. + * @param padding padding mode. Default to 'valid'. + * @param dataFormat data format. Defaults to 'channelsLast'. + * @param dilationRate dilation rate array. + * @returns Result of the 3D convolution. + */ + function conv3d$1(x, kernel, strides = [1, 1, 1], padding = 'valid', dataFormat, dilationRate) { + return tidy(() => { + checkDataFormat(dataFormat); + return conv3dWithBias(x, kernel, null, strides, padding, dataFormat, dilationRate); + }); + } + /** + * 3D Convolution with an added bias. + * Note: This function does not exist in the Python Keras Backend. This function + * is exactly the same as `conv3d`, except the added `bias`. + */ + function conv3dWithBias(x, kernel, bias, strides = [1, 1, 1], padding = 'valid', dataFormat, dilationRate) { + return tidy(() => { + if (dataFormat == null) { + dataFormat = imageDataFormat(); + } + checkDataFormat(dataFormat); + if (x.rank !== 4 && x.rank !== 5) { + throw new ValueError(`conv3dWithBias expects input to be of rank 4 or 5, but received ` + + `${x.rank}.`); + } + if (kernel.rank !== 4 && kernel.rank !== 5) { + throw new ValueError(`conv3dWithBias expects kernel to be of rank 4 or 5, but received ` + + `${x.rank}.`); + } + let y = preprocessConv3DInput(x, dataFormat); + if (padding === 'causal') { + throw new NotImplementedError('The support for CAUSAL padding mode in conv3dWithBias is not ' + + 'implemented yet.'); + } + y = conv3d$2(y, kernel, strides, padding === 'same' ? 'same' : 'valid', 'NDHWC', dilationRate); + if (bias != null) { + y = biasAdd(y, bias); + } + if (dataFormat === 'channelsFirst') { + y = transpose$2(y, [0, 4, 1, 2, 3]); + } + return y; + }); + } + /** + * Abstract convolution layer. + */ + class BaseConv extends Layer { + constructor(rank, args) { + super(args); + this.bias = null; + this.DEFAULT_KERNEL_INITIALIZER = 'glorotNormal'; + this.DEFAULT_BIAS_INITIALIZER = 'zeros'; + BaseConv.verifyArgs(args); + this.rank = rank; + assertPositiveInteger(this.rank, 'rank'); + if (this.rank !== 1 && this.rank !== 2 && this.rank !== 3) { + throw new NotImplementedError(`Convolution layer for rank other than 1, 2, or 3 (${this.rank}) is ` + + `not implemented yet.`); + } + this.kernelSize = normalizeArray(args.kernelSize, rank, 'kernelSize'); + this.strides = normalizeArray(args.strides == null ? 1 : args.strides, rank, 'strides'); + this.padding = args.padding == null ? 'valid' : args.padding; + checkPaddingMode(this.padding); + this.dataFormat = + args.dataFormat == null ? 'channelsLast' : args.dataFormat; + checkDataFormat(this.dataFormat); + this.activation = getActivation(args.activation); + this.useBias = args.useBias == null ? true : args.useBias; + this.biasInitializer = + getInitializer(args.biasInitializer || this.DEFAULT_BIAS_INITIALIZER); + this.biasConstraint = getConstraint(args.biasConstraint); + this.biasRegularizer = getRegularizer(args.biasRegularizer); + this.activityRegularizer = getRegularizer(args.activityRegularizer); + this.dilationRate = normalizeArray(args.dilationRate == null ? 1 : args.dilationRate, rank, 'dilationRate'); + if (this.rank === 1 && + (Array.isArray(this.dilationRate) && this.dilationRate.length !== 1)) { + throw new ValueError(`dilationRate must be a number or an array of a single number ` + + `for 1D convolution, but received ` + + `${JSON.stringify(this.dilationRate)}`); + } + else if (this.rank === 2) { + if (typeof this.dilationRate === 'number') { + this.dilationRate = [this.dilationRate, this.dilationRate]; + } + else if (this.dilationRate.length !== 2) { + throw new ValueError(`dilationRate must be a number or array of two numbers for 2D ` + + `convolution, but received ${JSON.stringify(this.dilationRate)}`); + } + } + else if (this.rank === 3) { + if (typeof this.dilationRate === 'number') { + this.dilationRate = + [this.dilationRate, this.dilationRate, this.dilationRate]; + } + else if (this.dilationRate.length !== 3) { + throw new ValueError(`dilationRate must be a number or array of three numbers for 3D ` + + `convolution, but received ${JSON.stringify(this.dilationRate)}`); + } + } + } + static verifyArgs(args) { + // Check config.kernelSize type and shape. + assert('kernelSize' in args, `required key 'kernelSize' not in config`); + if (typeof args.kernelSize !== 'number' && + !checkArrayTypeAndLength(args.kernelSize, 'number', 1, 3)) { + throw new ValueError(`BaseConv expects config.kernelSize to be number or number[] with ` + + `length 1, 2, or 3, but received ${JSON.stringify(args.kernelSize)}.`); + } + } + getConfig() { + const config = { + kernelSize: this.kernelSize, + strides: this.strides, + padding: this.padding, + dataFormat: this.dataFormat, + dilationRate: this.dilationRate, + activation: serializeActivation(this.activation), + useBias: this.useBias, + biasInitializer: serializeInitializer(this.biasInitializer), + biasRegularizer: serializeRegularizer(this.biasRegularizer), + activityRegularizer: serializeRegularizer(this.activityRegularizer), + biasConstraint: serializeConstraint(this.biasConstraint) + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** + * Abstract nD convolution layer. Ancestor of convolution layers which reduce + * across channels, i.e., Conv1D and Conv2D, but not DepthwiseConv2D. + */ + class Conv extends BaseConv { + constructor(rank, args) { + super(rank, args); + this.kernel = null; + Conv.verifyArgs(args); + this.filters = args.filters; + assertPositiveInteger(this.filters, 'filters'); + this.kernelInitializer = getInitializer(args.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER); + this.kernelConstraint = getConstraint(args.kernelConstraint); + this.kernelRegularizer = getRegularizer(args.kernelRegularizer); + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const channelAxis = this.dataFormat === 'channelsFirst' ? 1 : inputShape.length - 1; + if (inputShape[channelAxis] == null) { + throw new ValueError(`The channel dimension of the input should be defined. ` + + `Found ${inputShape[channelAxis]}`); + } + const inputDim = inputShape[channelAxis]; + const kernelShape = this.kernelSize.concat([inputDim, this.filters]); + this.kernel = this.addWeight('kernel', kernelShape, null, this.kernelInitializer, this.kernelRegularizer, true, this.kernelConstraint); + if (this.useBias) { + this.bias = this.addWeight('bias', [this.filters], null, this.biasInitializer, this.biasRegularizer, true, this.biasConstraint); + } + this.inputSpec = [{ ndim: this.rank + 2, axes: { [channelAxis]: inputDim } }]; + this.built = true; + } + call(inputs, kwargs) { + return tidy(() => { + inputs = getExactlyOneTensor(inputs); + let outputs; + const biasValue = this.bias == null ? null : this.bias.read(); + const fusedActivationName = mapActivationToFusedKernel(this.activation.getClassName()); + if (fusedActivationName != null && this.rank === 2) { + outputs = conv2dWithBiasActivation(inputs, this.kernel.read(), biasValue, this.strides, this.padding, this.dataFormat, this.dilationRate, fusedActivationName); + } + else { + if (this.rank === 1) { + outputs = conv1dWithBias(inputs, this.kernel.read(), biasValue, this.strides[0], this.padding, this.dataFormat, this.dilationRate[0]); + } + else if (this.rank === 2) { + // TODO(cais): Move up to constructor. + outputs = conv2dWithBiasActivation(inputs, this.kernel.read(), biasValue, this.strides, this.padding, this.dataFormat, this.dilationRate); + } + else if (this.rank === 3) { + outputs = conv3dWithBias(inputs, this.kernel.read(), biasValue, this.strides, this.padding, this.dataFormat, this.dilationRate); + } + else { + throw new NotImplementedError('convolutions greater than 3D are not implemented yet.'); + } + if (this.activation != null) { + outputs = this.activation.apply(outputs); + } + } + return outputs; + }); + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const newSpace = []; + const space = (this.dataFormat === 'channelsLast') ? + inputShape.slice(1, inputShape.length - 1) : + inputShape.slice(2); + for (let i = 0; i < space.length; ++i) { + const newDim = convOutputLength(space[i], this.kernelSize[i], this.padding, this.strides[i], typeof this.dilationRate === 'number' ? this.dilationRate : + this.dilationRate[i]); + newSpace.push(newDim); + } + let outputShape = [inputShape[0]]; + if (this.dataFormat === 'channelsLast') { + outputShape = outputShape.concat(newSpace); + outputShape.push(this.filters); + } + else { + outputShape.push(this.filters); + outputShape = outputShape.concat(newSpace); + } + return outputShape; + } + getConfig() { + const config = { + filters: this.filters, + kernelInitializer: serializeInitializer(this.kernelInitializer), + kernelRegularizer: serializeRegularizer(this.kernelRegularizer), + kernelConstraint: serializeConstraint(this.kernelConstraint) + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + static verifyArgs(args) { + // Check config.filters type, shape, and value. + if (!('filters' in args) || typeof args.filters !== 'number' || + args.filters < 1) { + throw new ValueError(`Convolution layer expected config.filters to be a 'number' > 0 ` + + `but got ${JSON.stringify(args.filters)}`); + } + } + } + class Conv2D extends Conv { + constructor(args) { + super(2, args); + Conv2D.verifyArgs(args); + } + getConfig() { + const config = super.getConfig(); + delete config['rank']; + return config; + } + static verifyArgs(args) { + // config.kernelSize must be a number or array of numbers. + if ((typeof args.kernelSize !== 'number') && + !checkArrayTypeAndLength(args.kernelSize, 'number', 1, 2)) { + throw new ValueError(`Conv2D expects config.kernelSize to be number or number[] with ` + + `length 1 or 2, but received ${JSON.stringify(args.kernelSize)}.`); + } + } + } + /** @nocollapse */ + Conv2D.className = 'Conv2D'; + registerClass(Conv2D); + class Conv3D extends Conv { + constructor(args) { + super(3, args); + Conv3D.verifyArgs(args); + } + getConfig() { + const config = super.getConfig(); + delete config['rank']; + return config; + } + static verifyArgs(args) { + // config.kernelSize must be a number or array of numbers. + if (typeof args.kernelSize !== 'number') { + if (!(Array.isArray(args.kernelSize) && + (args.kernelSize.length === 1 || args.kernelSize.length === 3))) { + throw new ValueError(`Conv3D expects config.kernelSize to be number or` + + ` [number, number, number], but received ${JSON.stringify(args.kernelSize)}.`); + } + } + } + } + /** @nocollapse */ + Conv3D.className = 'Conv3D'; + registerClass(Conv3D); + class Conv2DTranspose extends Conv2D { + constructor(args) { + super(args); + this.inputSpec = [new InputSpec({ ndim: 4 })]; + if (this.padding !== 'same' && this.padding !== 'valid') { + throw new ValueError(`Conv2DTranspose currently supports only padding modes 'same' ` + + `and 'valid', but received padding mode ${this.padding}`); + } + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + if (inputShape.length !== 4) { + throw new ValueError('Input should have rank 4; Received input shape: ' + + JSON.stringify(inputShape)); + } + const channelAxis = this.dataFormat === 'channelsFirst' ? 1 : inputShape.length - 1; + if (inputShape[channelAxis] == null) { + throw new ValueError('The channel dimension of the inputs should be defined. ' + + 'Found `None`.'); + } + const inputDim = inputShape[channelAxis]; + const kernelShape = this.kernelSize.concat([this.filters, inputDim]); + this.kernel = this.addWeight('kernel', kernelShape, 'float32', this.kernelInitializer, this.kernelRegularizer, true, this.kernelConstraint); + if (this.useBias) { + this.bias = this.addWeight('bias', [this.filters], 'float32', this.biasInitializer, this.biasRegularizer, true, this.biasConstraint); + } + // Set input spec. + this.inputSpec = + [new InputSpec({ ndim: 4, axes: { [channelAxis]: inputDim } })]; + this.built = true; + } + call(inputs, kwargs) { + return tidy(() => { + let input = getExactlyOneTensor(inputs); + if (input.shape.length !== 4) { + throw new ValueError(`Conv2DTranspose.call() expects input tensor to be rank-4, but ` + + `received a tensor of rank-${input.shape.length}`); + } + const inputShape = input.shape; + const batchSize = inputShape[0]; + let hAxis; + let wAxis; + if (this.dataFormat === 'channelsFirst') { + hAxis = 2; + wAxis = 3; + } + else { + hAxis = 1; + wAxis = 2; + } + const height = inputShape[hAxis]; + const width = inputShape[wAxis]; + const kernelH = this.kernelSize[0]; + const kernelW = this.kernelSize[1]; + const strideH = this.strides[0]; + const strideW = this.strides[1]; + // Infer the dynamic output shape. + const outHeight = deconvLength(height, strideH, kernelH, this.padding); + const outWidth = deconvLength(width, strideW, kernelW, this.padding); + // Porting Note: We don't branch based on `this.dataFormat` here, + // because + // the tjfs-core function `conv2dTranspose` called below always + // assumes channelsLast. + const outputShape = [batchSize, outHeight, outWidth, this.filters]; + if (this.dataFormat !== 'channelsLast') { + input = transpose$2(input, [0, 2, 3, 1]); + } + let outputs = conv2dTranspose$1(input, this.kernel.read(), outputShape, this.strides, this.padding); + if (this.dataFormat !== 'channelsLast') { + outputs = transpose$2(outputs, [0, 3, 1, 2]); + } + if (this.bias != null) { + outputs = + biasAdd(outputs, this.bias.read(), this.dataFormat); + } + if (this.activation != null) { + outputs = this.activation.apply(outputs); + } + return outputs; + }); + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const outputShape = inputShape.slice(); + let channelAxis; + let heightAxis; + let widthAxis; + if (this.dataFormat === 'channelsFirst') { + channelAxis = 1; + heightAxis = 2; + widthAxis = 3; + } + else { + channelAxis = 3; + heightAxis = 1; + widthAxis = 2; + } + const kernelH = this.kernelSize[0]; + const kernelW = this.kernelSize[1]; + const strideH = this.strides[0]; + const strideW = this.strides[1]; + outputShape[channelAxis] = this.filters; + outputShape[heightAxis] = + deconvLength(outputShape[heightAxis], strideH, kernelH, this.padding); + outputShape[widthAxis] = + deconvLength(outputShape[widthAxis], strideW, kernelW, this.padding); + return outputShape; + } + getConfig() { + const config = super.getConfig(); + delete config['dilationRate']; + return config; + } + } + /** @nocollapse */ + Conv2DTranspose.className = 'Conv2DTranspose'; + registerClass(Conv2DTranspose); + class Conv3DTranspose extends Conv3D { + constructor(args) { + super(args); + this.inputSpec = [new InputSpec({ ndim: 5 })]; + if (this.padding !== 'same' && this.padding !== 'valid') { + throw new ValueError(`Conv3DTranspose currently supports only padding modes 'same' ` + + `and 'valid', but received padding mode ${this.padding}`); + } + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + if (inputShape.length !== 5) { + throw new ValueError('Input should have rank 5; Received input shape: ' + + JSON.stringify(inputShape)); + } + const channelAxis = this.dataFormat === 'channelsFirst' ? 1 : inputShape.length - 1; + if (inputShape[channelAxis] == null) { + throw new ValueError('The channel dimension of the inputs should be defined. ' + + 'Found `None`.'); + } + const inputDim = inputShape[channelAxis]; + const kernelShape = this.kernelSize.concat([this.filters, inputDim]); + this.kernel = this.addWeight('kernel', kernelShape, 'float32', this.kernelInitializer, this.kernelRegularizer, true, this.kernelConstraint); + if (this.useBias) { + this.bias = this.addWeight('bias', [this.filters], 'float32', this.biasInitializer, this.biasRegularizer, true, this.biasConstraint); + } + // Set input spec. + this.inputSpec = + [new InputSpec({ ndim: 5, axes: { [channelAxis]: inputDim } })]; + this.built = true; + } + call(inputs, kwargs) { + return tidy(() => { + let input = getExactlyOneTensor(inputs); + if (input.shape.length !== 5) { + throw new ValueError(`Conv3DTranspose.call() expects input tensor to be rank-4, but ` + + `received a tensor of rank-${input.shape.length}`); + } + const inputShape = input.shape; + const batchSize = inputShape[0]; + let hAxis; + let wAxis; + let dAxis; + if (this.dataFormat === 'channelsFirst') { + dAxis = 2; + hAxis = 3; + wAxis = 4; + } + else { + dAxis = 1; + hAxis = 2; + wAxis = 3; + } + const depth = inputShape[dAxis]; + const height = inputShape[hAxis]; + const width = inputShape[wAxis]; + const kernelD = this.kernelSize[0]; + const kernelH = this.kernelSize[1]; + const kernelW = this.kernelSize[2]; + const strideD = this.strides[0]; + const strideH = this.strides[1]; + const strideW = this.strides[2]; + // Infer the dynamic output shape. + const outDepth = deconvLength(depth, strideD, kernelD, this.padding); + const outHeight = deconvLength(height, strideH, kernelH, this.padding); + const outWidth = deconvLength(width, strideW, kernelW, this.padding); + // Same as `conv2dTranspose`. We always assumes channelsLast. + const outputShape = [batchSize, outDepth, outHeight, outWidth, this.filters]; + if (this.dataFormat !== 'channelsLast') { + input = transpose$2(input, [0, 2, 3, 4, 1]); + } + let outputs = conv3dTranspose$1(input, this.kernel.read(), outputShape, this.strides, this.padding); + if (this.dataFormat !== 'channelsLast') { + outputs = transpose$2(outputs, [0, 4, 1, 2, 3]); + } + if (this.bias !== null) { + outputs = + biasAdd(outputs, this.bias.read(), this.dataFormat); + } + if (this.activation !== null) { + outputs = this.activation.apply(outputs); + } + return outputs; + }); + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const outputShape = inputShape.slice(); + let channelAxis; + let depthAxis; + let heightAxis; + let widthAxis; + if (this.dataFormat === 'channelsFirst') { + channelAxis = 1; + depthAxis = 2; + heightAxis = 3; + widthAxis = 4; + } + else { + channelAxis = 4; + depthAxis = 1; + heightAxis = 2; + widthAxis = 3; + } + const kernelD = this.kernelSize[0]; + const kernelH = this.kernelSize[1]; + const kernelW = this.kernelSize[2]; + const strideD = this.strides[0]; + const strideH = this.strides[1]; + const strideW = this.strides[2]; + outputShape[channelAxis] = this.filters; + outputShape[depthAxis] = + deconvLength(outputShape[depthAxis], strideD, kernelD, this.padding); + outputShape[heightAxis] = + deconvLength(outputShape[heightAxis], strideH, kernelH, this.padding); + outputShape[widthAxis] = + deconvLength(outputShape[widthAxis], strideW, kernelW, this.padding); + return outputShape; + } + getConfig() { + const config = super.getConfig(); + delete config['dilationRate']; + return config; + } + } + /** @nocollapse */ + Conv3DTranspose.className = 'Conv3DTranspose'; + registerClass(Conv3DTranspose); + class SeparableConv extends Conv { + constructor(rank, config) { + super(rank, config); + this.DEFAULT_DEPTHWISE_INITIALIZER = 'glorotUniform'; + this.DEFAULT_POINTWISE_INITIALIZER = 'glorotUniform'; + this.depthwiseKernel = null; + this.pointwiseKernel = null; + if (config.filters == null) { + throw new ValueError('The `filters` configuration field is required by SeparableConv, ' + + 'but is unspecified.'); + } + if (config.kernelInitializer != null || config.kernelRegularizer != null || + config.kernelConstraint != null) { + throw new ValueError('Fields kernelInitializer, kernelRegularizer and kernelConstraint ' + + 'are invalid for SeparableConv2D. Use depthwiseInitializer, ' + + 'depthwiseRegularizer, depthwiseConstraint, pointwiseInitializer, ' + + 'pointwiseRegularizer and pointwiseConstraint instead.'); + } + if (config.padding != null && config.padding !== 'same' && + config.padding !== 'valid') { + throw new ValueError(`SeparableConv${this.rank}D supports only padding modes: ` + + `'same' and 'valid', but received ${JSON.stringify(config.padding)}`); + } + this.depthMultiplier = + config.depthMultiplier == null ? 1 : config.depthMultiplier; + this.depthwiseInitializer = getInitializer(config.depthwiseInitializer || this.DEFAULT_DEPTHWISE_INITIALIZER); + this.depthwiseRegularizer = getRegularizer(config.depthwiseRegularizer); + this.depthwiseConstraint = getConstraint(config.depthwiseConstraint); + this.pointwiseInitializer = getInitializer(config.depthwiseInitializer || this.DEFAULT_POINTWISE_INITIALIZER); + this.pointwiseRegularizer = getRegularizer(config.pointwiseRegularizer); + this.pointwiseConstraint = getConstraint(config.pointwiseConstraint); + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + if (inputShape.length < this.rank + 2) { + throw new ValueError(`Inputs to SeparableConv${this.rank}D should have rank ` + + `${this.rank + 2}, but received input shape: ` + + `${JSON.stringify(inputShape)}`); + } + const channelAxis = this.dataFormat === 'channelsFirst' ? 1 : inputShape.length - 1; + if (inputShape[channelAxis] == null || inputShape[channelAxis] < 0) { + throw new ValueError(`The channel dimension of the inputs should be defined, ` + + `but found ${JSON.stringify(inputShape[channelAxis])}`); + } + const inputDim = inputShape[channelAxis]; + const depthwiseKernelShape = this.kernelSize.concat([inputDim, this.depthMultiplier]); + const pointwiseKernelShape = []; + for (let i = 0; i < this.rank; ++i) { + pointwiseKernelShape.push(1); + } + pointwiseKernelShape.push(inputDim * this.depthMultiplier, this.filters); + const trainable = true; + this.depthwiseKernel = this.addWeight('depthwise_kernel', depthwiseKernelShape, 'float32', this.depthwiseInitializer, this.depthwiseRegularizer, trainable, this.depthwiseConstraint); + this.pointwiseKernel = this.addWeight('pointwise_kernel', pointwiseKernelShape, 'float32', this.pointwiseInitializer, this.pointwiseRegularizer, trainable, this.pointwiseConstraint); + if (this.useBias) { + this.bias = this.addWeight('bias', [this.filters], 'float32', this.biasInitializer, this.biasRegularizer, trainable, this.biasConstraint); + } + else { + this.bias = null; + } + this.inputSpec = + [new InputSpec({ ndim: this.rank + 2, axes: { [channelAxis]: inputDim } })]; + this.built = true; + } + call(inputs, kwargs) { + return tidy(() => { + inputs = getExactlyOneTensor(inputs); + let output; + if (this.rank === 1) { + throw new NotImplementedError('1D separable convolution is not implemented yet.'); + } + else if (this.rank === 2) { + if (this.dataFormat === 'channelsFirst') { + inputs = transpose$2(inputs, [0, 2, 3, 1]); // NCHW -> NHWC. + } + output = separableConv2d$1(inputs, this.depthwiseKernel.read(), this.pointwiseKernel.read(), this.strides, this.padding, this.dilationRate, 'NHWC'); + } + if (this.useBias) { + output = biasAdd(output, this.bias.read(), this.dataFormat); + } + if (this.activation != null) { + output = this.activation.apply(output); + } + if (this.dataFormat === 'channelsFirst') { + output = transpose$2(output, [0, 3, 1, 2]); // NHWC -> NCHW. + } + return output; + }); + } + getConfig() { + const config = super.getConfig(); + delete config['rank']; + delete config['kernelInitializer']; + delete config['kernelRegularizer']; + delete config['kernelConstraint']; + config['depthwiseInitializer'] = + serializeInitializer(this.depthwiseInitializer); + config['pointwiseInitializer'] = + serializeInitializer(this.pointwiseInitializer); + config['depthwiseRegularizer'] = + serializeRegularizer(this.depthwiseRegularizer); + config['pointwiseRegularizer'] = + serializeRegularizer(this.pointwiseRegularizer); + config['depthwiseConstraint'] = + serializeConstraint(this.depthwiseConstraint); + config['pointwiseConstraint'] = + serializeConstraint(this.pointwiseConstraint); + return config; + } + } + /** @nocollapse */ + SeparableConv.className = 'SeparableConv'; + class SeparableConv2D extends SeparableConv { + constructor(args) { + super(2, args); + } + } + /** @nocollapse */ + SeparableConv2D.className = 'SeparableConv2D'; + registerClass(SeparableConv2D); + class Conv1D extends Conv { + constructor(args) { + super(1, args); + Conv1D.verifyArgs(args); + this.inputSpec = [{ ndim: 3 }]; + } + getConfig() { + const config = super.getConfig(); + delete config['rank']; + delete config['dataFormat']; + return config; + } + static verifyArgs(args) { + // config.kernelSize must be a number or array of numbers. + if (typeof args.kernelSize !== 'number' && + !checkArrayTypeAndLength(args.kernelSize, 'number', 1, 1)) { + throw new ValueError(`Conv1D expects config.kernelSize to be number or number[] with ` + + `length 1, but received ${JSON.stringify(args.kernelSize)}.`); + } + } + } + /** @nocollapse */ + Conv1D.className = 'Conv1D'; + registerClass(Conv1D); + class Cropping2D extends Layer { + constructor(args) { + super(args); + if (typeof args.cropping === 'number') { + this.cropping = + [[args.cropping, args.cropping], [args.cropping, args.cropping]]; + } + else if (typeof args.cropping[0] === 'number') { + this.cropping = [ + [args.cropping[0], args.cropping[0]], + [args.cropping[1], args.cropping[1]] + ]; + } + else { + this.cropping = args.cropping; + } + this.dataFormat = + args.dataFormat === undefined ? 'channelsLast' : args.dataFormat; + this.inputSpec = [{ ndim: 4 }]; + } + computeOutputShape(inputShape) { + if (this.dataFormat === 'channelsFirst') { + return [ + inputShape[0], inputShape[1], + inputShape[2] - this.cropping[0][0] - this.cropping[0][1], + inputShape[3] - this.cropping[1][0] - this.cropping[1][1] + ]; + } + else { + return [ + inputShape[0], + inputShape[1] - this.cropping[0][0] - this.cropping[0][1], + inputShape[2] - this.cropping[1][0] - this.cropping[1][1], inputShape[3] + ]; + } + } + call(inputs, kwargs) { + return tidy(() => { + inputs = getExactlyOneTensor(inputs); + if (this.dataFormat === 'channelsLast') { + const hSliced = sliceAlongAxis(inputs, this.cropping[0][0], inputs.shape[1] - this.cropping[0][0] - this.cropping[0][1], 2); + return sliceAlongAxis(hSliced, this.cropping[1][0], inputs.shape[2] - this.cropping[1][1] - this.cropping[1][0], 3); + } + else { + const hSliced = sliceAlongAxis(inputs, this.cropping[0][0], inputs.shape[2] - this.cropping[0][0] - this.cropping[0][1], 3); + return sliceAlongAxis(hSliced, this.cropping[1][0], inputs.shape[3] - this.cropping[1][1] - this.cropping[1][0], 4); + } + }); + } + getConfig() { + const config = { cropping: this.cropping, dataFormat: this.dataFormat }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Cropping2D.className = 'Cropping2D'; + registerClass(Cropping2D); + class UpSampling2D extends Layer { + constructor(args) { + super(args); + this.DEFAULT_SIZE = [2, 2]; + this.inputSpec = [{ ndim: 4 }]; + this.size = args.size == null ? this.DEFAULT_SIZE : args.size; + this.dataFormat = + args.dataFormat == null ? 'channelsLast' : args.dataFormat; + checkDataFormat(this.dataFormat); + this.interpolation = + args.interpolation == null ? 'nearest' : args.interpolation; + checkInterpolationFormat(this.interpolation); + } + computeOutputShape(inputShape) { + if (this.dataFormat === 'channelsFirst') { + const height = inputShape[2] == null ? null : this.size[0] * inputShape[2]; + const width = inputShape[3] == null ? null : this.size[1] * inputShape[3]; + return [inputShape[0], inputShape[1], height, width]; + } + else { + const height = inputShape[1] == null ? null : this.size[0] * inputShape[1]; + const width = inputShape[2] == null ? null : this.size[1] * inputShape[2]; + return [inputShape[0], height, width, inputShape[3]]; + } + } + call(inputs, kwargs) { + return tidy(() => { + let input = getExactlyOneTensor(inputs); + const inputShape = input.shape; + if (this.dataFormat === 'channelsFirst') { + input = transpose$2(input, [0, 2, 3, 1]); + const height = this.size[0] * inputShape[2]; + const width = this.size[1] * inputShape[3]; + const resized = this.interpolation === 'nearest' ? + image$1.resizeNearestNeighbor(input, [height, width]) : + image$1.resizeBilinear(input, [height, width]); + return transpose$2(resized, [0, 3, 1, 2]); + } + else { + const height = this.size[0] * inputShape[1]; + const width = this.size[1] * inputShape[2]; + return this.interpolation === 'nearest' ? + image$1.resizeNearestNeighbor(input, [height, width]) : + image$1.resizeBilinear(input, [height, width]); + } + }); + } + getConfig() { + const config = { + size: this.size, + dataFormat: this.dataFormat, + interpolation: this.interpolation + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + UpSampling2D.className = 'UpSampling2D'; + registerClass(UpSampling2D); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * 2D convolution with separable filters. + * @param x Input tensor. + * @param depthwiseKernel Convolution kernel for depthwise convolution. + * @param strides Strides (Array of two integers). + * @param padding Padding model. + * @param dataFormat Data format. + * @param dilationRate Array of two integers, dilation rates for the separable + * convolution. + * @returns Output tensor. + * @throws ValueError If depthwiseKernel is not a 4D array. + */ + function depthwiseConv2d$1(x, depthwiseKernel, strides = [1, 1], padding = 'valid', dataFormat, dilationRate) { + return tidy(() => { + if (dataFormat == null) { + dataFormat = imageDataFormat(); + } + checkDataFormat(dataFormat); + let y = preprocessConv2DInput(x, dataFormat); + if (x.rank !== 4) { + throw new ValueError(`Input for depthwiseConv2d is required to be 4-D, but is instead ` + + `${x.rank}-D`); + } + if (depthwiseKernel.rank !== 4) { + throw new ValueError(`depthwiseKernel is required to be 4-D, but is instead ` + + `${depthwiseKernel.rank}-D`); + } + y = depthwiseConv2d$3(y, depthwiseKernel, strides, padding === 'same' ? 'same' : 'valid', 'NHWC', dilationRate); + if (dataFormat === 'channelsFirst') { + y = transpose$2(y, [0, 3, 1, 2]); + } + return y; + }); + } + class DepthwiseConv2D extends BaseConv { + constructor(args) { + super(2, args); + this.depthwiseKernel = null; + this.depthMultiplier = + args.depthMultiplier == null ? 1 : args.depthMultiplier; + this.depthwiseInitializer = getInitializer(args.depthwiseInitializer || this.DEFAULT_KERNEL_INITIALIZER); + this.depthwiseConstraint = getConstraint(args.depthwiseConstraint); + this.depthwiseRegularizer = getRegularizer(args.depthwiseRegularizer); + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + if (inputShape.length < 4) { + throw new ValueError(`Inputs to DepthwiseConv2D should have rank 4. ` + + `Received input shape: ${JSON.stringify(inputShape)}.`); + } + const channelAxis = this.dataFormat === 'channelsFirst' ? 1 : 3; + if (inputShape[channelAxis] == null || inputShape[channelAxis] < 0) { + throw new ValueError('The channel dimension of the inputs to DepthwiseConv2D should ' + + `be defined, but is not (${inputShape[channelAxis]}).`); + } + const inputDim = inputShape[channelAxis]; + const depthwiseKernelShape = [ + this.kernelSize[0], this.kernelSize[1], inputDim, this.depthMultiplier + ]; + this.depthwiseKernel = this.addWeight('depthwise_kernel', depthwiseKernelShape, null, this.depthwiseInitializer, this.depthwiseRegularizer, true, this.depthwiseConstraint); + if (this.useBias) { + this.bias = this.addWeight('bias', [inputDim * this.depthMultiplier], null, this.biasInitializer, this.biasRegularizer, true, this.biasConstraint); + } + else { + this.bias = null; + } + this.built = true; + } + call(inputs, kwargs) { + return tidy(() => { + inputs = getExactlyOneTensor(inputs); + let outputs = depthwiseConv2d$1(inputs, this.depthwiseKernel.read(), this.strides, this.padding, this.dataFormat, null); + // TODO(cais): Add support for dilation. + if (this.useBias) { + outputs = biasAdd(outputs, this.bias.read(), this.dataFormat); + } + if (this.activation != null) { + outputs = this.activation.apply(outputs); + } + return outputs; + }); + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const rows = this.dataFormat === 'channelsFirst' ? inputShape[2] : inputShape[1]; + const cols = this.dataFormat === 'channelsFirst' ? inputShape[3] : inputShape[2]; + const outFilters = this.dataFormat === 'channelsFirst' ? + inputShape[1] * this.depthMultiplier : + inputShape[3] * this.depthMultiplier; + const outRows = convOutputLength(rows, this.kernelSize[0], this.padding, this.strides[0]); + const outCols = convOutputLength(cols, this.kernelSize[1], this.padding, this.strides[1]); + if (this.dataFormat === 'channelsFirst') { + return [inputShape[0], outFilters, outRows, outCols]; + } + else { + // In this case, assume 'channelsLast'. + return [inputShape[0], outRows, outCols, outFilters]; + } + } + getConfig() { + const config = super.getConfig(); + config['depthMultiplier'] = this.depthMultiplier; + config['depthwiseInitializer'] = + serializeInitializer(this.depthwiseInitializer); + config['depthwiseRegularizer'] = + serializeRegularizer(this.depthwiseRegularizer); + config['depthwiseConstraint'] = + serializeConstraint(this.depthwiseRegularizer); + return config; + } + } + /** @nocollapse */ + DepthwiseConv2D.className = 'DepthwiseConv2D'; + registerClass(DepthwiseConv2D); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Standardize `apply()` args to a single list of tensor inputs. + * + * When running a model loaded from file, the input tensors `initialState` and + * `constants` are passed to `RNN.apply()` as part of `inputs` instead of the + * dedicated kwargs fields. `inputs` consists of + * `[inputs, initialState0, initialState1, ..., constant0, constant1]` in this + * case. + * This method makes sure that arguments are + * separated and that `initialState` and `constants` are `Array`s of tensors + * (or None). + * + * @param inputs Tensor or `Array` of tensors. + * @param initialState Tensor or `Array` of tensors or `null`/`undefined`. + * @param constants Tensor or `Array` of tensors or `null`/`undefined`. + * @returns An object consisting of + * inputs: A tensor. + * initialState: `Array` of tensors or `null`. + * constants: `Array` of tensors or `null`. + * @throws ValueError, if `inputs` is an `Array` but either `initialState` or + * `constants` is provided. + */ + function standardizeArgs(inputs, initialState, constants, numConstants) { + if (Array.isArray(inputs)) { + if (initialState != null || constants != null) { + throw new ValueError('When inputs is an array, neither initialState or constants ' + + 'should be provided'); + } + if (numConstants != null) { + constants = inputs.slice(inputs.length - numConstants, inputs.length); + inputs = inputs.slice(0, inputs.length - numConstants); + } + if (inputs.length > 1) { + initialState = inputs.slice(1, inputs.length); + } + inputs = inputs[0]; + } + function toListOrNull(x) { + if (x == null || Array.isArray(x)) { + return x; + } + else { + return [x]; + } + } + initialState = toListOrNull(initialState); + constants = toListOrNull(constants); + return { inputs, initialState, constants }; + } + /** + * Iterates over the time dimension of a tensor. + * + * @param stepFunction RNN step function. + * Parameters: + * inputs: tensor with shape `[samples, ...]` (no time dimension), + * representing input for the batch of samples at a certain time step. + * states: an Array of tensors. + * Returns: + * outputs: tensor with shape `[samples, outputDim]` (no time dimension). + * newStates: list of tensors, same length and shapes as `states`. The first + * state in the list must be the output tensor at the previous timestep. + * @param inputs Tensor of temporal data of shape `[samples, time, ...]` (at + * least 3D). + * @param initialStates Tensor with shape `[samples, outputDim]` (no time + * dimension), containing the initial values of the states used in the step + * function. + * @param goBackwards If `true`, do the iteration over the time dimension in + * reverse order and return the reversed sequence. + * @param mask Binary tensor with shape `[sample, time, 1]`, with a zero for + * every element that is masked. + * @param constants An Array of constant values passed at each step. + * @param unroll Whether to unroll the RNN or to use a symbolic loop. *Not* + * applicable to this imperative deeplearn.js backend. Its value is ignored. + * @param needPerStepOutputs Whether the per-step outputs are to be + * concatenated into a single tensor and returned (as the second return + * value). Default: `false`. This arg is included so that the relatively + * expensive concatenation of the stepwise outputs can be omitted unless + * the stepwise outputs need to be kept (e.g., for an LSTM layer of which + * `returnSequence` is `true`.) + * @returns An Array: `[lastOutput, outputs, newStates]`. + * lastOutput: the lastest output of the RNN, of shape `[samples, ...]`. + * outputs: tensor with shape `[samples, time, ...]` where each entry + * `output[s, t]` is the output of the step function at time `t` for sample + * `s`. This return value is provided if and only if the + * `needPerStepOutputs` is set as `true`. If it is set as `false`, this + * return value will be `undefined`. + * newStates: Array of tensors, latest states returned by the step function, + * of shape `(samples, ...)`. + * @throws ValueError If input dimension is less than 3. + * + * TODO(nielsene): This needs to be tidy-ed. + */ + function rnn$1(stepFunction, inputs, initialStates, goBackwards = false, mask, constants, unroll = false, needPerStepOutputs = false) { + return tidy(() => { + const ndim = inputs.shape.length; + if (ndim < 3) { + throw new ValueError(`Input should be at least 3D, but is ${ndim}D.`); + } + // Transpose to time-major, i.e., from [batch, time, ...] to [time, batch, + // ...]. + const axes = [1, 0].concat(range$2(2, ndim)); + inputs = transpose$2(inputs, axes); + if (constants != null) { + throw new NotImplementedError('The rnn() functoin of the deeplearn.js backend does not support ' + + 'constants yet.'); + } + // Porting Note: the unroll option is ignored by the imperative backend. + if (unroll) { + console.warn('Backend rnn(): the unroll = true option is not applicable to the ' + + 'imperative deeplearn.js backend.'); + } + if (mask != null) { + mask = cast$3(cast$3(mask, 'bool'), 'float32'); + if (mask.rank === ndim - 1) { + mask = expandDims$3(mask, -1); + } + mask = transpose$2(mask, axes); + } + if (goBackwards) { + inputs = reverse$2(inputs, 0); + if (mask != null) { + mask = reverse$2(mask, 0); + } + } + // Porting Note: PyKeras with TensorFlow backend uses a symbolic loop + // (tf.while_loop). But for the imperative deeplearn.js backend, we just + // use the usual TypeScript control flow to iterate over the time steps in + // the inputs. + // Porting Note: PyKeras patches a "_use_learning_phase" attribute to + // outputs. + // This is not idiomatic in TypeScript. The info regarding whether we are + // in a learning (i.e., training) phase for RNN is passed in a different + // way. + const perStepOutputs = []; + let lastOutput; + let states = initialStates; + const timeSteps = inputs.shape[0]; + const perStepInputs = unstack(inputs); + let perStepMasks; + if (mask != null) { + perStepMasks = unstack(mask); + } + for (let t = 0; t < timeSteps; ++t) { + const currentInput = perStepInputs[t]; + const stepOutputs = tidy(() => stepFunction(currentInput, states)); + if (mask == null) { + lastOutput = stepOutputs[0]; + states = stepOutputs[1]; + } + else { + const maskedOutputs = tidy(() => { + const stepMask = perStepMasks[t]; + const negStepMask = sub$2(onesLike$3(stepMask), stepMask); + // TODO(cais): Would tfc.where() be better for performance? + const output = add$3(mul(stepOutputs[0], stepMask), mul(states[0], negStepMask)); + const newStates = states.map((state, i) => { + return add$3(mul(stepOutputs[1][i], stepMask), mul(state, negStepMask)); + }); + return { output, newStates }; + }); + lastOutput = maskedOutputs.output; + states = maskedOutputs.newStates; + } + if (needPerStepOutputs) { + perStepOutputs.push(lastOutput); + } + } + let outputs; + if (needPerStepOutputs) { + const axis = 1; + outputs = stack(perStepOutputs, axis); + } + return [lastOutput, outputs, states]; + }); + } + class RNN extends Layer { + constructor(args) { + super(args); + let cell; + if (args.cell == null) { + throw new ValueError('cell property is missing for the constructor of RNN.'); + } + else if (Array.isArray(args.cell)) { + cell = new StackedRNNCells({ cells: args.cell }); + } + else { + cell = args.cell; + } + if (cell.stateSize == null) { + throw new ValueError('The RNN cell should have an attribute `stateSize` (tuple of ' + + 'integers, one integer per RNN state).'); + } + this.cell = cell; + this.returnSequences = + args.returnSequences == null ? false : args.returnSequences; + this.returnState = args.returnState == null ? false : args.returnState; + this.goBackwards = args.goBackwards == null ? false : args.goBackwards; + this._stateful = args.stateful == null ? false : args.stateful; + this.unroll = args.unroll == null ? false : args.unroll; + this.supportsMasking = true; + this.inputSpec = [new InputSpec({ ndim: 3 })]; + this.stateSpec = null; + this.states_ = null; + // TODO(cais): Add constantsSpec and numConstants. + this.numConstants = null; + // TODO(cais): Look into the use of initial_state in the kwargs of the + // constructor. + this.keptStates = []; + } + // Porting Note: This is the equivalent of `RNN.states` property getter in + // PyKeras. + getStates() { + if (this.states_ == null) { + const numStates = Array.isArray(this.cell.stateSize) ? this.cell.stateSize.length : 1; + return range$2(0, numStates).map(x => null); + } + else { + return this.states_; + } + } + // Porting Note: This is the equivalent of the `RNN.states` property setter in + // PyKeras. + setStates(states) { + this.states_ = states; + } + computeOutputShape(inputShape) { + if (isArrayOfShapes(inputShape)) { + inputShape = inputShape[0]; + } + inputShape = inputShape; + // TODO(cais): Remove the casting once stacked RNN cells become supported. + let stateSize = this.cell.stateSize; + if (!Array.isArray(stateSize)) { + stateSize = [stateSize]; + } + const outputDim = stateSize[0]; + let outputShape; + if (this.returnSequences) { + outputShape = [inputShape[0], inputShape[1], outputDim]; + } + else { + outputShape = [inputShape[0], outputDim]; + } + if (this.returnState) { + const stateShape = []; + for (const dim of stateSize) { + stateShape.push([inputShape[0], dim]); + } + return [outputShape].concat(stateShape); + } + else { + return outputShape; + } + } + computeMask(inputs, mask) { + return tidy(() => { + if (Array.isArray(mask)) { + mask = mask[0]; + } + const outputMask = this.returnSequences ? mask : null; + if (this.returnState) { + const stateMask = this.states.map(s => null); + return [outputMask].concat(stateMask); + } + else { + return outputMask; + } + }); + } + /** + * Get the current state tensors of the RNN. + * + * If the state hasn't been set, return an array of `null`s of the correct + * length. + */ + get states() { + if (this.states_ == null) { + const numStates = Array.isArray(this.cell.stateSize) ? this.cell.stateSize.length : 1; + const output = []; + for (let i = 0; i < numStates; ++i) { + output.push(null); + } + return output; + } + else { + return this.states_; + } + } + set states(s) { + this.states_ = s; + } + build(inputShape) { + // Note inputShape will be an Array of Shapes of initial states and + // constants if these are passed in apply(). + const constantShape = null; + if (this.numConstants != null) { + throw new NotImplementedError('Constants support is not implemented in RNN yet.'); + } + if (isArrayOfShapes(inputShape)) { + inputShape = inputShape[0]; + } + inputShape = inputShape; + const batchSize = this.stateful ? inputShape[0] : null; + const inputDim = inputShape.slice(2); + this.inputSpec[0] = new InputSpec({ shape: [batchSize, null, ...inputDim] }); + // Allow cell (if RNNCell Layer) to build before we set or validate + // stateSpec. + const stepInputShape = [inputShape[0]].concat(inputShape.slice(2)); + if (constantShape != null) { + throw new NotImplementedError('Constants support is not implemented in RNN yet.'); + } + else { + this.cell.build(stepInputShape); + } + // Set or validate stateSpec. + let stateSize; + if (Array.isArray(this.cell.stateSize)) { + stateSize = this.cell.stateSize; + } + else { + stateSize = [this.cell.stateSize]; + } + if (this.stateSpec != null) { + if (!arraysEqual(this.stateSpec.map(spec => spec.shape[spec.shape.length - 1]), stateSize)) { + throw new ValueError(`An initialState was passed that is not compatible with ` + + `cell.stateSize. Received stateSpec=${this.stateSpec}; ` + + `However cell.stateSize is ${this.cell.stateSize}`); + } + } + else { + this.stateSpec = + stateSize.map(dim => new InputSpec({ shape: [null, dim] })); + } + if (this.stateful) { + this.resetStates(); + } + } + /** + * Reset the state tensors of the RNN. + * + * If the `states` argument is `undefined` or `null`, will set the + * state tensor(s) of the RNN to all-zero tensors of the appropriate + * shape(s). + * + * If `states` is provided, will set the state tensors of the RNN to its + * value. + * + * @param states Optional externally-provided initial states. + * @param training Whether this call is done during training. For stateful + * RNNs, this affects whether the old states are kept or discarded. In + * particular, if `training` is `true`, the old states will be kept so + * that subsequent backpropgataion through time (BPTT) may work properly. + * Else, the old states will be discarded. + */ + resetStates(states, training = false) { + tidy(() => { + if (!this.stateful) { + throw new AttributeError('Cannot call resetStates() on an RNN Layer that is not stateful.'); + } + const batchSize = this.inputSpec[0].shape[0]; + if (batchSize == null) { + throw new ValueError('If an RNN is stateful, it needs to know its batch size. Specify ' + + 'the batch size of your input tensors: \n' + + '- If using a Sequential model, specify the batch size by ' + + 'passing a `batchInputShape` option to your first layer.\n' + + '- If using the functional API, specify the batch size by ' + + 'passing a `batchShape` option to your Input layer.'); + } + // Initialize state if null. + if (this.states_ == null) { + if (Array.isArray(this.cell.stateSize)) { + this.states_ = + this.cell.stateSize.map(dim => zeros$2([batchSize, dim])); + } + else { + this.states_ = [zeros$2([batchSize, this.cell.stateSize])]; + } + } + else if (states == null) { + // Dispose old state tensors. + dispose(this.states_); + // For stateful RNNs, fully dispose kept old states. + if (this.keptStates != null) { + dispose(this.keptStates); + this.keptStates = []; + } + if (Array.isArray(this.cell.stateSize)) { + this.states_ = + this.cell.stateSize.map(dim => zeros$2([batchSize, dim])); + } + else { + this.states_[0] = zeros$2([batchSize, this.cell.stateSize]); + } + } + else { + if (!Array.isArray(states)) { + states = [states]; + } + if (states.length !== this.states_.length) { + throw new ValueError(`Layer ${this.name} expects ${this.states_.length} state(s), ` + + `but it received ${states.length} state value(s). Input ` + + `received: ${states}`); + } + if (training === true) { + // Store old state tensors for complete disposal later, i.e., during + // the next no-arg call to this method. We do not dispose the old + // states immediately because that BPTT (among other things) require + // them. + this.keptStates.push(this.states_.slice()); + } + else { + dispose(this.states_); + } + for (let index = 0; index < this.states_.length; ++index) { + const value = states[index]; + const dim = Array.isArray(this.cell.stateSize) ? + this.cell.stateSize[index] : + this.cell.stateSize; + const expectedShape = [batchSize, dim]; + if (!arraysEqual(value.shape, expectedShape)) { + throw new ValueError(`State ${index} is incompatible with layer ${this.name}: ` + + `expected shape=${expectedShape}, received shape=${value.shape}`); + } + this.states_[index] = value; + } + } + this.states_ = this.states_.map(state => keep(state.clone())); + }); + } + apply(inputs, kwargs) { + // TODO(cais): Figure out whether initialState is in kwargs or inputs. + let initialState = kwargs == null ? null : kwargs['initialState']; + let constants = kwargs == null ? null : kwargs['constants']; + if (kwargs == null) { + kwargs = {}; + } + const standardized = standardizeArgs(inputs, initialState, constants, this.numConstants); + inputs = standardized.inputs; + initialState = standardized.initialState; + constants = standardized.constants; + // If any of `initial_state` or `constants` are specified and are + // `tf.SymbolicTensor`s, then add them to the inputs and temporarily modify + // the input_spec to include them. + let additionalInputs = []; + let additionalSpecs = []; + if (initialState != null) { + kwargs['initialState'] = initialState; + additionalInputs = additionalInputs.concat(initialState); + this.stateSpec = []; + for (const state of initialState) { + this.stateSpec.push(new InputSpec({ shape: state.shape })); + } + // TODO(cais): Use the following instead. + // this.stateSpec = initialState.map(state => new InputSpec({shape: + // state.shape})); + additionalSpecs = additionalSpecs.concat(this.stateSpec); + } + if (constants != null) { + kwargs['constants'] = constants; + additionalInputs = additionalInputs.concat(constants); + // TODO(cais): Add this.constantsSpec. + this.numConstants = constants.length; + } + const isTensor = additionalInputs[0] instanceof SymbolicTensor; + if (isTensor) { + // Compute full input spec, including state and constants. + const fullInput = [inputs].concat(additionalInputs); + const fullInputSpec = this.inputSpec.concat(additionalSpecs); + // Perform the call with temporarily replaced inputSpec. + const originalInputSpec = this.inputSpec; + this.inputSpec = fullInputSpec; + const output = super.apply(fullInput, kwargs); + this.inputSpec = originalInputSpec; + return output; + } + else { + return super.apply(inputs, kwargs); + } + } + // tslint:disable-next-line:no-any + call(inputs, kwargs) { + // Input shape: `[samples, time (padded with zeros), input_dim]`. + // Note that the .build() method of subclasses **must** define + // this.inputSpec and this.stateSpec owith complete input shapes. + return tidy(() => { + const mask = kwargs == null ? null : kwargs['mask']; + const training = kwargs == null ? null : kwargs['training']; + let initialState = kwargs == null ? null : kwargs['initialState']; + inputs = getExactlyOneTensor(inputs); + if (initialState == null) { + if (this.stateful) { + initialState = this.states_; + } + else { + initialState = this.getInitialState(inputs); + } + } + const numStates = Array.isArray(this.cell.stateSize) ? this.cell.stateSize.length : 1; + if (initialState.length !== numStates) { + throw new ValueError(`RNN Layer has ${numStates} state(s) but was passed ` + + `${initialState.length} initial state(s).`); + } + if (this.unroll) { + console.warn('Ignoring unroll = true for RNN layer, due to imperative backend.'); + } + const cellCallKwargs = { training }; + // TODO(cais): Add support for constants. + const step = (inputs, states) => { + // `inputs` and `states` are concatenated to form a single `Array` of + // `tf.Tensor`s as the input to `cell.call()`. + const outputs = this.cell.call([inputs].concat(states), cellCallKwargs); + // Marshall the return value into output and new states. + return [outputs[0], outputs.slice(1)]; + }; + // TODO(cais): Add support for constants. + const rnnOutputs = rnn$1(step, inputs, initialState, this.goBackwards, mask, null, this.unroll, this.returnSequences); + const lastOutput = rnnOutputs[0]; + const outputs = rnnOutputs[1]; + const states = rnnOutputs[2]; + if (this.stateful) { + this.resetStates(states, training); + } + const output = this.returnSequences ? outputs : lastOutput; + // TODO(cais): Property set learning phase flag. + if (this.returnState) { + return [output].concat(states); + } + else { + return output; + } + }); + } + getInitialState(inputs) { + return tidy(() => { + // Build an all-zero tensor of shape [samples, outputDim]. + // [Samples, timeSteps, inputDim]. + let initialState = zeros$2(inputs.shape); + // [Samples]. + initialState = sum$3(initialState, [1, 2]); + initialState = expandDims$2(initialState); // [Samples, 1]. + if (Array.isArray(this.cell.stateSize)) { + return this.cell.stateSize.map(dim => dim > 1 ? tile$2(initialState, [1, dim]) : initialState); + } + else { + return this.cell.stateSize > 1 ? + [tile$2(initialState, [1, this.cell.stateSize])] : + [initialState]; + } + }); + } + get trainableWeights() { + if (!this.trainable) { + return []; + } + // Porting Note: In TypeScript, `this` is always an instance of `Layer`. + return this.cell.trainableWeights; + } + get nonTrainableWeights() { + // Porting Note: In TypeScript, `this` is always an instance of `Layer`. + if (!this.trainable) { + return this.cell.weights; + } + return this.cell.nonTrainableWeights; + } + setFastWeightInitDuringBuild(value) { + super.setFastWeightInitDuringBuild(value); + if (this.cell != null) { + this.cell.setFastWeightInitDuringBuild(value); + } + } + getConfig() { + const baseConfig = super.getConfig(); + const config = { + returnSequences: this.returnSequences, + returnState: this.returnState, + goBackwards: this.goBackwards, + stateful: this.stateful, + unroll: this.unroll, + }; + if (this.numConstants != null) { + config['numConstants'] = this.numConstants; + } + const cellConfig = this.cell.getConfig(); + if (this.getClassName() === RNN.className) { + config['cell'] = { + 'className': this.cell.getClassName(), + 'config': cellConfig, + }; + } + // this order is necessary, to prevent cell name from replacing layer name + return Object.assign(Object.assign(Object.assign({}, cellConfig), baseConfig), config); + } + /** @nocollapse */ + static fromConfig(cls, config, customObjects = {}) { + const cellConfig = config['cell']; + const cell = deserialize(cellConfig, customObjects); + return new cls(Object.assign(config, { cell })); + } + } + /** @nocollapse */ + RNN.className = 'RNN'; + registerClass(RNN); + // Porting Note: This is a common parent class for RNN cells. There is no + // equivalent of this in PyKeras. Having a common parent class forgoes the + // need for `has_attr(cell, ...)` checks or its TypeScript equivalent. + /** + * An RNNCell layer. + * + * @doc {heading: 'Layers', subheading: 'Classes'} + */ + class RNNCell extends Layer { + } + class SimpleRNNCell extends RNNCell { + constructor(args) { + super(args); + this.DEFAULT_ACTIVATION = 'tanh'; + this.DEFAULT_KERNEL_INITIALIZER = 'glorotNormal'; + this.DEFAULT_RECURRENT_INITIALIZER = 'orthogonal'; + this.DEFAULT_BIAS_INITIALIZER = 'zeros'; + this.units = args.units; + assertPositiveInteger(this.units, `units`); + this.activation = getActivation(args.activation == null ? this.DEFAULT_ACTIVATION : args.activation); + this.useBias = args.useBias == null ? true : args.useBias; + this.kernelInitializer = getInitializer(args.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER); + this.recurrentInitializer = getInitializer(args.recurrentInitializer || this.DEFAULT_RECURRENT_INITIALIZER); + this.biasInitializer = + getInitializer(args.biasInitializer || this.DEFAULT_BIAS_INITIALIZER); + this.kernelRegularizer = getRegularizer(args.kernelRegularizer); + this.recurrentRegularizer = getRegularizer(args.recurrentRegularizer); + this.biasRegularizer = getRegularizer(args.biasRegularizer); + this.kernelConstraint = getConstraint(args.kernelConstraint); + this.recurrentConstraint = getConstraint(args.recurrentConstraint); + this.biasConstraint = getConstraint(args.biasConstraint); + this.dropout = min$2([1, max$2([0, args.dropout == null ? 0 : args.dropout])]); + this.recurrentDropout = min$2([ + 1, + max$2([0, args.recurrentDropout == null ? 0 : args.recurrentDropout]) + ]); + this.dropoutFunc = args.dropoutFunc; + this.stateSize = this.units; + this.dropoutMask = null; + this.recurrentDropoutMask = null; + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + // TODO(cais): Use regularizer. + this.kernel = this.addWeight('kernel', [inputShape[inputShape.length - 1], this.units], null, this.kernelInitializer, this.kernelRegularizer, true, this.kernelConstraint); + this.recurrentKernel = this.addWeight('recurrent_kernel', [this.units, this.units], null, this.recurrentInitializer, this.recurrentRegularizer, true, this.recurrentConstraint); + if (this.useBias) { + this.bias = this.addWeight('bias', [this.units], null, this.biasInitializer, this.biasRegularizer, true, this.biasConstraint); + } + else { + this.bias = null; + } + this.built = true; + } + // Porting Note: PyKeras' equivalent of this method takes two tensor inputs: + // `inputs` and `states`. Here, the two tensors are combined into an + // `Tensor[]` Array as the first input argument. + // Similarly, PyKeras' equivalent of this method returns two values: + // `output` and `[output]`. Here the two are combined into one length-2 + // `Tensor[]`, consisting of `output` repeated. + call(inputs, kwargs) { + return tidy(() => { + inputs = inputs; + if (inputs.length !== 2) { + throw new ValueError(`SimpleRNNCell expects 2 input Tensors, got ${inputs.length}.`); + } + let prevOutput = inputs[1]; + inputs = inputs[0]; + const training = kwargs['training'] == null ? false : kwargs['training']; + if (0 < this.dropout && this.dropout < 1 && this.dropoutMask == null) { + this.dropoutMask = generateDropoutMask({ + ones: () => onesLike$3(inputs), + rate: this.dropout, + training, + dropoutFunc: this.dropoutFunc, + }); + } + if (0 < this.recurrentDropout && this.recurrentDropout < 1 && + this.recurrentDropoutMask == null) { + this.recurrentDropoutMask = generateDropoutMask({ + ones: () => onesLike$3(prevOutput), + rate: this.recurrentDropout, + training, + dropoutFunc: this.dropoutFunc, + }); + } + let h; + const dpMask = this.dropoutMask; + const recDpMask = this.recurrentDropoutMask; + if (dpMask != null) { + h = dot$1(mul(inputs, dpMask), this.kernel.read()); + } + else { + h = dot$1(inputs, this.kernel.read()); + } + if (this.bias != null) { + h = biasAdd(h, this.bias.read()); + } + if (recDpMask != null) { + prevOutput = mul(prevOutput, recDpMask); + } + let output = add$3(h, dot$1(prevOutput, this.recurrentKernel.read())); + if (this.activation != null) { + output = this.activation.apply(output); + } + // TODO(cais): Properly set learning phase on output tensor? + return [output, output]; + }); + } + getConfig() { + const baseConfig = super.getConfig(); + const config = { + units: this.units, + activation: serializeActivation(this.activation), + useBias: this.useBias, + kernelInitializer: serializeInitializer(this.kernelInitializer), + recurrentInitializer: serializeInitializer(this.recurrentInitializer), + biasInitializer: serializeInitializer(this.biasInitializer), + kernelRegularizer: serializeRegularizer(this.kernelRegularizer), + recurrentRegularizer: serializeRegularizer(this.recurrentRegularizer), + biasRegularizer: serializeRegularizer(this.biasRegularizer), + activityRegularizer: serializeRegularizer(this.activityRegularizer), + kernelConstraint: serializeConstraint(this.kernelConstraint), + recurrentConstraint: serializeConstraint(this.recurrentConstraint), + biasConstraint: serializeConstraint(this.biasConstraint), + dropout: this.dropout, + recurrentDropout: this.recurrentDropout, + }; + return Object.assign(Object.assign({}, baseConfig), config); + } + } + /** @nocollapse */ + SimpleRNNCell.className = 'SimpleRNNCell'; + registerClass(SimpleRNNCell); + class SimpleRNN extends RNN { + constructor(args) { + args.cell = new SimpleRNNCell(args); + super(args); + // TODO(cais): Add activityRegularizer. + } + call(inputs, kwargs) { + return tidy(() => { + if (this.cell.dropoutMask != null) { + dispose(this.cell.dropoutMask); + this.cell.dropoutMask = null; + } + if (this.cell.recurrentDropoutMask != null) { + dispose(this.cell.recurrentDropoutMask); + this.cell.recurrentDropoutMask = null; + } + const mask = kwargs == null ? null : kwargs['mask']; + const training = kwargs == null ? null : kwargs['training']; + const initialState = kwargs == null ? null : kwargs['initialState']; + return super.call(inputs, { mask, training, initialState }); + }); + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config); + } + } + /** @nocollapse */ + SimpleRNN.className = 'SimpleRNN'; + registerClass(SimpleRNN); + class GRUCell extends RNNCell { + constructor(args) { + super(args); + this.DEFAULT_ACTIVATION = 'tanh'; + this.DEFAULT_RECURRENT_ACTIVATION = 'hardSigmoid'; + this.DEFAULT_KERNEL_INITIALIZER = 'glorotNormal'; + this.DEFAULT_RECURRENT_INITIALIZER = 'orthogonal'; + this.DEFAULT_BIAS_INITIALIZER = 'zeros'; + if (args.resetAfter) { + throw new ValueError(`GRUCell does not support reset_after parameter set to true.`); + } + this.units = args.units; + assertPositiveInteger(this.units, 'units'); + this.activation = getActivation(args.activation === undefined ? this.DEFAULT_ACTIVATION : + args.activation); + this.recurrentActivation = getActivation(args.recurrentActivation === undefined ? + this.DEFAULT_RECURRENT_ACTIVATION : + args.recurrentActivation); + this.useBias = args.useBias == null ? true : args.useBias; + this.kernelInitializer = getInitializer(args.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER); + this.recurrentInitializer = getInitializer(args.recurrentInitializer || this.DEFAULT_RECURRENT_INITIALIZER); + this.biasInitializer = + getInitializer(args.biasInitializer || this.DEFAULT_BIAS_INITIALIZER); + this.kernelRegularizer = getRegularizer(args.kernelRegularizer); + this.recurrentRegularizer = getRegularizer(args.recurrentRegularizer); + this.biasRegularizer = getRegularizer(args.biasRegularizer); + this.kernelConstraint = getConstraint(args.kernelConstraint); + this.recurrentConstraint = getConstraint(args.recurrentConstraint); + this.biasConstraint = getConstraint(args.biasConstraint); + this.dropout = min$2([1, max$2([0, args.dropout == null ? 0 : args.dropout])]); + this.recurrentDropout = min$2([ + 1, + max$2([0, args.recurrentDropout == null ? 0 : args.recurrentDropout]) + ]); + this.dropoutFunc = args.dropoutFunc; + this.implementation = args.implementation; + this.stateSize = this.units; + this.dropoutMask = null; + this.recurrentDropoutMask = null; + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const inputDim = inputShape[inputShape.length - 1]; + this.kernel = this.addWeight('kernel', [inputDim, this.units * 3], null, this.kernelInitializer, this.kernelRegularizer, true, this.kernelConstraint); + this.recurrentKernel = this.addWeight('recurrent_kernel', [this.units, this.units * 3], null, this.recurrentInitializer, this.recurrentRegularizer, true, this.recurrentConstraint); + if (this.useBias) { + this.bias = this.addWeight('bias', [this.units * 3], null, this.biasInitializer, this.biasRegularizer, true, this.biasConstraint); + } + else { + this.bias = null; + } + // Porting Notes: Unlike the PyKeras implementation, we perform slicing + // of the weights and bias in the call() method, at execution time. + this.built = true; + } + call(inputs, kwargs) { + return tidy(() => { + inputs = inputs; + if (inputs.length !== 2) { + throw new ValueError(`GRUCell expects 2 input Tensors (inputs, h, c), got ` + + `${inputs.length}.`); + } + const training = kwargs['training'] == null ? false : kwargs['training']; + let hTMinus1 = inputs[1]; // Previous memory state. + inputs = inputs[0]; + // Note: For superior performance, TensorFlow.js always uses + // implementation 2, regardless of the actual value of + // config.implementation. + if (0 < this.dropout && this.dropout < 1 && this.dropoutMask == null) { + this.dropoutMask = generateDropoutMask({ + ones: () => onesLike$3(inputs), + rate: this.dropout, + training, + count: 3, + dropoutFunc: this.dropoutFunc, + }); + } + if (0 < this.recurrentDropout && this.recurrentDropout < 1 && + this.recurrentDropoutMask == null) { + this.recurrentDropoutMask = generateDropoutMask({ + ones: () => onesLike$3(hTMinus1), + rate: this.recurrentDropout, + training, + count: 3, + dropoutFunc: this.dropoutFunc, + }); + } + const dpMask = this.dropoutMask; + const recDpMask = this.recurrentDropoutMask; + let z; + let r; + let hh; + if (0 < this.dropout && this.dropout < 1) { + inputs = mul(inputs, dpMask[0]); + } + let matrixX = dot$1(inputs, this.kernel.read()); + if (this.useBias) { + matrixX = biasAdd(matrixX, this.bias.read()); + } + if (0 < this.recurrentDropout && this.recurrentDropout < 1) { + hTMinus1 = mul(hTMinus1, recDpMask[0]); + } + const recurrentKernelValue = this.recurrentKernel.read(); + const [rk1, rk2] = split$3(recurrentKernelValue, [2 * this.units, this.units], recurrentKernelValue.rank - 1); + const matrixInner = dot$1(hTMinus1, rk1); + const [xZ, xR, xH] = split$3(matrixX, 3, matrixX.rank - 1); + const [recurrentZ, recurrentR] = split$3(matrixInner, 2, matrixInner.rank - 1); + z = this.recurrentActivation.apply(add$3(xZ, recurrentZ)); + r = this.recurrentActivation.apply(add$3(xR, recurrentR)); + const recurrentH = dot$1(mul(r, hTMinus1), rk2); + hh = this.activation.apply(add$3(xH, recurrentH)); + const h = add$3(mul(z, hTMinus1), mul(add$3(1, neg$2(z)), hh)); + // TODO(cais): Add use_learning_phase flag properly. + return [h, h]; + }); + } + getConfig() { + const baseConfig = super.getConfig(); + const config = { + units: this.units, + activation: serializeActivation(this.activation), + recurrentActivation: serializeActivation(this.recurrentActivation), + useBias: this.useBias, + kernelInitializer: serializeInitializer(this.kernelInitializer), + recurrentInitializer: serializeInitializer(this.recurrentInitializer), + biasInitializer: serializeInitializer(this.biasInitializer), + kernelRegularizer: serializeRegularizer(this.kernelRegularizer), + recurrentRegularizer: serializeRegularizer(this.recurrentRegularizer), + biasRegularizer: serializeRegularizer(this.biasRegularizer), + activityRegularizer: serializeRegularizer(this.activityRegularizer), + kernelConstraint: serializeConstraint(this.kernelConstraint), + recurrentConstraint: serializeConstraint(this.recurrentConstraint), + biasConstraint: serializeConstraint(this.biasConstraint), + dropout: this.dropout, + recurrentDropout: this.recurrentDropout, + implementation: this.implementation, + resetAfter: false + }; + return Object.assign(Object.assign({}, baseConfig), config); + } + } + /** @nocollapse */ + GRUCell.className = 'GRUCell'; + registerClass(GRUCell); + class GRU extends RNN { + constructor(args) { + if (args.implementation === 0) { + console.warn('`implementation=0` has been deprecated, and now defaults to ' + + '`implementation=1`. Please update your layer call.'); + } + args.cell = new GRUCell(args); + super(args); + // TODO(cais): Add activityRegularizer. + } + call(inputs, kwargs) { + return tidy(() => { + if (this.cell.dropoutMask != null) { + dispose(this.cell.dropoutMask); + this.cell.dropoutMask = null; + } + if (this.cell.recurrentDropoutMask != null) { + dispose(this.cell.recurrentDropoutMask); + this.cell.recurrentDropoutMask = null; + } + const mask = kwargs == null ? null : kwargs['mask']; + const training = kwargs == null ? null : kwargs['training']; + const initialState = kwargs == null ? null : kwargs['initialState']; + return super.call(inputs, { mask, training, initialState }); + }); + } + /** @nocollapse */ + static fromConfig(cls, config) { + if (config['implmentation'] === 0) { + config['implementation'] = 1; + } + return new cls(config); + } + } + /** @nocollapse */ + GRU.className = 'GRU'; + registerClass(GRU); + class LSTMCell extends RNNCell { + constructor(args) { + super(args); + this.DEFAULT_ACTIVATION = 'tanh'; + this.DEFAULT_RECURRENT_ACTIVATION = 'hardSigmoid'; + this.DEFAULT_KERNEL_INITIALIZER = 'glorotNormal'; + this.DEFAULT_RECURRENT_INITIALIZER = 'orthogonal'; + this.DEFAULT_BIAS_INITIALIZER = 'zeros'; + this.units = args.units; + assertPositiveInteger(this.units, 'units'); + this.activation = getActivation(args.activation === undefined ? this.DEFAULT_ACTIVATION : + args.activation); + this.recurrentActivation = getActivation(args.recurrentActivation === undefined ? + this.DEFAULT_RECURRENT_ACTIVATION : + args.recurrentActivation); + this.useBias = args.useBias == null ? true : args.useBias; + this.kernelInitializer = getInitializer(args.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER); + this.recurrentInitializer = getInitializer(args.recurrentInitializer || this.DEFAULT_RECURRENT_INITIALIZER); + this.biasInitializer = + getInitializer(args.biasInitializer || this.DEFAULT_BIAS_INITIALIZER); + this.unitForgetBias = args.unitForgetBias; + this.kernelRegularizer = getRegularizer(args.kernelRegularizer); + this.recurrentRegularizer = getRegularizer(args.recurrentRegularizer); + this.biasRegularizer = getRegularizer(args.biasRegularizer); + this.kernelConstraint = getConstraint(args.kernelConstraint); + this.recurrentConstraint = getConstraint(args.recurrentConstraint); + this.biasConstraint = getConstraint(args.biasConstraint); + this.dropout = min$2([1, max$2([0, args.dropout == null ? 0 : args.dropout])]); + this.recurrentDropout = min$2([ + 1, + max$2([0, args.recurrentDropout == null ? 0 : args.recurrentDropout]) + ]); + this.dropoutFunc = args.dropoutFunc; + this.implementation = args.implementation; + this.stateSize = [this.units, this.units]; + this.dropoutMask = null; + this.recurrentDropoutMask = null; + } + build(inputShape) { + var _a; + inputShape = getExactlyOneShape(inputShape); + const inputDim = inputShape[inputShape.length - 1]; + this.kernel = this.addWeight('kernel', [inputDim, this.units * 4], null, this.kernelInitializer, this.kernelRegularizer, true, this.kernelConstraint); + this.recurrentKernel = this.addWeight('recurrent_kernel', [this.units, this.units * 4], null, this.recurrentInitializer, this.recurrentRegularizer, true, this.recurrentConstraint); + let biasInitializer; + if (this.useBias) { + if (this.unitForgetBias) { + const capturedBiasInit = this.biasInitializer; + const capturedUnits = this.units; + biasInitializer = new (_a = class CustomInit extends Initializer { + apply(shape, dtype) { + // TODO(cais): More informative variable names? + const bI = capturedBiasInit.apply([capturedUnits]); + const bF = (new Ones()).apply([capturedUnits]); + const bCAndH = capturedBiasInit.apply([capturedUnits * 2]); + return concatAlongFirstAxis(concatAlongFirstAxis(bI, bF), bCAndH); + } + }, + /** @nocollapse */ + _a.className = 'CustomInit', + _a)(); + } + else { + biasInitializer = this.biasInitializer; + } + this.bias = this.addWeight('bias', [this.units * 4], null, biasInitializer, this.biasRegularizer, true, this.biasConstraint); + } + else { + this.bias = null; + } + // Porting Notes: Unlike the PyKeras implementation, we perform slicing + // of the weights and bias in the call() method, at execution time. + this.built = true; + } + call(inputs, kwargs) { + return tidy(() => { + const training = kwargs['training'] == null ? false : kwargs['training']; + inputs = inputs; + if (inputs.length !== 3) { + throw new ValueError(`LSTMCell expects 3 input Tensors (inputs, h, c), got ` + + `${inputs.length}.`); + } + let hTMinus1 = inputs[1]; // Previous memory state. + const cTMinus1 = inputs[2]; // Previous carry state. + inputs = inputs[0]; + if (0 < this.dropout && this.dropout < 1 && this.dropoutMask == null) { + this.dropoutMask = generateDropoutMask({ + ones: () => onesLike$3(inputs), + rate: this.dropout, + training, + count: 4, + dropoutFunc: this.dropoutFunc + }); + } + if (0 < this.recurrentDropout && this.recurrentDropout < 1 && + this.recurrentDropoutMask == null) { + this.recurrentDropoutMask = generateDropoutMask({ + ones: () => onesLike$3(hTMinus1), + rate: this.recurrentDropout, + training, + count: 4, + dropoutFunc: this.dropoutFunc + }); + } + const dpMask = this.dropoutMask; + const recDpMask = this.recurrentDropoutMask; + // Note: For superior performance, TensorFlow.js always uses + // implementation 2 regardless of the actual value of + // config.implementation. + let i; + let f; + let c; + let o; + if (0 < this.dropout && this.dropout < 1) { + inputs = mul(inputs, dpMask[0]); + } + let z = dot$1(inputs, this.kernel.read()); + if (0 < this.recurrentDropout && this.recurrentDropout < 1) { + hTMinus1 = mul(hTMinus1, recDpMask[0]); + } + z = add$3(z, dot$1(hTMinus1, this.recurrentKernel.read())); + if (this.useBias) { + z = biasAdd(z, this.bias.read()); + } + const [z0, z1, z2, z3] = split$3(z, 4, z.rank - 1); + i = this.recurrentActivation.apply(z0); + f = this.recurrentActivation.apply(z1); + c = add$3(mul(f, cTMinus1), mul(i, this.activation.apply(z2))); + o = this.recurrentActivation.apply(z3); + const h = mul(o, this.activation.apply(c)); + // TODO(cais): Add use_learning_phase flag properly. + return [h, h, c]; + }); + } + getConfig() { + const baseConfig = super.getConfig(); + const config = { + units: this.units, + activation: serializeActivation(this.activation), + recurrentActivation: serializeActivation(this.recurrentActivation), + useBias: this.useBias, + kernelInitializer: serializeInitializer(this.kernelInitializer), + recurrentInitializer: serializeInitializer(this.recurrentInitializer), + biasInitializer: serializeInitializer(this.biasInitializer), + unitForgetBias: this.unitForgetBias, + kernelRegularizer: serializeRegularizer(this.kernelRegularizer), + recurrentRegularizer: serializeRegularizer(this.recurrentRegularizer), + biasRegularizer: serializeRegularizer(this.biasRegularizer), + activityRegularizer: serializeRegularizer(this.activityRegularizer), + kernelConstraint: serializeConstraint(this.kernelConstraint), + recurrentConstraint: serializeConstraint(this.recurrentConstraint), + biasConstraint: serializeConstraint(this.biasConstraint), + dropout: this.dropout, + recurrentDropout: this.recurrentDropout, + implementation: this.implementation, + }; + return Object.assign(Object.assign({}, baseConfig), config); + } + } + /** @nocollapse */ + LSTMCell.className = 'LSTMCell'; + registerClass(LSTMCell); + class LSTM extends RNN { + constructor(args) { + if (args.implementation === 0) { + console.warn('`implementation=0` has been deprecated, and now defaults to ' + + '`implementation=1`. Please update your layer call.'); + } + args.cell = new LSTMCell(args); + super(args); + // TODO(cais): Add activityRegularizer. + } + call(inputs, kwargs) { + return tidy(() => { + if (this.cell.dropoutMask != null) { + dispose(this.cell.dropoutMask); + this.cell.dropoutMask = null; + } + if (this.cell.recurrentDropoutMask != null) { + dispose(this.cell.recurrentDropoutMask); + this.cell.recurrentDropoutMask = null; + } + const mask = kwargs == null ? null : kwargs['mask']; + const training = kwargs == null ? null : kwargs['training']; + const initialState = kwargs == null ? null : kwargs['initialState']; + return super.call(inputs, { mask, training, initialState }); + }); + } + /** @nocollapse */ + static fromConfig(cls, config) { + if (config['implmentation'] === 0) { + config['implementation'] = 1; + } + return new cls(config); + } + } + /** @nocollapse */ + LSTM.className = 'LSTM'; + registerClass(LSTM); + class StackedRNNCells extends RNNCell { + constructor(args) { + super(args); + this.cells = args.cells; + } + get stateSize() { + // States are a flat list in reverse order of the cell stack. + // This allows preserving the requirement `stack.statesize[0] === + // outputDim`. E.g., states of a 2-layer LSTM would be `[h2, c2, h1, c1]`, + // assuming one LSTM has states `[h, c]`. + const stateSize = []; + for (const cell of this.cells.slice().reverse()) { + if (Array.isArray(cell.stateSize)) { + stateSize.push(...cell.stateSize); + } + else { + stateSize.push(cell.stateSize); + } + } + return stateSize; + } + call(inputs, kwargs) { + return tidy(() => { + inputs = inputs; + let states = inputs.slice(1); + // Recover per-cell states. + const nestedStates = []; + for (const cell of this.cells.slice().reverse()) { + if (Array.isArray(cell.stateSize)) { + nestedStates.push(states.splice(0, cell.stateSize.length)); + } + else { + nestedStates.push(states.splice(0, 1)); + } + } + nestedStates.reverse(); + // Call the cells in order and store the returned states. + const newNestedStates = []; + let callInputs; + for (let i = 0; i < this.cells.length; ++i) { + const cell = this.cells[i]; + states = nestedStates[i]; + // TODO(cais): Take care of constants. + if (i === 0) { + callInputs = [inputs[0]].concat(states); + } + else { + callInputs = [callInputs[0]].concat(states); + } + callInputs = cell.call(callInputs, kwargs); + newNestedStates.push(callInputs.slice(1)); + } + // Format the new states as a flat list in reverse cell order. + states = []; + for (const cellStates of newNestedStates.slice().reverse()) { + states.push(...cellStates); + } + return [callInputs[0]].concat(states); + }); + } + build(inputShape) { + if (isArrayOfShapes(inputShape)) { + // TODO(cais): Take care of input constants. + // const constantShape = inputShape.slice(1); + inputShape = inputShape[0]; + } + inputShape = inputShape; + let outputDim; + this.cells.forEach((cell, i) => { + nameScope(`RNNCell_${i}`, () => { + // TODO(cais): Take care of input constants. + cell.build(inputShape); + if (Array.isArray(cell.stateSize)) { + outputDim = cell.stateSize[0]; + } + else { + outputDim = cell.stateSize; + } + inputShape = [inputShape[0], outputDim]; + }); + }); + this.built = true; + } + getConfig() { + const baseConfig = super.getConfig(); + const getCellConfig = (cell) => { + return { + 'className': cell.getClassName(), + 'config': cell.getConfig(), + }; + }; + const cellConfigs = this.cells.map(getCellConfig); + const config = { 'cells': cellConfigs }; + return Object.assign(Object.assign({}, baseConfig), config); + } + /** @nocollapse */ + static fromConfig(cls, config, customObjects = {}) { + const cells = []; + for (const cellConfig of config['cells']) { + cells.push(deserialize(cellConfig, customObjects)); + } + return new cls({ cells }); + } + get trainableWeights() { + if (!this.trainable) { + return []; + } + const weights = []; + for (const cell of this.cells) { + weights.push(...cell.trainableWeights); + } + return weights; + } + get nonTrainableWeights() { + const weights = []; + for (const cell of this.cells) { + weights.push(...cell.nonTrainableWeights); + } + if (!this.trainable) { + const trainableWeights = []; + for (const cell of this.cells) { + trainableWeights.push(...cell.trainableWeights); + } + return trainableWeights.concat(weights); + } + return weights; + } + /** + * Retrieve the weights of a the model. + * + * @returns A flat `Array` of `tf.Tensor`s. + */ + getWeights() { + const weights = []; + for (const cell of this.cells) { + weights.push(...cell.weights); + } + return batchGetValue(weights); + } + /** + * Set the weights of the model. + * + * @param weights An `Array` of `tf.Tensor`s with shapes and types matching + * the output of `getWeights()`. + */ + setWeights(weights) { + const tuples = []; + for (const cell of this.cells) { + const numParams = cell.weights.length; + const inputWeights = weights.splice(numParams); + for (let i = 0; i < cell.weights.length; ++i) { + tuples.push([cell.weights[i], inputWeights[i]]); + } + } + batchSetValue(tuples); + } + } + /** @nocollapse */ + StackedRNNCells.className = 'StackedRNNCells'; + registerClass(StackedRNNCells); + function generateDropoutMask(args) { + const { ones, rate, training = false, count = 1, dropoutFunc } = args; + const droppedInputs = () => dropoutFunc != null ? dropoutFunc(ones(), rate) : dropout$1(ones(), rate); + const createMask = () => inTrainPhase(droppedInputs, ones, training); + // just in case count is provided with null or undefined + if (!count || count <= 1) { + return keep(createMask().clone()); + } + const masks = Array(count).fill(undefined).map(createMask); + return masks.map(m => keep(m.clone())); + } + + /** + * @license + * Copyright 2020 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + var __rest = (undefined && undefined.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + }; + class ConvRNN2DCell extends RNNCell { + } + /** + * Base class for convolutional-recurrent layers. + */ + class ConvRNN2D extends RNN { + constructor(args) { + if (args.unroll) { + throw new NotImplementedError('Unrolling is not possible with convolutional RNNs.'); + } + if (Array.isArray(args.cell)) { + throw new NotImplementedError('It is not possible at the moment to stack convolutional cells.'); + } + super(args); + this.inputSpec = [new InputSpec({ ndim: 5 })]; + } + call(inputs, kwargs) { + return tidy(() => { + if (this.cell.dropoutMask != null) { + dispose(this.cell.dropoutMask); + this.cell.dropoutMask = null; + } + if (this.cell.recurrentDropoutMask != null) { + dispose(this.cell.recurrentDropoutMask); + this.cell.recurrentDropoutMask = null; + } + if (kwargs && kwargs['constants']) { + throw new ValueError('ConvRNN2D cell does not support constants'); + } + const mask = kwargs == null ? null : kwargs['mask']; + const training = kwargs == null ? null : kwargs['training']; + const initialState = kwargs == null ? null : kwargs['initialState']; + return super.call(inputs, { mask, training, initialState }); + }); + } + computeOutputShape(inputShape) { + let outShape = this.computeSingleOutputShape(inputShape); + if (!this.returnSequences) { + outShape = [outShape[0], ...outShape.slice(2)]; + } + if (this.returnState) { + outShape = + [outShape, ...Array(2).fill([inputShape[0], ...outShape.slice(-3)])]; + } + return outShape; + } + getInitialState(inputs) { + return tidy(() => { + const { stateSize } = this.cell; + const inputShape = inputs.shape; + const outputShape = this.computeSingleOutputShape(inputShape); + const stateShape = [outputShape[0], ...outputShape.slice(2)]; + const initialState = zeros$2(stateShape); + if (Array.isArray(stateSize)) { + return Array(stateSize.length).fill(initialState); + } + return [initialState]; + }); + } + resetStates(states, training = false) { + tidy(() => { + if (!this.stateful) { + throw new AttributeError('Cannot call resetStates() on an RNN Layer that is not stateful.'); + } + const inputShape = this.inputSpec[0].shape; + const outputShape = this.computeSingleOutputShape(inputShape); + const stateShape = [outputShape[0], ...outputShape.slice(2)]; + const batchSize = inputShape[0]; + if (batchSize == null) { + throw new ValueError('If an RNN is stateful, it needs to know its batch size. Specify ' + + 'the batch size of your input tensors: \n' + + '- If using a Sequential model, specify the batch size by ' + + 'passing a `batchInputShape` option to your first layer.\n' + + '- If using the functional API, specify the batch size by ' + + 'passing a `batchShape` option to your Input layer.'); + } + // Initialize state if null. + if (this.getStates() == null) { + if (Array.isArray(this.cell.stateSize)) { + this.states_ = this.cell.stateSize.map(() => zeros$2(stateShape)); + } + else { + this.states_ = [zeros$2(stateShape)]; + } + } + else if (states == null) { + // Dispose old state tensors. + dispose(this.states_); + // For stateful RNNs, fully dispose kept old states. + if (this.keptStates != null) { + dispose(this.keptStates); + this.keptStates = []; + } + if (Array.isArray(this.cell.stateSize)) { + this.states_ = this.cell.stateSize.map(() => zeros$2(stateShape)); + } + else { + this.states_[0] = zeros$2(stateShape); + } + } + else { + if (!Array.isArray(states)) { + states = [states]; + } + if (states.length !== this.states_.length) { + throw new ValueError(`Layer ${this.name} expects ${this.states_.length} state(s), ` + + `but it received ${states.length} state value(s). Input ` + + `received: ${states}`); + } + if (training) { + // Store old state tensors for complete disposal later, i.e., during + // the next no-arg call to this method. We do not dispose the old + // states immediately because that BPTT (among other things) require + // them. + this.keptStates.push(this.states_.slice()); + } + else { + dispose(this.states_); + } + for (let index = 0; index < this.states_.length; ++index) { + const value = states[index]; + const expectedShape = stateShape; + if (!arraysEqual(value.shape, expectedShape)) { + throw new ValueError(`State ${index} is incompatible with layer ${this.name}: ` + + `expected shape=${expectedShape}, received shape=${value.shape}`); + } + this.states_[index] = value; + } + } + this.states_ = this.states_.map(state => keep(state.clone())); + }); + } + computeSingleOutputShape(inputShape) { + const { dataFormat, filters, kernelSize, padding, strides, dilationRate } = this.cell; + const isChannelsFirst = dataFormat === 'channelsFirst'; + const h = inputShape[isChannelsFirst ? 3 : 2]; + const w = inputShape[isChannelsFirst ? 4 : 3]; + const hOut = convOutputLength(h, kernelSize[0], padding, strides[0], dilationRate[0]); + const wOut = convOutputLength(w, kernelSize[1], padding, strides[1], dilationRate[1]); + const outShape = [ + ...inputShape.slice(0, 2), + ...(isChannelsFirst ? [filters, hOut, wOut] : [hOut, wOut, filters]) + ]; + return outShape; + } + } + /** @nocollapse */ + ConvRNN2D.className = 'ConvRNN2D'; + class ConvLSTM2DCell extends LSTMCell { + constructor(args) { + const { filters, kernelSize, strides, padding, dataFormat, dilationRate, } = args; + super(Object.assign(Object.assign({}, args), { units: filters })); + this.filters = filters; + assertPositiveInteger(this.filters, 'filters'); + this.kernelSize = normalizeArray(kernelSize, 2, 'kernelSize'); + this.kernelSize.forEach(size => assertPositiveInteger(size, 'kernelSize')); + this.strides = normalizeArray(strides || 1, 2, 'strides'); + this.strides.forEach(stride => assertPositiveInteger(stride, 'strides')); + this.padding = padding || 'valid'; + checkPaddingMode(this.padding); + this.dataFormat = dataFormat || 'channelsLast'; + checkDataFormat(this.dataFormat); + this.dilationRate = normalizeArray(dilationRate || 1, 2, 'dilationRate'); + this.dilationRate.forEach(rate => assertPositiveInteger(rate, 'dilationRate')); + } + build(inputShape) { + var _a; + inputShape = getExactlyOneShape(inputShape); + const channelAxis = this.dataFormat === 'channelsFirst' ? 1 : inputShape.length - 1; + if (inputShape[channelAxis] == null) { + throw new ValueError(`The channel dimension of the input should be defined. ` + + `Found ${inputShape[channelAxis]}`); + } + const inputDim = inputShape[channelAxis]; + const numOfKernels = 4; + const kernelShape = this.kernelSize.concat([inputDim, this.filters * numOfKernels]); + this.kernel = this.addWeight('kernel', kernelShape, null, this.kernelInitializer, this.kernelRegularizer, true, this.kernelConstraint); + const recurrentKernelShape = this.kernelSize.concat([this.filters, this.filters * numOfKernels]); + this.recurrentKernel = this.addWeight('recurrent_kernel', recurrentKernelShape, null, this.recurrentInitializer, this.recurrentRegularizer, true, this.recurrentConstraint); + if (this.useBias) { + let biasInitializer; + if (this.unitForgetBias) { + const init = this.biasInitializer; + const filters = this.filters; + biasInitializer = new (_a = class CustomInit extends Initializer { + apply(shape, dtype) { + const biasI = init.apply([filters]); + const biasF = ones$1([filters]); + const biasCAndO = init.apply([filters * 2]); + return concatenate$2([biasI, biasF, biasCAndO]); + } + }, + /** @nocollapse */ + _a.className = 'CustomInit', + _a)(); + } + else { + biasInitializer = this.biasInitializer; + } + this.bias = this.addWeight('bias', [this.filters * numOfKernels], null, biasInitializer, this.biasRegularizer, true, this.biasConstraint); + } + this.built = true; + } + call(inputs, kwargs) { + return tidy(() => { + if (inputs.length !== 3) { + throw new ValueError(`ConvLSTM2DCell expects 3 input Tensors (inputs, h, c), got ` + + `${inputs.length}.`); + } + const training = kwargs['training'] || false; + const x = inputs[0]; // Current input + const hTMinus1 = inputs[1]; // Previous memory state. + const cTMinus1 = inputs[2]; // Previous carry state. + const numOfKernels = 4; + if (0 < this.dropout && this.dropout < 1 && this.dropoutMask == null) { + this.dropoutMask = generateDropoutMask({ + ones: () => onesLike$3(x), + rate: this.dropout, + training, + count: numOfKernels, + dropoutFunc: this.dropoutFunc + }); + } + const dropoutMask = this.dropoutMask; + const applyDropout = (x, mask, index) => { + if (!mask || !mask[index]) { + return x; + } + return mul(mask[index], x); + }; + let xI = applyDropout(x, dropoutMask, 0); + let xF = applyDropout(x, dropoutMask, 1); + let xC = applyDropout(x, dropoutMask, 2); + let xO = applyDropout(x, dropoutMask, 3); + if (0 < this.recurrentDropout && this.recurrentDropout < 1 && + this.recurrentDropoutMask == null) { + this.recurrentDropoutMask = generateDropoutMask({ + ones: () => onesLike$3(hTMinus1), + rate: this.recurrentDropout, + training, + count: numOfKernels, + dropoutFunc: this.dropoutFunc + }); + } + const recDropoutMask = this.recurrentDropoutMask; + let hI = applyDropout(hTMinus1, recDropoutMask, 0); + let hF = applyDropout(hTMinus1, recDropoutMask, 1); + let hC = applyDropout(hTMinus1, recDropoutMask, 2); + let hO = applyDropout(hTMinus1, recDropoutMask, 3); + const kernelChannelAxis = 3; + const [kernelI, kernelF, kernelC, kernelO] = split$3(this.kernel.read(), numOfKernels, kernelChannelAxis); + const [biasI, biasF, biasC, biasO] = this.useBias ? + split$3(this.bias.read(), numOfKernels) : + [null, null, null, null]; + xI = this.inputConv(xI, kernelI, biasI, this.padding); + xF = this.inputConv(xF, kernelF, biasF, this.padding); + xC = this.inputConv(xC, kernelC, biasC, this.padding); + xO = this.inputConv(xO, kernelO, biasO, this.padding); + const [recKernelI, recKernelF, recKernelC, recKernelO] = split$3(this.recurrentKernel.read(), numOfKernels, kernelChannelAxis); + hI = this.recurrentConv(hI, recKernelI); + hF = this.recurrentConv(hF, recKernelF); + hC = this.recurrentConv(hC, recKernelC); + hO = this.recurrentConv(hO, recKernelO); + const i = this.recurrentActivation.apply(add$3(xI, hI)); + const f = this.recurrentActivation.apply(add$3(xF, hF)); + const c = add$3(mul(f, cTMinus1), mul(i, this.activation.apply(add$3(xC, hC)))); + const h = mul(this.recurrentActivation.apply(add$3(xO, hO)), this.activation.apply(c)); + return [h, h, c]; + }); + } + getConfig() { + const _a = super.getConfig(), { 'units': _ } = _a, baseConfig = __rest(_a, ['units']); + const config = { + filters: this.filters, + kernelSize: this.kernelSize, + padding: this.padding, + dataFormat: this.dataFormat, + dilationRate: this.dilationRate, + strides: this.strides, + }; + return Object.assign(Object.assign({}, baseConfig), config); + } + inputConv(x, w, b, padding) { + const out = conv2d$4(x, w, this.strides, (padding || 'valid'), this.dataFormat === 'channelsFirst' ? 'NCHW' : 'NHWC', this.dilationRate); + if (b) { + return biasAdd(out, b, this.dataFormat); + } + return out; + } + recurrentConv(x, w) { + const strides = 1; + return conv2d$4(x, w, strides, 'same', this.dataFormat === 'channelsFirst' ? 'NCHW' : 'NHWC'); + } + } + /** @nocollapse */ + ConvLSTM2DCell.className = 'ConvLSTM2DCell'; + registerClass(ConvLSTM2DCell); + class ConvLSTM2D extends ConvRNN2D { + constructor(args) { + const cell = new ConvLSTM2DCell(args); + super(Object.assign(Object.assign({}, args), { cell })); + } + /** @nocollapse */ + static fromConfig(cls, config) { + return new cls(config); + } + } + /** @nocollapse */ + ConvLSTM2D.className = 'ConvLSTM2D'; + registerClass(ConvLSTM2D); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + class Dropout extends Layer { + constructor(args) { + super(args); + this.rate = Math.max(Math.min(args.rate, 1), 0); + // So that the scalar doesn't get tidied up between executions. + this.noiseShape = args.noiseShape; + this.seed = args.seed; + this.supportsMasking = true; + } + getNoiseShape(input) { + if (this.noiseShape == null) { + return this.noiseShape; + } + const inputShape = input.shape; + const noiseShape = []; + for (let i = 0; i < this.noiseShape.length; ++i) { + noiseShape.push(this.noiseShape[i] == null ? inputShape[i] : this.noiseShape[i]); + } + return noiseShape; + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + const input = getExactlyOneTensor(inputs); + if (0 < this.rate && this.rate < 1) { + const training = kwargs['training'] == null ? false : kwargs['training']; + const noiseShape = this.getNoiseShape(input); + const output = inTrainPhase(() => dropout$1(input, this.rate, noiseShape, this.seed), () => input, training); + return output; + } + return inputs; + }); + } + getConfig() { + const config = { + rate: this.rate, + noiseShape: this.noiseShape, + seed: this.seed, + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + dispose() { + return super.dispose(); + } + } + /** @nocollapse */ + Dropout.className = 'Dropout'; + registerClass(Dropout); + class SpatialDropout1D extends Dropout { + constructor(args) { + super(args); + this.inputSpec = [{ ndim: 3 }]; + } + getNoiseShape(input) { + const inputShape = input.shape; + return [inputShape[0], 1, inputShape[2]]; + } + } + /** @nocollapse */ + SpatialDropout1D.className = 'SpatialDropout1D'; + registerClass(SpatialDropout1D); + class Dense extends Layer { + constructor(args) { + super(args); + // Default activation: Linear (none). + this.activation = null; + this.useBias = true; + this.kernel = null; + this.bias = null; + this.DEFAULT_KERNEL_INITIALIZER = 'glorotNormal'; + this.DEFAULT_BIAS_INITIALIZER = 'zeros'; + if (args.batchInputShape == null && args.inputShape == null && + args.inputDim != null) { + // This logic is copied from Layer's constructor, since we can't + // do exactly what the Python constructor does for Dense(). + let batchSize = null; + if (args.batchSize != null) { + batchSize = args.batchSize; + } + this.batchInputShape = [batchSize, args.inputDim]; + } + this.units = args.units; + assertPositiveInteger(this.units, 'units'); + this.activation = getActivation(args.activation); + if (args.useBias != null) { + this.useBias = args.useBias; + } + this.kernelInitializer = getInitializer(args.kernelInitializer || this.DEFAULT_KERNEL_INITIALIZER); + this.biasInitializer = + getInitializer(args.biasInitializer || this.DEFAULT_BIAS_INITIALIZER); + this.kernelConstraint = getConstraint(args.kernelConstraint); + this.biasConstraint = getConstraint(args.biasConstraint); + this.kernelRegularizer = getRegularizer(args.kernelRegularizer); + this.biasRegularizer = getRegularizer(args.biasRegularizer); + this.activityRegularizer = getRegularizer(args.activityRegularizer); + this.supportsMasking = true; + this.inputSpec = [{ minNDim: 2 }]; + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const inputLastDim = inputShape[inputShape.length - 1]; + if (this.kernel == null) { + this.kernel = this.addWeight('kernel', [inputLastDim, this.units], null, this.kernelInitializer, this.kernelRegularizer, true, this.kernelConstraint); + if (this.useBias) { + this.bias = this.addWeight('bias', [this.units], null, this.biasInitializer, this.biasRegularizer, true, this.biasConstraint); + } + } + this.inputSpec = [{ minNDim: 2, axes: { [-1]: inputLastDim } }]; + this.built = true; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const outputShape = inputShape.slice(); + outputShape[outputShape.length - 1] = this.units; + return outputShape; + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + // Dense layer accepts only a single input. + const input = getExactlyOneTensor(inputs); + const fusedActivationName = mapActivationToFusedKernel(this.activation.getClassName()); + let output; + if (fusedActivationName != null) { + output = dot$1(input, this.kernel.read(), fusedActivationName, this.bias ? this.bias.read() : null); + } + else { + output = dot$1(input, this.kernel.read()); + if (this.bias != null) { + output = biasAdd(output, this.bias.read()); + } + if (this.activation != null) { + output = this.activation.apply(output); + } + } + return output; + }); + } + getConfig() { + const config = { + units: this.units, + activation: serializeActivation(this.activation), + useBias: this.useBias, + kernelInitializer: serializeInitializer(this.kernelInitializer), + biasInitializer: serializeInitializer(this.biasInitializer), + kernelRegularizer: serializeRegularizer(this.kernelRegularizer), + biasRegularizer: serializeRegularizer(this.biasRegularizer), + activityRegularizer: serializeRegularizer(this.activityRegularizer), + kernelConstraint: serializeConstraint(this.kernelConstraint), + biasConstraint: serializeConstraint(this.biasConstraint) + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Dense.className = 'Dense'; + registerClass(Dense); + class Flatten extends Layer { + constructor(args) { + args = args || {}; + super(args); + this.inputSpec = [{ minNDim: 3 }]; + this.dataFormat = args.dataFormat; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + for (const dim of inputShape.slice(1)) { + if (dim == null) { + throw new ValueError(`The shape of the input to "Flatten" is not fully defined ` + + `(got ${inputShape.slice(1)}). Make sure to pass a complete ` + + `"input_shape" or "batch_input_shape" argument to the first ` + + `layer in your model.`); + } + } + return [inputShape[0], arrayProd(inputShape, 1)]; + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + let input = getExactlyOneTensor(inputs); + if (this.dataFormat === 'channelsFirst' && input.rank > 1) { + const permutation = [0]; + for (let i = 2; i < input.rank; ++i) { + permutation.push(i); + } + permutation.push(1); + input = transpose$2(input, permutation); + } + return batchFlatten(input); + }); + } + getConfig() { + const config = {}; + if (this.dataFormat != null) { + config['dataFormat'] = this.dataFormat; + } + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Flatten.className = 'Flatten'; + registerClass(Flatten); + class Activation extends Layer { + constructor(args) { + super(args); + this.supportsMasking = true; + this.activation = getActivation(args.activation); + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + const input = getExactlyOneTensor(inputs); + return this.activation.apply(input); + }); + } + getConfig() { + const config = { activation: serializeActivation(this.activation) }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Activation.className = 'Activation'; + registerClass(Activation); + class RepeatVector extends Layer { + constructor(args) { + super(args); + this.n = args.n; + this.inputSpec = [{ ndim: 2 }]; + } + computeOutputShape(inputShape) { + return [inputShape[0], this.n, inputShape[1]]; + } + call(inputs, kwargs) { + return tidy(() => { + inputs = getExactlyOneTensor(inputs); + return repeat(inputs, this.n); + }); + } + getConfig() { + const config = { + n: this.n, + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + RepeatVector.className = 'RepeatVector'; + registerClass(RepeatVector); + class Reshape extends Layer { + constructor(args) { + super(args); + this.targetShape = args.targetShape; + // Make sure that all unknown dimensions are represented as `null`. + for (let i = 0; i < this.targetShape.length; ++i) { + if (this.isUnknown(this.targetShape[i])) { + this.targetShape[i] = null; + } + } + } + isUnknown(dim) { + return dim < 0 || dim == null; + } + /** + * Finds and replaces a missing dimension in output shape. + * + * This is a near direct port of the internal Numpy function + * `_fix_unknown_dimension` in `numpy/core/src/multiarray/shape.c`. + * + * @param inputShape: Original shape of array begin reshape. + * @param outputShape: Target shape of the array, with at most a single + * `null` or negative number, which indicates an underdetermined dimension + * that should be derived from `inputShape` and the known dimensions of + * `outputShape`. + * @returns: The output shape with `null` replaced with its computed value. + * @throws: ValueError: If `inputShape` and `outputShape` do not match. + */ + fixUnknownDimension(inputShape, outputShape) { + const errorMsg = 'Total size of new array must be unchanged.'; + const finalShape = outputShape.slice(); + let known = 1; + let unknown = null; + for (let i = 0; i < finalShape.length; ++i) { + const dim = finalShape[i]; + if (this.isUnknown(dim)) { + if (unknown === null) { + unknown = i; + } + else { + throw new ValueError('Can only specifiy one unknown dimension.'); + } + } + else { + known *= dim; + } + } + const originalSize = arrayProd(inputShape); + if (unknown !== null) { + if (known === 0 || originalSize % known !== 0) { + throw new ValueError(errorMsg); + } + finalShape[unknown] = originalSize / known; + } + else if (originalSize !== known) { + throw new ValueError(errorMsg); + } + return finalShape; + } + computeOutputShape(inputShape) { + let anyUnknownDims = false; + for (let i = 0; i < inputShape.length; ++i) { + if (this.isUnknown(inputShape[i])) { + anyUnknownDims = true; + break; + } + } + if (anyUnknownDims) { + return inputShape.slice(0, 1).concat(this.targetShape); + } + else { + return inputShape.slice(0, 1).concat(this.fixUnknownDimension(inputShape.slice(1), this.targetShape)); + } + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + const input = getExactlyOneTensor(inputs); + const inputShape = input.shape; + const outputShape = inputShape.slice(0, 1).concat(this.fixUnknownDimension(inputShape.slice(1), this.targetShape)); + return reshape$3(input, outputShape); + }); + } + getConfig() { + const config = { + targetShape: this.targetShape, + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Reshape.className = 'Reshape'; + registerClass(Reshape); + class Permute extends Layer { + constructor(args) { + super(args); + if (args.dims == null) { + throw new Error('Required configuration field `dims` is missing during Permute ' + + 'constructor call.'); + } + if (!Array.isArray(args.dims)) { + throw new Error('Permute constructor requires `dims` to be an Array, but received ' + + `${args.dims} instead.`); + } + // Check the validity of the permutation indices. + const expectedSortedIndices = range$2(1, args.dims.length + 1); + if (!arraysEqual(args.dims.slice().sort(), expectedSortedIndices)) { + throw new Error('Invalid permutation `dims`: ' + JSON.stringify(args.dims) + + ' `dims` must contain consecutive integers starting from 1.'); + } + this.dims = args.dims; + this.dimsIncludingBatch = [0].concat(this.dims); + this.inputSpec = [new InputSpec({ ndim: this.dims.length + 1 })]; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const outputShape = inputShape.slice(); + this.dims.forEach((dim, i) => { + outputShape[i + 1] = inputShape[dim]; + }); + return outputShape; + } + call(inputs, kwargs) { + return transpose$2(getExactlyOneTensor(inputs), this.dimsIncludingBatch); + } + getConfig() { + const config = { + dims: this.dims, + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Permute.className = 'Permute'; + registerClass(Permute); + class Masking extends Layer { + constructor(args) { + super(args == null ? {} : args); + this.supportsMasking = true; + if (args != null) { + this.maskValue = args.maskValue == null ? 0 : args.maskValue; + } + else { + this.maskValue = 0; + } + } + computeOutputShape(inputShape) { + return inputShape; + } + getConfig() { + const baseConfig = super.getConfig(); + const config = { maskValue: this.maskValue }; + Object.assign(config, baseConfig); + return config; + } + computeMask(inputs, mask) { + const input = getExactlyOneTensor(inputs); + const axis = -1; + return any$2(notEqual$2(input, this.maskValue), axis); + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + const input = getExactlyOneTensor(inputs); + const axis = -1; + const keepDims = true; + const booleanMask = any$2(notEqual$2(input, this.maskValue), axis, keepDims); + const output = mul(input, cast$3(booleanMask, input.dtype)); + return output; + }); + } + } + /** @nocollapse */ + Masking.className = 'Masking'; + registerClass(Masking); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + class Embedding extends Layer { + constructor(args) { + super(args); + this.embeddings = null; + this.DEFAULT_EMBEDDINGS_INITIALIZER = 'randomUniform'; + if (args.batchInputShape == null && args.inputShape == null) { + // Porting Note: This logic is copied from Layer's constructor, since we + // can't do exactly what the Python constructor does for Embedding(). + // Specifically, the super constructor can not be called after the + // mutation of the `config` argument. + let batchSize = null; + if (args.batchSize != null) { + batchSize = args.batchSize; + } + if (args.inputLength == null) { + // Fix super-constructor to what it would have done if + // 'config.inputShape' were (None, ) + this.batchInputShape = [batchSize, null]; + } + else { + // Fix super-constructor to what it would have done if + // 'config.inputShape' were (config.inputLength, ) + this.batchInputShape = + [batchSize].concat(toList(args.inputLength)); + } + } + this.inputDim = args.inputDim; + assertPositiveInteger(this.inputDim, 'inputDim'); + this.outputDim = args.outputDim; + assertPositiveInteger(this.outputDim, 'outputDim'); + this.embeddingsInitializer = getInitializer(args.embeddingsInitializer || this.DEFAULT_EMBEDDINGS_INITIALIZER); + this.embeddingsRegularizer = getRegularizer(args.embeddingsRegularizer); + this.activityRegularizer = getRegularizer(args.activityRegularizer); + this.embeddingsConstraint = getConstraint(args.embeddingsConstraint); + this.maskZero = args.maskZero; + this.supportsMasking = args.maskZero; + this.inputLength = args.inputLength; + } + build(inputShape) { + this.embeddings = this.addWeight('embeddings', [this.inputDim, this.outputDim], this.dtype, this.embeddingsInitializer, this.embeddingsRegularizer, true, this.embeddingsConstraint); + this.built = true; + } + // Override warnOnIncompatibleInputShape because an embedding layer allows + // the input to have varying ranks. + warnOnIncompatibleInputShape(inputShape) { } + computeMask(inputs, mask) { + return tidy(() => { + if (!this.maskZero) { + return null; + } + else { + inputs = getExactlyOneTensor(inputs); + return notEqual$2(inputs, zerosLike$3(inputs)); + } + }); + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + if (this.inputLength == null) { + return [...inputShape, this.outputDim]; + } + // inputLength can be an array if input is 3D or higher. + const inLens = toList(this.inputLength); + if (inLens.length !== inputShape.length - 1) { + throw new ValueError(`"inputLength" is ${this.inputLength}, but received ` + + `input shape has shape ${inputShape}`); + } + else { + let i = 0; + for (let k = 0; k < inLens.length; ++k) { + const s1 = inLens[k]; + const s2 = inputShape[k + 1]; + if ((s1 != null) && (s2 != null) && (s1 !== s2)) { + throw new ValueError(`"inputLength" is ${this.inputLength}, but received ` + + `input shape has shape ${inputShape}`); + } + else if (s1 == null) { + inLens[i] = s2; + } + i++; + } + } + return [inputShape[0], ...inLens, this.outputDim]; + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + // Embedding layer accepts only a single input. + let input = getExactlyOneTensor(inputs); + if (input.dtype !== 'int32') { + input = cast$2(input, 'int32'); + } + const output = gather(this.embeddings.read(), reshape$3(input, [input.size])); + return reshape$3(output, getExactlyOneShape(this.computeOutputShape(input.shape))); + }); + } + getConfig() { + const config = { + inputDim: this.inputDim, + outputDim: this.outputDim, + embeddingsInitializer: serializeInitializer(this.embeddingsInitializer), + embeddingsRegularizer: serializeRegularizer(this.embeddingsRegularizer), + activityRegularizer: serializeRegularizer(this.activityRegularizer), + embeddingsConstraint: serializeConstraint(this.embeddingsConstraint), + maskZero: this.maskZero, + inputLength: this.inputLength + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Embedding.className = 'Embedding'; + registerClass(Embedding); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Generic Merge layer for element-wise merge functions. + * + * Used to implement `Sum`, `Average`, `Concatenate`, etc. + */ + class Merge extends Layer { + constructor(args) { + super(args || {}); + this.supportsMasking = true; + } + /** + * Logic for merging multiple tensors, to be overridden by subclasses. + * @param inputs + */ + mergeFunction(inputs) { + throw new NotImplementedError(); + } + /** + * Computes the shape of the result of an elementwise operation. + * + * @param shape1: Shape of the first tensor. + * @param shape2: Shape of the second tensor. + * @returns Expected output shape when an elementwise operation is carried + * out on 2 tensors with shapes `shape1` and `shape2`. + * @throws ValueError: If `shape1` and `shape2` are not compatible for + * element-wise operations. + */ + computeElementwiseOpOutputShape(shape1, shape2) { + if (shape1 == null || shape2 == null) { + return null; + } + else if (shape1.length < shape2.length) { + return this.computeElementwiseOpOutputShape(shape2, shape1); + } + else if (shape2.length === 0) { + return shape1; + } + const outputShape = shape1.slice(0, shape1.length - shape2.length); + for (let k = 0; k < shape2.length; ++k) { + const i = shape1[shape1.length - shape2.length + k]; + const j = shape2[k]; + if (i == null || j == null || i < 0 || j < 0) { + outputShape.push(null); + } + else if (i === 1) { + outputShape.push(j); + } + else if (j === 1) { + outputShape.push(i); + } + else { + if (i !== j) { + throw new ValueError('Operands could not be broadcast together with shapes ' + + JSON.stringify(shape1) + ' ' + JSON.stringify(shape2)); + } + outputShape.push(i); + } + } + return outputShape; + } + build(inputShape) { + // Used purely for shape validation. + if (Array.isArray(inputShape) && !Array.isArray(inputShape[0])) { + // Make sure that inputShape is an Array of shape. + inputShape = [getExactlyOneShape(inputShape)]; + } + inputShape = inputShape; + if (inputShape.length < 2) { + throw new ValueError('A merge layer should be called on an Array of at least 2 inputs.' + + ` Got ${inputShape.length} input(s).`); + } + // Make sure that there is at most one unique batch size among the input + // shapes. + let batchSizes = []; + for (const shape of inputShape) { + if (shape != null && shape[0] !== null) { + batchSizes.push(shape[0]); + } + } + batchSizes = unique$2(batchSizes); + if (batchSizes.length > 1) { + throw new ValueError(`Can not merge tensors with different batch sizes. ` + + `Got tensors with shapes: ${JSON.stringify(inputShape)}.`); + } + let outputShape = inputShape[0] == null ? null : inputShape[0].slice(1); + for (let i = 1; i < inputShape.length; ++i) { + const shape = inputShape[i] == null ? null : inputShape[i].slice(1); + outputShape = this.computeElementwiseOpOutputShape(outputShape, shape); + } + // If the inputs have different ranks, we have to reshape them to make them + // broadcastable. + const allRanks = inputShape.map(shape => shape.length); + if (inputShape.indexOf(null) === -1 && + unique$2(allRanks).length === 1) { + this.reshapeRequired = false; + } + else { + this.reshapeRequired = true; + } + } + call(inputs, kwargs) { + return tidy(() => { + inputs = inputs; + if (this.reshapeRequired) { + const reshapedInputs = []; + const inputDims = inputs.map(input => input.rank); + if (inputDims.indexOf(null) === -1) { + // If ranks of all inputs are available, we simply expand each of them + // at axis=1 until all of them have the same rank. + const maxNDim = max$2(inputDims); + for (let x of inputs) { + const xNDim = x.rank; + for (let k = 0; k < maxNDim - xNDim; ++k) { + x = expandDims$2(x, 1); + } + reshapedInputs.push(x); + } + return this.mergeFunction(reshapedInputs); + } + else { + // Transpose all inputs so that batch size is the last dimension. + // [batchSize, dim1, dim2, ...] -> [dim1, dim2, ..., batchSize] + let transposed = false; + for (const x of inputs) { + const xNDim = x.rank; + if (xNDim == null) { + const xShape = x.shape; + const batchSize = xShape[0]; + const newShape = xShape.slice(1).concat([batchSize]); + let xTransposed = reshape$3(x, [batchSize].concat(arrayProd(xShape.slice(1)))); + xTransposed = transpose$2(xTransposed, [1, 0]); + xTransposed = reshape$3(xTransposed, newShape); + reshapedInputs.push(xTransposed); + transposed = true; + } + else if (xNDim > 1) { + const dims = range$2(1, xNDim).concat([0]); + reshapedInputs.push(transpose$2(x, dims)); + transposed = true; + } + else { + // We don't transpose inputs if they are 1D vectors or scalars. + reshapedInputs.push(x); + } + } + let y = this.mergeFunction(reshapedInputs); + const yNDim = y.rank; + if (transposed) { + // If inputs have been transposed, we have to transpose the output + // too. + if (yNDim == null) { + const yShape = y.shape; + const yNDim = yShape.length; + const batchSize = yShape[yNDim - 1]; + const newShape = [batchSize].concat(yShape.slice(0, yShape.length - 1)); + y = reshape$3(transpose$2(reshape$3(y, [-1, batchSize]), [1, 0]), newShape); + } + else if (yNDim > 1) { + const dims = [yNDim - 1].concat(range$2(0, yNDim - 1)); + y = transpose$2(y, dims); + } + } + return y; + } + } + else { + return this.mergeFunction(inputs); + } + }); + } + computeOutputShape(inputShape) { + inputShape = inputShape; + let outputShape; + if (inputShape[0] == null) { + outputShape = null; + } + else { + outputShape = inputShape[0].slice(1); + } + for (let i = 1; i < inputShape.length; ++i) { + const shape = inputShape[i] == null ? null : inputShape[i].slice(1); + outputShape = this.computeElementwiseOpOutputShape(outputShape, shape); + } + let batchSizes = []; + for (const shape of inputShape) { + if (shape != null && shape[0] !== null) { + batchSizes.push(shape[0]); + } + } + batchSizes = unique$2(batchSizes); + if (batchSizes.length === 1) { + outputShape = batchSizes.concat(outputShape); + } + else { + outputShape = [null].concat(outputShape); + } + return outputShape; + } + computeMask(inputs, mask) { + return tidy(() => { + if (mask == null) { + return null; + } + if (!Array.isArray(mask)) { + throw new ValueError('`mask` should be an Array'); + } + if (!Array.isArray(inputs)) { + throw new ValueError('`inputs` should be an Array'); + } + if (mask.length !== inputs.length) { + throw new ValueError(`The Array 'inputs' and 'mask' are expected to have the same ` + + `length, but have different lengths ` + + `(${inputs.length} vs ${mask.length})`); + } + if (mask.every(m => m == null)) { + return null; + } + mask = mask.map(m => m == null ? m : expandDims$3(m, 0)); + let output = mask[0]; + for (let i = 1; i < mask.length - 1; ++i) { + output = logicalAnd$2(output, mask[i]); + } + return output; + }); + } + } + class Add extends Merge { + constructor(args) { + super(args); + } + mergeFunction(inputs) { + return tidy(() => { + let output = inputs[0].clone(); + for (let i = 1; i < inputs.length; ++i) { + output = add$3(output, inputs[i]); + } + return output; + }); + } + } + /** @nocollapse */ + Add.className = 'Add'; + registerClass(Add); + /** + * Calculate the element-wise sum of inputs, which all have the same shape. + * + * This function can be invoked in three ways. + * + * 1. Construct an instance of `Add` layer, by using no input argument + * or a single configuration argument. The resultant `Add` layer can then + * be used on `tf.SymbolicTensor`s or `tf.Tensor`s. For example: + * + * ```js + * const addLayer = tf.layers.add(); + * + * // The layer can be applied to inputs. + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = addLayer.apply([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 2. Invoke directly on an `Array` of `tf.SymbolicTensor`s. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.SymbolicTensor`. For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = tf.layers.add([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 3. Invoke directly on `tf.Tensor`s, i.e., concrete values. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.Tensor` as the result of the computation. For + * example: + * + * ```js + * const input1 = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * const input2 = tf.tensor2d([10, 20, 30, 40], [2, 2]); + * tf.layers.add([input1, input2]).print(); + * // Gives [[11, 22], [33, 44]]. + * + */ + function add$2(config) { + if (Array.isArray(config)) { + const layer = new Add({}); + return layer.apply(config); + } + else { + return new Add(config); + } + } + class Multiply extends Merge { + constructor(args) { + super(args); + } + mergeFunction(inputs) { + return tidy(() => { + let output = inputs[0].clone(); + for (let i = 1; i < inputs.length; ++i) { + output = mul(output, inputs[i]); + } + return output; + }); + } + } + /** @nocollapse */ + Multiply.className = 'Multiply'; + registerClass(Multiply); + /** + * Calculate the element-wise product of inputs, which all have the same shape. + * + * This function can be invoked in three ways. + * + * 1. Construct an instance of `Multiply` layer, by using no input argument + * or a single configuration argument. The resultant `Multiply` layer can + * then be used on `tf.SymbolicTensor`s or `tf.Tensor`s. For example: + * + * ```js + * const multiplyLayer = tf.layers.multiply(); + * + * // The layer can be applied to inputs. + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = multiplyLayer.apply([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 2. Invoke directly on an `Array` of `tf.SymbolicTensor`s. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.SymbolicTensor`. For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = tf.layers.multiply([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 3. Invoke directly on `tf.Tensor`s, i.e., concrete values. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.Tensor` as the result of the computation. For + * example: + * + * ```js + * const input1 = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * const input2 = tf.tensor2d([10, 20, 30, 40], [2, 2]); + * tf.layers.multiply([input1, input2]).print(); + * // Gives [[10, 40], [90, 160]]. + * + */ + function multiply$3(config) { + if (Array.isArray(config)) { + const layer = new Multiply({}); + return layer.apply(config); + } + else { + return new Multiply(config); + } + } + class Average extends Merge { + constructor(args) { + super(args); + } + mergeFunction(inputs) { + return tidy(() => { + let output = inputs[0].clone(); + for (let i = 1; i < inputs.length; ++i) { + output = add$3(output, inputs[i]); + } + return mul(1 / inputs.length, output); + }); + } + } + /** @nocollapse */ + Average.className = 'Average'; + registerClass(Average); + /** + * Calculate the element-wise arithmetic mean of inputs, which all have the same + * shape. + * + * This function can be invoked in three ways. + * + * 1. Construct an instance of `Average` layer, by using no input argument + * or a single configuration argument. The resultant `Average` layer can then + * be used on `tf.SymbolicTensor`s or `tf.Tensor`s. For example: + * + * ```js + * const averageLayer = tf.layers.average(); + * + * // The layer can be applied to inputs. + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = averageLayer.apply([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 2. Invoke directly on an `Array` of `tf.SymbolicTensor`s. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.SymbolicTensor`. For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = tf.layers.average([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 3. Invoke directly on `tf.Tensor`s, i.e., concrete values. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.Tensor` as the result of the computation. For + * example: + * + * ```js + * const input1 = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * const input2 = tf.tensor2d([10, 20, 30, 40], [2, 2]); + * tf.layers.average([input1, input2]).print(); + * // Gives [[5.5, 11], [16.5, 22]]. + * + */ + function average$1(config) { + if (Array.isArray(config)) { + const layer = new Average({}); + return layer.apply(config); + } + else { + return new Average(config); + } + } + class Maximum extends Merge { + constructor(args) { + super(args); + } + mergeFunction(inputs) { + return tidy(() => { + let output = inputs[0]; + for (let i = 1; i < inputs.length; ++i) { + output = maximum$4(output, inputs[i]); + } + return output; + }); + } + } + /** @nocollapse */ + Maximum.className = 'Maximum'; + registerClass(Maximum); + /** + * Calculate the element-wise maximum of inputs, which all have the same shape. + * + * This function can be invoked in three ways. + * + * 1. Construct an instance of `Maximum` layer, by using no input argument + * or a single configuration argument. The resultant `Maximum` layer can then + * be used on `tf.SymbolicTensor`s or `tf.Tensor`s. For example: + * + * ```js + * const maximumLayer = tf.layers.maximum(); + * + * // The layer can be applied to inputs. + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = maximumLayer.apply([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 2. Invoke directly on an `Array` of `tf.SymbolicTensor`s. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.SymbolicTensor`. For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = tf.layers.maximum([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 3. Invoke directly on `tf.Tensor`s, i.e., concrete values. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.Tensor` as the result of the computation. For + * example: + * + * ```js + * const input1 = tf.tensor2d([1, 20, 3, 40], [2, 2]); + * const input2 = tf.tensor2d([10, 2, 30, 4], [2, 2]); + * tf.layers.maximum([input1, input2]).print(); + * // Gives [[10, 20], [30, 40]]. + * + */ + function maximum$3(config) { + if (Array.isArray(config)) { + const layer = new Maximum({}); + return layer.apply(config); + } + else { + return new Maximum(config); + } + } + class Minimum extends Merge { + constructor(args) { + super(args); + } + mergeFunction(inputs) { + return tidy(() => { + let output = inputs[0]; + for (let i = 1; i < inputs.length; ++i) { + output = minimum$4(output, inputs[i]); + } + return output; + }); + } + } + /** @nocollapse */ + Minimum.className = 'Minimum'; + registerClass(Minimum); + /** + * Calculate the element-wise minimum of inputs, which all have the same shape. + * + * This function can be invoked in three ways. + * + * 1. Construct an instance of `Minimum` layer, by using no input argument + * or a single configuration argument. The resultant `Minimum` layer can then + * be used on `tf.SymbolicTensor`s or `tf.Tensor`s. For example: + * + * ```js + * const minimumLayer = tf.layers.minimum(); + * + * // The layer can be applied to inputs. + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = minimumLayer.apply([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 2. Invoke directly on an `Array` of `tf.SymbolicTensor`s. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.SymbolicTensor`. For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const output = tf.layers.minimum([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * 3. Invoke directly on `tf.Tensor`s, i.e., concrete values. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.Tensor` as the result of the computation. For + * example: + * + * ```js + * const input1 = tf.tensor2d([1, 20, 3, 40], [2, 2]); + * const input2 = tf.tensor2d([10, 2, 30, 4], [2, 2]); + * tf.layers.minimum([input1, input2]).print(); + * // Gives [[1, 2], [3, 4]]. + * + */ + function minimum$3(config) { + if (Array.isArray(config)) { + const layer = new Minimum({}); + return layer.apply(config); + } + else { + return new Minimum(config); + } + } + class Concatenate extends Merge { + constructor(args) { + super(args); + this.DEFAULT_AXIS = -1; + if (args == null) { + args = {}; + } + this.axis = args.axis == null ? this.DEFAULT_AXIS : args.axis; + this.supportsMasking = true; + this.reshapeRequired = false; + } + build(inputShape) { + // Used purely for shape validation.] + if (!(Array.isArray(inputShape) && Array.isArray(inputShape[0])) || + inputShape.length === 1) { + throw new ValueError('A `Concatenate` layer should be called on a list of at least 2 ' + + 'inputs'); + } + inputShape = inputShape; + let allNoneShape = true; + for (const shape of inputShape) { + if (shape != null) { + allNoneShape = false; + break; + } + } + if (allNoneShape) { + return; + } + const shapeSet = []; + for (let i = 0; i < inputShape.length; ++i) { + const shapeWithoutConcatAxis = inputShape[i].slice(); + shapeWithoutConcatAxis.splice(this.axis, 1); + let exists = false; + for (const shape of shapeSet) { + if (arraysEqual(shape, shapeWithoutConcatAxis)) { + exists = true; + break; + } + } + if (!exists) { + shapeSet.push(shapeWithoutConcatAxis); + } + } + if (shapeSet.length > 1) { + throw new ValueError('A `Concatenate` layer requires inputs with matching shapes ' + + 'except for the concat axis. Got input shapes: ' + + JSON.stringify(inputShape)); + } + } + mergeFunction(inputs) { + return tidy(() => { + return concatenate$2(inputs, this.axis); + }); + } + computeOutputShape(inputShape) { + if (!(Array.isArray(inputShape) && Array.isArray(inputShape[0]))) { + throw new ValueError('A `Concatenate` layer should be called on a list of inputs.'); + } + const inputShapes = inputShape; + const outputShape = inputShapes[0].slice(); + const axis = this.axis < 0 ? outputShape.length + this.axis : this.axis; + // Porting Note: the line above is because TypeScript doesn't support + // negative indices. + for (const shape of inputShapes.slice(1)) { + if (outputShape[axis] == null || shape[axis] == null) { + outputShape[axis] = null; + break; + } + outputShape[axis] += shape[axis]; + } + return outputShape; + } + computeMask(inputs, mask) { + if (mask == null) { + return null; + } + if (!Array.isArray(mask)) { + throw new ValueError('`mask` should be an array for Concatenate'); + } + if (!Array.isArray(inputs)) { + throw new ValueError('`inputs` should be an array for Concatenate'); + } + if (mask.length !== inputs.length) { + throw new ValueError(`Mismatch in the length of mask (${mask.length}) ` + + `and the legnth of inputs (${inputs.length})`); + } + return tidy(() => { + let allNullMasks = true; + mask.forEach(m => { + if (m != null) { + allNullMasks = false; + return; + } + }); + if (allNullMasks) { + return null; + } + const outputMasks = []; + for (let i = 0; i < inputs.length; ++i) { + if (mask[i] == null) { + // Input is unmasked. Append all 1's to masks. + outputMasks.push(cast$3(onesLike$3(inputs[i]), 'bool')); + } + else if (mask[i].rank < inputs[i].rank) { + // Mask is smaller than the input, expand it. + outputMasks.push(expandDims$3(mask[i], -1)); + } + else { + outputMasks.push(mask[i]); + } + } + const concatenatedMasks = concat$2(outputMasks, this.axis); + return all$2(concatenatedMasks, -1, false); + }); + } + getConfig() { + const config = { + 'axis': this.axis, + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Concatenate.className = 'Concatenate'; + registerClass(Concatenate); + /** + * Concatenate an `Array` of inputs. + * + * This function can be invoked in three ways. + * + * 1. Construct an instance of `Concatenate` layer, by using no input argument + * or a single configuration argument. The resultant `Concatenate` layer can + * then be used on `tf.SymbolicTensor`s or `tf.Tensor`s. For example: + * + * ```js + * const concatLayer = tf.layers.concatenate(); + * + * // The layer can be applied to inputs. + * const input1 = tf.input({shape: [2, 3]}); + * const input2 = tf.input({shape: [2, 4]}); + * const output = concatLayer.apply([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 7], with the first dimension as the undetermined batch + * // dimension and the last dimension as the result of concatenating the + * // last dimensions of the two inputs. + * ``` + * + * 2. Invoke directly on an `Array` of `tf.SymbolicTensor`s. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.SymbolicTensor`. For example: + * + * ```js + * const input1 = tf.input({shape: [2, 3]}); + * const input2 = tf.input({shape: [2, 4]}); + * const output = tf.layers.concatenate([input1, input2]); + * console.log(output.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension and the last dimension as the result of concatenating the + * // last dimensions of the two inputs. + * ``` + * + * 3. Invoke directly on `tf.Tensor`s, i.e., concrete values. This constructs + * an `Layer` object internally and calls its `apply` method on the inputs, + * generating a new `tf.Tensor` as the result of the computation. For + * example: + * + * ```js + * const input1 = tf.tensor2d([[1, 2], [3, 4]], [2, 2]); + * const input2 = tf.tensor2d([[10, 20], [30, 40]], [2, 2]); + * tf.layers.concatenate([input1, input2]).print(); + * // Gives [[1, 2, 10, 20], [3, 4, 30, 40]]. + * + */ + function concatenate$1(config) { + if (Array.isArray(config)) { + const layer = new Concatenate({}); + return layer.apply(config); + } + else { + return new Concatenate(config); + } + } + /** + * Interpretable potentially negative axis index. + * + * For example, given axis = -1, and dim = 3, this function will return 2. + * + * @param axis The axis index, may be a positive, zero or negative integer. + * @param dim Total number of dimensions, a positive integer. + * @returns A non-negative axis index equivalent to the input `axis`. + */ + function interpretAxis(axis, dim) { + while (axis < 0) { + axis += dim; + } + return axis; + } + function batchDot(x, y, axes) { + if (x.shape.length > 3 || y.shape.length > 3) { + throw new NotImplementedError('batchDot is not implemented for tensors of 4D or higher rank yet'); + } + assert$1(x.shape.length >= 2, () => `batchDot requires the rank of x to be >= 2, ` + + `but got ${x.shape.length}`); + assert$1(x.shape.length >= 2, () => `batchDot requires the rank of y to be >= 2, ` + + `but got ${y.shape.length}`); + if (typeof axes === 'number') { + axes = [axes, axes]; + } + if (x.dtype === 'complex64' || y.dtype === 'complex64') { + throw new NotImplementedError('batchDot is not implemented for complex64-type Tensors yet.'); + } + const xNDim = x.shape.length; + const yNDim = y.shape.length; + if (axes == null) { + // Behave like batchMatmul by default. + axes = [xNDim - 1, yNDim - 2]; + } + const axesArray = axes; + return tidy(() => { + let diff; + if (xNDim > yNDim) { + diff = xNDim - yNDim; + const diffShape = []; + for (let i = 0; i < diff; ++i) { + diffShape.push(1); + } + y = reshape$3(y, y.shape.concat(diffShape)); + } + else if (yNDim > xNDim) { + diff = yNDim - xNDim; + const diffShape = []; + for (let i = 0; i < diff; ++i) { + diffShape.push(1); + } + x = reshape$3(x, x.shape.concat(diffShape)); + } + else { + diff = 0; + } + let out; + if (x.shape.length === 2 && y.shape.length === 2) { + if (axesArray[0] === axesArray[1]) { + out = sum$3(mul(x, y), axesArray[0]); + } + else { + out = sum$3(mul(transpose$2(x, [1, 0]), y), axesArray[1]); + } + } + else { + const adjX = axesArray[0] !== x.shape.length - 1; + const adjY = axesArray[1] === y.shape.length - 1; + out = matMul$1(x, y, adjX, adjY); + } + if (diff > 0) { + let idx; + if (xNDim > yNDim) { + idx = xNDim + yNDim - 3; + } + else { + idx = xNDim - 1; + } + const squeezeAxes = []; + for (let i = idx; i < idx + diff; ++i) { + squeezeAxes.push(i); + } + out = squeeze(out, squeezeAxes); + } + if (out.shape.length === 1) { + out = expandDims$3(out, 1); + } + return out; + }); + } + class Dot extends Merge { + constructor(args) { + super(args); + this.axes = args.axes; + this.normalize = args.normalize == null ? false : args.normalize; + this.supportsMasking = true; + this.reshapeRequired = false; + } + build(inputShape) { + assert$1(Array.isArray(inputShape) && inputShape.length === 2 && + Array.isArray(inputShape[0]) && Array.isArray(inputShape[1]), () => 'A `Dot` layer should be called on a list of exactly 2 inputs.'); + const shape1 = inputShape[0]; + const shape2 = inputShape[1]; + if (shape1.length > 3 || shape2.length > 3) { + throw new NotImplementedError('Dot layer does not support tensors of 4D or higher rank yet.'); + } + const axes = this.interpretAxes(shape1, shape2); + if (shape1[axes[0]] !== shape2[axes[1]]) { + throw new ValueError(`Dimension incompatibility: ` + + `${shape1[axes[0]]} !== ${shape2[axes[1]]}`); + } + } + mergeFunction(inputs) { + if (inputs.length !== 2) { + throw new ValueError('A `Dot` layer must be called on exactly 2 inputs, ' + + `but received ${inputs.length} input(s).`); + } + let x1 = inputs[0]; + let x2 = inputs[1]; + let axes; + if (!Array.isArray(this.axes)) { + axes = [ + interpretAxis(this.axes, x1.shape.length), + interpretAxis(this.axes, x2.shape.length) + ]; + } + else { + axes = this.axes.map((axis, i) => interpretAxis(axis, inputs[i].shape.length)); + } + if (this.normalize) { + x1 = l2Normalize(x1, axes[0]); + x2 = l2Normalize(x2, axes[1]); + } + return batchDot(x1, x2, axes); + } + interpretAxes(shape1, shape2) { + let axes; + if (!Array.isArray(this.axes)) { + // `this.axes` is a single integer. + axes = [ + interpretAxis(this.axes, shape1.length), + interpretAxis(this.axes, shape2.length) + ]; + } + else { + // `this.axes` is an Array of integers. + axes = this.axes; + } + return axes; + } + computeOutputShape(inputShape) { + assert$1(Array.isArray(inputShape) && inputShape.length === 2 && + Array.isArray(inputShape[0]) && Array.isArray(inputShape[1]), () => 'A `Dot` layer should be called on a list of exactly 2 inputs.'); + const shape1 = inputShape[0].slice(); + const shape2 = inputShape[1].slice(); + if (shape1.length > 3 || shape2.length > 3) { + throw new NotImplementedError('Dot layer does not support tensors of 4D or higher rank yet.'); + } + const axes = this.interpretAxes(shape1, shape2); + shape1.splice(axes[0], 1); + shape2.splice(axes[1], 1); + shape2.splice(0, 1); + const outputShape = shape1.concat(shape2); + if (outputShape.length === 1) { + outputShape.push(1); + } + return outputShape; + } + computeMask(inputs, mask) { + return null; + } + getConfig() { + const config = { + 'axes': this.axes, + 'normalize': this.normalize + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + Dot.className = 'Dot'; + registerClass(Dot); + // TODO(cais): Add functional interfaces for the merge layers. + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + class GaussianNoise extends Layer { + constructor(args) { + super(args); + this.supportsMasking = true; + this.stddev = args.stddev; + } + computeOutputShape(inputShape) { + return inputShape; + } + getConfig() { + const baseConfig = super.getConfig(); + const config = { stddev: this.stddev }; + Object.assign(config, baseConfig); + return config; + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + const input = getExactlyOneTensor(inputs); + const noised = () => add$3(randomNormal$1(input.shape, 0, this.stddev), input); + const output = inTrainPhase(noised, () => input, kwargs['training'] || false); + return output; + }); + } + } + /** @nocollapse */ + GaussianNoise.className = 'GaussianNoise'; + registerClass(GaussianNoise); + class GaussianDropout extends Layer { + constructor(args) { + super(args); + this.supportsMasking = true; + this.rate = args.rate; + } + computeOutputShape(inputShape) { + return inputShape; + } + getConfig() { + const baseConfig = super.getConfig(); + const config = { rate: this.rate }; + Object.assign(config, baseConfig); + return config; + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + const input = getExactlyOneTensor(inputs); + if (this.rate > 0 && this.rate < 1) { + const noised = () => { + const stddev = Math.sqrt(this.rate / (1 - this.rate)); + return mul(input, randomNormal$1(input.shape, 1, stddev)); + }; + return inTrainPhase(noised, () => input, kwargs['training'] || false); + } + return input; + }); + } + } + /** @nocollapse */ + GaussianDropout.className = 'GaussianDropout'; + registerClass(GaussianDropout); + /** + * Applies Alpha Dropout to the input. + * + * As it is a regularization layer, it is only active at training time. + * + * Alpha Dropout is a `Dropout` that keeps mean and variance of inputs + * to their original values, in order to ensure the self-normalizing property + * even after this dropout. + * Alpha Dropout fits well to Scaled Exponential Linear Units + * by randomly setting activations to the negative saturation value. + * + * Arguments: + * - `rate`: float, drop probability (as with `Dropout`). + * The multiplicative noise will have + * standard deviation `sqrt(rate / (1 - rate))`. + * - `noise_shape`: A 1-D `Tensor` of type `int32`, representing the + * shape for randomly generated keep/drop flags. + * + * Input shape: + * Arbitrary. Use the keyword argument `inputShape` + * (tuple of integers, does not include the samples axis) + * when using this layer as the first layer in a model. + * + * Output shape: + * Same shape as input. + * + * References: + * - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515) + */ + class AlphaDropout extends Layer { + constructor(args) { + super(args); + this.supportsMasking = true; + this.rate = args.rate; + this.noiseShape = args.noiseShape; + } + _getNoiseShape(inputs) { + return this.noiseShape || getExactlyOneTensor(inputs).shape; + } + computeOutputShape(inputShape) { + return inputShape; + } + getConfig() { + const baseConfig = super.getConfig(); + const config = { rate: this.rate }; + Object.assign(config, baseConfig); + return config; + } + call(inputs, kwargs) { + return tidy(() => { + if (this.rate < 1 && this.rate > 0) { + const noiseShape = this._getNoiseShape(inputs); + const droppedInputs = () => { + const input = getExactlyOneTensor(inputs); + const alpha = 1.6732632423543772848170429916717; + const scale = 1.0507009873554804934193349852946; + const alphaP = -alpha * scale; + let keptIdx = greaterEqual$2(randomUniform$1(noiseShape), this.rate); + keptIdx = cast$2(keptIdx, 'float32'); // get default dtype. + // Get affine transformation params. + const a = ((1 - this.rate) * (1 + this.rate * alphaP ** 2)) ** -0.5; + const b = -a * alphaP * this.rate; + // Apply mask. + const x = add$3(mul(input, keptIdx), mul(add$3(keptIdx, -1), alphaP)); + return add$3(mul(x, a), b); + }; + return inTrainPhase(droppedInputs, () => getExactlyOneTensor(inputs), kwargs['training'] || false); + } + return inputs; + }); + } + } + /** @nocollapse */ + AlphaDropout.className = 'AlphaDropout'; + registerClass(AlphaDropout); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Applies batch normalization on x given mean, var, beta and gamma. + * + * I.e. returns: + * `output = (x - mean) / (sqrt(var) + epsilon) * gamma + beta` + * + * @param x Input tensor. + * @param mean Mean of batch. + * @param variance Variance of batch. + * @param beta Tensor with which to center the input. + * @param gamma Tensor by which to scale the input. + * @param epsilon Fuzz factor. + * @returns The result of the batch normalization. + */ + function batchNormalization$1(x, mean, variance, beta, gamma, epsilon = 1e-3) { + let out; + if (x.rank === 2) { + out = batchNorm2d(x, mean, variance, beta, gamma, epsilon); + } + else if (x.rank === 3) { + // TODO(cais): Check rank; give proper error message. + out = batchNorm3d(x, mean, variance, beta, gamma, epsilon); + } + else if (x.rank === 4) { + out = batchNorm4d(x, mean, variance, beta, gamma, epsilon); + } + else { + throw new NotImplementedError(`batchNormalization is not implemented for array of rank ${x.rank} ` + + `yet`); + } + return out; + } + /** + * Non-broadcasting batch normalization for use in training (not inference). + * + * The input is normalized to zero mean and unit variance along the + * `reductionAxes`, followed by scaling with `gamma` and shifted by `beta`. + * The result of that is returned as the first element + * of the returned `Array`. The other two elements are the mean and variance, + * respectively. + * + * @param x Input tensor to be normalized. + * @param gamma Tensor by which to scale the input. + * @param beta Tensor by which to center the input. + * @param reductionAxes Axes over which to normalize. + * @param epsilon Fuzz factor. + * @returns An `Array` of three `Tensors`: + * [normalized tensor, mean of input, variance of input]. + */ + function regularNormalizeBatchInTraining(x, gamma, beta, reductionAxes, epsilon = 1e-3) { + return tidy(() => { + const meanAndVariance = moments(x, reductionAxes); + const mean = meanAndVariance.mean; + const variance = meanAndVariance.variance; + const normed = batchNormalization$1(x, mean, variance, beta, gamma, epsilon); + return [normed, mean, variance]; + }); + } + /** + * Broadcasting batch normalization for use in training (not inference). + * + * The input is normalized to zero mean and unit variance along the + * `reductionAxes`, followed by scaling with `gamma` and shifted by `beta`. + * The result of that is returned as the first element + * of the returned `Array`. The other two elements are the mean and variance, + * respectively. + * + * @param x Input tensor to be normalized. + * @param gamma Tensor by which to scale the input. + * @param beta Tensor by which to center the input. + * @param reductionAxes Axes over which to normalize. + * @param epsilon Fuzz factor. + * @returns An `Array` of three `Tensors`: + * [normalized tensor, mean of input, variance of input]. + */ + function broadcastNormalizeBatchInTraining(x, gamma, beta, reductionAxes, epsilon = 1e-3) { + return tidy(() => { + const meanAndVariance = moments(x, reductionAxes); + const mean = meanAndVariance.mean; + const variance = meanAndVariance.variance; + const targetShape = []; + for (const axis of range$2(0, x.rank)) { + if (reductionAxes.indexOf(axis) !== -1) { + targetShape.push(1); + } + else { + targetShape.push(x.shape[axis]); + } + } + const broadcastMean = reshape$3(mean, targetShape); + const broadcastVariance = reshape$3(variance, targetShape); + const broadcastGamma = gamma == null ? null : reshape$3(gamma, targetShape); + const broadcastBeta = beta == null ? null : reshape$3(beta, targetShape); + const normed = batchNormalization$1(x, broadcastMean, broadcastVariance, broadcastBeta, broadcastGamma, epsilon); + return [normed, mean, variance]; + }); + } + /** + * Batch normalization for use in training (not inference). + * + * @param x Input tensor to be normalized. + * @param gamma Tensor by which to scale the input. + * @param beta Tensor by which to center the input. + * @param reductionAxes Axes over which to normalize. + * @param epsilon Fuzz factor. + * @returns An `Array` of three `Tensors`: + * [normalized tensor, mean of input, variance of input]. + */ + function normalizeBatchInTraining(x, gamma, beta, reductionAxes, epsilon = 1e-3) { + if (arraysEqual(reductionAxes.slice().sort(), range$2(0, x.rank - 1))) { + return regularNormalizeBatchInTraining(x, gamma, beta, reductionAxes, epsilon); + } + else { + return broadcastNormalizeBatchInTraining(x, gamma, beta, reductionAxes, epsilon); + } + } + class BatchNormalization extends Layer { + constructor(args) { + if (args == null) { + args = {}; + } + super(args); + this.supportsMasking = true; + this.axis = args.axis == null ? -1 : args.axis; + this.momentum = args.momentum == null ? 0.99 : args.momentum; + this.epsilon = args.epsilon == null ? 1e-3 : args.epsilon; + this.center = args.center == null ? true : args.center; + this.scale = args.scale == null ? true : args.scale; + this.betaInitializer = getInitializer(args.betaInitializer || 'zeros'); + this.gammaInitializer = getInitializer(args.gammaInitializer || 'ones'); + this.movingMeanInitializer = + getInitializer(args.movingMeanInitializer || 'zeros'); + this.movingVarianceInitializer = + getInitializer(args.movingVarianceInitializer || 'ones'); + this.betaConstraint = getConstraint(args.betaConstraint); + this.gammaConstraint = getConstraint(args.gammaConstraint); + this.betaRegularizer = getRegularizer(args.betaRegularizer); + this.gammaRegularizer = getRegularizer(args.gammaRegularizer); + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const axis = this.axis >= 0 ? this.axis : (this.axis + inputShape.length); + const dim = inputShape[axis]; + if (dim == null) { + throw new ValueError(`Axis ${axis} of input tensor should have a defined dimension but ` + + `the layer received an input with shape ` + + `${JSON.stringify(inputShape)}.`); + } + this.inputSpec = + [new InputSpec({ ndim: inputShape.length, axes: { [axis]: dim } })]; + const shape = [dim]; + if (this.scale) { + this.gamma = this.addWeight('gamma', shape, null, this.gammaInitializer, this.gammaRegularizer, true, this.gammaConstraint); + } + if (this.center) { + this.beta = this.addWeight('beta', shape, null, this.betaInitializer, this.betaRegularizer, true, this.betaConstraint); + } + this.movingMean = this.addWeight('moving_mean', shape, null, this.movingMeanInitializer, null, false); + this.movingVariance = this.addWeight('moving_variance', shape, null, this.movingVarianceInitializer, null, false); + this.built = true; + } + call(inputs, kwargs) { + return tidy(() => { + const training = kwargs['training'] == null ? false : kwargs['training']; + const input = getExactlyOneTensor(inputs); + const inputShape = input.shape; + const ndim = inputShape.length; + const reductionAxes = range$2(0, ndim); + const axis = this.axis >= 0 ? this.axis : (this.axis + ndim); + reductionAxes.splice(axis, 1); + const broadcastShape = pyListRepeat(1, ndim); + broadcastShape[axis] = inputShape[axis]; + const sortedReductionAxes = reductionAxes.slice(); + sortedReductionAxes.sort(); + const needsBroadcasting = !arraysEqual(sortedReductionAxes, range$2(0, ndim).slice(0, ndim - 1)); + const normalizeInference = () => { + if (needsBroadcasting) { + const broadcastMovingMean = reshape$3(this.movingMean.read(), broadcastShape); + const broadcastMovingVariance = reshape$3(this.movingVariance.read(), broadcastShape); + const broadcastBeta = this.center ? reshape$3(this.beta.read(), broadcastShape) : null; + const broadcastGamma = this.scale ? reshape$3(this.gamma.read(), broadcastShape) : null; + return batchNormalization$1(input, broadcastMovingMean, broadcastMovingVariance, broadcastBeta, broadcastGamma, this.epsilon); + } + else { + return batchNormalization$1(input, this.movingMean.read(), this.movingVariance.read(), this.beta == null ? null : this.beta.read(), this.gamma == null ? null : this.gamma.read(), this.epsilon); + } + }; + if (!training) { + return normalizeInference(); + } + const [normedTraining, mean, variance] = normalizeBatchInTraining(input, this.gamma.read(), this.beta.read(), reductionAxes, this.epsilon); + const doMovingAverage = (variable, value, momentum) => { + tidy(() => { + const decay = 1 - momentum; + const origValue = variable.read(); + const updateDelta = mul(sub$2(origValue, value), decay); + variable.write(sub$2(origValue, updateDelta)); + }); + }; + // Perform updates to moving mean and moving variance for training. + // Porting Note: In PyKeras, these updates to `movingMean` and + // `movingAverage` are done as a deferred Graph, added to the `Layer`'s + // `update`s using the `add_update()` method. Here we do it imperatively + // and encapsulate the updates in a function that is invoked + // immediately. + const updateMovingMeanAndVariance = () => { + doMovingAverage(this.movingMean, mean, this.momentum); + doMovingAverage(this.movingVariance, variance, this.momentum); + }; + updateMovingMeanAndVariance(); + return normedTraining; + }); + } + getConfig() { + const config = { + axis: this.axis, + momentum: this.momentum, + epsilon: this.epsilon, + center: this.center, + scale: this.scale, + betaInitializer: serializeInitializer(this.betaInitializer), + gammaInitializer: serializeInitializer(this.gammaInitializer), + movingMeanInitializer: serializeInitializer(this.movingMeanInitializer), + movingVarianceInitializer: serializeInitializer(this.movingVarianceInitializer), + betaRegularizer: serializeRegularizer(this.betaRegularizer), + gammaRegularizer: serializeRegularizer(this.gammaRegularizer), + betaConstraint: serializeConstraint(this.betaConstraint), + gammaConstraint: serializeConstraint(this.gammaConstraint) + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + BatchNormalization.className = 'BatchNormalization'; + registerClass(BatchNormalization); + class LayerNormalization extends Layer { + constructor(args) { + if (args == null) { + args = {}; + } + super(args); + this.axis = args.axis == null ? -1 : args.axis; + if (typeof this.axis === 'number') { + if (!Number.isInteger(this.axis)) { + throw new Error(`Expected axis to be an integer, but received ${this.axis}`); + } + } + else if (Array.isArray(this.axis)) { + for (const axis of this.axis) { + if (!Number.isInteger(axis)) { + throw new Error(`Expected axis to be an array of integers, ` + + `but received ${JSON.stringify(this.axis)}`); + } + } + } + else { + throw new Error(`Expected axis to be an integer or an array of integers, ` + + `but received ${JSON.stringify(this.axis)}`); + } + this.epsilon = args.epsilon == null ? 1e-3 : args.epsilon; + this.center = args.center == null ? true : args.center; + this.scale = args.scale == null ? true : args.scale; + this.betaInitializer = getInitializer(args.betaInitializer || 'zeros'); + this.gammaInitializer = getInitializer(args.gammaInitializer || 'ones'); + this.betaRegularizer = getRegularizer(args.betaRegularizer); + this.gammaRegularizer = getRegularizer(args.gammaRegularizer); + this.supportsMasking = true; + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const nDims = inputShape.length; + // Convert axis to array and resolve negatives. + if (typeof this.axis === 'number') { + this.axis = [this.axis]; + } + for (let i = 0; i < this.axis.length; ++i) { + if (this.axis[i] < 0) { + this.axis[i] += nDims; + } + } + // Further validate axes. + for (const axis of this.axis) { + if (axis < 0 || axis >= nDims) { + throw new Error(`Invalid axis: ${axis}`); + } + } + if (this.axis.length !== unique$2(this.axis).length) { + throw new Error(`Found duplicate axes in: ${this.axis}`); + } + const paramShape = this.axis.map(axis => inputShape[axis]); + const trainable = true; + if (this.scale) { + this.gamma = this.addWeight('gamma', paramShape, 'float32', this.gammaInitializer, this.gammaRegularizer, trainable); + } + else { + this.gamma = null; + } + if (this.center) { + this.beta = this.addWeight('beta', paramShape, 'float32', this.betaInitializer, this.betaRegularizer, trainable); + } + else { + this.beta = null; + } + this.built = true; + } + call(inputs, kwargs) { + const input = getExactlyOneTensor(inputs); + const inputShape = input.shape; + const nDims = inputShape.length; + return tidy(() => { + const keepDims = true; + let { mean, variance } = moments(input, this.axis, keepDims); + const broadcastShape = pyListRepeat(1, nDims); + for (const dim of this.axis) { + broadcastShape[dim] = inputShape[dim]; + } + const broadcast = (v) => { + if (v != null && v.shape.length !== nDims) { + return reshape$3(v, broadcastShape); + } + else { + return v; + } + }; + let scale = this.scale ? broadcast(this.gamma.read()) : null; + let offset = this.center ? broadcast(this.beta.read()) : null; + // TODO(https://github.com/tensorflow/tfjs/issues/2120): The tiling below + // is a workaround for the limitation of core's batchNormalization?d don't + // support broadcasting in their gradients. In addition, the tiling is + // necessary to ensure correctness on the browser CPU backend regardless + // of forward or backward computation. Remove this workaround once the + // limitation is addressed. See . + const momentsTiling = []; + const scaleOffsetTiling = []; + for (let i = 0; i < nDims; ++i) { + if (this.axis.indexOf(i) !== -1) { + momentsTiling.push(inputShape[i]); + scaleOffsetTiling.push(1); + } + else { + momentsTiling.push(1); + scaleOffsetTiling.push(inputShape[i]); + } + } + mean = tile$3(mean, momentsTiling); + variance = tile$3(variance, momentsTiling); + if (scale != null) { + scale = tile$3(scale, scaleOffsetTiling); + } + if (offset != null) { + offset = tile$3(offset, scaleOffsetTiling); + } + return batchNormalization$1(input, mean, variance, offset, scale, this.epsilon); + }); + } + getConfig() { + const config = { + axis: this.axis, + epsilon: this.epsilon, + center: this.center, + scale: this.scale, + betaInitializer: serializeInitializer(this.betaInitializer), + gammaInitializer: serializeInitializer(this.gammaInitializer), + betaRegularizer: serializeRegularizer(this.betaRegularizer), + gammaRegularizer: serializeRegularizer(this.gammaRegularizer) + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + LayerNormalization.className = 'LayerNormalization'; + registerClass(LayerNormalization); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Pads the middle dimension of a 3D tensor. + * + * @param x Input `tf.Tensor` to be padded. + * @param padding `Array` of 2 integers, how many zeros to add at the start and + * end of the middle dimension (i.e., dimension 1). + * @return A padded 3D `tf.Tensor`. + */ + function temporalPadding(x, padding) { + return tidy(() => { + if (x.rank !== 3) { + throw new ValueError(`temporalPadding expects input tensor to be 3-D, but received a ` + + `${x.rank}-D tensor.`); + } + if (padding == null) { + padding = [1, 1]; + } + if (padding.length !== 2) { + throw new ValueError(`temporalPadding expects input padding pattern to be a length-2 ` + + `array, but received a length-${padding.length} array.`); + } + const pattern = [[0, 0], padding, [0, 0]]; + return pad(x, pattern); + }); + } + /** + * Pads the 2nd and 3rd dimensions of a 4D tensor. + * + * @param x Input `tf.Tensor` to be padded. + * @param padding `Array` of two `Array`s, each of which is an `Array` of two + * integers. The amount of padding at the beginning and end of the 2nd and 3rd + * dimensions, respectively. + * @param dataFormat 'channelsLast' (default) or 'channelsFirst'. + * @return Padded 4D `tf.Tensor`. + */ + function spatial2dPadding(x, padding, dataFormat) { + return tidy(() => { + if (x.rank !== 4) { + throw new ValueError(`temporalPadding expects input tensor to be 4-D, but received a ` + + `${x.rank}-D tensor.`); + } + if (padding == null) { + padding = [[1, 1], [1, 1]]; + } + if (padding.length !== 2 || padding[0].length !== 2 || + padding[1].length !== 2) { + throw new ValueError('spatial2dPadding expects `padding` to be an Array of two Arrays, ' + + 'each of which is an Array of two integers.'); + } + if (dataFormat == null) { + dataFormat = imageDataFormat(); + } + if (dataFormat !== 'channelsLast' && dataFormat !== 'channelsFirst') { + throw new ValueError(`Unknown data format: ${dataFormat}. ` + + `Supported data formats are 'channelsLast' and 'channelsFirst.`); + } + let pattern; + if (dataFormat === 'channelsFirst') { + pattern = [[0, 0], [0, 0], padding[0], padding[1]]; + } + else { + pattern = [[0, 0], padding[0], padding[1], [0, 0]]; + } + return pad(x, pattern); + }); + } + class ZeroPadding2D extends Layer { + constructor(args) { + if (args == null) { + args = {}; + } + super(args); + this.dataFormat = + args.dataFormat == null ? imageDataFormat() : args.dataFormat; + // TODO(cais): Maybe refactor the following logic surrounding `padding` + // into a helper method. + if (args.padding == null) { + this.padding = [[1, 1], [1, 1]]; + } + else if (typeof args.padding === 'number') { + this.padding = + [[args.padding, args.padding], [args.padding, args.padding]]; + } + else { + args.padding = args.padding; + if (args.padding.length !== 2) { + throw new ValueError(`ZeroPadding2D expects padding to be a length-2 array, but ` + + `received a length-${args.padding.length} array.`); + } + let heightPadding; + let widthPadding; + if (typeof args.padding[0] === 'number') { + heightPadding = [args.padding[0], args.padding[0]]; + widthPadding = [args.padding[1], args.padding[1]]; + } + else { + args.padding = args.padding; + if (args.padding[0].length !== 2) { + throw new ValueError(`ZeroPadding2D expects height padding to be a length-2 array, ` + + `but received a length-${args.padding[0].length} array.`); + } + heightPadding = args.padding[0]; + if (args.padding[1].length !== 2) { + throw new ValueError(`ZeroPadding2D expects width padding to be a length-2 array, ` + + `but received a length-${args.padding[1].length} array.`); + } + widthPadding = args.padding[1]; + } + this.padding = [heightPadding, widthPadding]; + } + this.inputSpec = [new InputSpec({ ndim: 4 })]; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + let rows; + let cols; + if (this.dataFormat === 'channelsFirst') { + if (inputShape[2] != null && inputShape[2] >= 0) { + rows = inputShape[2] + this.padding[0][0] + this.padding[0][1]; + } + else { + rows = null; + } + if (inputShape[3] != null && inputShape[3] >= 0) { + cols = inputShape[3] + this.padding[1][0] + this.padding[1][1]; + } + else { + cols = null; + } + return [inputShape[0], inputShape[1], rows, cols]; + } + else { + if (inputShape[1] != null && inputShape[1] >= 0) { + rows = inputShape[1] + this.padding[0][0] + this.padding[0][1]; + } + else { + rows = null; + } + if (inputShape[2] != null && inputShape[2] >= 0) { + cols = inputShape[2] + this.padding[1][0] + this.padding[1][1]; + } + else { + cols = null; + } + return [inputShape[0], rows, cols, inputShape[3]]; + } + } + call(inputs, kwargs) { + return tidy(() => spatial2dPadding(getExactlyOneTensor(inputs), this.padding, this.dataFormat)); + } + getConfig() { + const config = { + padding: this.padding, + dataFormat: this.dataFormat, + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + /** @nocollapse */ + ZeroPadding2D.className = 'ZeroPadding2D'; + registerClass(ZeroPadding2D); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * 2D pooling. + * @param x + * @param poolSize + * @param strides strides. Defaults to [1, 1]. + * @param padding padding. Defaults to 'valid'. + * @param dataFormat data format. Defaults to 'channelsLast'. + * @param poolMode Mode of pooling. Defaults to 'max'. + * @returns Result of the 2D pooling. + */ + function pool2d(x, poolSize, strides, padding, dataFormat, poolMode) { + return tidy(() => { + checkDataFormat(dataFormat); + checkPoolMode(poolMode); + checkPaddingMode(padding); + if (strides == null) { + strides = [1, 1]; + } + if (padding == null) { + padding = 'valid'; + } + if (dataFormat == null) { + dataFormat = imageDataFormat(); + } + if (poolMode == null) { + poolMode = 'max'; + } + // TODO(cais): Remove the preprocessing step once deeplearn.js supports + // dataFormat as an input argument. + x = preprocessConv2DInput(x, dataFormat); // x is NHWC after preprocessing. + let y; + const paddingString = (padding === 'same') ? 'same' : 'valid'; + if (poolMode === 'max') { + // TODO(cais): Rank check? + y = maxPool$2(x, poolSize, strides, paddingString); + } + else { // 'avg' + // TODO(cais): Check the dtype and rank of x and give clear error message + // if those are incorrect. + y = avgPool$2( + // TODO(cais): Rank check? + x, poolSize, strides, paddingString); + } + if (dataFormat === 'channelsFirst') { + y = transpose$2(y, [0, 3, 1, 2]); // NHWC -> NCHW. + } + return y; + }); + } + /** + * 3D pooling. + * @param x + * @param poolSize. Default to [1, 1, 1]. + * @param strides strides. Defaults to [1, 1, 1]. + * @param padding padding. Defaults to 'valid'. + * @param dataFormat data format. Defaults to 'channelsLast'. + * @param poolMode Mode of pooling. Defaults to 'max'. + * @returns Result of the 3D pooling. + */ + function pool3d$1(x, poolSize, strides, padding, dataFormat, poolMode) { + return tidy(() => { + checkDataFormat(dataFormat); + checkPoolMode(poolMode); + checkPaddingMode(padding); + if (strides == null) { + strides = [1, 1, 1]; + } + if (padding == null) { + padding = 'valid'; + } + if (dataFormat == null) { + dataFormat = imageDataFormat(); + } + if (poolMode == null) { + poolMode = 'max'; + } + // x is NDHWC after preprocessing. + x = preprocessConv3DInput(x, dataFormat); + let y; + const paddingString = (padding === 'same') ? 'same' : 'valid'; + if (poolMode === 'max') { + y = maxPool3d$1(x, poolSize, strides, paddingString); + } + else { // 'avg' + y = avgPool3d$1(x, poolSize, strides, paddingString); + } + if (dataFormat === 'channelsFirst') { + y = transpose$2(y, [0, 4, 1, 2, 3]); // NDHWC -> NCDHW. + } + return y; + }); + } + /** + * Abstract class for different pooling 1D layers. + */ + class Pooling1D extends Layer { + /** + * + * @param args Parameters for the Pooling layer. + * + * config.poolSize defaults to 2. + */ + constructor(args) { + if (args.poolSize == null) { + args.poolSize = 2; + } + super(args); + if (typeof args.poolSize === 'number') { + this.poolSize = [args.poolSize]; + } + else if (Array.isArray(args.poolSize) && + args.poolSize.length === 1 && + typeof args.poolSize[0] === 'number') { + this.poolSize = args.poolSize; + } + else { + throw new ValueError(`poolSize for 1D convolutional layer must be a number or an ` + + `Array of a single number, but received ` + + `${JSON.stringify(args.poolSize)}`); + } + assertPositiveInteger(this.poolSize, 'poolSize'); + if (args.strides == null) { + this.strides = this.poolSize; + } + else { + if (typeof args.strides === 'number') { + this.strides = [args.strides]; + } + else if (Array.isArray(args.strides) && + args.strides.length === 1 && + typeof args.strides[0] === 'number') { + this.strides = args.strides; + } + else { + throw new ValueError(`strides for 1D convolutional layer must be a number or an ` + + `Array of a single number, but received ` + + `${JSON.stringify(args.strides)}`); + } + } + assertPositiveInteger(this.strides, 'strides'); + this.padding = args.padding == null ? 'valid' : args.padding; + checkPaddingMode(this.padding); + this.inputSpec = [new InputSpec({ ndim: 3 })]; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const length = convOutputLength(inputShape[1], this.poolSize[0], this.padding, this.strides[0]); + return [inputShape[0], length, inputShape[2]]; + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + // Add dummy last dimension. + inputs = expandDims$2(getExactlyOneTensor(inputs), 2); + const output = this.poolingFunction(getExactlyOneTensor(inputs), [this.poolSize[0], 1], [this.strides[0], 1], this.padding, 'channelsLast'); + // Remove dummy last dimension. + return squeeze(output, [2]); + }); + } + getConfig() { + const config = { + poolSize: this.poolSize, + padding: this.padding, + strides: this.strides, + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + class MaxPooling1D extends Pooling1D { + constructor(args) { + super(args); + } + poolingFunction(inputs, poolSize, strides, padding, dataFormat) { + checkDataFormat(dataFormat); + checkPaddingMode(padding); + return pool2d(inputs, poolSize, strides, padding, dataFormat, 'max'); + } + } + /** @nocollapse */ + MaxPooling1D.className = 'MaxPooling1D'; + registerClass(MaxPooling1D); + class AveragePooling1D extends Pooling1D { + constructor(args) { + super(args); + } + poolingFunction(inputs, poolSize, strides, padding, dataFormat) { + checkDataFormat(dataFormat); + checkPaddingMode(padding); + return pool2d(inputs, poolSize, strides, padding, dataFormat, 'avg'); + } + } + /** @nocollapse */ + AveragePooling1D.className = 'AveragePooling1D'; + registerClass(AveragePooling1D); + /** + * Abstract class for different pooling 2D layers. + */ + class Pooling2D extends Layer { + constructor(args) { + if (args.poolSize == null) { + args.poolSize = [2, 2]; + } + super(args); + this.poolSize = Array.isArray(args.poolSize) ? + args.poolSize : + [args.poolSize, args.poolSize]; + if (args.strides == null) { + this.strides = this.poolSize; + } + else if (Array.isArray(args.strides)) { + if (args.strides.length !== 2) { + throw new ValueError(`If the strides property of a 2D pooling layer is an Array, ` + + `it is expected to have a length of 2, but received length ` + + `${args.strides.length}.`); + } + this.strides = args.strides; + } + else { + // `config.strides` is a number. + this.strides = [args.strides, args.strides]; + } + assertPositiveInteger(this.poolSize, 'poolSize'); + assertPositiveInteger(this.strides, 'strides'); + this.padding = args.padding == null ? 'valid' : args.padding; + this.dataFormat = + args.dataFormat == null ? 'channelsLast' : args.dataFormat; + checkDataFormat(this.dataFormat); + checkPaddingMode(this.padding); + this.inputSpec = [new InputSpec({ ndim: 4 })]; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + let rows = this.dataFormat === 'channelsFirst' ? inputShape[2] : inputShape[1]; + let cols = this.dataFormat === 'channelsFirst' ? inputShape[3] : inputShape[2]; + rows = + convOutputLength(rows, this.poolSize[0], this.padding, this.strides[0]); + cols = + convOutputLength(cols, this.poolSize[1], this.padding, this.strides[1]); + if (this.dataFormat === 'channelsFirst') { + return [inputShape[0], inputShape[1], rows, cols]; + } + else { + return [inputShape[0], rows, cols, inputShape[3]]; + } + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + return this.poolingFunction(getExactlyOneTensor(inputs), this.poolSize, this.strides, this.padding, this.dataFormat); + }); + } + getConfig() { + const config = { + poolSize: this.poolSize, + padding: this.padding, + strides: this.strides, + dataFormat: this.dataFormat + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + class MaxPooling2D extends Pooling2D { + constructor(args) { + super(args); + } + poolingFunction(inputs, poolSize, strides, padding, dataFormat) { + checkDataFormat(dataFormat); + checkPaddingMode(padding); + return pool2d(inputs, poolSize, strides, padding, dataFormat, 'max'); + } + } + /** @nocollapse */ + MaxPooling2D.className = 'MaxPooling2D'; + registerClass(MaxPooling2D); + class AveragePooling2D extends Pooling2D { + constructor(args) { + super(args); + } + poolingFunction(inputs, poolSize, strides, padding, dataFormat) { + checkDataFormat(dataFormat); + checkPaddingMode(padding); + return pool2d(inputs, poolSize, strides, padding, dataFormat, 'avg'); + } + } + /** @nocollapse */ + AveragePooling2D.className = 'AveragePooling2D'; + registerClass(AveragePooling2D); + /** + * Abstract class for different pooling 3D layers. + */ + class Pooling3D extends Layer { + constructor(args) { + if (args.poolSize == null) { + args.poolSize = [2, 2, 2]; + } + super(args); + this.poolSize = Array.isArray(args.poolSize) ? + args.poolSize : + [args.poolSize, args.poolSize, args.poolSize]; + if (args.strides == null) { + this.strides = this.poolSize; + } + else if (Array.isArray(args.strides)) { + if (args.strides.length !== 3) { + throw new ValueError(`If the strides property of a 3D pooling layer is an Array, ` + + `it is expected to have a length of 3, but received length ` + + `${args.strides.length}.`); + } + this.strides = args.strides; + } + else { + // `config.strides` is a number. + this.strides = [args.strides, args.strides, args.strides]; + } + assertPositiveInteger(this.poolSize, 'poolSize'); + assertPositiveInteger(this.strides, 'strides'); + this.padding = args.padding == null ? 'valid' : args.padding; + this.dataFormat = + args.dataFormat == null ? 'channelsLast' : args.dataFormat; + checkDataFormat(this.dataFormat); + checkPaddingMode(this.padding); + this.inputSpec = [new InputSpec({ ndim: 5 })]; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + let depths = this.dataFormat === 'channelsFirst' ? inputShape[2] : inputShape[1]; + let rows = this.dataFormat === 'channelsFirst' ? inputShape[3] : inputShape[2]; + let cols = this.dataFormat === 'channelsFirst' ? inputShape[4] : inputShape[3]; + depths = convOutputLength(depths, this.poolSize[0], this.padding, this.strides[0]); + rows = + convOutputLength(rows, this.poolSize[1], this.padding, this.strides[1]); + cols = + convOutputLength(cols, this.poolSize[2], this.padding, this.strides[2]); + if (this.dataFormat === 'channelsFirst') { + return [inputShape[0], inputShape[1], depths, rows, cols]; + } + else { + return [inputShape[0], depths, rows, cols, inputShape[4]]; + } + } + call(inputs, kwargs) { + return tidy(() => { + this.invokeCallHook(inputs, kwargs); + return this.poolingFunction(getExactlyOneTensor(inputs), this.poolSize, this.strides, this.padding, this.dataFormat); + }); + } + getConfig() { + const config = { + poolSize: this.poolSize, + padding: this.padding, + strides: this.strides, + dataFormat: this.dataFormat + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + class MaxPooling3D extends Pooling3D { + constructor(args) { + super(args); + } + poolingFunction(inputs, poolSize, strides, padding, dataFormat) { + checkDataFormat(dataFormat); + checkPaddingMode(padding); + return pool3d$1(inputs, poolSize, strides, padding, dataFormat, 'max'); + } + } + /** @nocollapse */ + MaxPooling3D.className = 'MaxPooling3D'; + registerClass(MaxPooling3D); + class AveragePooling3D extends Pooling3D { + constructor(args) { + super(args); + } + poolingFunction(inputs, poolSize, strides, padding, dataFormat) { + checkDataFormat(dataFormat); + checkPaddingMode(padding); + return pool3d$1(inputs, poolSize, strides, padding, dataFormat, 'avg'); + } + } + /** @nocollapse */ + AveragePooling3D.className = 'AveragePooling3D'; + registerClass(AveragePooling3D); + /** + * Abstract class for different global pooling 1D layers. + */ + class GlobalPooling1D extends Layer { + constructor(args) { + super(args); + this.inputSpec = [new InputSpec({ ndim: 3 })]; + } + computeOutputShape(inputShape) { + return [inputShape[0], inputShape[2]]; + } + call(inputs, kwargs) { + throw new NotImplementedError(); + } + } + class GlobalAveragePooling1D extends GlobalPooling1D { + constructor(args) { + super(args || {}); + } + call(inputs, kwargs) { + return tidy(() => { + const input = getExactlyOneTensor(inputs); + return mean$3(input, 1); + }); + } + } + /** @nocollapse */ + GlobalAveragePooling1D.className = 'GlobalAveragePooling1D'; + registerClass(GlobalAveragePooling1D); + class GlobalMaxPooling1D extends GlobalPooling1D { + constructor(args) { + super(args || {}); + } + call(inputs, kwargs) { + return tidy(() => { + const input = getExactlyOneTensor(inputs); + return max$3(input, 1); + }); + } + } + /** @nocollapse */ + GlobalMaxPooling1D.className = 'GlobalMaxPooling1D'; + registerClass(GlobalMaxPooling1D); + /** + * Abstract class for different global pooling 2D layers. + */ + class GlobalPooling2D extends Layer { + constructor(args) { + super(args); + this.dataFormat = + args.dataFormat == null ? 'channelsLast' : args.dataFormat; + checkDataFormat(this.dataFormat); + this.inputSpec = [new InputSpec({ ndim: 4 })]; + } + computeOutputShape(inputShape) { + inputShape = inputShape; + if (this.dataFormat === 'channelsLast') { + return [inputShape[0], inputShape[3]]; + } + else { + return [inputShape[0], inputShape[1]]; + } + } + call(inputs, kwargs) { + throw new NotImplementedError(); + } + getConfig() { + const config = { dataFormat: this.dataFormat }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + class GlobalAveragePooling2D extends GlobalPooling2D { + call(inputs, kwargs) { + return tidy(() => { + const input = getExactlyOneTensor(inputs); + if (this.dataFormat === 'channelsLast') { + return mean$3(input, [1, 2]); + } + else { + return mean$3(input, [2, 3]); + } + }); + } + } + /** @nocollapse */ + GlobalAveragePooling2D.className = 'GlobalAveragePooling2D'; + registerClass(GlobalAveragePooling2D); + class GlobalMaxPooling2D extends GlobalPooling2D { + call(inputs, kwargs) { + return tidy(() => { + const input = getExactlyOneTensor(inputs); + if (this.dataFormat === 'channelsLast') { + return max$3(input, [1, 2]); + } + else { + return max$3(input, [2, 3]); + } + }); + } + } + /** @nocollapse */ + GlobalMaxPooling2D.className = 'GlobalMaxPooling2D'; + registerClass(GlobalMaxPooling2D); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Abstract wrapper base class. + * + * Wrappers take another layer and augment it in various ways. + * Do not use this class as a layer, it is only an abstract base class. + * Two usable wrappers are the `TimeDistributed` and `Bidirectional` wrappers. + */ + class Wrapper extends Layer { + constructor(args) { + // Porting Note: In PyKeras, `self.layer` is set prior to the calling + // `super()`. But we can't do that here due to TypeScript's restriction. + // See: https://github.com/Microsoft/TypeScript/issues/8277 + // As a result, we have to add checks in `get trainable()` and + // `set trainable()` below in order to prevent using `this.layer` when + // its value is `undefined`. The super constructor does use the getter + // and the setter of `this.layer`. + super(args); + this.layer = args.layer; + } + build(inputShape) { + this.built = true; + } + // TODO(cais): Implement activityRegularizer getter. + get trainable() { + // Porting Note: the check of `this.layer` here is necessary due to the + // way the `constructor` of this class is written (see Porting Note + // above). + if (this.layer != null) { + return this.layer.trainable; + } + else { + return false; + } + } + set trainable(value) { + // Porting Note: the check of `this.layer` here is necessary due to the + // way the `constructor` of this class is written (see Porting Note + // above). + if (this.layer != null) { + this.layer.trainable = value; + } + } + get trainableWeights() { + return this.layer.trainableWeights; + } + // TODO(cais): Implement setter for trainableWeights. + get nonTrainableWeights() { + return this.layer.nonTrainableWeights; + } + // TODO(cais): Implement setter for nonTrainableWeights. + get updates() { + // tslint:disable-next-line:no-any + return this.layer._updates; + } + // TODO(cais): Implement getUpdatesFor(). + get losses() { + return this.layer.losses; + } + // TODO(cais): Implement getLossesFor(). + getWeights() { + return this.layer.getWeights(); + } + setWeights(weights) { + this.layer.setWeights(weights); + } + getConfig() { + const config = { + 'layer': { + 'className': this.layer.getClassName(), + 'config': this.layer.getConfig(), + } + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + setFastWeightInitDuringBuild(value) { + super.setFastWeightInitDuringBuild(value); + if (this.layer != null) { + this.layer.setFastWeightInitDuringBuild(value); + } + } + /** @nocollapse */ + static fromConfig(cls, config, customObjects = {}) { + const layerConfig = config['layer']; + const layer = deserialize(layerConfig, customObjects); + delete config['layer']; + const newConfig = { layer }; + Object.assign(newConfig, config); + return new cls(newConfig); + } + } + class TimeDistributed extends Wrapper { + constructor(args) { + super(args); + this.supportsMasking = true; + } + build(inputShape) { + inputShape = getExactlyOneShape(inputShape); + if (inputShape.length < 3) { + throw new ValueError(`TimeDistributed layer expects an input shape >= 3D, but received ` + + `input shape ${JSON.stringify(inputShape)}`); + } + this.inputSpec = [{ shape: inputShape }]; + const childInputShape = [inputShape[0]].concat(inputShape.slice(2)); + if (!this.layer.built) { + this.layer.build(childInputShape); + this.layer.built = true; + } + super.build(inputShape); + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const childInputShape = [inputShape[0]].concat(inputShape.slice(2)); + const childOutputShape = this.layer.computeOutputShape(childInputShape); + const timesteps = inputShape[1]; + return [childOutputShape[0], timesteps].concat(childOutputShape.slice(1)); + } + call(inputs, kwargs) { + return tidy(() => { + // TODO(cais): Add 'training' and 'useLearningPhase' to kwargs. + inputs = getExactlyOneTensor(inputs); + // Porting Note: In tfjs-layers, `inputs` are always concrete tensor + // values. Hence the inputs can't have an undetermined first (batch) + // dimension, which is why we always use the K.rnn approach here. + const step = (inputs, states) => { + // TODO(cais): Add useLearningPhase. + // NOTE(cais): `layer.call` may return a length-1 array of Tensor in + // some cases (e.g., `layer` is a `Sequential` instance), which is + // why `getExactlyOneTensor` is used below. + const output = getExactlyOneTensor(this.layer.call(inputs, kwargs)); + return [output, []]; + }; + const rnnOutputs = rnn$1(step, inputs, [], false /* goBackwards */, null /* mask */, null /* constants */, false /* unroll */, true /* needPerStepOutputs */); + const y = rnnOutputs[1]; + // TODO(cais): Add activity regularization. + // TODO(cais): Add useLearningPhase. + return y; + }); + } + } + /** @nocollapse */ + TimeDistributed.className = 'TimeDistributed'; + registerClass(TimeDistributed); + function checkBidirectionalMergeMode(value) { + checkStringTypeUnionValue(VALID_BIDIRECTIONAL_MERGE_MODES, 'BidirectionalMergeMode', value); + } + const DEFAULT_BIDIRECTIONAL_MERGE_MODE = 'concat'; + class Bidirectional extends Wrapper { + constructor(args) { + super(args); + // Note: When creating `this.forwardLayer`, the original Layer object + // (`config.layer`) ought to be cloned. This is why we call + // `getConfig()` followed by `deserialize()`. Without this cloning, + // the layer names saved during serialization will incorrectly contain + // the 'forward_' prefix. In Python Keras, this is done using + // `copy.copy` (shallow copy), which does not have a simple equivalent + // in JavaScript. JavaScript's `Object.assign()` does not copy + // methods. + const layerConfig = args.layer.getConfig(); + const forwDict = {}; + forwDict['className'] = args.layer.getClassName(); + forwDict['config'] = layerConfig; + this.forwardLayer = deserialize(forwDict); + layerConfig['goBackwards'] = + layerConfig['goBackwards'] === true ? false : true; + const backDict = {}; + backDict['className'] = args.layer.getClassName(); + backDict['config'] = layerConfig; + this.backwardLayer = deserialize(backDict); + this.forwardLayer.name = 'forward_' + this.forwardLayer.name; + this.backwardLayer.name = 'backward_' + this.backwardLayer.name; + this.mergeMode = args.mergeMode === undefined ? + DEFAULT_BIDIRECTIONAL_MERGE_MODE : + args.mergeMode; + checkBidirectionalMergeMode(this.mergeMode); + if (args.weights) { + throw new NotImplementedError('weights support is not implemented for Bidirectional layer yet.'); + } + this._stateful = args.layer.stateful; + this.returnSequences = args.layer.returnSequences; + this.returnState = args.layer.returnState; + this.supportsMasking = true; + this._trainable = true; + this.inputSpec = args.layer.inputSpec; + this.numConstants = null; + } + get trainable() { + return this._trainable; + } + set trainable(value) { + // Porting Note: the check of `this.layer` here is necessary due to the + // way the `constructor` of this class is written (see Porting Note + // above). + this._trainable = value; + if (this.forwardLayer != null) { + this.forwardLayer.trainable = value; + } + if (this.backwardLayer != null) { + this.backwardLayer.trainable = value; + } + } + getWeights() { + return this.forwardLayer.getWeights().concat(this.backwardLayer.getWeights()); + } + setWeights(weights) { + const numWeights = weights.length; + const numeightsOver2 = Math.floor(numWeights / 2); + this.forwardLayer.setWeights(weights.slice(0, numeightsOver2)); + this.backwardLayer.setWeights(weights.slice(numeightsOver2)); + } + computeOutputShape(inputShape) { + let layerShapes = this.forwardLayer.computeOutputShape(inputShape); + if (!(Array.isArray(layerShapes) && Array.isArray(layerShapes[0]))) { + layerShapes = [layerShapes]; + } + layerShapes = layerShapes; + let outputShape; + let outputShapes; + let stateShape; + if (this.returnState) { + stateShape = layerShapes.slice(1); + outputShape = layerShapes[0]; + } + else { + outputShape = layerShapes[0]; + } + outputShape = outputShape; + if (this.mergeMode === 'concat') { + outputShape[outputShape.length - 1] *= 2; + outputShapes = [outputShape]; + } + else if (this.mergeMode == null) { + outputShapes = [outputShape, outputShape.slice()]; + } + else { + outputShapes = [outputShape]; + } + if (this.returnState) { + if (this.mergeMode == null) { + return outputShapes.concat(stateShape).concat(stateShape.slice()); + } + return [outputShape].concat(stateShape).concat(stateShape.slice()); + } + return singletonOrArray(outputShapes); + } + apply(inputs, kwargs) { + let initialState = kwargs == null ? null : kwargs['initialState']; + let constants = kwargs == null ? null : kwargs['constants']; + if (kwargs == null) { + kwargs = {}; + } + const standardized = standardizeArgs(inputs, initialState, constants, this.numConstants); + inputs = standardized.inputs; + initialState = standardized.initialState; + constants = standardized.constants; + if (Array.isArray(inputs)) { + initialState = inputs.slice(1); + inputs = inputs[0]; + } + if ((initialState == null || initialState.length === 0) && + constants == null) { + return super.apply(inputs, kwargs); + } + const additionalInputs = []; + const additionalSpecs = []; + if (initialState != null) { + const numStates = initialState.length; + if (numStates % 2 > 0) { + throw new ValueError('When passing `initialState` to a Bidrectional RNN, ' + + 'the state should be an Array containing the states of ' + + 'the underlying RNNs.'); + } + kwargs['initialState'] = initialState; + additionalInputs.push(...initialState); + const stateSpecs = initialState + .map(state => new InputSpec({ shape: state.shape })); + this.forwardLayer.stateSpec = stateSpecs.slice(0, numStates / 2); + this.backwardLayer.stateSpec = stateSpecs.slice(numStates / 2); + additionalSpecs.push(...stateSpecs); + } + if (constants != null) { + throw new NotImplementedError('Support for constants in Bidirectional layers is not ' + + 'implemented yet.'); + } + const isSymbolicTensor = additionalInputs[0] instanceof SymbolicTensor; + for (const tensor of additionalInputs) { + if (tensor instanceof SymbolicTensor !== isSymbolicTensor) { + throw new ValueError('The initial state of a Bidirectional layer cannot be ' + + 'specified as a mix of symbolic and non-symbolic tensors'); + } + } + if (isSymbolicTensor) { + // Compute the full input and specs, including the states. + const fullInput = [inputs].concat(additionalInputs); + const fullInputSpec = this.inputSpec.concat(additionalSpecs); + // Perform the call temporarily and replace inputSpec. + // Note: with initial states symbolic calls and non-symbolic calls to + // this method differ in how the initial states are passed. For + // symbolic calls, the initial states are passed in the first arg, as + // an Array of SymbolicTensors; for non-symbolic calls, they are + // passed in the second arg as a part of the kwargs. Hence the need to + // temporarily modify inputSpec here. + // TODO(cais): Make refactoring so that this hacky code below is no + // longer needed. + const originalInputSpec = this.inputSpec; + this.inputSpec = fullInputSpec; + const output = super.apply(fullInput, kwargs); + this.inputSpec = originalInputSpec; + return output; + } + else { + return super.apply(inputs, kwargs); + } + } + call(inputs, kwargs) { + return tidy(() => { + const initialState = kwargs['initialState']; + let y; + let yRev; + if (initialState == null) { + y = this.forwardLayer.call(inputs, kwargs); + yRev = this.backwardLayer.call(inputs, kwargs); + } + else { + const forwardState = initialState.slice(0, initialState.length / 2); + const backwardState = initialState.slice(initialState.length / 2); + y = this.forwardLayer.call(inputs, Object.assign(kwargs, { initialState: forwardState })); + yRev = this.backwardLayer.call(inputs, Object.assign(kwargs, { initialState: backwardState })); + } + let states; + if (this.returnState) { + if (Array.isArray(y)) { + states = y.slice(1).concat(yRev.slice(1)); + } + else { + } + y = y[0]; + yRev = yRev[0]; + } + if (this.returnSequences) { + yRev = reverse$2(yRev, 1); + } + let output; + if (this.mergeMode === 'concat') { + output = concatenate$2([y, yRev]); + } + else if (this.mergeMode === 'sum') { + output = add$3(y, yRev); + } + else if (this.mergeMode === 'ave') { + output = mul(.5, add$3(y, yRev)); + } + else if (this.mergeMode === 'mul') { + output = mul(y, yRev); + } + else if (this.mergeMode == null) { + output = [y, yRev]; + } + // TODO(cais): Properly set learning phase. + if (this.returnState) { + if (this.mergeMode == null) { + return output.concat(states); + } + return [output].concat(states); + } + return output; + }); + } + resetStates(states) { + this.forwardLayer.resetStates(); + this.backwardLayer.resetStates(); + } + build(inputShape) { + nameScope(this.forwardLayer.name, () => { + this.forwardLayer.build(inputShape); + }); + nameScope(this.backwardLayer.name, () => { + this.backwardLayer.build(inputShape); + }); + this.built = true; + } + computeMask(inputs, mask) { + if (Array.isArray(mask)) { + mask = mask[0]; + } + let outputMask; + if (this.returnSequences) { + if (this.mergeMode == null) { + outputMask = [mask, mask]; + } + else { + outputMask = mask; + } + } + else { + if (this.mergeMode == null) { + outputMask = [null, null]; + } + else { + outputMask = null; + } + } + if (this.returnState) { + const states = this.forwardLayer.states; + const stateMask = states.map(state => null); + if (Array.isArray(outputMask)) { + return outputMask.concat(stateMask).concat(stateMask); + } + else { + return [outputMask].concat(stateMask).concat(stateMask); + } + } + else { + return outputMask; + } + } + get trainableWeights() { + return this.forwardLayer.trainableWeights.concat(this.backwardLayer.trainableWeights); + } + get nonTrainableWeights() { + return this.forwardLayer.nonTrainableWeights.concat(this.backwardLayer.nonTrainableWeights); + } + // TODO(cais): Implement constraints(). + setFastWeightInitDuringBuild(value) { + super.setFastWeightInitDuringBuild(value); + if (this.forwardLayer != null) { + this.forwardLayer.setFastWeightInitDuringBuild(value); + } + if (this.backwardLayer != null) { + this.backwardLayer.setFastWeightInitDuringBuild(value); + } + } + getConfig() { + const config = { + 'mergeMode': this.mergeMode, + }; + // TODO(cais): Add logic for `numConstants` once the property is added. + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + /** @nocollapse */ + static fromConfig(cls, config) { + const rnnLayer = deserialize(config['layer']); + delete config['layer']; + // TODO(cais): Add logic for `numConstants` once the property is added. + if (config['numConstants'] != null) { + throw new NotImplementedError(`Deserialization of a Bidirectional layer with numConstants ` + + `present is not supported yet.`); + } + // tslint:disable-next-line:no-any + const newConfig = config; + newConfig['layer'] = rnnLayer; + return new cls(newConfig); + } + } + /** @nocollapse */ + Bidirectional.className = 'Bidirectional'; + registerClass(Bidirectional); + + /** + * @license + * Copyright 2022 CodeSmith LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Preprocessing Rescaling Layer + * + * This rescales images by a scaling and offset factor + */ + class Rescaling extends Layer { + constructor(args) { + super(args); + this.scale = args.scale; + if (args.offset) { + this.offset = args.offset; + } + else { + this.offset = 0; + } + } + getConfig() { + const config = { + 'scale': this.scale, + 'offset': this.offset + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + call(inputs, kwargs) { + return tidy(() => { + inputs = getExactlyOneTensor(inputs); + if (inputs.dtype !== 'float32') { + inputs = cast$2(inputs, 'float32'); + } + return add$3(mul(inputs, this.scale), this.offset); + }); + } + } + /** @nocollapse */ + Rescaling.className = 'Rescaling'; + registerClass(Rescaling); + + /** + * @license + * Copyright 2022 CodeSmith LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + const { resizeBilinear: resizeBilinear$2, cropAndResize: cropAndResize$2 } = image$1; + class CenterCrop extends Layer { + constructor(args) { + super(args); + this.height = args.height; + this.width = args.width; + } + centerCrop(inputs, hBuffer, wBuffer, height, width, inputHeight, inputWidth, dtype) { + return tidy(() => { + let input; + let isRank3 = false; + const top = hBuffer / inputHeight; + const left = wBuffer / inputWidth; + const bottom = ((height) + hBuffer) / inputHeight; + const right = ((width) + wBuffer) / inputWidth; + const bound = [top, left, bottom, right]; + const boxesArr = []; + if (inputs.rank === 3) { + isRank3 = true; + input = stack([inputs]); + } + else { + input = inputs; + } + for (let i = 0; i < input.shape[0]; i++) { + boxesArr.push(bound); + } + const boxes = tensor(boxesArr, [boxesArr.length, 4]); + const boxInd = range$3(0, boxesArr.length, 1, 'int32'); + const cropSize = [height, width]; + const cropped = cropAndResize$2(input, boxes, boxInd, cropSize, 'nearest'); + if (isRank3) { + return cast$2(getExactlyOneTensor(unstack(cropped)), dtype); + } + return cast$2(cropped, dtype); + }); + } + upsize(inputs, height, width, dtype) { + return tidy(() => { + const outputs = resizeBilinear$2(inputs, [height, width]); + return cast$2(outputs, dtype); + }); + } + call(inputs, kwargs) { + return tidy(() => { + const rankedInputs = getExactlyOneTensor(inputs); + const dtype = rankedInputs.dtype; + const inputShape = rankedInputs.shape; + const inputHeight = inputShape[inputShape.length - 3]; + const inputWidth = inputShape[inputShape.length - 2]; + let hBuffer = 0; + if (inputHeight !== this.height) { + hBuffer = Math.floor((inputHeight - this.height) / 2); + } + let wBuffer = 0; + if (inputWidth !== this.width) { + wBuffer = Math.floor((inputWidth - this.width) / 2); + if (wBuffer === 0) { + wBuffer = 1; + } + } + if (hBuffer >= 0 && wBuffer >= 0) { + return this.centerCrop(rankedInputs, hBuffer, wBuffer, this.height, this.width, inputHeight, inputWidth, dtype); + } + else { + return this.upsize(inputs, this.height, this.width, dtype); + } + }); + } + getConfig() { + const config = { + 'height': this.height, + 'width': this.width + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const hAxis = inputShape.length - 3; + const wAxis = inputShape.length - 2; + inputShape[hAxis] = this.height; + inputShape[wAxis] = this.width; + return inputShape; + } + } + /** @nocollapse */ + CenterCrop.className = 'CenterCrop'; + registerClass(CenterCrop); + + /** + * @license + * Copyright 2022 CodeSmith LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + function encodeCategoricalInputs(inputs, outputMode, depth, weights) { + let input = getExactlyOneTensor(inputs); + if (input.dtype !== 'int32') { + input = cast$2(input, 'int32'); + } + if (outputMode === 'int') { + return input; + } + const originalShape = input.shape; + if (input.rank === 0) { + input = expandDims$3(input, -1); + } + if (outputMode === 'oneHot') { + if (input.shape[input.shape.length - 1] !== 1) { + input = expandDims$3(input, -1); + } + } + if (input.rank > 2) { + throw new ValueError(`When outputMode is not int, maximum output rank is 2` + + ` Received outputMode ${outputMode} and input shape ${originalShape}` + + ` which would result in output rank ${input.rank}.`); + } + const binaryOutput = ['multiHot', 'oneHot'].includes(outputMode); + const denseBincountInput = input; + let binCounts; + if ((typeof weights) !== 'undefined' && outputMode === 'count') { + binCounts = denseBincount$2(denseBincountInput, weights, depth, binaryOutput); + } + else { + binCounts = denseBincount$2(denseBincountInput, [], depth, binaryOutput); + } + if (outputMode !== 'tfIdf') { + return binCounts; + } + if (weights) { + return mul(binCounts, weights); + } + else { + throw new ValueError(`When outputMode is 'tfIdf', weights must be provided.`); + } + } + + /** + * @license + * Copyright 2022 CodeSmith LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + class CategoryEncoding extends Layer { + constructor(args) { + super(args); + this.numTokens = args.numTokens; + if (args.outputMode) { + this.outputMode = args.outputMode; + } + else { + this.outputMode = 'multiHot'; + } + } + getConfig() { + const config = { + 'numTokens': this.numTokens, + 'outputMode': this.outputMode, + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + if (inputShape == null) { + return [this.numTokens]; + } + if (this.outputMode === 'oneHot' && inputShape[inputShape.length - 1] !== 1) { + inputShape.push(this.numTokens); + return inputShape; + } + inputShape[inputShape.length - 1] = this.numTokens; + return inputShape; + } + call(inputs, kwargs) { + return tidy(() => { + inputs = getExactlyOneTensor(inputs); + if (inputs.dtype !== 'int32') { + inputs = cast$2(inputs, 'int32'); + } + let countWeights; + if ((typeof kwargs['countWeights']) !== 'undefined') { + if (this.outputMode !== 'count') { + throw new ValueError(`countWeights is not used when outputMode !== count. + Received countWeights=${kwargs['countWeights']}`); + } + countWeights + = getExactlyOneTensor(kwargs['countWeights']); + } + const maxValue = max$3(inputs); + const minValue = min$3(inputs); + const greaterEqualMax = greater$3(this.numTokens, maxValue) + .bufferSync().get(0); + const greaterMin = greaterEqual$2(minValue, 0).bufferSync().get(0); + if (!(greaterEqualMax && greaterMin)) { + throw new ValueError('Input values must be between 0 < values <=' + + ` numTokens with numTokens=${this.numTokens}`); + } + return encodeCategoricalInputs(inputs, this.outputMode, this.numTokens, countWeights); + }); + } + } + /** @nocollapse */ + CategoryEncoding.className = 'CategoryEncoding'; + registerClass(CategoryEncoding); + + /** + * @license + * Copyright 2022 CodeSmith LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // tf methods unimplemented in tfjs: 'bicubic', 'area', 'lanczos3', 'lanczos5', + // 'gaussian', 'mitchellcubic' + const INTERPOLATION_KEYS$1 = ['bilinear', 'nearest']; + const INTERPOLATION_METHODS$1 = new Set(INTERPOLATION_KEYS$1); + /** + * Preprocessing Resizing Layer + * + * This resizes images by a scaling and offset factor + */ + class Resizing extends Layer { + constructor(args) { + super(args); + this.height = args.height; + this.width = args.width; + if (args.interpolation) { + if (INTERPOLATION_METHODS$1.has(args.interpolation)) { + this.interpolation = args.interpolation; + } + else { + throw new ValueError(`Invalid interpolation parameter: ${args.interpolation} is not implemented`); + } + } + else { + this.interpolation = 'bilinear'; + } + this.cropToAspectRatio = Boolean(args.cropToAspectRatio); + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const numChannels = inputShape[2]; + return [this.height, this.width, numChannels]; + } + getConfig() { + const config = { + 'height': this.height, + 'width': this.width, + 'interpolation': this.interpolation, + 'cropToAspectRatio': this.cropToAspectRatio + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + call(inputs, kwargs) { + return tidy(() => { + const size = [this.height, this.width]; + if (this.interpolation === 'bilinear') { + return image$1.resizeBilinear(inputs, size, !this.cropToAspectRatio); + } + else if (this.interpolation === 'nearest') { + return image$1.resizeNearestNeighbor(inputs, size, !this.cropToAspectRatio); + } + else { + throw new Error(`Interpolation is ${this.interpolation} but only ${[...INTERPOLATION_METHODS$1]} are supported`); + } + }); + } + } + /** @nocollapse */ + Resizing.className = 'Resizing'; + registerClass(Resizing); + + /** + * @license + * Copyright 2023 CodeSmith LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Keeps track of seed and handles pseudorandomness + * Instance created in BaseRandomLayer class + * Utilized for random preprocessing layers + */ + class RandomSeed { + constructor(seed) { + this.seed = seed; + } + next() { + if (this.seed === undefined) { + return undefined; + } + return this.seed++; + } + } + RandomSeed.className = 'RandomSeed'; + + /** + * @license + * Copyright 2023 CodeSmith LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + class BaseRandomLayer extends Layer { + constructor(args) { + super(args); + this.randomGenerator = new RandomSeed(args.seed); + } + getConfig() { + const config = { + 'seed': this.randomGenerator.seed + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + } + // A layer handle the random number creation and savemodel behavior. + /** @nocollapse */ + BaseRandomLayer.className = 'BaseRandomLayer'; + + /** + * @license + * Copyright 2023 CodeSmith LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + const INTERPOLATION_KEYS = ['bilinear', 'nearest']; + const INTERPOLATION_METHODS = new Set(INTERPOLATION_KEYS); + /** + * Preprocessing Layer with randomly varies image during training + * + * This layer randomly adjusts the width of a batch of images of a + * batch of images by a random factor. + * + * The input should be a 3D (unbatched) or + * 4D (batched) tensor in the `"channels_last"` image data format. Input pixel + * values can be of any range (e.g. `[0., 1.)` or `[0, 255]`) and of integer + * or floating point dtype. By default, the layer will output floats. + * + * tf methods implemented in tfjs: 'bilinear', 'nearest', + * tf methods unimplemented in tfjs: 'bicubic', 'area', 'lanczos3', 'lanczos5', + * 'gaussian', 'mitchellcubic' + * + */ + class RandomWidth extends BaseRandomLayer { + constructor(args) { + super(args); + const { factor, interpolation = 'bilinear' } = args; + this.factor = factor; + if (Array.isArray(this.factor) && this.factor.length === 2) { + this.widthLower = this.factor[0]; + this.widthUpper = this.factor[1]; + } + else if (!Array.isArray(this.factor) && this.factor > 0) { + this.widthLower = -this.factor; + this.widthUpper = this.factor; + } + else { + throw new ValueError(`Invalid factor: ${this.factor}. Must be positive number or tuple of 2 numbers`); + } + if (this.widthLower < -1.0 || this.widthUpper < -1.0) { + throw new ValueError(`factor must have values larger than -1. Got: ${this.factor}`); + } + if (this.widthUpper < this.widthLower) { + throw new ValueError(`factor cannot have upper bound less than lower bound. + Got upper bound: ${this.widthUpper}. + Got lower bound: ${this.widthLower} + `); + } + if (interpolation) { + if (INTERPOLATION_METHODS.has(interpolation)) { + this.interpolation = interpolation; + } + else { + throw new ValueError(`Invalid interpolation parameter: ${interpolation} is not implemented`); + } + } + } + getConfig() { + const config = { + 'factor': this.factor, + 'interpolation': this.interpolation, + }; + const baseConfig = super.getConfig(); + Object.assign(config, baseConfig); + return config; + } + computeOutputShape(inputShape) { + inputShape = getExactlyOneShape(inputShape); + const numChannels = inputShape[2]; + return [this.imgHeight, -1, numChannels]; + } + call(inputs, kwargs) { + return tidy(() => { + const input = getExactlyOneTensor(inputs); + this.imgHeight = input.shape[input.shape.length - 3]; + const imgWidth = input.shape[input.shape.length - 2]; + this.widthFactor = randomUniform$1([1], (1.0 + this.widthLower), (1.0 + this.widthUpper), 'float32', this.randomGenerator.next()); + let adjustedWidth = this.widthFactor.dataSync()[0] * imgWidth; + adjustedWidth = Math.round(adjustedWidth); + const size = [this.imgHeight, adjustedWidth]; + switch (this.interpolation) { + case 'bilinear': + return image$1.resizeBilinear(inputs, size); + case 'nearest': + return image$1.resizeNearestNeighbor(inputs, size); + default: + throw new Error(`Interpolation is ${this.interpolation} + but only ${[...INTERPOLATION_METHODS]} are supported`); + } + }); + } + } + /** @nocollapse */ + RandomWidth.className = 'RandomWidth'; + registerClass(RandomWidth); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + // TODO(cais): Add doc string to all the public static functions in this + // class; include exectuable JavaScript code snippets where applicable + // (b/74074458). + // Input Layer. + /** + * An input layer is an entry point into a `tf.LayersModel`. + * + * `InputLayer` is generated automatically for `tf.Sequential` models by + * specifying the `inputshape` or `batchInputShape` for the first layer. It + * should not be specified explicitly. However, it can be useful sometimes, + * e.g., when constructing a sequential model from a subset of another + * sequential model's layers. Like the code snippet below shows. + * + * ```js + * // Define a model which simply adds two inputs. + * const model1 = tf.sequential(); + * model1.add(tf.layers.dense({inputShape: [4], units: 3, activation: 'relu'})); + * model1.add(tf.layers.dense({units: 1, activation: 'sigmoid'})); + * model1.summary(); + * model1.predict(tf.zeros([1, 4])).print(); + * + * // Construct another model, reusing the second layer of `model1` while + * // not using the first layer of `model1`. Note that you cannot add the second + * // layer of `model` directly as the first layer of the new sequential model, + * // because doing so will lead to an error related to the fact that the layer + * // is not an input layer. Instead, you need to create an `inputLayer` and add + * // it to the new sequential model before adding the reused layer. + * const model2 = tf.sequential(); + * // Use an inputShape that matches the input shape of `model1`'s second + * // layer. + * model2.add(tf.layers.inputLayer({inputShape: [3]})); + * model2.add(model1.layers[1]); + * model2.summary(); + * model2.predict(tf.zeros([1, 3])).print(); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Inputs', namespace: 'layers'} + */ + function inputLayer(args) { + return new InputLayer(args); + } + // Advanced Activation Layers. + /** + * Exponential Linear Unit (ELU). + * + * It follows: + * `f(x) = alpha * (exp(x) - 1.) for x < 0`, + * `f(x) = x for x >= 0`. + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * References: + * - [Fast and Accurate Deep Network Learning by Exponential Linear Units + * (ELUs)](https://arxiv.org/abs/1511.07289v1) + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ + function elu$2(args) { + return new ELU$3(args); + } + /** + * Rectified Linear Unit activation function. + * + * Input shape: + * Arbitrary. Use the config field `inputShape` (Array of integers, does + * not include the sample axis) when using this layer as the first layer + * in a model. + * + * Output shape: + * Same shape as the input. + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ + function reLU(args) { + return new ReLU(args); + } + /** + * Leaky version of a rectified linear unit. + * + * It allows a small gradient when the unit is not active: + * `f(x) = alpha * x for x < 0.` + * `f(x) = x for x >= 0.` + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ + function leakyReLU(args) { + return new LeakyReLU(args); + } + /** + * Parameterized version of a leaky rectified linear unit. + * + * It follows + * `f(x) = alpha * x for x < 0.` + * `f(x) = x for x >= 0.` + * wherein `alpha` is a trainable weight. + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ + function prelu$2(args) { + return new PReLU(args); + } + /** + * Softmax activation layer. + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ + function softmax$2(args) { + return new Softmax(args); + } + /** + * Thresholded Rectified Linear Unit. + * + * It follows: + * `f(x) = x for x > theta`, + * `f(x) = 0 otherwise`. + * + * Input shape: + * Arbitrary. Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * Output shape: + * Same shape as the input. + * + * References: + * - [Zero-Bias Autoencoders and the Benefits of Co-Adapting + * Features](http://arxiv.org/abs/1402.3337) + * + * @doc { + * heading: 'Layers', + * subheading: 'Advanced Activation', + * namespace: 'layers' + * } + */ + function thresholdedReLU(args) { + return new ThresholdedReLU(args); + } + // Convolutional Layers. + /** + * 1D convolution layer (e.g., temporal convolution). + * + * This layer creates a convolution kernel that is convolved + * with the layer input over a single spatial (or temporal) dimension + * to produce a tensor of outputs. + * + * If `use_bias` is True, a bias vector is created and added to the outputs. + * + * If `activation` is not `null`, it is applied to the outputs as well. + * + * When using this layer as the first layer in a model, provide an + * `inputShape` argument `Array` or `null`. + * + * For example, `inputShape` would be: + * - `[10, 128]` for sequences of 10 vectors of 128-dimensional vectors + * - `[null, 128]` for variable-length sequences of 128-dimensional vectors. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ + function conv1d(args) { + return new Conv1D(args); + } + /** + * 2D convolution layer (e.g. spatial convolution over images). + * + * This layer creates a convolution kernel that is convolved + * with the layer input to produce a tensor of outputs. + * + * If `useBias` is True, a bias vector is created and added to the outputs. + * + * If `activation` is not `null`, it is applied to the outputs as well. + * + * When using this layer as the first layer in a model, + * provide the keyword argument `inputShape` + * (Array of integers, does not include the sample axis), + * e.g. `inputShape=[128, 128, 3]` for 128x128 RGB pictures + * in `dataFormat='channelsLast'`. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ + function conv2d$1(args) { + return new Conv2D(args); + } + /** + * Transposed convolutional layer (sometimes called Deconvolution). + * + * The need for transposed convolutions generally arises + * from the desire to use a transformation going in the opposite direction of + * a normal convolution, i.e., from something that has the shape of the output + * of some convolution to something that has the shape of its input while + * maintaining a connectivity pattern that is compatible with said + * convolution. + * + * When using this layer as the first layer in a model, provide the + * configuration `inputShape` (`Array` of integers, does not include the + * sample axis), e.g., `inputShape: [128, 128, 3]` for 128x128 RGB pictures in + * `dataFormat: 'channelsLast'`. + * + * Input shape: + * 4D tensor with shape: + * `[batch, channels, rows, cols]` if `dataFormat` is `'channelsFirst'`. + * or 4D tensor with shape + * `[batch, rows, cols, channels]` if `dataFormat` is `'channelsLast'`. + * + * Output shape: + * 4D tensor with shape: + * `[batch, filters, newRows, newCols]` if `dataFormat` is + * `'channelsFirst'`. or 4D tensor with shape: + * `[batch, newRows, newCols, filters]` if `dataFormat` is `'channelsLast'`. + * + * References: + * - [A guide to convolution arithmetic for deep + * learning](https://arxiv.org/abs/1603.07285v1) + * - [Deconvolutional + * Networks](http://www.matthewzeiler.com/pubs/cvpr2010/cvpr2010.pdf) + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ + function conv2dTranspose(args) { + return new Conv2DTranspose(args); + } + /** + * 3D convolution layer (e.g. spatial convolution over volumes). + * + * This layer creates a convolution kernel that is convolved + * with the layer input to produce a tensor of outputs. + * + * If `useBias` is True, a bias vector is created and added to the outputs. + * + * If `activation` is not `null`, it is applied to the outputs as well. + * + * When using this layer as the first layer in a model, + * provide the keyword argument `inputShape` + * (Array of integers, does not include the sample axis), + * e.g. `inputShape=[128, 128, 128, 1]` for 128x128x128 grayscale volumes + * in `dataFormat='channelsLast'`. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ + function conv3d(args) { + return new Conv3D(args); + } + function conv3dTranspose(args) { + return new Conv3DTranspose(args); + } + /** + * Depthwise separable 2D convolution. + * + * Separable convolution consists of first performing + * a depthwise spatial convolution + * (which acts on each input channel separately) + * followed by a pointwise convolution which mixes together the resulting + * output channels. The `depthMultiplier` argument controls how many + * output channels are generated per input channel in the depthwise step. + * + * Intuitively, separable convolutions can be understood as + * a way to factorize a convolution kernel into two smaller kernels, + * or as an extreme version of an Inception block. + * + * Input shape: + * 4D tensor with shape: + * `[batch, channels, rows, cols]` if data_format='channelsFirst' + * or 4D tensor with shape: + * `[batch, rows, cols, channels]` if data_format='channelsLast'. + * + * Output shape: + * 4D tensor with shape: + * `[batch, filters, newRows, newCols]` if data_format='channelsFirst' + * or 4D tensor with shape: + * `[batch, newRows, newCols, filters]` if data_format='channelsLast'. + * `rows` and `cols` values might have changed due to padding. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ + function separableConv2d(args) { + return new SeparableConv2D(args); + } + /** + * Cropping layer for 2D input (e.g., image). + * + * This layer can crop an input + * at the top, bottom, left and right side of an image tensor. + * + * Input shape: + * 4D tensor with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, rows, cols, channels]` + * - If `data_format` is `"channels_first"`: + * `[batch, channels, rows, cols]`. + * + * Output shape: + * 4D with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, croppedRows, croppedCols, channels]` + * - If `dataFormat` is `"channelsFirst"`: + * `[batch, channels, croppedRows, croppedCols]`. + * + * Examples + * ```js + * + * const model = tf.sequential(); + * model.add(tf.layers.cropping2D({cropping:[[2, 2], [2, 2]], + * inputShape: [128, 128, 3]})); + * //now output shape is [batch, 124, 124, 3] + * ``` + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ + function cropping2D(args) { + return new Cropping2D(args); + } + /** + * Upsampling layer for 2D inputs. + * + * Repeats the rows and columns of the data + * by size[0] and size[1] respectively. + * + * + * Input shape: + * 4D tensor with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, rows, cols, channels]` + * - If `dataFormat` is `"channelsFirst"`: + * `[batch, channels, rows, cols]` + * + * Output shape: + * 4D tensor with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, upsampledRows, upsampledCols, channels]` + * - If `dataFormat` is `"channelsFirst"`: + * `[batch, channels, upsampledRows, upsampledCols]` + * + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ + function upSampling2d(args) { + return new UpSampling2D(args); + } + // Convolutional(depthwise) Layers. + /** + * Depthwise separable 2D convolution. + * + * Depthwise Separable convolutions consists in performing just the first step + * in a depthwise spatial convolution (which acts on each input channel + * separately). The `depthMultiplier` argument controls how many output channels + * are generated per input channel in the depthwise step. + * + * @doc {heading: 'Layers', subheading: 'Convolutional', namespace: 'layers'} + */ + function depthwiseConv2d(args) { + return new DepthwiseConv2D(args); + } + // Basic Layers. + /** + * Applies an activation function to an output. + * + * This layer applies element-wise activation function. Other layers, notably + * `dense` can also apply activation functions. Use this isolated activation + * function to extract the values before and after the + * activation. For instance: + * + * ```js + * const input = tf.input({shape: [5]}); + * const denseLayer = tf.layers.dense({units: 1}); + * const activationLayer = tf.layers.activation({activation: 'relu6'}); + * + * // Obtain the output symbolic tensors by applying the layers in order. + * const denseOutput = denseLayer.apply(input); + * const activationOutput = activationLayer.apply(denseOutput); + * + * // Create the model based on the inputs. + * const model = tf.model({ + * inputs: input, + * outputs: [denseOutput, activationOutput] + * }); + * + * // Collect both outputs and print separately. + * const [denseOut, activationOut] = model.predict(tf.randomNormal([6, 5])); + * denseOut.print(); + * activationOut.print(); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ + function activation(args) { + return new Activation(args); + } + /** + * Creates a dense (fully connected) layer. + * + * This layer implements the operation: + * `output = activation(dot(input, kernel) + bias)` + * + * `activation` is the element-wise activation function + * passed as the `activation` argument. + * + * `kernel` is a weights matrix created by the layer. + * + * `bias` is a bias vector created by the layer (only applicable if `useBias` + * is `true`). + * + * **Input shape:** + * + * nD `tf.Tensor` with shape: `(batchSize, ..., inputDim)`. + * + * The most common situation would be + * a 2D input with shape `(batchSize, inputDim)`. + * + * **Output shape:** + * + * nD tensor with shape: `(batchSize, ..., units)`. + * + * For instance, for a 2D input with shape `(batchSize, inputDim)`, + * the output would have shape `(batchSize, units)`. + * + * Note: if the input to the layer has a rank greater than 2, then it is + * flattened prior to the initial dot product with the kernel. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ + function dense(args) { + return new Dense(args); + } + /** + * Applies + * [dropout](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) to + * the input. + * + * Dropout consists in randomly setting a fraction `rate` of input units to 0 at + * each update during training time, which helps prevent overfitting. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ + function dropout(args) { + return new Dropout(args); + } + /** + * Spatial 1D version of Dropout. + * + * This Layer type performs the same function as the Dropout layer, but it drops + * entire 1D feature maps instead of individual elements. For example, if an + * input example consists of 3 timesteps and the feature map for each timestep + * has a size of 4, a `spatialDropout1d` layer may zero out the feature maps + * of the 1st timesteps and 2nd timesteps completely while sparing all feature + * elements of the 3rd timestep. + * + * If adjacent frames (timesteps) are strongly correlated (as is normally the + * case in early convolution layers), regular dropout will not regularize the + * activation and will otherwise just result in merely an effective learning + * rate decrease. In this case, `spatialDropout1d` will help promote + * independence among feature maps and should be used instead. + * + * **Arguments:** + * rate: A floating-point number >=0 and <=1. Fraction of the input elements + * to drop. + * + * **Input shape:** + * 3D tensor with shape `(samples, timesteps, channels)`. + * + * **Output shape:** + * Same as the input shape. + * + * References: + * - [Efficient Object Localization Using Convolutional + * Networks](https://arxiv.org/abs/1411.4280) + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ + function spatialDropout1d(args) { + return new SpatialDropout1D(args); + } + /** + * Flattens the input. Does not affect the batch size. + * + * A `Flatten` layer flattens each batch in its inputs to 1D (making the output + * 2D). + * + * For example: + * + * ```js + * const input = tf.input({shape: [4, 3]}); + * const flattenLayer = tf.layers.flatten(); + * // Inspect the inferred output shape of the flatten layer, which + * // equals `[null, 12]`. The 2nd dimension is 4 * 3, i.e., the result of the + * // flattening. (The 1st dimension is the undermined batch size.) + * console.log(JSON.stringify(flattenLayer.apply(input).shape)); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ + function flatten(args) { + return new Flatten(args); + } + /** + * Repeats the input n times in a new dimension. + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.repeatVector({n: 4, inputShape: [2]})); + * const x = tf.tensor2d([[10, 20]]); + * // Use the model to do inference on a data point the model hasn't seen + * model.predict(x).print(); + * // output shape is now [batch, 2, 4] + * ``` + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ + function repeatVector(args) { + return new RepeatVector(args); + } + /** + * Reshapes an input to a certain shape. + * + * ```js + * const input = tf.input({shape: [4, 3]}); + * const reshapeLayer = tf.layers.reshape({targetShape: [2, 6]}); + * // Inspect the inferred output shape of the Reshape layer, which + * // equals `[null, 2, 6]`. (The 1st dimension is the undermined batch size.) + * console.log(JSON.stringify(reshapeLayer.apply(input).shape)); + * ``` + * + * Input shape: + * Arbitrary, although all dimensions in the input shape must be fixed. + * Use the configuration `inputShape` when using this layer as the + * first layer in a model. + * + * + * Output shape: + * [batchSize, targetShape[0], targetShape[1], ..., + * targetShape[targetShape.length - 1]]. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ + function reshape$2(args) { + return new Reshape(args); + } + /** + * Permutes the dimensions of the input according to a given pattern. + * + * Useful for, e.g., connecting RNNs and convnets together. + * + * Example: + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.permute({ + * dims: [2, 1], + * inputShape: [10, 64] + * })); + * console.log(model.outputShape); + * // Now model's output shape is [null, 64, 10], where null is the + * // unpermuted sample (batch) dimension. + * ``` + * + * Input shape: + * Arbitrary. Use the configuration field `inputShape` when using this + * layer as the first layer in a model. + * + * Output shape: + * Same rank as the input shape, but with the dimensions re-ordered (i.e., + * permuted) according to the `dims` configuration of this layer. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ + function permute(args) { + return new Permute(args); + } + /** + * Maps positive integers (indices) into dense vectors of fixed size. + * E.g. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]] + * + * **Input shape:** 2D tensor with shape: `[batchSize, sequenceLength]`. + * + * **Output shape:** 3D tensor with shape: `[batchSize, sequenceLength, + * outputDim]`. + * + * @doc {heading: 'Layers', subheading: 'Basic', namespace: 'layers'} + */ + function embedding(args) { + return new Embedding(args); + } + // Merge Layers. + /** + * Layer that performs element-wise addition on an `Array` of inputs. + * + * It takes as input a list of tensors, all of the same shape, and returns a + * single tensor (also of the same shape). The inputs are specified as an + * `Array` when the `apply` method of the `Add` layer instance is called. For + * example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const addLayer = tf.layers.add(); + * const sum = addLayer.apply([input1, input2]); + * console.log(JSON.stringify(sum.shape)); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ + function add$1(args) { + return new Add(args); + } + /** + * Layer that performs element-wise averaging on an `Array` of inputs. + * + * It takes as input a list of tensors, all of the same shape, and returns a + * single tensor (also of the same shape). For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const averageLayer = tf.layers.average(); + * const average = averageLayer.apply([input1, input2]); + * console.log(JSON.stringify(average.shape)); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ + function average(args) { + return new Average(args); + } + /** + * Layer that concatenates an `Array` of inputs. + * + * It takes a list of tensors, all of the same shape except for the + * concatenation axis, and returns a single tensor, the concatenation + * of all inputs. For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 3]}); + * const concatLayer = tf.layers.concatenate(); + * const output = concatLayer.apply([input1, input2]); + * console.log(JSON.stringify(output.shape)); + * // You get [null, 2, 5], with the first dimension as the undetermined batch + * // dimension. The last dimension (5) is the result of concatenating the + * // last dimensions of the inputs (2 and 3). + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ + function concatenate(args) { + return new Concatenate(args); + } + /** + * Layer that computes the element-wise maximum of an `Array` of inputs. + * + * It takes as input a list of tensors, all of the same shape, and returns a + * single tensor (also of the same shape). For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const maxLayer = tf.layers.maximum(); + * const max = maxLayer.apply([input1, input2]); + * console.log(JSON.stringify(max.shape)); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ + function maximum$2(args) { + return new Maximum(args); + } + /** + * Layer that computes the element-wise minimum of an `Array` of inputs. + * + * It takes as input a list of tensors, all of the same shape, and returns a + * single tensor (also of the same shape). For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const minLayer = tf.layers.minimum(); + * const min = minLayer.apply([input1, input2]); + * console.log(JSON.stringify(min.shape)); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ + function minimum$2(args) { + return new Minimum(args); + } + /** + * Layer that multiplies (element-wise) an `Array` of inputs. + * + * It takes as input an Array of tensors, all of the same + * shape, and returns a single tensor (also of the same shape). + * For example: + * + * ```js + * const input1 = tf.input({shape: [2, 2]}); + * const input2 = tf.input({shape: [2, 2]}); + * const input3 = tf.input({shape: [2, 2]}); + * const multiplyLayer = tf.layers.multiply(); + * const product = multiplyLayer.apply([input1, input2, input3]); + * console.log(product.shape); + * // You get [null, 2, 2], with the first dimension as the undetermined batch + * // dimension. + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ + function multiply$2(args) { + return new Multiply(args); + } + /** + * Layer that computes a dot product between samples in two tensors. + * + * E.g., if applied to a list of two tensors `a` and `b` both of shape + * `[batchSize, n]`, the output will be a tensor of shape `[batchSize, 1]`, + * where each entry at index `[i, 0]` will be the dot product between + * `a[i, :]` and `b[i, :]`. + * + * Example: + * + * ```js + * const dotLayer = tf.layers.dot({axes: -1}); + * const x1 = tf.tensor2d([[10, 20], [30, 40]]); + * const x2 = tf.tensor2d([[-1, -2], [-3, -4]]); + * + * // Invoke the layer's apply() method in eager (imperative) mode. + * const y = dotLayer.apply([x1, x2]); + * y.print(); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Merge', namespace: 'layers'} + */ + function dot(args) { + return new Dot(args); + } + // Normalization Layers. + /** + * Batch normalization layer (Ioffe and Szegedy, 2014). + * + * Normalize the activations of the previous layer at each batch, + * i.e. applies a transformation that maintains the mean activation + * close to 0 and the activation standard deviation close to 1. + * + * Input shape: + * Arbitrary. Use the keyword argument `inputShape` (Array of integers, does + * not include the sample axis) when calling the constructor of this class, + * if this layer is used as a first layer in a model. + * + * Output shape: + * Same shape as input. + * + * References: + * - [Batch Normalization: Accelerating Deep Network Training by Reducing + * Internal Covariate Shift](https://arxiv.org/abs/1502.03167) + * + * @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} + */ + function batchNormalization(args) { + return new BatchNormalization(args); + } + /** + * Layer-normalization layer (Ba et al., 2016). + * + * Normalizes the activations of the previous layer for each given example in a + * batch independently, instead of across a batch like in `batchNormalization`. + * In other words, this layer applies a transformation that maintains the mean + * activation within each example close to 0 and activation variance close to 1. + * + * Input shape: + * Arbitrary. Use the argument `inputShape` when using this layer as the first + * layer in a model. + * + * Output shape: + * Same as input. + * + * References: + * - [Layer Normalization](https://arxiv.org/abs/1607.06450) + * + * @doc {heading: 'Layers', subheading: 'Normalization', namespace: 'layers'} + */ + function layerNormalization(args) { + return new LayerNormalization(args); + } + // Padding Layers. + /** + * Zero-padding layer for 2D input (e.g., image). + * + * This layer can add rows and columns of zeros + * at the top, bottom, left and right side of an image tensor. + * + * Input shape: + * 4D tensor with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, rows, cols, channels]` + * - If `data_format` is `"channels_first"`: + * `[batch, channels, rows, cols]`. + * + * Output shape: + * 4D with shape: + * - If `dataFormat` is `"channelsLast"`: + * `[batch, paddedRows, paddedCols, channels]` + * - If `dataFormat` is `"channelsFirst"`: + * `[batch, channels, paddedRows, paddedCols]`. + * + * @doc {heading: 'Layers', subheading: 'Padding', namespace: 'layers'} + */ + function zeroPadding2d(args) { + return new ZeroPadding2D(args); + } + // Pooling Layers. + /** + * Average pooling operation for spatial data. + * + * Input shape: `[batchSize, inLength, channels]` + * + * Output shape: `[batchSize, pooledLength, channels]` + * + * `tf.avgPool1d` is an alias. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function averagePooling1d(args) { + return new AveragePooling1D(args); + } + function avgPool1d(args) { + return averagePooling1d(args); + } + // For backwards compatibility. + // See https://github.com/tensorflow/tfjs/issues/152 + function avgPooling1d(args) { + return averagePooling1d(args); + } + /** + * Average pooling operation for spatial data. + * + * Input shape: + * - If `dataFormat === CHANNEL_LAST`: + * 4D tensor with shape: + * `[batchSize, rows, cols, channels]` + * - If `dataFormat === CHANNEL_FIRST`: + * 4D tensor with shape: + * `[batchSize, channels, rows, cols]` + * + * Output shape + * - If `dataFormat === CHANNEL_LAST`: + * 4D tensor with shape: + * `[batchSize, pooledRows, pooledCols, channels]` + * - If `dataFormat === CHANNEL_FIRST`: + * 4D tensor with shape: + * `[batchSize, channels, pooledRows, pooledCols]` + * + * `tf.avgPool2d` is an alias. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function averagePooling2d(args) { + return new AveragePooling2D(args); + } + function avgPool2d(args) { + return averagePooling2d(args); + } + // For backwards compatibility. + // See https://github.com/tensorflow/tfjs/issues/152 + function avgPooling2d(args) { + return averagePooling2d(args); + } + /** + * Average pooling operation for 3D data. + * + * Input shape + * - If `dataFormat === channelsLast`: + * 5D tensor with shape: + * `[batchSize, depths, rows, cols, channels]` + * - If `dataFormat === channelsFirst`: + * 4D tensor with shape: + * `[batchSize, channels, depths, rows, cols]` + * + * Output shape + * - If `dataFormat=channelsLast`: + * 5D tensor with shape: + * `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` + * - If `dataFormat=channelsFirst`: + * 5D tensor with shape: + * `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function averagePooling3d(args) { + return new AveragePooling3D(args); + } + function avgPool3d(args) { + return averagePooling3d(args); + } + // For backwards compatibility. + // See https://github.com/tensorflow/tfjs/issues/152 + function avgPooling3d(args) { + return averagePooling3d(args); + } + /** + * Global average pooling operation for temporal data. + * + * Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. + * + * Output Shape: 2D tensor with shape: `[batchSize, features]`. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function globalAveragePooling1d(args) { + return new GlobalAveragePooling1D(args); + } + /** + * Global average pooling operation for spatial data. + * + * Input shape: + * - If `dataFormat` is `CHANNEL_LAST`: + * 4D tensor with shape: `[batchSize, rows, cols, channels]`. + * - If `dataFormat` is `CHANNEL_FIRST`: + * 4D tensor with shape: `[batchSize, channels, rows, cols]`. + * + * Output shape: + * 2D tensor with shape: `[batchSize, channels]`. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function globalAveragePooling2d(args) { + return new GlobalAveragePooling2D(args); + } + /** + * Global max pooling operation for temporal data. + * + * Input Shape: 3D tensor with shape: `[batchSize, steps, features]`. + * + * Output Shape: 2D tensor with shape: `[batchSize, features]`. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function globalMaxPooling1d(args) { + return new GlobalMaxPooling1D(args); + } + /** + * Global max pooling operation for spatial data. + * + * Input shape: + * - If `dataFormat` is `CHANNEL_LAST`: + * 4D tensor with shape: `[batchSize, rows, cols, channels]`. + * - If `dataFormat` is `CHANNEL_FIRST`: + * 4D tensor with shape: `[batchSize, channels, rows, cols]`. + * + * Output shape: + * 2D tensor with shape: `[batchSize, channels]`. + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function globalMaxPooling2d(args) { + return new GlobalMaxPooling2D(args); + } + /** + * Max pooling operation for temporal data. + * + * Input shape: `[batchSize, inLength, channels]` + * + * Output shape: `[batchSize, pooledLength, channels]` + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function maxPooling1d(args) { + return new MaxPooling1D(args); + } + /** + * Max pooling operation for spatial data. + * + * Input shape + * - If `dataFormat === CHANNEL_LAST`: + * 4D tensor with shape: + * `[batchSize, rows, cols, channels]` + * - If `dataFormat === CHANNEL_FIRST`: + * 4D tensor with shape: + * `[batchSize, channels, rows, cols]` + * + * Output shape + * - If `dataFormat=CHANNEL_LAST`: + * 4D tensor with shape: + * `[batchSize, pooledRows, pooledCols, channels]` + * - If `dataFormat=CHANNEL_FIRST`: + * 4D tensor with shape: + * `[batchSize, channels, pooledRows, pooledCols]` + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function maxPooling2d(args) { + return new MaxPooling2D(args); + } + /** + * Max pooling operation for 3D data. + * + * Input shape + * - If `dataFormat === channelsLast`: + * 5D tensor with shape: + * `[batchSize, depths, rows, cols, channels]` + * - If `dataFormat === channelsFirst`: + * 5D tensor with shape: + * `[batchSize, channels, depths, rows, cols]` + * + * Output shape + * - If `dataFormat=channelsLast`: + * 5D tensor with shape: + * `[batchSize, pooledDepths, pooledRows, pooledCols, channels]` + * - If `dataFormat=channelsFirst`: + * 5D tensor with shape: + * `[batchSize, channels, pooledDepths, pooledRows, pooledCols]` + * + * @doc {heading: 'Layers', subheading: 'Pooling', namespace: 'layers'} + */ + function maxPooling3d(args) { + return new MaxPooling3D(args); + } + // Recurrent Layers. + /** + * Gated Recurrent Unit - Cho et al. 2014. + * + * This is an `RNN` layer consisting of one `GRUCell`. However, unlike + * the underlying `GRUCell`, the `apply` method of `SimpleRNN` operates + * on a sequence of inputs. The shape of the input (not including the first, + * batch dimension) needs to be at least 2-D, with the first dimension being + * time steps. For example: + * + * ```js + * const rnn = tf.layers.gru({units: 8, returnSequences: true}); + * + * // Create an input with 10 time steps. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the `GRUCell`'s number of units. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ + function gru(args) { + return new GRU(args); + } + /** + * Cell class for `GRU`. + * + * `GRUCell` is distinct from the `RNN` subclass `GRU` in that its + * `apply` method takes the input data of only a single time step and returns + * the cell's output at the time step, while `GRU` takes the input data + * over a number of time steps. For example: + * + * ```js + * const cell = tf.layers.gruCell({units: 2}); + * const input = tf.input({shape: [10]}); + * const output = cell.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10]: This is the cell's output at a single time step. The 1st + * // dimension is the unknown batch size. + * ``` + * + * Instance(s) of `GRUCell` can be used to construct `RNN` layers. The + * most typical use of this workflow is to combine a number of cells into a + * stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an + * RNN. For example: + * + * ```js + * const cells = [ + * tf.layers.gruCell({units: 4}), + * tf.layers.gruCell({units: 8}), + * ]; + * const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); + * + * // Create an input with 10 time steps and a length-20 vector at each step. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the last `gruCell`'s number of units. + * ``` + * + * To create an `RNN` consisting of only *one* `GRUCell`, use the + * `tf.layers.gru`. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ + function gruCell(args) { + return new GRUCell(args); + } + /** + * Long-Short Term Memory layer - Hochreiter 1997. + * + * This is an `RNN` layer consisting of one `LSTMCell`. However, unlike + * the underlying `LSTMCell`, the `apply` method of `LSTM` operates + * on a sequence of inputs. The shape of the input (not including the first, + * batch dimension) needs to be at least 2-D, with the first dimension being + * time steps. For example: + * + * ```js + * const lstm = tf.layers.lstm({units: 8, returnSequences: true}); + * + * // Create an input with 10 time steps. + * const input = tf.input({shape: [10, 20]}); + * const output = lstm.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the `LSTMCell`'s number of units. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ + function lstm(args) { + return new LSTM(args); + } + /** + * Cell class for `LSTM`. + * + * `LSTMCell` is distinct from the `RNN` subclass `LSTM` in that its + * `apply` method takes the input data of only a single time step and returns + * the cell's output at the time step, while `LSTM` takes the input data + * over a number of time steps. For example: + * + * ```js + * const cell = tf.layers.lstmCell({units: 2}); + * const input = tf.input({shape: [10]}); + * const output = cell.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10]: This is the cell's output at a single time step. The 1st + * // dimension is the unknown batch size. + * ``` + * + * Instance(s) of `LSTMCell` can be used to construct `RNN` layers. The + * most typical use of this workflow is to combine a number of cells into a + * stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an + * RNN. For example: + * + * ```js + * const cells = [ + * tf.layers.lstmCell({units: 4}), + * tf.layers.lstmCell({units: 8}), + * ]; + * const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); + * + * // Create an input with 10 time steps and a length-20 vector at each step. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the last `lstmCell`'s number of units. + * ``` + * + * To create an `RNN` consisting of only *one* `LSTMCell`, use the + * `tf.layers.lstm`. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ + function lstmCell(args) { + return new LSTMCell(args); + } + /** + * Fully-connected RNN where the output is to be fed back to input. + * + * This is an `RNN` layer consisting of one `SimpleRNNCell`. However, unlike + * the underlying `SimpleRNNCell`, the `apply` method of `SimpleRNN` operates + * on a sequence of inputs. The shape of the input (not including the first, + * batch dimension) needs to be at least 2-D, with the first dimension being + * time steps. For example: + * + * ```js + * const rnn = tf.layers.simpleRNN({units: 8, returnSequences: true}); + * + * // Create an input with 10 time steps. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the `SimpleRNNCell`'s number of units. + * ``` + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ + function simpleRNN(args) { + return new SimpleRNN(args); + } + /** + * Cell class for `SimpleRNN`. + * + * `SimpleRNNCell` is distinct from the `RNN` subclass `SimpleRNN` in that its + * `apply` method takes the input data of only a single time step and returns + * the cell's output at the time step, while `SimpleRNN` takes the input data + * over a number of time steps. For example: + * + * ```js + * const cell = tf.layers.simpleRNNCell({units: 2}); + * const input = tf.input({shape: [10]}); + * const output = cell.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10]: This is the cell's output at a single time step. The 1st + * // dimension is the unknown batch size. + * ``` + * + * Instance(s) of `SimpleRNNCell` can be used to construct `RNN` layers. The + * most typical use of this workflow is to combine a number of cells into a + * stacked RNN cell (i.e., `StackedRNNCell` internally) and use it to create an + * RNN. For example: + * + * ```js + * const cells = [ + * tf.layers.simpleRNNCell({units: 4}), + * tf.layers.simpleRNNCell({units: 8}), + * ]; + * const rnn = tf.layers.rnn({cell: cells, returnSequences: true}); + * + * // Create an input with 10 time steps and a length-20 vector at each step. + * const input = tf.input({shape: [10, 20]}); + * const output = rnn.apply(input); + * + * console.log(JSON.stringify(output.shape)); + * // [null, 10, 8]: 1st dimension is unknown batch size; 2nd dimension is the + * // same as the sequence length of `input`, due to `returnSequences`: `true`; + * // 3rd dimension is the last `SimpleRNNCell`'s number of units. + * ``` + * + * To create an `RNN` consisting of only *one* `SimpleRNNCell`, use the + * `tf.layers.simpleRNN`. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ + function simpleRNNCell(args) { + return new SimpleRNNCell(args); + } + /** + * Convolutional LSTM layer - Xingjian Shi 2015. + * + * This is a `ConvRNN2D` layer consisting of one `ConvLSTM2DCell`. However, + * unlike the underlying `ConvLSTM2DCell`, the `apply` method of `ConvLSTM2D` + * operates on a sequence of inputs. The shape of the input (not including the + * first, batch dimension) needs to be 4-D, with the first dimension being time + * steps. For example: + * + * ```js + * const filters = 3; + * const kernelSize = 3; + * + * const batchSize = 4; + * const sequenceLength = 2; + * const size = 5; + * const channels = 3; + * + * const inputShape = [batchSize, sequenceLength, size, size, channels]; + * const input = tf.ones(inputShape); + * + * const layer = tf.layers.convLstm2d({filters, kernelSize}); + * + * const output = layer.apply(input); + * ``` + */ + /** @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} */ + function convLstm2d(args) { + return new ConvLSTM2D(args); + } + /** + * Cell class for `ConvLSTM2D`. + * + * `ConvLSTM2DCell` is distinct from the `ConvRNN2D` subclass `ConvLSTM2D` in + * that its `call` method takes the input data of only a single time step and + * returns the cell's output at the time step, while `ConvLSTM2D` takes the + * input data over a number of time steps. For example: + * + * ```js + * const filters = 3; + * const kernelSize = 3; + * + * const sequenceLength = 1; + * const size = 5; + * const channels = 3; + * + * const inputShape = [sequenceLength, size, size, channels]; + * const input = tf.ones(inputShape); + * + * const cell = tf.layers.convLstm2dCell({filters, kernelSize}); + * + * cell.build(input.shape); + * + * const outputSize = size - kernelSize + 1; + * const outShape = [sequenceLength, outputSize, outputSize, filters]; + * + * const initialH = tf.zeros(outShape); + * const initialC = tf.zeros(outShape); + * + * const [o, h, c] = cell.call([input, initialH, initialC], {}); + * ``` + */ + /** @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} */ + function convLstm2dCell(args) { + return new ConvLSTM2DCell(args); + } + /** + * Base class for recurrent layers. + * + * Input shape: + * 3D tensor with shape `[batchSize, timeSteps, inputDim]`. + * + * Output shape: + * - if `returnState`, an Array of tensors (i.e., `tf.Tensor`s). The first + * tensor is the output. The remaining tensors are the states at the + * last time step, each with shape `[batchSize, units]`. + * - if `returnSequences`, the output will have shape + * `[batchSize, timeSteps, units]`. + * - else, the output will have shape `[batchSize, units]`. + * + * Masking: + * This layer supports masking for input data with a variable number + * of timesteps. To introduce masks to your data, + * use an embedding layer with the `mask_zero` parameter + * set to `True`. + * + * Notes on using statefulness in RNNs: + * You can set RNN layers to be 'stateful', which means that the states + * computed for the samples in one batch will be reused as initial states + * for the samples in the next batch. This assumes a one-to-one mapping + * between samples in different successive batches. + * + * To enable statefulness: + * - specify `stateful: true` in the layer constructor. + * - specify a fixed batch size for your model, by passing + * if sequential model: + * `batchInputShape=[...]` to the first layer in your model. + * else for functional model with 1 or more Input layers: + * `batchShape=[...]` to all the first layers in your model. + * This is the expected shape of your inputs *including the batch size*. + * It should be a tuple of integers, e.g. `(32, 10, 100)`. + * - specify `shuffle=False` when calling fit(). + * + * To reset the states of your model, call `.resetStates()` on either + * a specific layer, or on your entire model. + * + * Note on specifying the initial state of RNNs + * You can specify the initial state of RNN layers symbolically by + * calling them with the option `initialState`. The value of + * `initialState` should be a tensor or list of tensors representing + * the initial state of the RNN layer. + * + * You can specify the initial state of RNN layers numerically by + * calling `resetStates` with the keyword argument `states`. The value of + * `states` should be a numpy array or list of numpy arrays representing + * the initial state of the RNN layer. + * + * Note on passing external constants to RNNs + * You can pass "external" constants to the cell using the `constants` + * keyword argument of `RNN.call` method. This requires that the `cell.call` + * method accepts the same keyword argument `constants`. Such constants + * can be used to condition the cell transformation on additional static + * inputs (not changing over time), a.k.a. an attention mechanism. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ + function rnn(args) { + return new RNN(args); + } + /** + * Wrapper allowing a stack of RNN cells to behave as a single cell. + * + * Used to implement efficient stacked RNNs. + * + * @doc {heading: 'Layers', subheading: 'Recurrent', namespace: 'layers'} + */ + function stackedRNNCells(args) { + return new StackedRNNCells(args); + } + // Wrapper Layers. + /** @doc {heading: 'Layers', subheading: 'Wrapper', namespace: 'layers'} */ + function bidirectional(args) { + return new Bidirectional(args); + } + /** + * This wrapper applies a layer to every temporal slice of an input. + * + * The input should be at least 3D, and the dimension of the index `1` will be + * considered to be the temporal dimension. + * + * Consider a batch of 32 samples, where each sample is a sequence of 10 vectors + * of 16 dimensions. The batch input shape of the layer is then `[32, 10, + * 16]`, and the `inputShape`, not including the sample dimension, is + * `[10, 16]`. + * + * You can then use `TimeDistributed` to apply a `Dense` layer to each of the 10 + * timesteps, independently: + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.timeDistributed({ + * layer: tf.layers.dense({units: 8}), + * inputShape: [10, 16], + * })); + * + * // Now model.outputShape = [null, 10, 8]. + * // The output will then have shape `[32, 10, 8]`. + * + * // In subsequent layers, there is no need for `inputShape`: + * model.add(tf.layers.timeDistributed({layer: tf.layers.dense({units: 32})})); + * console.log(JSON.stringify(model.outputs[0].shape)); + * // Now model.outputShape = [null, 10, 32]. + * ``` + * + * The output will then have shape `[32, 10, 32]`. + * + * `TimeDistributed` can be used with arbitrary layers, not just `Dense`, for + * instance a `Conv2D` layer. + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.timeDistributed({ + * layer: tf.layers.conv2d({filters: 64, kernelSize: [3, 3]}), + * inputShape: [10, 299, 299, 3], + * })); + * console.log(JSON.stringify(model.outputs[0].shape)); + * ``` + * + * @doc {heading: 'Layers', subheading: 'Wrapper', namespace: 'layers'} + */ + function timeDistributed(args) { + return new TimeDistributed(args); + } + // Aliases for pooling. + const globalMaxPool1d = globalMaxPooling1d; + const globalMaxPool2d = globalMaxPooling2d; + const maxPool1d = maxPooling1d; + const maxPool2d = maxPooling2d; + /** + * Apply additive zero-centered Gaussian noise. + * + * As it is a regularization layer, it is only active at training time. + * + * This is useful to mitigate overfitting + * (you could see it as a form of random data augmentation). + * Gaussian Noise (GS) is a natural choice as corruption process + * for real valued inputs. + * + * # Arguments + * stddev: float, standard deviation of the noise distribution. + * + * # Input shape + * Arbitrary. Use the keyword argument `input_shape` + * (tuple of integers, does not include the samples axis) + * when using this layer as the first layer in a model. + * + * # Output shape + * Same shape as input. + * + * @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} + */ + function gaussianNoise(args) { + return new GaussianNoise(args); + } + /** + * Apply multiplicative 1-centered Gaussian noise. + * + * As it is a regularization layer, it is only active at training time. + * + * Arguments: + * - `rate`: float, drop probability (as with `Dropout`). + * The multiplicative noise will have + * standard deviation `sqrt(rate / (1 - rate))`. + * + * Input shape: + * Arbitrary. Use the keyword argument `inputShape` + * (tuple of integers, does not include the samples axis) + * when using this layer as the first layer in a model. + * + * Output shape: + * Same shape as input. + * + * References: + * - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting]( + * http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) + * + * @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} + */ + function gaussianDropout(args) { + return new GaussianDropout(args); + } + /** + * Applies Alpha Dropout to the input. + * + * As it is a regularization layer, it is only active at training time. + * + * Alpha Dropout is a `Dropout` that keeps mean and variance of inputs + * to their original values, in order to ensure the self-normalizing property + * even after this dropout. + * Alpha Dropout fits well to Scaled Exponential Linear Units + * by randomly setting activations to the negative saturation value. + * + * Arguments: + * - `rate`: float, drop probability (as with `Dropout`). + * The multiplicative noise will have + * standard deviation `sqrt(rate / (1 - rate))`. + * - `noise_shape`: A 1-D `Tensor` of type `int32`, representing the + * shape for randomly generated keep/drop flags. + * + * Input shape: + * Arbitrary. Use the keyword argument `inputShape` + * (tuple of integers, does not include the samples axis) + * when using this layer as the first layer in a model. + * + * Output shape: + * Same shape as input. + * + * References: + * - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515) + * + * @doc {heading: 'Layers', subheading: 'Noise', namespace: 'layers'} + */ + function alphaDropout(args) { + return new AlphaDropout(args); + } + /** + * Masks a sequence by using a mask value to skip timesteps. + * + * If all features for a given sample timestep are equal to `mask_value`, + * then the sample timestep will be masked (skipped) in all downstream layers + * (as long as they support masking). + * + * If any downstream layer does not support masking yet receives such + * an input mask, an exception will be raised. + * + * Arguments: + * - `maskValue`: Either None or mask value to skip. + * + * Input shape: + * Arbitrary. Use the keyword argument `inputShape` + * (tuple of integers, does not include the samples axis) + * when using this layer as the first layer in a model. + * + * Output shape: + * Same shape as input. + * + * @doc {heading: 'Layers', subheading: 'Mask', namespace: 'layers'} + */ + function masking(args) { + return new Masking(args); + } + /** + * A preprocessing layer which rescales input values to a new range. + * + * This layer rescales every value of an input (often an image) by multiplying + * by `scale` and adding `offset`. + * + * For instance: + * 1. To rescale an input in the ``[0, 255]`` range + * to be in the `[0, 1]` range, you would pass `scale=1/255`. + * 2. To rescale an input in the ``[0, 255]`` range to be in the `[-1, 1]` + * range, you would pass `scale=1./127.5, offset=-1`. + * The rescaling is applied both during training and inference. Inputs can be + * of integer or floating point dtype, and by default the layer will output + * floats. + * + * Arguments: + * - `scale`: Float, the scale to apply to the inputs. + * - `offset`: Float, the offset to apply to the inputs. + * + * Input shape: + * Arbitrary. + * + * Output shape: + * Same as input. + * + * @doc {heading: 'Layers', subheading: 'Rescaling', namespace: 'layers'} + */ + function rescaling(args) { + return new Rescaling(args); + } + /** + * A preprocessing layer which center crops images. + * + * This layers crops the central portion of the images to a target size. If an + * image is smaller than the target size, it will be resized and cropped so as + * to return the largest possible window in the image that matches the target + * aspect ratio. + * + * Input pixel values can be of any range (e.g. `[0., 1.)` or `[0, 255]`) and + * of integer or floating point dtype. + * + * If the input height/width is even and the target height/width is odd (or + * inversely), the input image is left-padded by 1 pixel. + * + * Arguments: + * `height`: Integer, the height of the output shape. + * `width`: Integer, the width of the output shape. + * + * Input shape: + * 3D (unbatched) or 4D (batched) tensor with shape: + * `(..., height, width, channels)`, in `channelsLast` format. + * + * Output shape: + * 3D (unbatched) or 4D (batched) tensor with shape: + * `(..., targetHeight, targetWidth, channels)`. + * + * + * @doc {heading: 'Layers', subheading: 'CenterCrop', namespace: 'layers'} + */ + function centerCrop(args) { + return new CenterCrop(args); + } + /** + * A preprocessing layer which resizes images. + * This layer resizes an image input to a target height and width. The input + * should be a 4D (batched) or 3D (unbatched) tensor in `"channels_last"` + * format. Input pixel values can be of any range (e.g. `[0., 1.)` or `[0, + * 255]`) and of interger or floating point dtype. By default, the layer will + * output floats. + * + * Arguments: + * - `height`: number, the height for the output tensor. + * - `width`: number, the width for the output tensor. + * - `interpolation`: string, the method for image resizing interpolation. + * - `cropToAspectRatio`: boolean, whether to keep image aspect ratio. + * + * Input shape: + * Arbitrary. + * + * Output shape: + * height, width, num channels. + * + * @doc {heading: 'Layers', subheading: 'Resizing', namespace: 'layers'} + */ + function resizing(args) { + return new Resizing(args); + } + /** + * A preprocessing layer which encodes integer features. + * + * This layer provides options for condensing data into a categorical encoding + * when the total number of tokens are known in advance. It accepts integer + * values as inputs, and it outputs a dense representation of those + * inputs. + * + * Arguments: + * + * numTokens: The total number of tokens the layer should support. All + * inputs to the layer must integers in the range `0 <= value < + * numTokens`, or an error will be thrown. + * + * outputMode: Specification for the output of the layer. + * Defaults to `multiHot`. Values can be `oneHot`, `multiHot` or + * `count`, configuring the layer as follows: + * + * oneHot: Encodes each individual element in the input into an + * array of `numTokens` size, containing a 1 at the element index. If + * the last dimension is size 1, will encode on that dimension. If the + * last dimension is not size 1, will append a new dimension for the + * encoded output. + * + * multiHot: Encodes each sample in the input into a single array + * of `numTokens` size, containing a 1 for each vocabulary term + * present in the sample. Treats the last dimension as the sample + * dimension, if input shape is `(..., sampleLength)`, output shape + * will be `(..., numTokens)`. + * + * count: Like `multiHot`, but the int array contains a count of + * the number of times the token at that index appeared in the sample. + * + * For all output modes, currently only output up to rank 2 is supported. + * Call arguments: + * inputs: A 1D or 2D tensor of integer inputs. + * countWeights: A tensor in the same shape as `inputs` indicating the + * weight for each sample value when summing up in `count` mode. Not used + * in `multiHot` or `oneHot` modes. + * + * + * @doc {heading: 'Layers', subheading: 'CategoryEncoding', namespace: 'layers'} + */ + function categoryEncoding(args) { + return new CategoryEncoding(args); + } + /** + * A preprocessing layer which randomly varies image width during training. + * + * This layer will randomly adjusts the width of a batch of images of a batch + * of images by a random factor. + * + * The input should be a 3D (unbatched) or 4D (batched) tensor in + * the `"channels_last"` image data format. Input pixel values can be of any + * range (e.g. `[0., 1.)` or `[0, 255]`) and of integer or floating point + * dtype. By default, the layer will output floats. By default, this layer is + * inactive during inference. For an overview and full list of preprocessing + * layers, see the preprocessing [guide] + * (https://www.tensorflow.org/guide/keras/preprocessing_layers). + * + * Arguments: + * + * factor: + * A positive float (fraction of original width), or a tuple of size 2 + * representing lower and upper bound for resizing vertically. + * When represented as a single float, this value is used for both the upper + * and lower bound. For instance, `factor=(0.2, 0.3)` results in an output + * with width changed by a random amount in the range `[20%, 30%]`. + * `factor=(-0.2, 0.3)` results in an output with width changed by a random + * amount in the range `[-20%, +30%]`. `factor=0.2` results in an output + * with width changed by a random amount in the range `[-20%, +20%]`. + * interpolation: + * String, the interpolation method. + * Defaults to `bilinear`. + * Supports `"bilinear"`, `"nearest"`. + * The tf methods `"bicubic"`, `"area"`, `"lanczos3"`, `"lanczos5"`, + * `"gaussian"`, `"mitchellcubic"` are unimplemented in tfjs. + * seed: + * Integer. Used to create a random seed. + * + * Input shape: + * 3D (unbatched) or 4D (batched) tensor with shape: + * `(..., height, width, channels)`, in `"channels_last"` format. + * Output shape: + * 3D (unbatched) or 4D (batched) tensor with shape: + * `(..., height, random_width, channels)`. + * + * + * @doc {heading: 'Layers', subheading: 'RandomWidth', namespace: 'layers'} + */ + function randomWidth(args) { + return new RandomWidth(args); + } + + var exports_layers = /*#__PURE__*/Object.freeze({ + __proto__: null, + Layer: Layer, + RNN: RNN, + RNNCell: RNNCell, + activation: activation, + add: add$1, + alphaDropout: alphaDropout, + average: average, + averagePooling1d: averagePooling1d, + averagePooling2d: averagePooling2d, + averagePooling3d: averagePooling3d, + avgPool1d: avgPool1d, + avgPool2d: avgPool2d, + avgPool3d: avgPool3d, + avgPooling1d: avgPooling1d, + avgPooling2d: avgPooling2d, + avgPooling3d: avgPooling3d, + batchNormalization: batchNormalization, + bidirectional: bidirectional, + categoryEncoding: categoryEncoding, + centerCrop: centerCrop, + concatenate: concatenate, + conv1d: conv1d, + conv2d: conv2d$1, + conv2dTranspose: conv2dTranspose, + conv3d: conv3d, + conv3dTranspose: conv3dTranspose, + convLstm2d: convLstm2d, + convLstm2dCell: convLstm2dCell, + cropping2D: cropping2D, + dense: dense, + depthwiseConv2d: depthwiseConv2d, + dot: dot, + dropout: dropout, + elu: elu$2, + embedding: embedding, + flatten: flatten, + gaussianDropout: gaussianDropout, + gaussianNoise: gaussianNoise, + globalAveragePooling1d: globalAveragePooling1d, + globalAveragePooling2d: globalAveragePooling2d, + globalMaxPool1d: globalMaxPool1d, + globalMaxPool2d: globalMaxPool2d, + globalMaxPooling1d: globalMaxPooling1d, + globalMaxPooling2d: globalMaxPooling2d, + gru: gru, + gruCell: gruCell, + input: input, + inputLayer: inputLayer, + layerNormalization: layerNormalization, + leakyReLU: leakyReLU, + lstm: lstm, + lstmCell: lstmCell, + masking: masking, + maxPool1d: maxPool1d, + maxPool2d: maxPool2d, + maxPooling1d: maxPooling1d, + maxPooling2d: maxPooling2d, + maxPooling3d: maxPooling3d, + maximum: maximum$2, + minimum: minimum$2, + multiply: multiply$2, + permute: permute, + prelu: prelu$2, + randomWidth: randomWidth, + reLU: reLU, + repeatVector: repeatVector, + rescaling: rescaling, + reshape: reshape$2, + resizing: resizing, + rnn: rnn, + separableConv2d: separableConv2d, + simpleRNN: simpleRNN, + simpleRNNCell: simpleRNNCell, + softmax: softmax$2, + spatialDropout1d: spatialDropout1d, + stackedRNNCells: stackedRNNCells, + thresholdedReLU: thresholdedReLU, + timeDistributed: timeDistributed, + upSampling2d: upSampling2d, + zeroPadding2d: zeroPadding2d + }); + + /** + * Binary accuracy metric function. + * + * `yTrue` and `yPred` can have 0-1 values. Example: + * ```js + * const x = tf.tensor2d([[1, 1, 1, 1], [0, 0, 0, 0]], [2, 4]); + * const y = tf.tensor2d([[1, 0, 1, 0], [0, 0, 0, 1]], [2, 4]); + * const accuracy = tf.metrics.binaryAccuracy(x, y); + * accuracy.print(); + * ``` + * + * `yTrue` and `yPred` can also have floating-number values between 0 and 1, in + * which case the values will be thresholded at 0.5 to yield 0-1 values (i.e., + * a value >= 0.5 and <= 1.0 is interpreted as 1). + * + * Example: + * ```js + * const x = tf.tensor1d([1, 1, 1, 1, 0, 0, 0, 0]); + * const y = tf.tensor1d([0.2, 0.4, 0.6, 0.8, 0.2, 0.3, 0.4, 0.7]); + * const accuracy = tf.metrics.binaryAccuracy(x, y); + * accuracy.print(); + * ``` + * + * @param yTrue Binary Tensor of truth. + * @param yPred Binary Tensor of prediction. + * @return Accuracy Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function binaryAccuracy(yTrue, yPred) { + return binaryAccuracy$1(yTrue, yPred); + } + /** + * Binary crossentropy metric function. + * + * Example: + * ```js + * const x = tf.tensor2d([[0], [1], [1], [1]]); + * const y = tf.tensor2d([[0], [0], [0.5], [1]]); + * const crossentropy = tf.metrics.binaryCrossentropy(x, y); + * crossentropy.print(); + * ``` + * + * @param yTrue Binary Tensor of truth. + * @param yPred Binary Tensor of prediction, probabilities for the `1` case. + * @return Accuracy Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function binaryCrossentropy(yTrue, yPred) { + return binaryCrossentropy$1(yTrue, yPred); + } + /** + * Sparse categorical accuracy metric function. + * + * Example: + * ```js + * + * const yTrue = tf.tensor1d([1, 1, 2, 2, 0]); + * const yPred = tf.tensor2d( + * [[0, 1, 0], [1, 0, 0], [0, 0.4, 0.6], [0, 0.6, 0.4], [0.7, 0.3, 0]]); + * const crossentropy = tf.metrics.sparseCategoricalAccuracy(yTrue, yPred); + * crossentropy.print(); + * ``` + * + * @param yTrue True labels: indices. + * @param yPred Predicted probabilities or logits. + * @returns Accuracy tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function sparseCategoricalAccuracy(yTrue, yPred) { + return sparseCategoricalAccuracy$1(yTrue, yPred); + } + /** + * Categorical accuracy metric function. + * + * Example: + * ```js + * const x = tf.tensor2d([[0, 0, 0, 1], [0, 0, 0, 1]]); + * const y = tf.tensor2d([[0.1, 0.8, 0.05, 0.05], [0.1, 0.05, 0.05, 0.8]]); + * const accuracy = tf.metrics.categoricalAccuracy(x, y); + * accuracy.print(); + * ``` + * + * @param yTrue Binary Tensor of truth: one-hot encoding of categories. + * @param yPred Binary Tensor of prediction: probabilities or logits for the + * same categories as in `yTrue`. + * @return Accuracy Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function categoricalAccuracy(yTrue, yPred) { + return categoricalAccuracy$1(yTrue, yPred); + } + /** + * Categorical crossentropy between an output tensor and a target tensor. + * + * @param target A tensor of the same shape as `output`. + * @param output A tensor resulting from a softmax (unless `fromLogits` is + * `true`, in which case `output` is expected to be the logits). + * @param fromLogits Boolean, whether `output` is the result of a softmax, or is + * a tensor of logits. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function categoricalCrossentropy(yTrue, yPred) { + return categoricalCrossentropy$1(yTrue, yPred); + } + /** + * Computes the precision of the predictions with respect to the labels. + * + * Example: + * ```js + * const x = tf.tensor2d( + * [ + * [0, 0, 0, 1], + * [0, 1, 0, 0], + * [0, 0, 0, 1], + * [1, 0, 0, 0], + * [0, 0, 1, 0] + * ] + * ); + * + * const y = tf.tensor2d( + * [ + * [0, 0, 1, 0], + * [0, 1, 0, 0], + * [0, 0, 0, 1], + * [0, 1, 0, 0], + * [0, 1, 0, 0] + * ] + * ); + * + * const precision = tf.metrics.precision(x, y); + * precision.print(); + * ``` + * + * @param yTrue The ground truth values. Expected to contain only 0-1 values. + * @param yPred The predicted values. Expected to contain only 0-1 values. + * @return Precision Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function precision(yTrue, yPred) { + return precision$1(yTrue, yPred); + } + /** + * Computes the recall of the predictions with respect to the labels. + * + * Example: + * ```js + * const x = tf.tensor2d( + * [ + * [0, 0, 0, 1], + * [0, 1, 0, 0], + * [0, 0, 0, 1], + * [1, 0, 0, 0], + * [0, 0, 1, 0] + * ] + * ); + * + * const y = tf.tensor2d( + * [ + * [0, 0, 1, 0], + * [0, 1, 0, 0], + * [0, 0, 0, 1], + * [0, 1, 0, 0], + * [0, 1, 0, 0] + * ] + * ); + * + * const recall = tf.metrics.recall(x, y); + * recall.print(); + * ``` + * + * @param yTrue The ground truth values. Expected to contain only 0-1 values. + * @param yPred The predicted values. Expected to contain only 0-1 values. + * @return Recall Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function recall(yTrue, yPred) { + return recall$1(yTrue, yPred); + } + /** + * Loss or metric function: Cosine proximity. + * + * Mathematically, cosine proximity is defined as: + * `-sum(l2Normalize(yTrue) * l2Normalize(yPred))`, + * wherein `l2Normalize()` normalizes the L2 norm of the input to 1 and `*` + * represents element-wise multiplication. + * + * ```js + * const yTrue = tf.tensor2d([[1, 0], [1, 0]]); + * const yPred = tf.tensor2d([[1 / Math.sqrt(2), 1 / Math.sqrt(2)], [0, 1]]); + * const proximity = tf.metrics.cosineProximity(yTrue, yPred); + * proximity.print(); + * ``` + * + * @param yTrue Truth Tensor. + * @param yPred Prediction Tensor. + * @return Cosine proximity Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function cosineProximity(yTrue, yPred) { + return cosineProximity$1(yTrue, yPred); + } + /** + * Loss or metric function: Mean absolute error. + * + * Mathematically, mean absolute error is defined as: + * `mean(abs(yPred - yTrue))`, + * wherein the `mean` is applied over feature dimensions. + * + * ```js + * const yTrue = tf.tensor2d([[0, 1], [0, 0], [2, 3]]); + * const yPred = tf.tensor2d([[0, 1], [0, 1], [-2, -3]]); + * const mse = tf.metrics.meanAbsoluteError(yTrue, yPred); + * mse.print(); + * ``` + * + * @param yTrue Truth Tensor. + * @param yPred Prediction Tensor. + * @return Mean absolute error Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function meanAbsoluteError(yTrue, yPred) { + return meanAbsoluteError$1(yTrue, yPred); + } + /** + * Loss or metric function: Mean absolute percentage error. + * + * ```js + * const yTrue = tf.tensor2d([[0, 1], [10, 20]]); + * const yPred = tf.tensor2d([[0, 1], [11, 24]]); + * const mse = tf.metrics.meanAbsolutePercentageError(yTrue, yPred); + * mse.print(); + * ``` + * + * Aliases: `tf.metrics.MAPE`, `tf.metrics.mape`. + * + * @param yTrue Truth Tensor. + * @param yPred Prediction Tensor. + * @return Mean absolute percentage error Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function meanAbsolutePercentageError(yTrue, yPred) { + return meanAbsolutePercentageError$1(yTrue, yPred); + } + function MAPE(yTrue, yPred) { + return meanAbsolutePercentageError$1(yTrue, yPred); + } + function mape(yTrue, yPred) { + return meanAbsolutePercentageError$1(yTrue, yPred); + } + /** + * Loss or metric function: Mean squared error. + * + * ```js + * const yTrue = tf.tensor2d([[0, 1], [3, 4]]); + * const yPred = tf.tensor2d([[0, 1], [-3, -4]]); + * const mse = tf.metrics.meanSquaredError(yTrue, yPred); + * mse.print(); + * ``` + * + * Aliases: `tf.metrics.MSE`, `tf.metrics.mse`. + * + * @param yTrue Truth Tensor. + * @param yPred Prediction Tensor. + * @return Mean squared error Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function meanSquaredError(yTrue, yPred) { + return meanSquaredError$1(yTrue, yPred); + } + function MSE(yTrue, yPred) { + return meanSquaredError$1(yTrue, yPred); + } + function mse(yTrue, yPred) { + return meanSquaredError$1(yTrue, yPred); + } + /** + * Computes R2 score. + * + * ```js + * const yTrue = tf.tensor2d([[0, 1], [3, 4]]); + * const yPred = tf.tensor2d([[0, 1], [-3, -4]]); + * const r2Score = tf.metrics.r2Score(yTrue, yPred); + * r2Score.print(); + * ``` + * @param yTrue Truth Tensor. + * @param yPred Prediction Tensor. + * @return R2 score Tensor. + * + * @doc {heading: 'Metrics', namespace: 'metrics'} + */ + function r2Score(yTrue, yPred) { + return r2Score$1(yTrue, yPred); + } + + var exports_metrics = /*#__PURE__*/Object.freeze({ + __proto__: null, + MAPE: MAPE, + MSE: MSE, + binaryAccuracy: binaryAccuracy, + binaryCrossentropy: binaryCrossentropy, + categoricalAccuracy: categoricalAccuracy, + categoricalCrossentropy: categoricalCrossentropy, + cosineProximity: cosineProximity, + mape: mape, + meanAbsoluteError: meanAbsoluteError, + meanAbsolutePercentageError: meanAbsolutePercentageError, + meanSquaredError: meanSquaredError, + mse: mse, + precision: precision, + r2Score: r2Score, + recall: recall, + sparseCategoricalAccuracy: sparseCategoricalAccuracy + }); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + + var exports_models = /*#__PURE__*/Object.freeze({ + __proto__: null, + modelFromJSON: modelFromJSON + }); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + /** + * Regularizer for L1 and L2 regularization. + * + * Adds a term to the loss to penalize large weights: + * loss += sum(l1 * abs(x)) + sum(l2 * x^2) + * + * @doc {heading: 'Regularizers', namespace: 'regularizers'} + */ + function l1l2(config) { + return new L1L2(config); + } + /** + * Regularizer for L1 regularization. + * + * Adds a term to the loss to penalize large weights: + * loss += sum(l1 * abs(x)) + * @param args l1 config. + * + * @doc {heading: 'Regularizers', namespace: 'regularizers'} + */ + function l1(config) { + return l1$1(config); + } + /** + * Regularizer for L2 regularization. + * + * Adds a term to the loss to penalize large weights: + * loss += sum(l2 * x^2) + * @param args l2 config. + * + * @doc {heading: 'Regularizers', namespace: 'regularizers'} + */ + function l2(config) { + return l2$1(config); + } + + var exports_regularizers = /*#__PURE__*/Object.freeze({ + __proto__: null, + l1: l1, + l1l2: l1l2, + l2: l2 + }); + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + class Callback extends BaseCallback { + constructor() { + super(...arguments); + /** Instance of `keras.models.Model`. Reference of the model being trained. */ + this.model = null; + } + setModel(model) { + if (!(model instanceof LayersModel)) { + throw new Error('model must be a LayersModel, not some other Container'); + } + this.model = model; + } + } + function less$2(currVal, prevVal) { + return currVal < prevVal; + } + function greater$2(currVal, prevVal) { + return currVal > prevVal; + } + /** + * A Callback that stops training when a monitored quantity has stopped + * improving. + */ + class EarlyStopping extends Callback { + constructor(args) { + super(); + if (args == null) { + args = {}; + } + if (args.restoreBestWeights) { + throw new NotImplementedError('restoreBestWeights = True is not implemented in EarlyStopping yet.'); + } + this.monitor = args.monitor || 'val_loss'; + this.minDelta = Math.abs(args.minDelta || 0); + this.patience = args.patience || 0; + this.verbose = args.verbose || 0; + this.mode = args.mode || 'auto'; + this.baseline = args.baseline; + if (['auto', 'min', 'max'].indexOf(this.mode) === -1) { + console.warn(`EarlyStopping mode '${this.mode}' is invalid. ` + + `Falling back to mode 'auto'.`); + this.mode = 'auto'; + } + if (this.mode === 'min') { + this.monitorFunc = less$2; + } + else if (this.mode === 'max') { + this.monitorFunc = greater$2; + } + else { + // For mode === 'auto'. + if (this.monitor.indexOf('acc') !== -1) { + this.monitorFunc = greater$2; + } + else { + this.monitorFunc = less$2; + } + } + if (this.monitorFunc === less$2) { + this.minDelta *= -1; + } + } + async onTrainBegin(logs) { + this.wait = 0; + this.stoppedEpoch = 0; + if (this.baseline != null) { + this.best = this.baseline; + } + else { + this.best = this.monitorFunc === less$2 ? Infinity : -Infinity; + } + } + async onEpochEnd(epoch, logs) { + await resolveScalarsInLogs(logs); + const current = this.getMonitorValue(logs); + if (current == null) { + return; + } + if (this.monitorFunc(current - this.minDelta, this.best)) { + this.best = current; + this.wait = 0; + // TODO(cais): Logic for restoreBestWeights. + } + else { + this.wait++; + if (this.wait >= this.patience) { + this.stoppedEpoch = epoch; + this.model.stopTraining = true; + } + // TODO(cais): Logic for restoreBestWeights. + } + } + async onTrainEnd(logs) { + if (this.stoppedEpoch > 0 && this.verbose) { + console.log(`Epoch ${this.stoppedEpoch}: early stopping.`); + } + } + getMonitorValue(logs) { + if (logs == null) { + logs = {}; + } + const monitorValue = logs[this.monitor]; + if (monitorValue == null) { + console.warn(`Metric for EarlyStopping ${this.monitor} is not available. ` + + `Available metrics are: ${Object.keys(logs)}`); + } + return monitorValue; + } + } + /** + * Factory function for a Callback that stops training when a monitored + * quantity has stopped improving. + * + * Early stopping is a type of regularization, and protects model against + * overfitting. + * + * The following example based on fake data illustrates how this callback + * can be used during `tf.LayersModel.fit()`: + * + * ```js + * const model = tf.sequential(); + * model.add(tf.layers.dense({ + * units: 3, + * activation: 'softmax', + * kernelInitializer: 'ones', + * inputShape: [2] + * })); + * const xs = tf.tensor2d([1, 2, 3, 4], [2, 2]); + * const ys = tf.tensor2d([[1, 0, 0], [0, 1, 0]], [2, 3]); + * const xsVal = tf.tensor2d([4, 3, 2, 1], [2, 2]); + * const ysVal = tf.tensor2d([[0, 0, 1], [0, 1, 0]], [2, 3]); + * model.compile( + * {loss: 'categoricalCrossentropy', optimizer: 'sgd', metrics: ['acc']}); + * + * // Without the EarlyStopping callback, the val_acc value would be: + * // 0.5, 0.5, 0.5, 0.5, ... + * // With val_acc being monitored, training should stop after the 2nd epoch. + * const history = await model.fit(xs, ys, { + * epochs: 10, + * validationData: [xsVal, ysVal], + * callbacks: tf.callbacks.earlyStopping({monitor: 'val_acc'}) + * }); + * + * // Expect to see a length-2 array. + * console.log(history.history.val_acc); + * ``` + * + * @doc { + * heading: 'Callbacks', + * namespace: 'callbacks' + * } + */ + function earlyStopping(args) { + return new EarlyStopping(args); + } + const callbacks = { earlyStopping }; + + /** + * @license + * Copyright 2018 Google LLC + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ENV$1 = env(); + /** Whether to keep intermediate tensors. */ + ENV$1.registerFlag('KEEP_INTERMEDIATE_TENSORS', () => false, debugValue => { + if (debugValue) { + console.warn('Keep intermediate tensors is ON. This will print the values of all ' + + 'intermediate tensors during model inference. Not all models ' + + 'support this mode. For details, check e2e/benchmarks/ ' + + 'model_config.js. This significantly impacts performance.'); + } + }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** DataType enum. */ + var DataType; + (function (DataType) { + // These properties must be quoted since they are used by parseDtypeParam + // in tfjs-converter/src/operations/operation_mapper.ts to look up dtypes + // by string name. If they are not quoted, Closure will mangle their names. + // Not a legal value for DataType. Used to indicate a DataType field + // has not been set. + DataType[DataType["DT_INVALID"] = 0] = "DT_INVALID"; + // Data types that all computation devices are expected to be + // capable to support. + DataType[DataType["DT_FLOAT"] = 1] = "DT_FLOAT"; + DataType[DataType["DT_DOUBLE"] = 2] = "DT_DOUBLE"; + DataType[DataType["DT_INT32"] = 3] = "DT_INT32"; + DataType[DataType["DT_UINT8"] = 4] = "DT_UINT8"; + DataType[DataType["DT_INT16"] = 5] = "DT_INT16"; + DataType[DataType["DT_INT8"] = 6] = "DT_INT8"; + DataType[DataType["DT_STRING"] = 7] = "DT_STRING"; + DataType[DataType["DT_COMPLEX64"] = 8] = "DT_COMPLEX64"; + DataType[DataType["DT_INT64"] = 9] = "DT_INT64"; + DataType[DataType["DT_BOOL"] = 10] = "DT_BOOL"; + DataType[DataType["DT_QINT8"] = 11] = "DT_QINT8"; + DataType[DataType["DT_QUINT8"] = 12] = "DT_QUINT8"; + DataType[DataType["DT_QINT32"] = 13] = "DT_QINT32"; + DataType[DataType["DT_BFLOAT16"] = 14] = "DT_BFLOAT16"; + DataType[DataType["DT_QINT16"] = 15] = "DT_QINT16"; + DataType[DataType["DT_QUINT16"] = 16] = "DT_QUINT16"; + DataType[DataType["DT_UINT16"] = 17] = "DT_UINT16"; + DataType[DataType["DT_COMPLEX128"] = 18] = "DT_COMPLEX128"; + DataType[DataType["DT_HALF"] = 19] = "DT_HALF"; + DataType[DataType["DT_RESOURCE"] = 20] = "DT_RESOURCE"; + DataType[DataType["DT_VARIANT"] = 21] = "DT_VARIANT"; + DataType[DataType["DT_UINT32"] = 22] = "DT_UINT32"; + DataType[DataType["DT_UINT64"] = 23] = "DT_UINT64"; + // Do not use! These are only for parameters. Every enum above + // should have a corresponding value below (verified by types_test). + DataType[DataType["DT_FLOAT_REF"] = 101] = "DT_FLOAT_REF"; + DataType[DataType["DT_DOUBLE_REF"] = 102] = "DT_DOUBLE_REF"; + DataType[DataType["DT_INT32_REF"] = 103] = "DT_INT32_REF"; + DataType[DataType["DT_UINT8_REF"] = 104] = "DT_UINT8_REF"; + DataType[DataType["DT_INT16_REF"] = 105] = "DT_INT16_REF"; + DataType[DataType["DT_INT8_REF"] = 106] = "DT_INT8_REF"; + DataType[DataType["DT_STRING_REF"] = 107] = "DT_STRING_REF"; + DataType[DataType["DT_COMPLEX64_REF"] = 108] = "DT_COMPLEX64_REF"; + DataType[DataType["DT_INT64_REF"] = 109] = "DT_INT64_REF"; + DataType[DataType["DT_BOOL_REF"] = 110] = "DT_BOOL_REF"; + DataType[DataType["DT_QINT8_REF"] = 111] = "DT_QINT8_REF"; + DataType[DataType["DT_QUINT8_REF"] = 112] = "DT_QUINT8_REF"; + DataType[DataType["DT_QINT32_REF"] = 113] = "DT_QINT32_REF"; + DataType[DataType["DT_BFLOAT16_REF"] = 114] = "DT_BFLOAT16_REF"; + DataType[DataType["DT_QINT16_REF"] = 115] = "DT_QINT16_REF"; + DataType[DataType["DT_QUINT16_REF"] = 116] = "DT_QUINT16_REF"; + DataType[DataType["DT_UINT16_REF"] = 117] = "DT_UINT16_REF"; + DataType[DataType["DT_COMPLEX128_REF"] = 118] = "DT_COMPLEX128_REF"; + DataType[DataType["DT_HALF_REF"] = 119] = "DT_HALF_REF"; + DataType[DataType["DT_RESOURCE_REF"] = 120] = "DT_RESOURCE_REF"; + DataType[DataType["DT_VARIANT_REF"] = 121] = "DT_VARIANT_REF"; + DataType[DataType["DT_UINT32_REF"] = 122] = "DT_UINT32_REF"; + DataType[DataType["DT_UINT64_REF"] = 123] = "DT_UINT64_REF"; + })(DataType || (DataType = {})); + var SaverDef; + (function (SaverDef) { + /** CheckpointFormatVersion enum. */ + let CheckpointFormatVersion; + (function (CheckpointFormatVersion) { + CheckpointFormatVersion[CheckpointFormatVersion["LEGACY"] = 0] = "LEGACY"; + CheckpointFormatVersion[CheckpointFormatVersion["V1"] = 1] = "V1"; + CheckpointFormatVersion[CheckpointFormatVersion["V2"] = 2] = "V2"; + })(CheckpointFormatVersion = SaverDef.CheckpointFormatVersion || (SaverDef.CheckpointFormatVersion = {})); + })(SaverDef || (SaverDef = {})); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const CUSTOM_OPS = {}; + /** + * Register an Op for graph model executor. This allows you to register + * TensorFlow custom op or override existing op. + * + * Here is an example of registering a new MatMul Op. + * ```js + * const customMatmul = (node) => + * tf.matMul( + * node.inputs[0], node.inputs[1], + * node.attrs['transpose_a'], node.attrs['transpose_b']); + * + * tf.registerOp('MatMul', customMatmul); + * ``` + * The inputs and attrs of the node object are based on the TensorFlow op + * registry. + * + * @param name The Tensorflow Op name. + * @param opFunc An op function which is called with the current graph node + * during execution and needs to return a tensor or a list of tensors. The node + * has the following attributes: + * - attr: A map from attribute name to its value + * - inputs: A list of input tensors + * + * @doc {heading: 'Models', subheading: 'Op Registry'} + */ + function registerOp(name, opFunc) { + const opMapper = { + tfOpName: name, + category: 'custom', + inputs: [], + attrs: [], + customExecutor: opFunc + }; + CUSTOM_OPS[name] = opMapper; + } + /** + * Retrieve the OpMapper object for the registered op. + * + * @param name The Tensorflow Op name. + * + * @doc {heading: 'Models', subheading: 'Op Registry'} + */ + function getRegisteredOp(name) { + return CUSTOM_OPS[name]; + } + /** + * Deregister the Op for graph model executor. + * + * @param name The Tensorflow Op name. + * + * @doc {heading: 'Models', subheading: 'Op Registry'} + */ + function deregisterOp(name) { + delete CUSTOM_OPS[name]; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function getParamValue(paramName, node, tensorMap, context, resourceManager) { + const inputParam = node.inputParams[paramName]; + if (inputParam && inputParam.inputIndexStart !== undefined) { + const start = inputParam.inputIndexStart; + const end = inputParam.inputIndexEnd === 0 ? + undefined : + (inputParam.inputIndexEnd === undefined ? start + 1 : + inputParam.inputIndexEnd); + const shiftedStart = start < 0 ? node.inputNames.length + start : start; + if (inputParam.type === 'tensor') { + return getTensor(node.inputNames[shiftedStart], tensorMap, context, resourceManager); + } + if (inputParam.type === 'tensors') { + // TODO(mattSoulanille): This filters out NoOp nodes during execution, but + // these should really never be in the execution graph in the first place. + // They're necessary for ordering the graph, but should not be visible + // during execution. Perhaps have different sets of children, one for + // control dependencies and another for real dependencies. + const inputs = node.inputs.slice(start, end); + const inputNames = node.inputNames.slice(start, end) + .filter((_name, index) => { var _a; return ((_a = inputs[index]) === null || _a === void 0 ? void 0 : _a.op) !== 'NoOp'; }); + return inputNames.map(name => getTensor(name, tensorMap, context, resourceManager)); + } + const tensor = getTensor(node.inputNames[shiftedStart], tensorMap, context, resourceManager); + const data = tensor.dataSync(); + return inputParam.type === 'number' ? + data[0] : + toNestedArray(tensor.shape, data); + } + const attrParam = node.attrParams[paramName]; + return attrParam && attrParam.value; + } + /** + * Retrieve the tensor from tensorsMap based on input name. + * @param name Node input name + * @param tensorsMap Tensors map keyed by the node + * @param context contains tensors and information for running the current node. + * @param resourceManager Optional. Contains global resources of the model. + */ + function getTensor(name, tensorsMap, context, resourceManager) { + const [nodeName, index] = parseNodeName(name, context); + if (resourceManager != null) { + const tensor = resourceManager.getHashTableHandleByName(nodeName); + if (tensor != null) { + return tensor; + } + } + const contextId = context.currentContextIds.find(contextId => { + return !!tensorsMap[getNodeNameWithContextId(nodeName, contextId)]; + }); + return contextId !== undefined ? + tensorsMap[getNodeNameWithContextId(nodeName, contextId)][index] : + undefined; + } + /** + * Retrieve the tensors based on input name for current context. + * @param name Node input name + * @param tensorsMap Tensors map keyed by the node + */ + function getTensorsForCurrentContext(name, tensorsMap, context) { + return tensorsMap[getNodeNameWithContextId(name, context.currentContextId)]; + } + /** + * Returns the node name, outputName and index from the Node input name. + * @param inputName The input name of the node, in format of + * node_name:output_index, i.e. MatMul:0, if the output_index is not set, it is + * default to 0. + * If the input name contains output name i.e. StringSplit:indices:0, it will + * return ['StringSplit', 0, 'indices']. + */ + function getNodeNameAndIndex(inputName, context) { + const [nodeName, index, outputName] = parseNodeName(inputName, context); + return [ + getNodeNameWithContextId(nodeName, context && context.currentContextId), + index, outputName + ]; + } + function getNodeNameWithContextId(name, contextId) { + return !!contextId ? `${name}-${contextId}` : name; + } + function parseNodeName(name, context) { + if (name === '') { + return ['', 0, undefined]; + } + const isCacheEnabled = context != null && context.parseNodeNameCache != null; + if (isCacheEnabled) { + const cachedResult = context.parseNodeNameCache.get(name); + if (cachedResult != null) { + return cachedResult; + } + } + const parts = name.split(':'); + let result; + if (parts.length === 1) { + result = [name, 0, undefined]; + } + else { + const nodeName = parts[0]; + const outputName = parts.length === 3 ? parts[1] : undefined; + const index = Number(parts[parts.length - 1]); + result = [nodeName, index, outputName]; + } + if (isCacheEnabled) { + context.parseNodeNameCache.set(name, result); + } + return result; + } + function split$2(arr, size) { + const res = []; + for (let i = 0; i < arr.length; i += size) { + res.push(arr.slice(i, i + size)); + } + return res; + } + function getPadding(node, tensorMap, context) { + let pad = getParamValue('pad', node, tensorMap, context); + if (pad === 'explicit') { + // This is 1d array, we need to convert it to 2d array + pad = getParamValue('explicitPaddings', node, tensorMap, context); + const explicitPadding = [[0, 0], [0, 0], [0, 0], [0, 0]]; + for (let i = 0; i < 4; i++) { + explicitPadding[i][0] = pad[i * 2]; + explicitPadding[i][1] = pad[i * 2 + 1]; + } + return explicitPadding; + } + return pad; + } + /** + * Reuse the tensor if it is marked as keep, otherwise clone the tensor to + * avoid disposal. This is important for TensorArray and TensorList ops, since + * internally they use a tensor as the id for TensorArray and TensorList, and + * to simplify lookup, they also use Tensor.id as the key to the internal map. + * These id tensors have been marked as kept in the backend, we need avoid clone + * them in order to create new Tensor.id. + * @param tensor + */ + function cloneTensor(tensor) { + return tensor.kept ? tensor : clone(tensor); + } + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$i = [ + { + 'tfOpName': 'Add', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'AddV2', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'AddN', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'end': 0, + 'name': 'tensors', + 'type': 'tensors' + } + ] + }, + { + 'tfOpName': 'BiasAdd', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Sub', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'RealDiv', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Div', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'DivNoNan', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'FloorDiv', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Mul', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Maximum', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Minimum', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Pow', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'SquaredDifference', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Mod', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'FloorMod', + 'category': 'arithmetic', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + } + ]; + + var arithmetic = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$i + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$h = [ + { + 'tfOpName': 'Abs', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Acos', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Asin', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Atan', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Atan2', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'y', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Ceil', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'ClipByValue', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'clipValueMin', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'clipValueMax', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Complex', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'real', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'imag', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'ComplexAbs', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Cos', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Cosh', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Elu', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Exp', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Floor', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Log', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Imag', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'Tout', + 'name': 'outputType', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Neg', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Real', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'Tout', + 'name': 'outputType', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Prelu', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'alpha', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Relu', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Relu6', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Selu', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Sigmoid', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Sin', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Sinh', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Sqrt', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Rsqrt', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Square', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Tan', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Tanh', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Sign', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Round', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Expm1', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Log1p', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Reciprocal', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Softplus', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Asinh', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Acosh', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Atanh', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Erf', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LeakyRelu', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'alpha', + 'name': 'alpha', + 'type': 'number', + 'defaultValue': 0.2 + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'IsNan', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'IsFinite', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'IsInf', + 'category': 'basic_math', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + } + ]; + + var basicMath = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$h + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$g = [ + { + 'tfOpName': 'EmptyTensorList', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'elementShape', + 'type': 'shape' + }, + { + 'start': 1, + 'name': 'maxNumElements', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'LoopCond', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'pred', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'Switch', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'data', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'pred', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'Merge', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'end': 0, + 'name': 'tensors', + 'type': 'tensors' + } + ] + }, + { + 'tfOpName': 'Enter', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensor', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'frame_name', + 'name': 'frameName', + 'type': 'string' + }, + { + 'tfName': 'is_constant', + 'name': 'isConstant', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'Exit', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensor', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'NextIteration', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensor', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'TensorArrayV3', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'size', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype' + }, + { + 'tfName': 'element_shape', + 'name': 'elementShape', + 'type': 'shape' + }, + { + 'tfName': 'dynamic_size', + 'name': 'dynamicSize', + 'type': 'bool' + }, + { + 'tfName': 'clear_after_read', + 'name': 'clearAfterRead', + 'type': 'bool' + }, + { + 'tfName': 'identical_element_shapes', + 'name': 'identicalElementShapes', + 'type': 'bool' + }, + { + 'tfName': 'tensor_array_name', + 'name': 'name', + 'type': 'string' + } + ] + }, + { + 'tfOpName': 'TensorArrayWriteV3', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorArrayId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'index', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'tensor', + 'type': 'tensor' + }, + { + 'start': 3, + 'name': 'flowIn', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'TensorArrayReadV3', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorArrayId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'index', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'flowIn', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'TensorArrayGatherV3', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorArrayId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'flowIn', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype' + }, + { + 'tfName': 'element_shape', + 'name': 'elementShape', + 'type': 'shape' + } + ] + }, + { + 'tfOpName': 'TensorArrayScatterV3', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorArrayId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'tensor', + 'type': 'tensor' + }, + { + 'start': 3, + 'name': 'flowIn', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorArrayConcatV3', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorArrayId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'flowIn', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype' + }, + { + 'tfName': 'element_shape_except0', + 'name': 'elementShapeExcept0', + 'type': 'shape', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'TensorArraySplitV3', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorArrayId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'tensor', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'lengths', + 'type': 'number[]' + }, + { + 'start': 3, + 'name': 'flowIn', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorArraySizeV3', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorArrayId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'flowIn', + 'type': 'number' + } + ] + }, + { + 'tfOpName': 'TensorArrayCloseV3', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorArrayId', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'StatelessIf', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'cond', + 'type': 'tensor' + }, + { + 'start': 1, + 'end': 0, + 'name': 'args', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'then_branch', + 'name': 'thenBranch', + 'type': 'func' + }, + { + 'tfName': 'else_branch', + 'name': 'elseBranch', + 'type': 'func' + } + ] + }, + { + 'tfOpName': 'If', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'cond', + 'type': 'tensor' + }, + { + 'start': 1, + 'end': 0, + 'name': 'args', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'then_branch', + 'name': 'thenBranch', + 'type': 'func' + }, + { + 'tfName': 'else_branch', + 'name': 'elseBranch', + 'type': 'func' + } + ] + }, + { + 'tfOpName': 'StatelessWhile', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'end': 0, + 'name': 'args', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'cond', + 'name': 'cond', + 'type': 'func' + }, + { + 'tfName': 'body', + 'name': 'body', + 'type': 'func' + } + ] + }, + { + 'tfOpName': 'While', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'end': 0, + 'name': 'args', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'cond', + 'name': 'cond', + 'type': 'func' + }, + { + 'tfName': 'body', + 'name': 'body', + 'type': 'func' + } + ] + }, + { + 'tfOpName': 'TensorListScatter', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensor', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'elementShape', + 'type': 'shape' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListScatterV2', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensor', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'elementShape', + 'type': 'shape' + }, + { + 'start': 3, + 'name': 'numElements', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListGather', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'elementShape', + 'type': 'shape' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListGetItem', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'index', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'elementShape', + 'type': 'shape' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListSetItem', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'index', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'tensor', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListReserve', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'elementShape', + 'type': 'shape' + }, + { + 'start': 1, + 'name': 'numElements', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListFromTensor', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensor', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'elementShape', + 'type': 'shape' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListStack', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'elementShape', + 'type': 'shape' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + }, + { + 'tfName': 'num_elements', + 'name': 'numElements', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListSplit', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensor', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'elementShape', + 'type': 'shape' + }, + { + 'start': 2, + 'name': 'lengths', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListConcat', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'element_shape', + 'name': 'elementShape', + 'type': 'shape' + }, + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListConcatV2', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'element_shape', + 'name': 'elementShape', + 'type': 'shape' + }, + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListPopBack', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'elementShape', + 'type': 'shape' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListPushBack', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'tensor', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'element_dtype', + 'name': 'elementDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TensorListLength', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'TensorListResize', + 'category': 'control', + 'inputs': [ + { + 'start': 0, + 'name': 'tensorListId', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'size', + 'type': 'number' + } + ] + } + ]; + + var control = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$g + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$f = [ + { + 'tfOpName': 'AvgPool', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'notSupported': true + }, + { + 'tfName': 'ksize', + 'name': 'kernelSize', + 'type': 'number[]' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'MaxPool', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'notSupported': true + }, + { + 'tfName': 'ksize', + 'name': 'kernelSize', + 'type': 'number[]' + }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [], + 'notSupported': true + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'MaxPoolWithArgmax', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'ksize', + 'name': 'kernelSize', + 'type': 'number[]' + }, + { + 'tfName': 'include_batch_in_index', + 'name': 'includeBatchInIndex', + 'type': 'bool' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'AvgPool3D', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'notSupported': true + }, + { + 'tfName': 'ksize', + 'name': 'kernelSize', + 'type': 'number[]' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'MaxPool3D', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'notSupported': true + }, + { + 'tfName': 'ksize', + 'name': 'kernelSize', + 'type': 'number[]' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Conv1D', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'filter', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'stride', + 'name': 'stride', + 'type': 'number' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'defaultValue': 'NWC' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'dilation', + 'name': 'dilation', + 'type': 'number', + 'defaultValue': 1 + } + ] + }, + { + 'tfOpName': 'Conv2D', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'filter', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'useCudnnOnGpu', + 'name': 'useCudnnOnGpu', + 'type': 'bool' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'defaultValue': 'NHWC' + }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + }, + { + 'tfName': 'dilations', + 'name': 'dilations', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': '_FusedConv2D', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'filter', + 'type': 'tensor' + }, + { + 'start': 2, + 'end': 0, + 'name': 'args', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'num_args', + 'name': 'numArgs', + 'type': 'number' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + }, + { + 'tfName': 'use_cudnn_on_gpu', + 'name': 'useCudnnOnGpu', + 'type': 'bool', + 'defaultValue': true + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'defaultValue': 'NHWC' + }, + { + 'tfName': 'dilations', + 'name': 'dilations', + 'type': 'number[]', + 'defaultValue': [ + 1, + 1, + 1, + 1 + ] + }, + { + 'tfName': 'fused_ops', + 'name': 'fusedOps', + 'type': 'string[]', + 'defaultValue': [] + }, + { + 'tfName': 'epsilon', + 'name': 'epsilon', + 'type': 'number', + 'defaultValue': 0.0001 + }, + { + 'tfName': 'leakyrelu_alpha', + 'name': 'leakyreluAlpha', + 'type': 'number', + 'defaultValue': 0.2 + } + ] + }, + { + 'tfOpName': 'Conv2DBackpropInput', + 'category': 'convolution', + 'inputs': [ + { + 'start': 2, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'filter', + 'type': 'tensor' + }, + { + 'start': 0, + 'name': 'outputShape', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'notSupported': true + }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + }, + { + 'tfName': 'dilations', + 'name': 'dilations', + 'type': 'number[]', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'DepthwiseConv2d', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'input', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'filter', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'defaultValue': 'NHWC' + }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + }, + { + 'tfName': 'dilations', + 'name': 'dilations', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'DepthwiseConv2dNative', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'input', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'filter', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'defaultValue': 'NHWC' + }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + }, + { + 'tfName': 'dilations', + 'name': 'dilations', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'FusedDepthwiseConv2dNative', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'filter', + 'type': 'tensor' + }, + { + 'start': 2, + 'end': 0, + 'name': 'args', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'num_args', + 'name': 'numArgs', + 'type': 'number' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'defaultValue': 'NHWC' + }, + { + 'tfName': 'dilations', + 'name': 'dilations', + 'type': 'number[]', + 'defaultValue': [ + 1, + 1, + 1, + 1 + ] + }, + { + 'tfName': 'fused_ops', + 'name': 'fusedOps', + 'type': 'string[]', + 'defaultValue': [] + }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + } + ] + }, + { + 'tfOpName': 'Conv3D', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'filter', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'defaultValue': 'NHWC' + }, + { + 'tfName': 'dilations', + 'name': 'dilations', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'Dilation2D', + 'category': 'convolution', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'filter', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'strides', + 'name': 'strides', + 'type': 'number[]' + }, + { + 'tfName': 'rates', + 'name': 'dilations', + 'type': 'number[]' + }, + { + 'tfName': 'padding', + 'name': 'pad', + 'type': 'string' + } + ] + } + ]; + + var convolution = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$f + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$e = [ + { + 'tfOpName': 'Fill', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'shape', + 'type': 'number[]' + }, + { + 'start': 1, + 'name': 'value', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'LinSpace', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'start', + 'type': 'number' + }, + { + 'start': 1, + 'name': 'stop', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'num', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'OneHot', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'indices', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'depth', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'onValue', + 'type': 'number', + 'defaultValue': 1 + }, + { + 'start': 3, + 'name': 'offValue', + 'type': 'number', + 'defaultValue': 0 + } + ], + 'attrs': [ + { + 'tfName': 'axis', + 'name': 'axis', + 'type': 'number', + 'notSupported': true + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'Ones', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'shape', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'OnesLike', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'RandomStandardNormal', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'shape', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'seed', + 'name': 'seed', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'seed2', + 'name': 'seed2', + 'type': 'number', + 'defaultValue': 0, + 'notSupported': true + }, + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype' + }, + { + 'tfName': 'T', + 'name': 'T', + 'type': 'number', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'RandomUniform', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'shape', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'minval', + 'name': 'minval', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'maxval', + 'name': 'maxval', + 'type': 'number', + 'defaultValue': 1 + }, + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype' + }, + { + 'tfName': 'seed', + 'name': 'seed', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'seed2', + 'name': 'seed2', + 'type': 'number', + 'defaultValue': 0, + 'notSupported': true + }, + { + 'tfName': 'T', + 'name': 'T', + 'type': 'number', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'RandomUniformInt', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'shape', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'minval', + 'name': 'minval', + 'type': 'number' + }, + { + 'tfName': 'maxval', + 'name': 'maxval', + 'type': 'number' + }, + { + 'tfName': 'seed', + 'name': 'seed', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'seed2', + 'name': 'seed2', + 'type': 'number', + 'defaultValue': 0, + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Range', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'start', + 'type': 'number' + }, + { + 'start': 1, + 'name': 'stop', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'step', + 'type': 'number', + 'defaultValue': 0 + } + ], + 'attrs': [ + { + 'tfName': 'Tidx', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'TruncatedNormal', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'shape', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'means', + 'name': 'mean', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'stddev', + 'name': 'stdDev', + 'type': 'number', + 'defaultValue': 1 + }, + { + 'tfName': 'seed', + 'name': 'seed', + 'type': 'number' + }, + { + 'tfName': 'seed2', + 'name': 'seed2', + 'type': 'number', + 'defaultValue': 0, + 'notSupported': true + }, + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype' + }, + { + 'tfName': 'T', + 'name': 'T', + 'type': 'number', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Zeros', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'shape', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'ZerosLike', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'Multinomial', + 'category': 'creation', + 'inputs': [ + { + 'start': 0, + 'name': 'logits', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'numSamples', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'seed', + 'name': 'seed', + 'type': 'number' + }, + { + 'tfName': 'seed2', + 'name': 'seed2', + 'type': 'number' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype' + }, + { + 'tfName': 'output_dtype', + 'name': 'output_dtype', + 'type': 'dtype' + } + ] + } + ]; + + var creation = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$e + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$d = [ + { + 'tfOpName': 'NonMaxSuppressionV2', + 'category': 'dynamic', + 'inputs': [ + { + 'start': 0, + 'name': 'boxes', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'scores', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'maxOutputSize', + 'type': 'number' + }, + { + 'start': 3, + 'name': 'iouThreshold', + 'type': 'number' + } + ] + }, + { + 'tfOpName': 'NonMaxSuppressionV3', + 'category': 'dynamic', + 'inputs': [ + { + 'start': 0, + 'name': 'boxes', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'scores', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'maxOutputSize', + 'type': 'number' + }, + { + 'start': 3, + 'name': 'iouThreshold', + 'type': 'number' + }, + { + 'start': 4, + 'name': 'scoreThreshold', + 'type': 'number' + } + ] + }, + { + 'tfOpName': 'NonMaxSuppressionV4', + 'category': 'dynamic', + 'inputs': [ + { + 'start': 0, + 'name': 'boxes', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'scores', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'maxOutputSize', + 'type': 'number' + }, + { + 'start': 3, + 'name': 'iouThreshold', + 'type': 'number' + }, + { + 'start': 4, + 'name': 'scoreThreshold', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'T_threshold', + 'name': 'threshold', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'pad_to_max_output_size', + 'name': 'padToMaxOutputSize', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'NonMaxSuppressionV5', + 'category': 'dynamic', + 'inputs': [ + { + 'start': 0, + 'name': 'boxes', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'scores', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'maxOutputSize', + 'type': 'number' + }, + { + 'start': 3, + 'name': 'iouThreshold', + 'type': 'number' + }, + { + 'start': 4, + 'name': 'scoreThreshold', + 'type': 'number' + }, + { + 'start': 5, + 'name': 'softNmsSigma', + 'type': 'number' + } + ] + }, + { + 'tfOpName': 'Where', + 'category': 'dynamic', + 'inputs': [ + { + 'start': 0, + 'name': 'condition', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'ListDiff', + 'category': 'dynamic', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'y', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + } + ]; + + var dynamic = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$d + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$c = [ + { + 'tfOpName': 'LowerBound', + 'category': 'evaluation', + 'inputs': [ + { + 'start': 0, + 'name': 'sortedSequence', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'values', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'TopKV2', + 'category': 'evaluation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'k', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'sorted', + 'name': 'sorted', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'UpperBound', + 'category': 'evaluation', + 'inputs': [ + { + 'start': 0, + 'name': 'sortedSequence', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'values', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'Unique', + 'category': 'evaluation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'UniqueV2', + 'category': 'evaluation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number' + } + ] + } + ]; + + var evaluation = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$c + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$b = [ + { + 'tfOpName': 'PlaceholderWithDefault', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'name': 'default', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'shape', + 'name': 'shape', + 'type': 'shape' + }, + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'Placeholder', + 'category': 'graph', + 'attrs': [ + { + 'tfName': 'shape', + 'name': 'shape', + 'type': 'shape' + }, + { + 'tfName': 'dtype', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'Const', + 'category': 'graph' + }, + { + 'tfOpName': 'Identity', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'IdentityN', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'end': 0, + 'name': 'x', + 'type': 'tensors' + } + ] + }, + { + 'tfOpName': 'Snapshot', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'Rank', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'Size', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'Shape', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'ShapeN', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'end': 0, + 'name': 'x', + 'type': 'tensors' + } + ] + }, + { + 'tfOpName': 'Print', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'data', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'message', + 'name': 'message', + 'type': 'string' + }, + { + 'tfName': 'first_n', + 'name': 'firstN', + 'type': 'number', + 'notSupported': true + }, + { + 'tfName': 'summarize', + 'name': 'summarize', + 'type': 'number', + 'defaultValue': 3 + } + ] + }, + { + 'tfOpName': 'NoOp', + 'category': 'graph', + 'inputs': [] + }, + { + 'tfOpName': 'StopGradient', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'FakeQuantWithMinMaxVars', + 'category': 'graph', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'min', + 'name': 'min', + 'type': 'number' + }, + { + 'tfName': 'max', + 'name': 'max', + 'type': 'number' + } + ] + } + ]; + + var graph = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$b + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$a = [ + { + 'tfOpName': 'HashTable', + 'category': 'hash_table', + 'inputs': [], + 'attrs': [ + { + 'tfName': 'shared_name', + 'name': 'sharedName', + 'type': 'string' + }, + { + 'tfName': 'use_node_name_sharing', + 'name': 'useNodeNameSharing', + 'type': 'bool' + }, + { + 'tfName': 'key_dtype', + 'name': 'keyDType', + 'type': 'dtype' + }, + { + 'tfName': 'value_dtype', + 'name': 'valueDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'HashTableV2', + 'category': 'hash_table', + 'inputs': [], + 'attrs': [ + { + 'tfName': 'shared_name', + 'name': 'sharedName', + 'type': 'string' + }, + { + 'tfName': 'use_node_name_sharing', + 'name': 'useNodeNameSharing', + 'type': 'bool' + }, + { + 'tfName': 'key_dtype', + 'name': 'keyDType', + 'type': 'dtype' + }, + { + 'tfName': 'value_dtype', + 'name': 'valueDType', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'LookupTableImport', + 'category': 'hash_table', + 'inputs': [ + { + 'start': 0, + 'name': 'tableHandle', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'keys', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'values', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'Tin', + 'name': 'tIn', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'Tout', + 'name': 'tOut', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LookupTableImportV2', + 'category': 'hash_table', + 'inputs': [ + { + 'start': 0, + 'name': 'tableHandle', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'keys', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'values', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'Tin', + 'name': 'tIn', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'Tout', + 'name': 'tOut', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LookupTableFind', + 'category': 'hash_table', + 'inputs': [ + { + 'start': 0, + 'name': 'tableHandle', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'keys', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'defaultValue', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'Tin', + 'name': 'tIn', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'Tout', + 'name': 'tOut', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LookupTableFindV2', + 'category': 'hash_table', + 'inputs': [ + { + 'start': 0, + 'name': 'tableHandle', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'keys', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'defaultValue', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'Tin', + 'name': 'tIn', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'Tout', + 'name': 'tOut', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LookupTableSize', + 'category': 'hash_table', + 'inputs': [ + { + 'start': 0, + 'name': 'tableHandle', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'LookupTableSizeV2', + 'category': 'hash_table', + 'inputs': [ + { + 'start': 0, + 'name': 'tableHandle', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'InitializeTable', + 'category': 'hash_table', + 'inputs': [ + { + 'start': 0, + 'name': 'tableHandle', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'keys', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'values', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'InitializeTableV2', + 'category': 'hash_table', + 'inputs': [ + { + 'start': 0, + 'name': 'tableHandle', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'keys', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'values', + 'type': 'tensor' + } + ] + } + ]; + + var hashTable = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$a + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$9 = [ + { + 'tfOpName': 'ResizeBilinear', + 'category': 'image', + 'inputs': [ + { + 'start': 0, + 'name': 'images', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'size', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'align_corners', + 'name': 'alignCorners', + 'type': 'bool' + }, + { + 'tfName': 'half_pixel_centers', + 'name': 'halfPixelCenters', + 'type': 'bool' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'ResizeNearestNeighbor', + 'category': 'image', + 'inputs': [ + { + 'start': 0, + 'name': 'images', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'size', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'align_corners', + 'name': 'alignCorners', + 'type': 'bool' + }, + { + 'tfName': 'half_pixel_centers', + 'name': 'halfPixelCenters', + 'type': 'bool' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'CropAndResize', + 'category': 'image', + 'inputs': [ + { + 'start': 0, + 'name': 'image', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'boxes', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'boxInd', + 'type': 'tensor' + }, + { + 'start': 3, + 'name': 'cropSize', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'method', + 'name': 'method', + 'type': 'string' + }, + { + 'tfName': 'extrapolation_value', + 'name': 'extrapolationValue', + 'type': 'number' + } + ] + }, + { + 'tfOpName': 'ImageProjectiveTransformV3', + 'category': 'image', + 'inputs': [ + { + 'start': 0, + 'name': 'images', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'transforms', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'outputShape', + 'type': 'number[]' + }, + { + 'start': 3, + 'name': 'fillValue', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'interpolation', + 'name': 'interpolation', + 'type': 'string' + }, + { + 'tfName': 'fill_mode', + 'name': 'fillMode', + 'type': 'string' + } + ] + } + ]; + + var image = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$9 + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$8 = [ + { + 'tfOpName': 'Equal', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'NotEqual', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Greater', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'GreaterEqual', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Less', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LessEqual', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LogicalAnd', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LogicalNot', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LogicalOr', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Select', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'condition', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'SelectV2', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'condition', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'BitwiseAnd', + 'category': 'logical', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'y', + 'type': 'tensor' + } + ] + } + ]; + + var logical = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$8 + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$7 = [ + { + 'tfOpName': '_FusedMatMul', + 'category': 'matrices', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + }, + { + 'start': 2, + 'end': 0, + 'name': 'args', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'num_args', + 'name': 'numArgs', + 'type': 'number' + }, + { + 'tfName': 'fused_ops', + 'name': 'fusedOps', + 'type': 'string[]', + 'defaultValue': [] + }, + { + 'tfName': 'epsilon', + 'name': 'epsilon', + 'type': 'number', + 'defaultValue': 0.0001 + }, + { + 'tfName': 'transpose_a', + 'name': 'transposeA', + 'type': 'bool', + 'defaultValue': false + }, + { + 'tfName': 'transpose_b', + 'name': 'transposeB', + 'type': 'bool', + 'defaultValue': false + }, + { + 'tfName': 'leakyrelu_alpha', + 'name': 'leakyreluAlpha', + 'type': 'number', + 'defaultValue': 0.2 + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'MatMul', + 'category': 'matrices', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'transpose_a', + 'name': 'transposeA', + 'type': 'bool', + 'defaultValue': false + }, + { + 'tfName': 'transpose_b', + 'name': 'transposeB', + 'type': 'bool', + 'defaultValue': false + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'BatchMatMul', + 'category': 'matrices', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'adj_x', + 'name': 'transposeA', + 'type': 'bool', + 'defaultValue': false + }, + { + 'tfName': 'adj_y', + 'name': 'transposeB', + 'type': 'bool', + 'defaultValue': false + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'BatchMatMulV2', + 'category': 'matrices', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'b', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'adj_x', + 'name': 'transposeA', + 'type': 'bool', + 'defaultValue': false + }, + { + 'tfName': 'adj_y', + 'name': 'transposeB', + 'type': 'bool', + 'defaultValue': false + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Transpose', + 'category': 'matrices', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'perm', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Einsum', + 'category': 'matrices', + 'inputs': [ + { + 'start': 0, + 'end': 0, + 'name': 'tensors', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'equation', + 'name': 'equation', + 'type': 'string' + }, + { + 'tfName': 'N', + 'name': 'n', + 'type': 'number', + 'defaultValue': 2 + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'MatrixBandPart', + 'category': 'matrices', + 'inputs': [ + { + 'start': 0, + 'name': 'a', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'numLower', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'numUpper', + 'type': 'tensor' + } + ] + } + ]; + + var matrices = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$7 + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$6 = [ + { + 'tfOpName': 'EuclideanNorm', + 'category': 'normalization', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'keep_dims', + 'name': 'keepDims', + 'type': 'bool', + 'defaultValue': false + } + ] + }, + { + 'tfOpName': 'FusedBatchNorm', + 'category': 'normalization', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'scale', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'offset', + 'type': 'tensor' + }, + { + 'start': 3, + 'name': 'mean', + 'type': 'tensor' + }, + { + 'start': 4, + 'name': 'variance', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'epsilon', + 'name': 'epsilon', + 'type': 'number', + 'defaultValue': 0.001 + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'FusedBatchNormV2', + 'category': 'normalization', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'scale', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'offset', + 'type': 'tensor' + }, + { + 'start': 3, + 'name': 'mean', + 'type': 'tensor' + }, + { + 'start': 4, + 'name': 'variance', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'epsilon', + 'name': 'epsilon', + 'type': 'number', + 'defaultValue': 0.001 + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'FusedBatchNormV3', + 'category': 'normalization', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'scale', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'offset', + 'type': 'tensor' + }, + { + 'start': 3, + 'name': 'mean', + 'type': 'tensor' + }, + { + 'start': 4, + 'name': 'variance', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'epsilon', + 'name': 'epsilon', + 'type': 'number', + 'defaultValue': 0.001 + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'LRN', + 'category': 'normalization', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'depth_radius', + 'name': 'radius', + 'type': 'number', + 'defaultValue': 5 + }, + { + 'tfName': 'bias', + 'name': 'bias', + 'type': 'number', + 'defaultValue': 1 + }, + { + 'tfName': 'alpha', + 'name': 'alpha', + 'type': 'number', + 'defaultValue': 1 + }, + { + 'tfName': 'beta', + 'name': 'beta', + 'type': 'number', + 'defaultValue': 0.5 + } + ] + }, + { + 'tfOpName': 'Softmax', + 'category': 'normalization', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'LogSoftmax', + 'category': 'normalization', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + } + ]; + + var normalization = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$6 + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$5 = [ + { + 'tfOpName': 'Bincount', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'size', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'weights', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'DenseBincount', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'size', + 'type': 'number' + }, + { + 'start': 2, + 'name': 'weights', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'binary_output', + 'name': 'binaryOutput', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'Max', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'keep_dims', + 'name': 'keepDims', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'Mean', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'keep_dims', + 'name': 'keepDims', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'Min', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'keep_dims', + 'name': 'keepDims', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'Sum', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'keep_dims', + 'name': 'keepDims', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'All', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'keep_dims', + 'name': 'keepDims', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'Any', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'keep_dims', + 'name': 'keepDims', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'ArgMax', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number' + } + ] + }, + { + 'tfOpName': 'ArgMin', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number' + } + ] + }, + { + 'tfOpName': 'Prod', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'keep_dims', + 'name': 'keepDims', + 'type': 'bool' + }, + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Cumprod', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'exclusive', + 'name': 'exclusive', + 'type': 'bool' + }, + { + 'tfName': 'reverse', + 'name': 'reverse', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'Cumsum', + 'category': 'reduction', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'exclusive', + 'name': 'exclusive', + 'type': 'bool' + }, + { + 'tfName': 'reverse', + 'name': 'reverse', + 'type': 'bool' + } + ] + } + ]; + + var reduction = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$5 + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$4 = [ + { + 'tfOpName': 'ConcatV2', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'end': -1, + 'name': 'tensors', + 'type': 'tensors' + }, + { + 'start': -1, + 'name': 'axis', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'N', + 'name': 'n', + 'type': 'number', + 'defaultValue': 2 + } + ] + }, + { + 'tfOpName': 'Concat', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 1, + 'end': 0, + 'name': 'tensors', + 'type': 'tensors' + }, + { + 'start': 0, + 'name': 'axis', + 'type': 'number' + } + ], + 'attrs': [ + { + 'tfName': 'N', + 'name': 'n', + 'type': 'number', + 'defaultValue': 2 + } + ] + }, + { + 'tfOpName': 'GatherV2', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'axis', + 'type': 'number', + 'defaultValue': 0 + } + ], + 'attrs': [ + { + 'tfName': 'batch_dims', + 'name': 'batchDims', + 'type': 'number', + 'defaultValue': 0 + } + ] + }, + { + 'tfOpName': 'Gather', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'validate_indices', + 'name': 'validateIndices', + 'type': 'bool', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Reverse', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'dims', + 'type': 'bool[]' + } + ] + }, + { + 'tfOpName': 'ReverseV2', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'Slice', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'begin', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'size', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'StridedSlice', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'begin', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'end', + 'type': 'number[]' + }, + { + 'start': 3, + 'name': 'strides', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'begin_mask', + 'name': 'beginMask', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'end_mask', + 'name': 'endMask', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'new_axis_mask', + 'name': 'newAxisMask', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'ellipsis_mask', + 'name': 'ellipsisMask', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'shrink_axis_mask', + 'name': 'shrinkAxisMask', + 'type': 'number', + 'defaultValue': 0 + } + ] + }, + { + 'tfOpName': 'Pack', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'end': 0, + 'name': 'tensors', + 'type': 'tensors' + } + ], + 'attrs': [ + { + 'tfName': 'axis', + 'name': 'axis', + 'type': 'number', + 'defaultValue': 0 + } + ] + }, + { + 'tfOpName': 'Unpack', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'tensor', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'axis', + 'name': 'axis', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'tfName': 'num', + 'name': 'num', + 'type': 'number', + 'defaultValue': 0, + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'Tile', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'reps', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'Split', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'axis', + 'type': 'number', + 'defaultValue': 0 + }, + { + 'start': 1, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'num_split', + 'name': 'numOrSizeSplits', + 'type': 'number', + 'defaultValue': 1 + } + ] + }, + { + 'tfOpName': 'SplitV', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'numOrSizeSplits', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'axis', + 'type': 'number', + 'defaultValue': 0 + } + ] + }, + { + 'tfOpName': 'ScatterNd', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'indices', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'values', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'shape', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'GatherNd', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'SparseToDense', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'sparseIndices', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'outputShape', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'sparseValues', + 'type': 'tensor' + }, + { + 'start': 3, + 'name': 'defaultValue', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'validate_indices', + 'name': 'validateIndices', + 'type': 'bool', + 'defaultValue': false, + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'TensorScatterUpdate', + 'category': 'slice_join', + 'inputs': [ + { + 'start': 0, + 'name': 'tensor', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'values', + 'type': 'tensor' + } + ] + } + ]; + + var sliceJoin = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$4 + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$3 = [ + { + 'tfOpName': 'SparseFillEmptyRows', + 'category': 'sparse', + 'inputs': [ + { + 'start': 0, + 'name': 'indices', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'values', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'denseShape', + 'type': 'tensor' + }, + { + 'start': 3, + 'name': 'defaultValue', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'SparseReshape', + 'category': 'sparse', + 'inputs': [ + { + 'start': 0, + 'name': 'inputIndices', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'inputShape', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'newShape', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'T', + 'name': 'dtype', + 'type': 'dtype', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'SparseSegmentMean', + 'category': 'sparse', + 'inputs': [ + { + 'start': 0, + 'name': 'data', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'segmentIds', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'SparseSegmentSum', + 'category': 'sparse', + 'inputs': [ + { + 'start': 0, + 'name': 'data', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'indices', + 'type': 'tensor' + }, + { + 'start': 2, + 'name': 'segmentIds', + 'type': 'tensor' + } + ] + } + ]; + + var sparse = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$3 + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$2 = [ + { + 'tfOpName': 'FFT', + 'category': 'spectral', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'IFFT', + 'category': 'spectral', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ] + }, + { + 'tfOpName': 'RFFT', + 'category': 'spectral', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'fft_length', + 'type': 'number', + 'notSupported': true + } + ] + }, + { + 'tfOpName': 'IRFFT', + 'category': 'spectral', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'fft_length', + 'type': 'number', + 'notSupported': true + } + ] + } + ]; + + var spectral = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$2 + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json$1 = [ + { + 'tfOpName': 'StaticRegexReplace', + 'category': 'string', + 'inputs': [ + { + 'start': 0, + 'name': 'input', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'pattern', + 'name': 'pattern', + 'type': 'string' + }, + { + 'tfName': 'rewrite', + 'name': 'rewrite', + 'type': 'string' + }, + { + 'tfName': 'replace_global', + 'name': 'replaceGlobal', + 'type': 'bool' + } + ] + }, + { + 'tfOpName': 'StringNGrams', + 'category': 'string', + 'inputs': [ + { + 'start': 0, + 'name': 'data', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'dataSplits', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'separator', + 'name': 'separator', + 'type': 'string' + }, + { + 'tfName': 'ngram_widths', + 'name': 'nGramWidths', + 'type': 'number[]' + }, + { + 'tfName': 'left_pad', + 'name': 'leftPad', + 'type': 'string' + }, + { + 'tfName': 'right_pad', + 'name': 'rightPad', + 'type': 'string' + }, + { + 'tfName': 'pad_width', + 'name': 'padWidth', + 'type': 'number' + }, + { + 'tfName': 'preserve_short_sequences', + 'name': 'preserveShortSequences', + 'type': 'bool' + } + ], + 'outputs': [ + 'ngrams', + 'ngrams_splits' + ] + }, + { + 'tfOpName': 'StringSplit', + 'category': 'string', + 'inputs': [ + { + 'start': 0, + 'name': 'input', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'delimiter', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'skip_empty', + 'name': 'skipEmpty', + 'type': 'bool' + } + ], + 'outputs': [ + 'indices', + 'values', + 'shape' + ] + }, + { + 'tfOpName': 'StringToHashBucketFast', + 'category': 'string', + 'inputs': [ + { + 'start': 0, + 'name': 'input', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'num_buckets', + 'name': 'numBuckets', + 'type': 'number' + } + ] + } + ]; + + var string = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json$1 + }); + + /** + * @license + * Copyright 2023 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const json = [ + { + 'tfOpName': 'Cast', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'SrcT', + 'name': 'sdtype', + 'type': 'dtype', + 'notSupported': true + }, + { + 'tfName': 'DstT', + 'name': 'dtype', + 'type': 'dtype' + } + ] + }, + { + 'tfOpName': 'ExpandDims', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'axis', + 'type': 'number' + } + ] + }, + { + 'tfOpName': 'MirrorPad', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'padding', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'mode', + 'name': 'mode', + 'type': 'string' + } + ] + }, + { + 'tfOpName': 'Pad', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'padding', + 'type': 'number[]' + } + ], + 'attrs': [ + { + 'tfName': 'constant_value', + 'name': 'constantValue', + 'type': 'number', + 'defaultValue': 0 + } + ] + }, + { + 'tfOpName': 'PadV2', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'padding', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'constantValue', + 'type': 'number', + 'defaultValue': 0 + } + ] + }, + { + 'tfOpName': 'Reshape', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'shape', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'EnsureShape', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'shape', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'Squeeze', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'axis', + 'tfDeprecatedName': 'squeeze_dims', + 'name': 'axis', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'SpaceToBatchND', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'blockShape', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'paddings', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'BatchToSpaceND', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'blockShape', + 'type': 'number[]' + }, + { + 'start': 2, + 'name': 'crops', + 'type': 'number[]' + } + ] + }, + { + 'tfOpName': 'DepthToSpace', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + } + ], + 'attrs': [ + { + 'tfName': 'block_size', + 'name': 'blockSize', + 'type': 'number' + }, + { + 'tfName': 'data_format', + 'name': 'dataFormat', + 'type': 'string' + } + ] + }, + { + 'tfOpName': 'BroadcastTo', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 'x', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 'shape', + 'type': 'number[]' + } + ], + 'attrs': [] + }, + { + 'tfOpName': 'BroadcastArgs', + 'category': 'transformation', + 'inputs': [ + { + 'start': 0, + 'name': 's0', + 'type': 'tensor' + }, + { + 'start': 1, + 'name': 's1', + 'type': 'tensor' + } + ], + 'attrs': [] + } + ]; + + var transformation = /*#__PURE__*/Object.freeze({ + __proto__: null, + json: json + }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class OperationMapper { + // Singleton instance for the mapper + static get Instance() { + return this._instance || (this._instance = new this()); + } + // Loads the op mapping from the JSON file. + constructor() { + const ops = [ + arithmetic, basicMath, control, convolution, creation, dynamic, + evaluation, graph, hashTable, image, logical, matrices, normalization, + reduction, sliceJoin, sparse, spectral, string, transformation + ]; + const mappersJson = [].concat(...ops.map(op => op.json)); + this.opMappers = mappersJson.reduce((map, mapper) => { + map[mapper.tfOpName] = mapper; + return map; + }, {}); + } + // Converts the model inference graph from Tensorflow GraphDef to local + // representation for TensorFlow.js API + transformGraph(graph, signature = {}) { + const tfNodes = graph.node; + const placeholders = []; + const weights = []; + const initNodes = []; + const nodes = tfNodes.reduce((map, node) => { + map[node.name] = this.mapNode(node); + if (node.op.startsWith('Placeholder')) { + placeholders.push(map[node.name]); + } + else if (node.op === 'Const') { + weights.push(map[node.name]); + } + else if (node.input == null || node.input.length === 0) { + initNodes.push(map[node.name]); + } + return map; + }, {}); + let inputs = []; + const outputs = []; + let inputNodeNameToKey = {}; + let outputNodeNameToKey = {}; + if (signature != null) { + inputNodeNameToKey = this.mapSignatureEntries(signature.inputs); + outputNodeNameToKey = this.mapSignatureEntries(signature.outputs); + } + const allNodes = Object.keys(nodes); + allNodes.forEach(key => { + const node = nodes[key]; + node.inputNames.forEach((name, index) => { + const [nodeName, , outputName] = getNodeNameAndIndex(name); + const inputNode = nodes[nodeName]; + if (inputNode.outputs != null) { + const outputIndex = inputNode.outputs.indexOf(outputName); + if (outputIndex !== -1) { + const inputName = `${nodeName}:${outputIndex}`; + // update the input name to use the mapped output index directly. + node.inputNames[index] = inputName; + } + } + node.inputs.push(inputNode); + inputNode.children.push(node); + }); + }); + // if signature has not outputs set, add any node that does not have + // outputs. + if (Object.keys(outputNodeNameToKey).length === 0) { + allNodes.forEach(key => { + const node = nodes[key]; + if (node.children.length === 0) { + outputs.push(node); + } + }); + } + else { + Object.keys(outputNodeNameToKey).forEach(name => { + const [nodeName,] = getNodeNameAndIndex(name); + const node = nodes[nodeName]; + if (node != null) { + node.signatureKey = outputNodeNameToKey[name]; + outputs.push(node); + } + }); + } + if (Object.keys(inputNodeNameToKey).length > 0) { + Object.keys(inputNodeNameToKey).forEach(name => { + const [nodeName,] = getNodeNameAndIndex(name); + const node = nodes[nodeName]; + if (node) { + node.signatureKey = inputNodeNameToKey[name]; + inputs.push(node); + } + }); + } + else { + inputs = placeholders; + } + let functions = {}; + if (graph.library != null && graph.library.function != null) { + functions = graph.library.function.reduce((functions, func) => { + functions[func.signature.name] = this.mapFunction(func); + return functions; + }, {}); + } + const result = { nodes, inputs, outputs, weights, placeholders, signature, functions }; + if (initNodes.length > 0) { + result.initNodes = initNodes; + } + return result; + } + mapSignatureEntries(entries) { + return Object.keys(entries || {}) + .reduce((prev, curr) => { + prev[entries[curr].name] = curr; + return prev; + }, {}); + } + mapNode(node) { + // Unsupported ops will cause an error at run-time (not parse time), since + // they may not be used by the actual execution subgraph. + const mapper = getRegisteredOp(node.op) || this.opMappers[node.op] || {}; + if (node.attr == null) { + node.attr = {}; + } + const newNode = { + name: node.name, + op: node.op, + category: mapper.category, + inputNames: (node.input || + []).map(input => input.startsWith('^') ? input.slice(1) : input), + inputs: [], + children: [], + inputParams: {}, + attrParams: {}, + rawAttrs: node.attr, + outputs: mapper.outputs + }; + if (mapper.inputs != null) { + newNode.inputParams = + mapper.inputs.reduce((map, param) => { + map[param.name] = { + type: param.type, + inputIndexStart: param.start, + inputIndexEnd: param.end + }; + return map; + }, {}); + } + if (mapper.attrs != null) { + newNode.attrParams = + mapper.attrs.reduce((map, param) => { + const type = param.type; + let value = undefined; + switch (param.type) { + case 'string': + value = getStringParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getStringParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'string[]': + value = getStringArrayParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getStringArrayParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'number': + value = getNumberParam(node.attr, param.tfName, (param.defaultValue || 0)); + if (value === undefined && !!param.tfDeprecatedName) { + value = getNumberParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'number[]': + value = getNumericArrayParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getNumericArrayParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'bool': + value = getBoolParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getBoolParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'bool[]': + value = getBoolArrayParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getBoolArrayParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'shape': + value = getTensorShapeParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getTensorShapeParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'shape[]': + value = getTensorShapeArrayParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getTensorShapeArrayParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'dtype': + value = getDtypeParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getDtypeParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'dtype[]': + value = getDtypeArrayParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getDtypeArrayParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'func': + value = getFuncParam(node.attr, param.tfName, param.defaultValue); + if (value === undefined && !!param.tfDeprecatedName) { + value = getFuncParam(node.attr, param.tfDeprecatedName, param.defaultValue); + } + break; + case 'tensor': + case 'tensors': + break; + default: + throw new Error(`Unsupported param type: ${param.type} for op: ${node.op}`); + } + map[param.name] = { value, type }; + return map; + }, {}); + } + return newNode; + } + // map the TFunctionDef to TFJS graph object + mapFunction(functionDef) { + const tfNodes = functionDef.nodeDef; + const placeholders = []; + const weights = []; + let nodes = {}; + if (tfNodes != null) { + nodes = tfNodes.reduce((map, node) => { + map[node.name] = this.mapNode(node); + if (node.op === 'Const') { + weights.push(map[node.name]); + } + return map; + }, {}); + } + const inputs = []; + const outputs = []; + functionDef.signature.inputArg.forEach(arg => { + const [nodeName,] = getNodeNameAndIndex(arg.name); + const node = { + name: nodeName, + op: 'Placeholder', + inputs: [], + inputNames: [], + category: 'graph', + inputParams: {}, + attrParams: { dtype: { value: parseDtypeParam(arg.type), type: 'dtype' } }, + children: [] + }; + node.signatureKey = arg.name; + inputs.push(node); + nodes[nodeName] = node; + }); + const allNodes = Object.keys(nodes); + allNodes.forEach(key => { + const node = nodes[key]; + node.inputNames.forEach((name, index) => { + const [nodeName, , outputName] = getNodeNameAndIndex(name); + const inputNode = nodes[nodeName]; + if (inputNode.outputs != null) { + const outputIndex = inputNode.outputs.indexOf(outputName); + if (outputIndex !== -1) { + const inputName = `${nodeName}:${outputIndex}`; + // update the input name to use the mapped output index directly. + node.inputNames[index] = inputName; + } + } + node.inputs.push(inputNode); + inputNode.children.push(node); + }); + }); + const returnNodeMap = functionDef.ret; + functionDef.signature.outputArg.forEach(output => { + const [nodeName, index] = getNodeNameAndIndex(returnNodeMap[output.name]); + const node = nodes[nodeName]; + if (node != null) { + node.defaultOutput = index; + outputs.push(node); + } + }); + const signature = this.mapArgsToSignature(functionDef); + return { nodes, inputs, outputs, weights, placeholders, signature }; + } + mapArgsToSignature(functionDef) { + return { + methodName: functionDef.signature.name, + inputs: functionDef.signature.inputArg.reduce((map, arg) => { + map[arg.name] = this.mapArgToTensorInfo(arg); + return map; + }, {}), + outputs: functionDef.signature.outputArg.reduce((map, arg) => { + map[arg.name] = this.mapArgToTensorInfo(arg, functionDef.ret); + return map; + }, {}), + }; + } + mapArgToTensorInfo(arg, nameMap) { + let name = arg.name; + if (nameMap != null) { + name = nameMap[name]; + } + return { name, dtype: arg.type }; + } + } + function decodeBase64(text) { + const global = env().global; + if (typeof global.atob !== 'undefined') { + return global.atob(text); + } + else if (typeof Buffer !== 'undefined') { + return new Buffer(text, 'base64').toString(); + } + else { + throw new Error('Unable to decode base64 in this environment. ' + + 'Missing built-in atob() or Buffer()'); + } + } + function parseStringParam(s, keepCase) { + const value = Array.isArray(s) ? String.fromCharCode.apply(null, s) : decodeBase64(s); + return keepCase ? value : value.toLowerCase(); + } + function getStringParam(attrs, name, def, keepCase = false) { + const param = attrs[name]; + if (param != null) { + return parseStringParam(param.s, keepCase); + } + return def; + } + function getBoolParam(attrs, name, def) { + const param = attrs[name]; + return param ? param.b : def; + } + function getNumberParam(attrs, name, def) { + const param = attrs[name] || {}; + const value = param['i'] != null ? param['i'] : (param['f'] != null ? param['f'] : def); + return (typeof value === 'number') ? value : parseInt(value, 10); + } + function parseDtypeParam(value) { + if (typeof (value) === 'string') { + // tslint:disable-next-line:no-any + value = DataType[value]; + } + switch (value) { + case DataType.DT_FLOAT: + case DataType.DT_HALF: + return 'float32'; + case DataType.DT_INT32: + case DataType.DT_INT64: + case DataType.DT_INT8: + case DataType.DT_UINT8: + return 'int32'; + case DataType.DT_BOOL: + return 'bool'; + case DataType.DT_DOUBLE: + return 'float32'; + case DataType.DT_STRING: + return 'string'; + case DataType.DT_COMPLEX64: + case DataType.DT_COMPLEX128: + return 'complex64'; + default: + // Unknown dtype error will happen at runtime (instead of parse time), + // since these nodes might not be used by the actual subgraph execution. + return null; + } + } + function getFuncParam(attrs, name, def) { + const param = attrs[name]; + if (param && param.func) { + return param.func.name; + } + return def; + } + function getDtypeParam(attrs, name, def) { + const param = attrs[name]; + if (param && param.type) { + return parseDtypeParam(param.type); + } + return def; + } + function getDtypeArrayParam(attrs, name, def) { + const param = attrs[name]; + if (param && param.list && param.list.type) { + return param.list.type.map(v => parseDtypeParam(v)); + } + return def; + } + function parseTensorShapeParam(shape) { + if (shape.unknownRank) { + return undefined; + } + if (shape.dim != null) { + return shape.dim.map(dim => (typeof dim.size === 'number') ? dim.size : parseInt(dim.size, 10)); + } + return []; + } + function getTensorShapeParam(attrs, name, def) { + const param = attrs[name]; + if (param && param.shape) { + return parseTensorShapeParam(param.shape); + } + return def; + } + function getNumericArrayParam(attrs, name, def) { + const param = attrs[name]; + if (param) { + return ((param.list.f && param.list.f.length ? param.list.f : + param.list.i) || + []) + .map(v => (typeof v === 'number') ? v : parseInt(v, 10)); + } + return def; + } + function getStringArrayParam(attrs, name, def, keepCase = false) { + const param = attrs[name]; + if (param && param.list && param.list.s) { + return param.list.s.map((v) => { + return parseStringParam(v, keepCase); + }); + } + return def; + } + function getTensorShapeArrayParam(attrs, name, def) { + const param = attrs[name]; + if (param && param.list && param.list.shape) { + return param.list.shape.map((v) => { + return parseTensorShapeParam(v); + }); + } + return def; + } + function getBoolArrayParam(attrs, name, def) { + const param = attrs[name]; + if (param && param.list && param.list.b) { + return param.list.b; + } + return def; + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Helper class for lookup inputs and params for nodes in the model graph. + */ + class NodeValueImpl { + constructor(node, tensorMap, context) { + this.node = node; + this.tensorMap = tensorMap; + this.context = context; + this.inputs = []; + this.attrs = {}; + this.inputs = node.inputNames.map(name => this.getInput(name)); + if (node.rawAttrs != null) { + this.attrs = Object.keys(node.rawAttrs) + .reduce((attrs, key) => { + attrs[key] = this.getAttr(key); + return attrs; + }, {}); + } + } + /** + * Return the value of the attribute or input param. + * @param name String: name of attribute or input param. + */ + getInput(name) { + return getTensor(name, this.tensorMap, this.context); + } + /** + * Return the value of the attribute or input param. + * @param name String: name of attribute or input param. + */ + getAttr(name, defaultValue) { + const value = this.node.rawAttrs[name]; + if (value.tensor != null) { + return getTensor(name, this.tensorMap, this.context); + } + if (value.i != null || value.f != null) { + return getNumberParam(this.node.rawAttrs, name, defaultValue); + } + if (value.s != null) { + return getStringParam(this.node.rawAttrs, name, defaultValue); + } + if (value.b != null) { + return getBoolParam(this.node.rawAttrs, name, defaultValue); + } + if (value.shape != null) { + return getTensorShapeParam(this.node.rawAttrs, name, defaultValue); + } + if (value.type != null) { + return getDtypeParam(this.node.rawAttrs, name, defaultValue); + } + if (value.list != null) { + if (value.list.i != null || value.list.f != null) { + return getNumericArrayParam(this.node.rawAttrs, name, defaultValue); + } + if (value.list.s != null) { + return getStringArrayParam(this.node.rawAttrs, name, defaultValue); + } + if (value.list.shape != null) { + return getTensorShapeArrayParam(this.node.rawAttrs, name, defaultValue); + } + if (value.list.b != null) { + return getBoolArrayParam(this.node.rawAttrs, name, defaultValue); + } + if (value.list.type != null) { + return getDtypeArrayParam(this.node.rawAttrs, name, defaultValue); + } + } + return defaultValue; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + var tfOps = /*#__PURE__*/Object.freeze({ + __proto__: null, + OP_SCOPE_SUFFIX: OP_SCOPE_SUFFIX, + abs: abs$2, + acos: acos$2, + acosh: acosh$2, + add: add$3, + addN: addN$2, + all: all$2, + any: any$2, + argMax: argMax$2, + argMin: argMin$2, + asin: asin$2, + asinh: asinh$2, + atan: atan$2, + atan2: atan2$2, + atanh: atanh$2, + avgPool: avgPool$2, + avgPool3d: avgPool3d$1, + basicLSTMCell: basicLSTMCell, + batchNorm: batchNorm$2, + batchNorm2d: batchNorm2d, + batchNorm3d: batchNorm3d, + batchNorm4d: batchNorm4d, + batchToSpaceND: batchToSpaceND$2, + bincount: bincount$2, + bitwiseAnd: bitwiseAnd$2, + booleanMaskAsync: booleanMaskAsync, + broadcastArgs: broadcastArgs$2, + broadcastTo: broadcastTo, + buffer: buffer, + cast: cast$3, + ceil: ceil$2, + clipByValue: clipByValue$2, + clone: clone, + complex: complex$2, + concat: concat$2, + concat1d: concat1d, + concat2d: concat2d, + concat3d: concat3d, + concat4d: concat4d, + conv1d: conv1d$2, + conv2d: conv2d$4, + conv2dTranspose: conv2dTranspose$1, + conv3d: conv3d$2, + conv3dTranspose: conv3dTranspose$1, + cos: cos$2, + cosh: cosh$2, + cosineWindow: cosineWindow, + cumprod: cumprod$2, + cumsum: cumsum$2, + denseBincount: denseBincount$2, + depthToSpace: depthToSpace$2, + depthwiseConv2d: depthwiseConv2d$3, + diag: diag$2, + dilation2d: dilation2d, + div: div$1, + divNoNan: divNoNan, + dot: dot$2, + dropout: dropout$2, + einsum: einsum$2, + elu: elu$4, + enclosingPowerOfTwo: enclosingPowerOfTwo, + ensureShape: ensureShape, + equal: equal$2, + erf: erf$2, + euclideanNorm: euclideanNorm, + exp: exp$2, + expandDims: expandDims$3, + expm1: expm1$2, + eye: eye, + fft: fft$2, + fill: fill$2, + floor: floor$2, + floorDiv: floorDiv$2, + fused: fused_ops, + gather: gather$1, + gatherND: gatherND, + greater: greater$3, + greaterEqual: greaterEqual$2, + ifft: ifft$2, + imag: imag$2, + image: image$1, + inTopKAsync: inTopKAsync, + irfft: irfft, + isFinite: isFinite$3, + isInf: isInf$2, + isNaN: isNaN$3, + leakyRelu: leakyRelu$2, + less: less$3, + lessEqual: lessEqual$2, + linalg: linalg, + linspace: linspace, + localResponseNormalization: localResponseNormalization, + log: log$2, + log1p: log1p$2, + logSigmoid: logSigmoid, + logSoftmax: logSoftmax, + logSumExp: logSumExp, + logicalAnd: logicalAnd$2, + logicalNot: logicalNot$2, + logicalOr: logicalOr$2, + logicalXor: logicalXor, + losses: losses, + lowerBound: lowerBound$1, + matMul: matMul$1, + max: max$3, + maxPool: maxPool$2, + maxPool3d: maxPool3d$1, + maxPoolWithArgmax: maxPoolWithArgmax, + maximum: maximum$4, + mean: mean$3, + meshgrid: meshgrid, + min: min$3, + minimum: minimum$4, + mirrorPad: mirrorPad$1, + mod: mod$2, + moments: moments, + movingAverage: movingAverage, + mul: mul, + multiRNNCell: multiRNNCell, + multinomial: multinomial$2, + neg: neg$2, + norm: norm, + notEqual: notEqual$2, + oneHot: oneHot$3, + ones: ones$1, + onesLike: onesLike$3, + op: op, + outerProduct: outerProduct, + pad: pad, + pad1d: pad1d, + pad2d: pad2d, + pad3d: pad3d, + pad4d: pad4d, + pool: pool$1, + pow: pow$3, + prelu: prelu$3, + print: print, + prod: prod$2, + raggedGather: raggedGather$2, + raggedRange: raggedRange$2, + raggedTensorToTensor: raggedTensorToTensor$2, + rand: rand, + randomGamma: randomGamma, + randomNormal: randomNormal$2, + randomStandardNormal: randomStandardNormal, + randomUniform: randomUniform$1, + randomUniformInt: randomUniformInt, + range: range$3, + real: real$2, + reciprocal: reciprocal$2, + relu: relu$2, + relu6: relu6$2, + reshape: reshape$3, + reverse: reverse$2, + reverse1d: reverse1d, + reverse2d: reverse2d, + reverse3d: reverse3d, + reverse4d: reverse4d, + rfft: rfft, + round: round$2, + rsqrt: rsqrt$2, + scalar: scalar, + scatterND: scatterND, + searchSorted: searchSorted$2, + selu: selu$2, + separableConv2d: separableConv2d$1, + setdiff1dAsync: setdiff1dAsync, + sigmoid: sigmoid$2, + sign: sign$3, + signal: signal, + sin: sin$2, + sinh: sinh$2, + slice: slice$2, + slice1d: slice1d, + slice2d: slice2d, + slice3d: slice3d, + slice4d: slice4d, + softmax: softmax$3, + softplus: softplus$2, + spaceToBatchND: spaceToBatchND$2, + sparse: sparse$1, + sparseToDense: sparseToDense$2, + spectral: spectral$1, + split: split$3, + sqrt: sqrt$2, + square: square$2, + squaredDifference: squaredDifference$2, + squeeze: squeeze, + stack: stack, + step: step$2, + stridedSlice: stridedSlice$2, + string: string$1, + sub: sub$2, + sum: sum$3, + tan: tan$2, + tanh: tanh$2, + tensor: tensor, + tensor1d: tensor1d, + tensor2d: tensor2d, + tensor3d: tensor3d, + tensor4d: tensor4d, + tensor5d: tensor5d, + tensor6d: tensor6d, + tensorScatterUpdate: tensorScatterUpdate$2, + tile: tile$3, + topk: topk, + transpose: transpose$2, + truncatedNormal: truncatedNormal$1, + unique: unique$3, + unsortedSegmentSum: unsortedSegmentSum$2, + unstack: unstack, + upperBound: upperBound$1, + variable: variable$1, + where: where, + whereAsync: whereAsync, + zeros: zeros$2, + zerosLike: zerosLike$3 + }); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$k = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'BiasAdd': + case 'AddV2': + case 'Add': { + return [ops.add(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'AddN': { + return [ops.addN(getParamValue('tensors', node, tensorMap, context))]; + } + case 'FloorMod': + case 'Mod': + return [ops.mod(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + case 'Mul': + return [ops.mul(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + case 'RealDiv': + case 'Div': { + return [ops.div(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'DivNoNan': { + return [ops.divNoNan(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'FloorDiv': { + return [ops.floorDiv(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'Sub': { + return [ops.sub(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'Minimum': { + return [ops.minimum(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'Maximum': { + return [ops.maximum(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'Pow': { + return [ops.pow(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'SquaredDifference': { + return [ops.squaredDifference(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$j = 'arithmetic'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$j = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'Abs': + case 'ComplexAbs': + return [ops.abs(getParamValue('x', node, tensorMap, context))]; + case 'Acos': + return [ops.acos(getParamValue('x', node, tensorMap, context))]; + case 'Acosh': + return [ops.acosh(getParamValue('x', node, tensorMap, context))]; + case 'Asin': + return [ops.asin(getParamValue('x', node, tensorMap, context))]; + case 'Asinh': + return [ops.asinh(getParamValue('x', node, tensorMap, context))]; + case 'Atan': + return [ops.atan(getParamValue('x', node, tensorMap, context))]; + case 'Atan2': + return [ops.atan2(getParamValue('x', node, tensorMap, context), getParamValue('y', node, tensorMap, context))]; + case 'Atanh': + return [ops.atanh(getParamValue('x', node, tensorMap, context))]; + case 'Ceil': + return [ops.ceil(getParamValue('x', node, tensorMap, context))]; + case 'Complex': + return [ops.complex(getParamValue('real', node, tensorMap, context), getParamValue('imag', node, tensorMap, context))]; + case 'Cos': + return [ops.cos(getParamValue('x', node, tensorMap, context))]; + case 'Cosh': + return [ops.cosh(getParamValue('x', node, tensorMap, context))]; + case 'Elu': + return [ops.elu(getParamValue('x', node, tensorMap, context))]; + case 'Erf': + return [ops.erf(getParamValue('x', node, tensorMap, context))]; + case 'Exp': + return [ops.exp(getParamValue('x', node, tensorMap, context))]; + case 'Expm1': { + return [ops.expm1(getParamValue('x', node, tensorMap, context))]; + } + case 'Floor': + return [ops.floor(getParamValue('x', node, tensorMap, context))]; + case 'Log': + return [ops.log(getParamValue('x', node, tensorMap, context))]; + case 'Log1p': { + return [ops.log1p(getParamValue('x', node, tensorMap, context))]; + } + case 'Imag': + return [ops.imag(getParamValue('x', node, tensorMap, context))]; + case 'Neg': + return [ops.neg(getParamValue('x', node, tensorMap, context))]; + case 'Reciprocal': { + return [ops.reciprocal(getParamValue('x', node, tensorMap, context))]; + } + case 'Real': + return [ops.real(getParamValue('x', node, tensorMap, context))]; + case 'Relu': + return [ops.relu(getParamValue('x', node, tensorMap, context))]; + case 'Round': { + return [ops.round(getParamValue('x', node, tensorMap, context))]; + } + case 'Selu': + return [ops.selu(getParamValue('x', node, tensorMap, context))]; + case 'Sigmoid': + return [ops.sigmoid(getParamValue('x', node, tensorMap, context))]; + case 'Sin': + return [ops.sin(getParamValue('x', node, tensorMap, context))]; + case 'Sign': { + return [ops.sign(getParamValue('x', node, tensorMap, context))]; + } + case 'Sinh': { + return [ops.sinh(getParamValue('x', node, tensorMap, context))]; + } + case 'Softplus': { + return [ops.softplus(getParamValue('x', node, tensorMap, context))]; + } + case 'Sqrt': { + return [ops.sqrt(getParamValue('x', node, tensorMap, context))]; + } + case 'Square': { + return [ops.square(getParamValue('x', node, tensorMap, context))]; + } + case 'Tanh': { + return [ops.tanh(getParamValue('x', node, tensorMap, context))]; + } + case 'Tan': + return [ops.tan(getParamValue('x', node, tensorMap, context))]; + case 'ClipByValue': + return [ops.clipByValue(getParamValue('x', node, tensorMap, context), getParamValue('clipValueMin', node, tensorMap, context), getParamValue('clipValueMax', node, tensorMap, context))]; + case 'Relu6': + return [ops.relu6(getParamValue('x', node, tensorMap, context))]; + case 'Rsqrt': + return [ops.rsqrt(getTensor(node.inputNames[0], tensorMap, context))]; + case 'LeakyRelu': + return [ops.leakyRelu(getParamValue('x', node, tensorMap, context), getParamValue('alpha', node, tensorMap, context))]; + case 'Prelu': + return [ops.prelu(getParamValue('x', node, tensorMap, context), getParamValue('alpha', node, tensorMap, context))]; + case 'IsNan': + return [ops.isNaN(getTensor(node.inputNames[0], tensorMap, context))]; + case 'IsInf': + return [ops.isInf(getTensor(node.inputNames[0], tensorMap, context))]; + case 'IsFinite': + return [ops.isFinite(getTensor(node.inputNames[0], tensorMap, context))]; + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$i = 'basic_math'; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Used by TensorList and TensorArray to verify if elementShape matches, support + * negative value as the dim shape. + * @param shapeA + * @param shapeB + * @param errorMessagePrefix + */ + function assertShapesMatchAllowUndefinedSize(shapeA, shapeB, errorMessagePrefix = '') { + // constant shape means unknown rank + if (typeof shapeA === 'number' || typeof shapeB === 'number') { + return; + } + assert$1(shapeA.length === shapeB.length, () => errorMessagePrefix + ` Shapes ${shapeA} and ${shapeB} must match`); + for (let i = 0; i < shapeA.length; i++) { + const dim0 = shapeA[i]; + const dim1 = shapeB[i]; + assert$1(dim0 < 0 || dim1 < 0 || dim0 === dim1, () => errorMessagePrefix + ` Shapes ${shapeA} and ${shapeB} must match`); + } + } + function fullDefinedShape(elementShape) { + if (typeof elementShape === 'number' || elementShape.some(dim => dim < 0)) { + return false; + } + return true; + } + /** + * Generate the output element shape from the list elementShape, list tensors + * and input param. + * @param listElementShape + * @param tensors + * @param elementShape + */ + function inferElementShape(listElementShape, tensors, elementShape) { + let partialShape = mergeElementShape(listElementShape, elementShape); + const notfullDefinedShape = !fullDefinedShape(partialShape); + if (notfullDefinedShape && tensors.length === 0) { + throw new Error(`Tried to calculate elements of an empty list` + + ` with non-fully-defined elementShape: ${partialShape}`); + } + if (notfullDefinedShape) { + tensors.forEach(tensor => { + partialShape = mergeElementShape(tensor.shape, partialShape); + }); + } + if (!fullDefinedShape(partialShape)) { + throw new Error(`Non-fully-defined elementShape: ${partialShape}`); + } + return partialShape; + } + function mergeElementShape(elementShapeA, elementShapeB) { + if (typeof elementShapeA === 'number') { + return elementShapeB; + } + if (typeof elementShapeB === 'number') { + return elementShapeA; + } + if (elementShapeA.length !== elementShapeB.length) { + throw new Error(`Incompatible ranks during merge: ${elementShapeA} vs. ${elementShapeB}`); + } + const result = []; + for (let i = 0; i < elementShapeA.length; ++i) { + const dim0 = elementShapeA[i]; + const dim1 = elementShapeB[i]; + if (dim0 >= 0 && dim1 >= 0 && dim0 !== dim1) { + throw new Error(`Incompatible shape during merge: ${elementShapeA} vs. ${elementShapeB}`); + } + result[i] = dim0 >= 0 ? dim0 : dim1; + } + return result; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * The TensorArray object keeps an array of Tensors. It + * allows reading from the array and writing to the array. + */ + class TensorArray { + constructor(name, dtype, maxSize, elementShape, identicalElementShapes, dynamicSize, clearAfterRead) { + this.name = name; + this.dtype = dtype; + this.maxSize = maxSize; + this.elementShape = elementShape; + this.identicalElementShapes = identicalElementShapes; + this.dynamicSize = dynamicSize; + this.clearAfterRead = clearAfterRead; + this.tensors = []; + this.closed_ = false; + this.idTensor = scalar(0); + keep(this.idTensor); + } + get id() { + return this.idTensor.id; + } + get closed() { + return this.closed_; + } + /** + * Dispose the tensors and idTensor and mark the TensoryArray as closed. + */ + clearAndClose(keepIds) { + this.tensors.forEach(tensor => { + if (keepIds == null || !keepIds.has(tensor.tensor.id)) { + tensor.tensor.dispose(); + } + }); + this.tensors = []; + this.closed_ = true; + this.idTensor.dispose(); + } + size() { + return this.tensors.length; + } + /** + * Read the value at location index in the TensorArray. + * @param index Number the index to read from. + */ + read(index) { + if (this.closed_) { + throw new Error(`TensorArray ${this.name} has already been closed.`); + } + if (index < 0 || index >= this.size()) { + throw new Error(`Tried to read from index ${index}, but array size is: ${this.size()}`); + } + const tensorWithState = this.tensors[index]; + if (tensorWithState.cleared) { + throw new Error(`TensorArray ${this.name}: Could not read index ${index} twice because it was cleared after a previous read ` + + `(perhaps try setting clear_after_read = false?).`); + } + if (this.clearAfterRead) { + tensorWithState.cleared = true; + } + tensorWithState.read = true; + return tensorWithState.tensor; + } + /** + * Helper method to read multiple tensors from the specified indices. + */ + readMany(indices) { + return indices.map(index => this.read(index)); + } + /** + * Write value into the index of the TensorArray. + * @param index number the index to write to. + * @param tensor + */ + write(index, tensor) { + if (this.closed_) { + throw new Error(`TensorArray ${this.name} has already been closed.`); + } + if (index < 0 || !this.dynamicSize && index >= this.maxSize) { + throw new Error(`Tried to write to index ${index}, but array is not resizeable and size is: ${this.maxSize}`); + } + const t = this.tensors[index] || {}; + if (tensor.dtype !== this.dtype) { + throw new Error(`TensorArray ${this.name}: Could not write to TensorArray index ${index}, + because the value dtype is ${tensor.dtype}, but TensorArray dtype is ${this.dtype}.`); + } + // Set the shape for the first time write to unknow shape tensor array + if (this.size() === 0 && + (this.elementShape == null || this.elementShape.length === 0)) { + this.elementShape = tensor.shape; + } + assertShapesMatchAllowUndefinedSize(this.elementShape, tensor.shape, `TensorArray ${this.name}: Could not write to TensorArray index ${index}.`); + if (t.read) { + throw new Error(`TensorArray ${this.name}: Could not write to TensorArray index ${index}, because it has already been read.`); + } + if (t.written) { + throw new Error(`TensorArray ${this.name}: Could not write to TensorArray index ${index}, because it has already been written.`); + } + t.tensor = tensor; + keep(tensor); + t.written = true; + this.tensors[index] = t; + } + /** + * Helper method to write multiple tensors to the specified indices. + */ + writeMany(indices, tensors) { + if (indices.length !== tensors.length) { + throw new Error(`TensorArray ${this.name}: could not write multiple tensors,` + + `because the index size: ${indices.length} is not the same as tensors size: ${tensors.length}.`); + } + indices.forEach((i, index) => this.write(i, tensors[index])); + } + /** + * Return selected values in the TensorArray as a packed Tensor. All of + * selected values must have been written and their shapes must all match. + * @param [indices] number[] Optional. Taking values in [0, max_value). If the + * TensorArray is not dynamic, max_value=size(). If not specified returns + * all tensors in the original order. + * @param [dtype] + */ + gather(indices, dtype) { + if (!!dtype && dtype !== this.dtype) { + throw new Error(`TensorArray dtype is ${this.dtype} but gather requested dtype ${dtype}`); + } + if (!indices) { + indices = []; + for (let i = 0; i < this.size(); i++) { + indices.push(i); + } + } + else { + indices = indices.slice(0, this.size()); + } + if (indices.length === 0) { + return tensor([], [0].concat(this.elementShape)); + } + // Read all the PersistentTensors into a vector to keep track of + // their memory. + const tensors = this.readMany(indices); + assertShapesMatchAllowUndefinedSize(this.elementShape, tensors[0].shape, 'TensorArray shape mismatch: '); + return stack(tensors, 0); + } + /** + * Return the values in the TensorArray as a concatenated Tensor. + */ + concat(dtype) { + if (!!dtype && dtype !== this.dtype) { + throw new Error(`TensorArray dtype is ${this.dtype} but concat requested dtype ${dtype}`); + } + if (this.size() === 0) { + return tensor([], [0].concat(this.elementShape)); + } + const indices = []; + for (let i = 0; i < this.size(); i++) { + indices.push(i); + } + // Collect all the tensors from the tensors array. + const tensors = this.readMany(indices); + assertShapesMatchAllowUndefinedSize(this.elementShape, tensors[0].shape, `TensorArray shape mismatch: tensor array shape (${this.elementShape}) vs first tensor shape (${tensors[0].shape})`); + return concat$2(tensors, 0); + } + /** + * Scatter the values of a Tensor in specific indices of a TensorArray. + * @param indices number[] values in [0, max_value). If the + * TensorArray is not dynamic, max_value=size(). + * @param tensor Tensor input tensor. + */ + scatter(indices, tensor) { + if (tensor.dtype !== this.dtype) { + throw new Error(`TensorArray dtype is ${this.dtype} but tensor has dtype ${tensor.dtype}`); + } + if (indices.length !== tensor.shape[0]) { + throw new Error(`Expected len(indices) == tensor.shape[0], but saw: ${indices.length} vs. ${tensor.shape[0]}`); + } + const maxIndex = Math.max(...indices); + if (!this.dynamicSize && maxIndex >= this.maxSize) { + throw new Error(`Max index must be < array size (${maxIndex} vs. ${this.maxSize})`); + } + this.writeMany(indices, unstack(tensor, 0)); + } + /** + * Split the values of a Tensor into the TensorArray. + * @param length number[] with the lengths to use when splitting value along + * its first dimension. + * @param tensor Tensor, the tensor to split. + */ + split(length, tensor) { + if (tensor.dtype !== this.dtype) { + throw new Error(`TensorArray dtype is ${this.dtype} but tensor has dtype ${tensor.dtype}`); + } + let totalLength = 0; + const cumulativeLengths = length.map(len => { + totalLength += len; + return totalLength; + }); + if (totalLength !== tensor.shape[0]) { + throw new Error(`Expected sum of lengths to be equal to + tensor.shape[0], but sum of lengths is + ${totalLength}, and tensor's shape is: ${tensor.shape}`); + } + if (!this.dynamicSize && length.length !== this.maxSize) { + throw new Error(`TensorArray's size is not equal to the size of lengths (${this.maxSize} vs. ${length.length}), ` + + 'and the TensorArray is not marked as dynamically resizeable'); + } + const elementPerRow = totalLength === 0 ? 0 : tensor.size / totalLength; + const tensors = []; + tidy(() => { + tensor = reshape$3(tensor, [1, totalLength, elementPerRow]); + for (let i = 0; i < length.length; ++i) { + const previousLength = (i === 0) ? 0 : cumulativeLengths[i - 1]; + const indices = [0, previousLength, 0]; + const sizes = [1, length[i], elementPerRow]; + tensors[i] = reshape$3(slice$2(tensor, indices, sizes), this.elementShape); + } + return tensors; + }); + const indices = []; + for (let i = 0; i < length.length; i++) { + indices[i] = i; + } + this.writeMany(indices, tensors); + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * TensorList stores a container of `tf.Tensor` objects, which are accessible + * via tensors field. + * + * In order to get a copy of the underlying list, use the copy method: + * ``` + * TensorList b = a.copy(); + * b.tensors().pushBack(t); // This does not modify a.tensors(). + * ``` + * + * Note that this is not a deep copy: the memory locations of the underlying + * tensors will still point to the same locations of the corresponding tensors + * in the original. + */ + class TensorList { + get id() { + return this.idTensor.id; + } + /** + * + * @param tensors list of tensors + * @param elementShape shape of each tensor, this can be a single number (any + * shape is allowed) or partial shape (dim = -1). + * @param elementDtype data type of each tensor + * @param maxNumElements The maximum allowed size of `tensors`. Defaults to -1 + * meaning that the size of `tensors` is unbounded. + */ + constructor(tensors, elementShape, elementDtype, maxNumElements = -1) { + this.tensors = tensors; + this.elementShape = elementShape; + this.elementDtype = elementDtype; + if (tensors != null) { + tensors.forEach(tensor => { + if (elementDtype !== tensor.dtype) { + throw new Error(`Invalid data types; op elements ${elementDtype}, but list elements ${tensor.dtype}`); + } + assertShapesMatchAllowUndefinedSize(elementShape, tensor.shape, 'TensorList shape mismatch: '); + keep(tensor); + }); + } + this.idTensor = scalar(0); + this.maxNumElements = maxNumElements; + keep(this.idTensor); + } + /** + * Get a new TensorList containing a copy of the underlying tensor container. + */ + copy() { + return new TensorList([...this.tensors], this.elementShape, this.elementDtype); + } + /** + * Dispose the tensors and idTensor and clear the tensor list. + */ + clearAndClose(keepIds) { + this.tensors.forEach(tensor => { + if (keepIds == null || !keepIds.has(tensor.id)) { + tensor.dispose(); + } + }); + this.tensors.length = 0; + this.idTensor.dispose(); + } + /** + * The size of the tensors in the tensor list. + */ + size() { + return this.tensors.length; + } + /** + * Return a tensor that stacks a list of rank-R tf.Tensors into one rank-(R+1) + * tf.Tensor. + * @param elementShape shape of each tensor + * @param elementDtype data type of each tensor + * @param numElements the number of elements to stack + */ + stack(elementShape, elementDtype, numElements = -1) { + if (elementDtype !== this.elementDtype) { + throw new Error(`Invalid data types; op elements ${elementDtype}, but list elements ${this.elementDtype}`); + } + if (numElements !== -1 && this.tensors.length !== numElements) { + throw new Error(`Operation expected a list with ${numElements} elements but got a list with ${this.tensors.length} elements.`); + } + assertShapesMatchAllowUndefinedSize(elementShape, this.elementShape, 'TensorList shape mismatch: '); + const outputElementShape = inferElementShape(this.elementShape, this.tensors, elementShape); + return tidy(() => { + const reshapedTensors = this.tensors.map(tensor => reshape$3(tensor, outputElementShape)); + return stack(reshapedTensors, 0); + }); + } + /** + * Pop a tensor from the end of the list. + * @param elementShape shape of the tensor + * @param elementDtype data type of the tensor + */ + popBack(elementShape, elementDtype) { + if (elementDtype !== this.elementDtype) { + throw new Error(`Invalid data types; op elements ${elementDtype}, but list elements ${this.elementDtype}`); + } + if (this.size() === 0) { + throw new Error('Trying to pop from an empty list.'); + } + const outputElementShape = inferElementShape(this.elementShape, this.tensors, elementShape); + const tensor = this.tensors.pop(); + tensor.kept = false; + assertShapesMatchAllowUndefinedSize(tensor.shape, elementShape, 'TensorList shape mismatch: '); + return reshape$3(tensor, outputElementShape); + } + /** + * Push a tensor to the end of the list. + * @param tensor Tensor to be pushed. + */ + pushBack(tensor) { + if (tensor.dtype !== this.elementDtype) { + throw new Error(`Invalid data types; op elements ${tensor.dtype}, but list elements ${this.elementDtype}`); + } + assertShapesMatchAllowUndefinedSize(tensor.shape, this.elementShape, 'TensorList shape mismatch: '); + if (this.maxNumElements === this.size()) { + throw new Error(`Trying to push element into a full list.`); + } + keep(tensor); + this.tensors.push(tensor); + } + /** + * Update the size of the list. + * @param size the new size of the list. + */ + resize(size) { + if (size < 0) { + throw new Error(`TensorListResize expects size to be non-negative. Got: ${size}`); + } + if (this.maxNumElements !== -1 && size > this.maxNumElements) { + throw new Error(`TensorListResize input size ${size} is greater maxNumElement ${this.maxNumElements}.`); + } + const destTensorList = new TensorList([], this.elementShape, this.elementDtype, this.maxNumElements); + destTensorList.tensors.length = size; + for (let i = 0; i < Math.min(this.tensors.length, size); ++i) { + destTensorList.tensors[i] = this.tensors[i]; + } + return destTensorList; + } + /** + * Retrieve the element at the provided index + * @param elementShape shape of the tensor + * @param elementDtype dtype of the tensor + * @param elementIndex index of the tensor + */ + getItem(elementIndex, elementShape, elementDtype) { + if (elementDtype !== this.elementDtype) { + throw new Error(`Invalid data types; op elements ${elementDtype}, but list elements ${this.elementDtype}`); + } + if (elementIndex < 0 || elementIndex > this.tensors.length) { + throw new Error(`Trying to access element ${elementIndex} in a list with ${this.tensors.length} elements.`); + } + if (this.tensors[elementIndex] == null) { + throw new Error(`element at index ${elementIndex} is null.`); + } + assertShapesMatchAllowUndefinedSize(this.tensors[elementIndex].shape, elementShape, 'TensorList shape mismatch: '); + const outputElementShape = inferElementShape(this.elementShape, this.tensors, elementShape); + return reshape$3(this.tensors[elementIndex], outputElementShape); + } + /** + * Set the tensor at the index + * @param elementIndex index of the tensor + * @param tensor the tensor to be inserted into the list + */ + setItem(elementIndex, tensor) { + if (tensor.dtype !== this.elementDtype) { + throw new Error(`Invalid data types; op elements ${tensor.dtype}, but list elements ${this.elementDtype}`); + } + if (elementIndex < 0 || + this.maxNumElements !== -1 && elementIndex >= this.maxNumElements) { + throw new Error(`Trying to set element ${elementIndex} in a list with max ${this.maxNumElements} elements.`); + } + assertShapesMatchAllowUndefinedSize(this.elementShape, tensor.shape, 'TensorList shape mismatch: '); + keep(tensor); + // dispose the previous value if it is replacing. + if (this.tensors[elementIndex] != null) { + this.tensors[elementIndex].kept = false; + } + this.tensors[elementIndex] = tensor; + } + /** + * Return selected values in the TensorList as a stacked Tensor. All of + * selected values must have been written and their shapes must all match. + * @param indices indices of tensors to gather + * @param elementDtype output tensor dtype + * @param elementShape output tensor element shape + */ + gather(indices, elementDtype, elementShape) { + if (elementDtype !== this.elementDtype) { + throw new Error(`Invalid data types; op elements ${elementDtype}, but list elements ${this.elementDtype}`); + } + assertShapesMatchAllowUndefinedSize(this.elementShape, elementShape, 'TensorList shape mismatch: '); + // When indices is greater than the size of the list, indices beyond the + // size of the list are ignored. + indices = indices.slice(0, this.size()); + const outputElementShape = inferElementShape(this.elementShape, this.tensors, elementShape); + if (indices.length === 0) { + return tensor([], [0].concat(outputElementShape)); + } + return tidy(() => { + const tensors = indices.map(i => reshape$3(this.tensors[i], outputElementShape)); + return stack(tensors, 0); + }); + } + /** + * Return the values in the TensorList as a concatenated Tensor. + * @param elementDtype output tensor dtype + * @param elementShape output tensor element shape + */ + concat(elementDtype, elementShape) { + if (!!elementDtype && elementDtype !== this.elementDtype) { + throw new Error(`TensorList dtype is ${this.elementDtype} but concat requested dtype ${elementDtype}`); + } + assertShapesMatchAllowUndefinedSize(this.elementShape, elementShape, 'TensorList shape mismatch: '); + const outputElementShape = inferElementShape(this.elementShape, this.tensors, elementShape); + if (this.size() === 0) { + return tensor([], [0].concat(outputElementShape)); + } + return tidy(() => { + const tensors = this.tensors.map(t => reshape$3(t, outputElementShape)); + return concat$2(tensors, 0); + }); + } + } + /** + * Creates a TensorList which, when stacked, has the value of tensor. + * @param tensor from tensor + * @param elementShape output tensor element shape + */ + function fromTensor(tensor, elementShape, elementDtype) { + const dtype = tensor.dtype; + if (tensor.shape.length < 1) { + throw new Error(`Tensor must be at least a vector, but saw shape: ${tensor.shape}`); + } + if (tensor.dtype !== elementDtype) { + throw new Error(`Invalid data types; op elements ${tensor.dtype}, but list elements ${elementDtype}`); + } + const tensorElementShape = tensor.shape.slice(1); + assertShapesMatchAllowUndefinedSize(tensorElementShape, elementShape, 'TensorList shape mismatch: '); + const tensorList = unstack(tensor); + return new TensorList(tensorList, elementShape, dtype); + } + /** + * Return a TensorList of the given size with empty elements. + * @param elementShape the shape of the future elements of the list + * @param elementDtype the desired type of elements in the list + * @param numElements the number of elements to reserve + * @param maxNumElements the maximum number of elements in th list + */ + function reserve(elementShape, elementDtype, numElements, maxNumElements) { + return new TensorList([], elementShape, elementDtype, maxNumElements); + } + /** + * Put tensors at specific indices of a stacked tensor into a TensorList. + * @param indices list of indices on how to scatter the tensor. + * @param tensor input tensor. + * @param elementShape the shape of the future elements of the list + * @param numElements the number of elements to scatter + */ + function scatter(tensor, indices, elementShape, numElements) { + if (indices.length !== tensor.shape[0]) { + throw new Error(`Expected len(indices) == tensor.shape[0], but saw: ${indices.length} vs. ${tensor.shape[0]}`); + } + const maxIndex = Math.max(...indices); + if (numElements != null && numElements !== -1 && maxIndex >= numElements) { + throw new Error(`Max index must be < array size (${maxIndex} vs. ${numElements})`); + } + const list = new TensorList([], elementShape, tensor.dtype, numElements); + const tensors = unstack(tensor, 0); + indices.forEach((value, index) => { + list.setItem(value, tensors[index]); + }); + return list; + } + /** + * Split the values of a Tensor into a TensorList. + * @param length the lengths to use when splitting value along + * its first dimension. + * @param tensor the tensor to split. + * @param elementShape the shape of the future elements of the list + */ + function split$1(tensor, length, elementShape) { + let totalLength = 0; + const cumulativeLengths = length.map(len => { + totalLength += len; + return totalLength; + }); + if (totalLength !== tensor.shape[0]) { + throw new Error(`Expected sum of lengths to be equal to + tensor.shape[0], but sum of lengths is + ${totalLength}, and tensor's shape is: ${tensor.shape}`); + } + const shapeWithoutFirstDim = tensor.shape.slice(1); + const outputElementShape = mergeElementShape(shapeWithoutFirstDim, elementShape); + const elementPerRow = totalLength === 0 ? 0 : tensor.size / totalLength; + const tensors = tidy(() => { + const tensors = []; + tensor = reshape$3(tensor, [1, totalLength, elementPerRow]); + for (let i = 0; i < length.length; ++i) { + const previousLength = (i === 0) ? 0 : cumulativeLengths[i - 1]; + const indices = [0, previousLength, 0]; + const sizes = [1, length[i], elementPerRow]; + tensors[i] = reshape$3(slice$2(tensor, indices, sizes), outputElementShape); + } + tensor.dispose(); + return tensors; + }); + const list = new TensorList([], elementShape, tensor.dtype, length.length); + for (let i = 0; i < tensors.length; i++) { + list.setItem(i, tensors[i]); + } + return list; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$i = async (node, tensorMap, context) => { + switch (node.op) { + case 'If': + case 'StatelessIf': { + const thenFunc = getParamValue('thenBranch', node, tensorMap, context); + const elseFunc = getParamValue('elseBranch', node, tensorMap, context); + const cond = getParamValue('cond', node, tensorMap, context); + const args = getParamValue('args', node, tensorMap, context); + const condValue = await cond.data(); + if (condValue[0]) { + return context.functionMap[thenFunc].executeFunctionAsync(args, context.tensorArrayMap, context.tensorListMap); + } + else { + return context.functionMap[elseFunc].executeFunctionAsync(args, context.tensorArrayMap, context.tensorListMap); + } + } + case 'While': + case 'StatelessWhile': { + const bodyFunc = getParamValue('body', node, tensorMap, context); + const condFunc = getParamValue('cond', node, tensorMap, context); + const args = getParamValue('args', node, tensorMap, context); + // Calculate the condition of the loop + const condResult = (await context.functionMap[condFunc].executeFunctionAsync(args, context.tensorArrayMap, context.tensorListMap)); + const argIds = args.map(tensor => tensor.id); + let condValue = await condResult[0].data(); + // Dispose the intermediate tensors for condition function + condResult.forEach(tensor => { + if (!tensor.kept && argIds.indexOf(tensor.id) === -1) { + tensor.dispose(); + } + }); + let result = args; + while (condValue[0]) { + // Record the previous result for intermediate tensor tracking + const origResult = result; + // Execution the body of the loop + result = await context.functionMap[bodyFunc].executeFunctionAsync(result, context.tensorArrayMap, context.tensorListMap); + const resultIds = result.map(tensor => tensor.id); + // Dispose the intermediate tensor for body function that is not global + // kept, not input/output of the body function + origResult.forEach(tensor => { + if (!tensor.kept && argIds.indexOf(tensor.id) === -1 && + resultIds.indexOf(tensor.id) === -1) { + tensor.dispose(); + } + }); + // Recalcuate the condition of the loop using the latest results. + const condResult = (await context.functionMap[condFunc].executeFunctionAsync(result, context.tensorArrayMap, context.tensorListMap)); + condValue = await condResult[0].data(); + // Dispose the intermediate tensors for condition function + condResult.forEach(tensor => { + if (!tensor.kept && argIds.indexOf(tensor.id) === -1 && + resultIds.indexOf(tensor.id) === -1) { + tensor.dispose(); + } + }); + } + return result; + } + case 'LoopCond': { + const pred = getParamValue('pred', node, tensorMap, context); + return [cloneTensor(pred)]; + } + case 'Switch': { + const pred = getParamValue('pred', node, tensorMap, context); + let data = getParamValue('data', node, tensorMap, context); + if (!data.kept) { + data = cloneTensor(data); + } + // Outputs nodes :0 => false, :1 => true + return (await pred.data())[0] ? [undefined, data] : [data, undefined]; + } + case 'Merge': { + const inputName = node.inputNames.find(name => getTensor(name, tensorMap, context) !== undefined); + if (inputName) { + const data = getTensor(inputName, tensorMap, context); + return [cloneTensor(data)]; + } + return undefined; + } + case 'Enter': { + const frameId = getParamValue('frameName', node, tensorMap, context); + const data = getParamValue('tensor', node, tensorMap, context); + context.enterFrame(frameId); + return [cloneTensor(data)]; + } + case 'Exit': { + const data = getParamValue('tensor', node, tensorMap, context); + context.exitFrame(); + return [cloneTensor(data)]; + } + case 'NextIteration': { + const data = getParamValue('tensor', node, tensorMap, context); + context.nextIteration(); + return [cloneTensor(data)]; + } + case 'TensorArrayV3': { + const size = getParamValue('size', node, tensorMap, context); + const dtype = getParamValue('dtype', node, tensorMap, context); + const elementShape = getParamValue('elementShape', node, tensorMap, context); + const dynamicSize = getParamValue('dynamicSize', node, tensorMap, context); + const clearAfterRead = getParamValue('clearAfterRead', node, tensorMap, context); + const identicalElementShapes = getParamValue('identicalElementShapes', node, tensorMap, context); + const name = getParamValue('name', node, tensorMap, context); + const tensorArray = new TensorArray(name, dtype, size, elementShape, identicalElementShapes, dynamicSize, clearAfterRead); + context.addTensorArray(tensorArray); + return [tensorArray.idTensor, scalar(1.0)]; + } + case 'TensorArrayWriteV3': { + const id = getParamValue('tensorArrayId', node, tensorMap, context); + const index = getParamValue('index', node, tensorMap, context); + const writeTensor = getParamValue('tensor', node, tensorMap, context); + const writeTensorArray = context.getTensorArray(id.id); + writeTensorArray.write(index, writeTensor); + return [writeTensorArray.idTensor]; + } + case 'TensorArrayReadV3': { + const readId = getParamValue('tensorArrayId', node, tensorMap, context); + const readIndex = getParamValue('index', node, tensorMap, context); + const readTensorArray = context.getTensorArray(readId.id); + return [readTensorArray.read(readIndex)]; + } + case 'TensorArrayGatherV3': { + const gatherId = getParamValue('tensorArrayId', node, tensorMap, context); + const gatherIndices = getParamValue('indices', node, tensorMap, context); + const gatherDtype = getParamValue('dtype', node, tensorMap, context); + const gatherTensorArray = context.getTensorArray(gatherId.id); + return [gatherTensorArray.gather(gatherIndices, gatherDtype)]; + } + case 'TensorArrayScatterV3': { + const scatterId = getParamValue('tensorArrayId', node, tensorMap, context); + const scatterIndices = getParamValue('indices', node, tensorMap, context); + const scatterTensor = getParamValue('tensor', node, tensorMap, context); + const scatterTensorArray = context.getTensorArray(scatterId.id); + scatterTensorArray.scatter(scatterIndices, scatterTensor); + return [scatterTensorArray.idTensor]; + } + case 'TensorArrayConcatV3': { + const concatId = getParamValue('tensorArrayId', node, tensorMap, context); + const concatTensorArray = context.getTensorArray(concatId.id); + const concatDtype = getParamValue('dtype', node, tensorMap, context); + return [concatTensorArray.concat(concatDtype)]; + } + case 'TensorArraySplitV3': { + const splitId = getParamValue('tensorArrayId', node, tensorMap, context); + const splitTensor = getParamValue('tensor', node, tensorMap, context); + const lengths = getParamValue('lengths', node, tensorMap, context); + const splitTensorArray = context.getTensorArray(splitId.id); + splitTensorArray.split(lengths, splitTensor); + return [splitTensorArray.idTensor]; + } + case 'TensorArraySizeV3': { + const sizeId = getParamValue('tensorArrayId', node, tensorMap, context); + const sizeTensorArray = context.getTensorArray(sizeId.id); + return [scalar(sizeTensorArray.size(), 'int32')]; + } + case 'TensorArrayCloseV3': { + const closeId = getParamValue('tensorArrayId', node, tensorMap, context); + const closeTensorArray = context.getTensorArray(closeId.id); + closeTensorArray.clearAndClose(); + return [closeTensorArray.idTensor]; + } + case 'TensorListSetItem': { + const idTensor = getParamValue('tensorListId', node, tensorMap, context); + const index = getParamValue('index', node, tensorMap, context); + const writeTensor = getParamValue('tensor', node, tensorMap, context); + const tensorList = context.getTensorList(idTensor.id); + tensorList.setItem(index, writeTensor); + return [tensorList.idTensor]; + } + case 'TensorListGetItem': { + const idTensor = getParamValue('tensorListId', node, tensorMap, context); + const readIndex = getParamValue('index', node, tensorMap, context); + const elementShape = getParamValue('elementShape', node, tensorMap, context); + const elementDType = getParamValue('elementDType', node, tensorMap, context); + const tensorList = context.getTensorList(idTensor.id); + return [tensorList.getItem(readIndex, elementShape, elementDType)]; + } + case 'TensorListScatterV2': + case 'TensorListScatter': { + const scatterIndices = getParamValue('indices', node, tensorMap, context); + const scatterTensor = getParamValue('tensor', node, tensorMap, context); + const elementShape = getParamValue('elementShape', node, tensorMap, context); + const numElements = getParamValue('numElements', node, tensorMap, context); + const tensorList = scatter(scatterTensor, scatterIndices, elementShape, numElements); + context.addTensorList(tensorList); + return [tensorList.idTensor]; + } + case 'TensorListReserve': + case 'EmptyTensorList': { + const elementShape = getParamValue('elementShape', node, tensorMap, context); + const elementDtype = getParamValue('elementDType', node, tensorMap, context); + let numElementsParam; + if (node.op === 'TensorListReserve') { + numElementsParam = 'numElements'; + } + else { + numElementsParam = 'maxNumElements'; + } + const numElements = getParamValue(numElementsParam, node, tensorMap, context); + const maxNumElements = node.op === 'TensorListReserve' ? -1 : numElements; + const tensorList = reserve(elementShape, elementDtype, numElements, maxNumElements); + context.addTensorList(tensorList); + return [tensorList.idTensor]; + } + case 'TensorListGather': { + const gatherId = getParamValue('tensorListId', node, tensorMap, context); + const gatherIndices = getParamValue('indices', node, tensorMap, context); + const elementShape = getParamValue('elementShape', node, tensorMap, context); + const elementDtype = getParamValue('elementDType', node, tensorMap, context); + const tensorList = context.getTensorList(gatherId.id); + return [tensorList.gather(gatherIndices, elementDtype, elementShape)]; + } + case 'TensorListStack': { + const idTensor = getParamValue('tensorListId', node, tensorMap, context); + const elementShape = getParamValue('elementShape', node, tensorMap, context); + const elementDtype = getParamValue('elementDType', node, tensorMap, context); + const numElements = getParamValue('numElements', node, tensorMap, context); + const tensorList = context.getTensorList(idTensor.id); + return [tensorList.stack(elementShape, elementDtype, numElements)]; + } + case 'TensorListFromTensor': { + const tensor = getParamValue('tensor', node, tensorMap, context); + const elementShape = getParamValue('elementShape', node, tensorMap, context); + const elementDtype = getParamValue('elementDType', node, tensorMap, context); + const tensorList = fromTensor(tensor, elementShape, elementDtype); + context.addTensorList(tensorList); + return [tensorList.idTensor]; + } + case 'TensorListConcat': + case 'TensorListConcatV2': { + const concatId = getParamValue('tensorListId', node, tensorMap, context); + const tensorList = context.getTensorList(concatId.id); + const concatDtype = getParamValue('dtype', node, tensorMap, context); + const elementShape = getParamValue('elementShape', node, tensorMap, context); + return [tensorList.concat(concatDtype, elementShape)]; + } + case 'TensorListPushBack': { + const idTensor = getParamValue('tensorListId', node, tensorMap, context); + const writeTensor = getParamValue('tensor', node, tensorMap, context); + const tensorList = context.getTensorList(idTensor.id); + tensorList.pushBack(writeTensor); + return [tensorList.idTensor]; + } + case 'TensorListPopBack': { + const idTensor = getParamValue('tensorListId', node, tensorMap, context); + const elementShape = getParamValue('elementShape', node, tensorMap, context); + const elementDType = getParamValue('elementDType', node, tensorMap, context); + const tensorList = context.getTensorList(idTensor.id); + return [tensorList.popBack(elementShape, elementDType)]; + } + case 'TensorListSplit': { + const splitTensor = getParamValue('tensor', node, tensorMap, context); + const elementShape = getParamValue('elementShape', node, tensorMap, context); + const lengths = getParamValue('lengths', node, tensorMap, context); + const tensorList = split$1(splitTensor, lengths, elementShape); + context.addTensorList(tensorList); + return [tensorList.idTensor]; + } + case 'TensorListLength': { + const idTensor = getParamValue('tensorListId', node, tensorMap, context); + const tensorList = context.getTensorList(idTensor.id); + return [scalar(tensorList.size(), 'int32')]; + } + case 'TensorListResize': { + const idTensor = getParamValue('tensorListId', node, tensorMap, context); + const size = getParamValue('size', node, tensorMap, context); + const srcTensorList = context.getTensorList(idTensor.id); + const destTensorList = srcTensorList.resize(size); + context.addTensorList(destTensorList); + return [destTensorList.idTensor]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$h = 'control'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fusedConvAndDepthWiseParams(node, tensorMap, context) { + const [extraOp, activationFunc] = getParamValue('fusedOps', node, tensorMap, context); + const isBiasAdd = extraOp === 'biasadd'; + const noBiasAdd = !isBiasAdd; + const isPrelu = activationFunc === 'prelu'; + const isBatchNorm = extraOp === 'fusedbatchnorm'; + const numArgs = getParamValue('numArgs', node, tensorMap, context); + if (isBiasAdd) { + if (isPrelu && numArgs !== 2) { + throw new Error('FusedConv2d and DepthwiseConv2d with BiasAdd and Prelu ' + + 'must have two extra arguments: bias and alpha.'); + } + if (!isPrelu && isBiasAdd && numArgs !== 1) { + throw new Error('FusedConv2d and DepthwiseConv2d with BiasAdd must have ' + + 'one extra argument: bias.'); + } + } + if (isBatchNorm) { + throw new Error('FusedConv2d and DepthwiseConv2d with FusedBatchNorm is not supported'); + } + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getPadding(node, tensorMap, context); + const dataFormat = getParamValue('dataFormat', node, tensorMap, context) + .toUpperCase(); + const dilations = getParamValue('dilations', node, tensorMap, context); + let [biasArg, preluArg] = getParamValue('args', node, tensorMap, context); + if (noBiasAdd) { + preluArg = biasArg; + biasArg = undefined; + } + const leakyreluAlpha = getParamValue('leakyreluAlpha', node, tensorMap, context); + return { + stride, + pad, + dataFormat, + dilations, + biasArg, + preluArg, + activationFunc, + leakyreluAlpha + }; + } + const executeOp$h = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'Conv1D': { + const stride = getParamValue('stride', node, tensorMap, context); + const pad = getParamValue('pad', node, tensorMap, context); + const dataFormat = getParamValue('dataFormat', node, tensorMap, context) + .toUpperCase(); + const dilation = getParamValue('dilation', node, tensorMap, context); + return [ops.conv1d(getParamValue('x', node, tensorMap, context), getParamValue('filter', node, tensorMap, context), stride, pad, dataFormat, dilation)]; + } + case 'Conv2D': { + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getPadding(node, tensorMap, context); + const dataFormat = getParamValue('dataFormat', node, tensorMap, context) + .toUpperCase(); + const dilations = getParamValue('dilations', node, tensorMap, context); + return [ops.conv2d(getParamValue('x', node, tensorMap, context), getParamValue('filter', node, tensorMap, context), [stride[1], stride[2]], pad, dataFormat, [dilations[1], dilations[2]])]; + } + case '_FusedConv2D': { + const { stride, pad, dataFormat, dilations, biasArg, preluArg, activationFunc, leakyreluAlpha } = fusedConvAndDepthWiseParams(node, tensorMap, context); + return [ops.fused.conv2d({ + x: getParamValue('x', node, tensorMap, context), + filter: getParamValue('filter', node, tensorMap, context), + strides: [stride[1], stride[2]], + pad: pad, + dataFormat: dataFormat, + dilations: [dilations[1], dilations[2]], + bias: biasArg, + activation: activationFunc, + preluActivationWeights: preluArg, + leakyreluAlpha + })]; + } + case 'FusedDepthwiseConv2dNative': { + const { stride, pad, dataFormat, dilations, biasArg, preluArg, activationFunc, leakyreluAlpha, } = fusedConvAndDepthWiseParams(node, tensorMap, context); + return [ops.fused.depthwiseConv2d({ + x: getParamValue('x', node, tensorMap, context), + filter: getParamValue('filter', node, tensorMap, context), + strides: [stride[1], stride[2]], + pad: pad, + dataFormat: dataFormat, + dilations: [dilations[1], dilations[2]], + bias: biasArg, + activation: activationFunc, + preluActivationWeights: preluArg, + leakyreluAlpha + })]; + } + case 'Conv2DBackpropInput': + case 'Conv2dTranspose': { + const shape = getParamValue('outputShape', node, tensorMap, context); + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getPadding(node, tensorMap, context); + return [ops.conv2dTranspose(getParamValue('x', node, tensorMap, context), getParamValue('filter', node, tensorMap, context), shape, [stride[1], stride[2]], pad)]; + } + case 'DepthwiseConv2dNative': + case 'DepthwiseConv2d': { + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getPadding(node, tensorMap, context); + const dilations = getParamValue('dilations', node, tensorMap, context); + const dataFormat = getParamValue('dataFormat', node, tensorMap, context) + .toUpperCase(); + return [ops.depthwiseConv2d(getParamValue('input', node, tensorMap, context), getParamValue('filter', node, tensorMap, context), [stride[1], stride[2]], pad, dataFormat, [dilations[1], dilations[2]])]; + } + case 'Conv3D': { + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getParamValue('pad', node, tensorMap, context); + const dataFormat = getParamValue('dataFormat', node, tensorMap, context) + .toUpperCase(); + const dilations = getParamValue('dilations', node, tensorMap, context); + return [ops.conv3d(getParamValue('x', node, tensorMap, context), getParamValue('filter', node, tensorMap, context), [stride[1], stride[2], stride[3]], pad, dataFormat, [dilations[1], dilations[2], dilations[3]])]; + } + case 'AvgPool': { + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getParamValue('pad', node, tensorMap, context); + const kernelSize = getParamValue('kernelSize', node, tensorMap, context); + return [ops.avgPool(getParamValue('x', node, tensorMap, context), [kernelSize[1], kernelSize[2]], [stride[1], stride[2]], pad)]; + } + case 'MaxPool': { + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getParamValue('pad', node, tensorMap, context); + const kernelSize = getParamValue('kernelSize', node, tensorMap, context); + return [ops.maxPool(getParamValue('x', node, tensorMap, context), [kernelSize[1], kernelSize[2]], [stride[1], stride[2]], pad)]; + } + case 'MaxPoolWithArgmax': { + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getParamValue('pad', node, tensorMap, context); + const kernelSize = getParamValue('kernelSize', node, tensorMap, context); + const includeBatchInIndex = getParamValue('includeBatchInIndex', node, tensorMap, context); + const { result, indexes } = ops.maxPoolWithArgmax(getParamValue('x', node, tensorMap, context), [kernelSize[1], kernelSize[2]], [stride[1], stride[2]], pad, includeBatchInIndex); + return [result, indexes]; + } + case 'AvgPool3D': { + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getParamValue('pad', node, tensorMap, context); + const kernelSize = getParamValue('kernelSize', node, tensorMap, context); + return [ops.avgPool3d(getParamValue('x', node, tensorMap, context), [kernelSize[1], kernelSize[2], kernelSize[3]], [stride[1], stride[2], stride[3]], pad)]; + } + case 'MaxPool3D': { + const stride = getParamValue('strides', node, tensorMap, context); + const pad = getParamValue('pad', node, tensorMap, context); + const kernelSize = getParamValue('kernelSize', node, tensorMap, context); + return [ops.maxPool3d(getParamValue('x', node, tensorMap, context), [kernelSize[1], kernelSize[2], kernelSize[3]], [stride[1], stride[2], stride[3]], pad)]; + } + case 'Dilation2D': { + const strides = getParamValue('strides', node, tensorMap, context); + const pad = getParamValue('pad', node, tensorMap, context); + const dilations = getParamValue('dilations', node, tensorMap, context); + // strides: [1, stride_height, stride_width, 1]. + const strideHeight = strides[1]; + const strideWidth = strides[2]; + // dilations: [1, dilation_height, dilation_width, 1]. + const dilationHeight = dilations[1]; + const dilationWidth = dilations[2]; + return [ops.dilation2d(getParamValue('x', node, tensorMap, context), getParamValue('filter', node, tensorMap, context), [strideHeight, strideWidth], pad, [dilationHeight, dilationWidth], 'NHWC' /* dataFormat */)]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$g = 'convolution'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$g = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'Fill': { + const shape = getParamValue('shape', node, tensorMap, context); + const dtype = getParamValue('dtype', node, tensorMap, context); + const value = getParamValue('value', node, tensorMap, context); + return [ops.fill(shape, value, dtype)]; + } + case 'LinSpace': { + const start = getParamValue('start', node, tensorMap, context); + const stop = getParamValue('stop', node, tensorMap, context); + const num = getParamValue('num', node, tensorMap, context); + return [ops.linspace(start, stop, num)]; + } + case 'Multinomial': { + const logits = getParamValue('logits', node, tensorMap, context); + const numSamples = getParamValue('numSamples', node, tensorMap, context); + const seed = getParamValue('seed', node, tensorMap, context); + return [ops.multinomial(logits, numSamples, seed)]; + } + case 'OneHot': { + const indices = getParamValue('indices', node, tensorMap, context); + const depth = getParamValue('depth', node, tensorMap, context); + const onValue = getParamValue('onValue', node, tensorMap, context); + const offValue = getParamValue('offValue', node, tensorMap, context); + const dtype = getParamValue('dtype', node, tensorMap, context); + return [ops.oneHot(indices, depth, onValue, offValue, dtype)]; + } + case 'Ones': { + return [ops.ones(getParamValue('shape', node, tensorMap, context), getParamValue('dtype', node, tensorMap, context))]; + } + case 'OnesLike': { + return [ops.onesLike(getParamValue('x', node, tensorMap, context))]; + } + case 'RandomStandardNormal': { + return [ops.randomStandardNormal(getParamValue('shape', node, tensorMap, context), getParamValue('dtype', node, tensorMap, context), getParamValue('seed', node, tensorMap, context))]; + } + case 'RandomUniform': { + return [ops.randomUniform( + // tslint:disable-next-line:no-any + getParamValue('shape', node, tensorMap, context), getParamValue('minval', node, tensorMap, context), getParamValue('maxval', node, tensorMap, context), getParamValue('dtype', node, tensorMap, context))]; + } + case 'RandomUniformInt': { + return [ops.randomUniformInt(getParamValue('shape', node, tensorMap, context), getParamValue('minval', node, tensorMap, context), getParamValue('maxval', node, tensorMap, context), getParamValue('seed', node, tensorMap, context))]; + } + case 'Range': { + const start = getParamValue('start', node, tensorMap, context); + const stop = getParamValue('stop', node, tensorMap, context); + const step = getParamValue('step', node, tensorMap, context); + return [ops.range(start, stop, step, getParamValue('dtype', node, tensorMap, context))]; + } + case 'TruncatedNormal': { + const shape = getParamValue('shape', node, tensorMap, context); + const mean = getParamValue('mean', node, tensorMap, context); + const stdDev = getParamValue('stdDev', node, tensorMap, context); + const seed = getParamValue('seed', node, tensorMap, context); + return [ops.truncatedNormal(shape, mean, stdDev, getParamValue('dtype', node, tensorMap, context), seed)]; + } + case 'Zeros': { + return [ops.zeros(getParamValue('shape', node, tensorMap, context), getParamValue('dtype', node, tensorMap, context))]; + } + case 'ZerosLike': { + return [ops.zerosLike(getParamValue('x', node, tensorMap, context))]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$f = 'creation'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function nmsParams(node, tensorMap, context) { + const boxes = getParamValue('boxes', node, tensorMap, context); + const scores = getParamValue('scores', node, tensorMap, context); + const maxOutputSize = getParamValue('maxOutputSize', node, tensorMap, context); + const iouThreshold = getParamValue('iouThreshold', node, tensorMap, context); + const scoreThreshold = getParamValue('scoreThreshold', node, tensorMap, context); + const softNmsSigma = getParamValue('softNmsSigma', node, tensorMap, context); + return { + boxes, + scores, + maxOutputSize, + iouThreshold, + scoreThreshold, + softNmsSigma + }; + } + const executeOp$f = async (node, tensorMap, context, resourceManager, ops = tfOps) => { + switch (node.op) { + case 'NonMaxSuppressionV5': { + const { boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma } = nmsParams(node, tensorMap, context); + const result = await ops.image.nonMaxSuppressionWithScoreAsync(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma); + return [result.selectedIndices, result.selectedScores]; + } + case 'NonMaxSuppressionV4': { + const { boxes, scores, maxOutputSize, iouThreshold, scoreThreshold } = nmsParams(node, tensorMap, context); + const padToMaxOutputSize = getParamValue('padToMaxOutputSize', node, tensorMap, context); + const result = await ops.image.nonMaxSuppressionPaddedAsync(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold, padToMaxOutputSize); + return [result.selectedIndices, result.validOutputs]; + } + case 'NonMaxSuppressionV3': + case 'NonMaxSuppressionV2': { + const { boxes, scores, maxOutputSize, iouThreshold, scoreThreshold } = nmsParams(node, tensorMap, context); + return [await ops.image.nonMaxSuppressionAsync(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold)]; + } + case 'Where': { + const condition = ops.cast(getParamValue('condition', node, tensorMap, context), 'bool'); + const result = [await ops.whereAsync(condition)]; + condition.dispose(); + return result; + } + case 'ListDiff': { + return ops.setdiff1dAsync(getParamValue('x', node, tensorMap, context), getParamValue('y', node, tensorMap, context)); + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$e = 'dynamic'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$e = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'LowerBound': { + const sortedSequence = getParamValue('sortedSequence', node, tensorMap, context); + const values = getParamValue('values', node, tensorMap, context); + return [ops.lowerBound(sortedSequence, values)]; + } + case 'TopKV2': { + const x = getParamValue('x', node, tensorMap, context); + const k = getParamValue('k', node, tensorMap, context); + const sorted = getParamValue('sorted', node, tensorMap, context); + const result = ops.topk(x, k, sorted); + return [result.values, result.indices]; + } + case 'UpperBound': { + const sortedSequence = getParamValue('sortedSequence', node, tensorMap, context); + const values = getParamValue('values', node, tensorMap, context); + return [ops.upperBound(sortedSequence, values)]; + } + case 'Unique': { + const x = getParamValue('x', node, tensorMap, context); + const result = ops.unique(x); + return [result.values, result.indices]; + } + case 'UniqueV2': { + const x = getParamValue('x', node, tensorMap, context); + const axis = getParamValue('axis', node, tensorMap, context); + const result = ops.unique(x, axis); + return [result.values, result.indices]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$d = 'evaluation'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$d = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'Const': { + return tensorMap[node.name]; + } + case 'PlaceholderWithDefault': + const def = getParamValue('default', node, tensorMap, context); + return [getTensor(node.name, tensorMap, context) || def]; + case 'Placeholder': + return [getTensor(node.name, tensorMap, context)]; + case 'Identity': + case 'StopGradient': + case 'FakeQuantWithMinMaxVars': { // This op is currently ignored. + const data = getParamValue('x', node, tensorMap, context); + return [cloneTensor(data)]; + } + case 'IdentityN': + return getParamValue('x', node, tensorMap, context) + .map((t) => cloneTensor(t)); + case 'Snapshot': + const snapshot = getParamValue('x', node, tensorMap, context); + return [cloneTensor(snapshot)]; + case 'Shape': + return [ops.tensor1d(getParamValue('x', node, tensorMap, context).shape, 'int32')]; + case 'ShapeN': + return getParamValue('x', node, tensorMap, context) + .map((t) => ops.tensor1d(t.shape)); + case 'Size': + return [ops.scalar(getParamValue('x', node, tensorMap, context).size, 'int32')]; + case 'Rank': + return [ops.scalar(getParamValue('x', node, tensorMap, context).rank, 'int32')]; + case 'NoOp': + return [ops.scalar(1)]; + case 'Print': + const input = getParamValue('x', node, tensorMap, context); + const data = getParamValue('data', node, tensorMap, context); + const message = getParamValue('message', node, tensorMap, context); + const summarize = getParamValue('summarize', node, tensorMap, context); + console.warn('The graph has a tf.print() operation,' + + 'usually used for debugging, which slows down performance.'); + console.log(message); + for (let i = 0; i < data.length; i++) { + console.log(Array.prototype.slice.call(data[i].dataSync()) + .slice(0, summarize)); + } + return [input]; + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$c = 'graph'; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Hashtable contains a set of tensors, which can be accessed by key. + */ + class HashTable { + get id() { + return this.handle.id; + } + /** + * Constructor of HashTable. Creates a hash table. + * + * @param keyDType `dtype` of the table keys. + * @param valueDType `dtype` of the table values. + */ + constructor(keyDType, valueDType) { + this.keyDType = keyDType; + this.valueDType = valueDType; + this.handle = scalar(0); + // tslint:disable-next-line: no-any + this.tensorMap = new Map(); + keep(this.handle); + } + /** + * Dispose the tensors and handle and clear the hashtable. + */ + clearAndClose() { + this.tensorMap.forEach(value => value.dispose()); + this.tensorMap.clear(); + this.handle.dispose(); + } + /** + * The number of items in the hash table. + */ + size() { + return this.tensorMap.size; + } + /** + * The number of items in the hash table as a rank-0 tensor. + */ + tensorSize() { + return scalar(this.size(), 'int32'); + } + /** + * Replaces the contents of the table with the specified keys and values. + * @param keys Keys to store in the hashtable. + * @param values Values to store in the hashtable. + */ + async import(keys, values) { + this.checkKeyAndValueTensor(keys, values); + // We only store the primitive values of the keys, this allows lookup + // to be O(1). + const $keys = await keys.data(); + // Clear the hashTable before inserting new values. + this.tensorMap.forEach(value => value.dispose()); + this.tensorMap.clear(); + return tidy(() => { + const $values = unstack(values); + const keysLength = $keys.length; + const valuesLength = $values.length; + assert$1(keysLength === valuesLength, () => `The number of elements doesn't match, keys has ` + + `${keysLength} elements, the values has ${valuesLength} ` + + `elements.`); + for (let i = 0; i < keysLength; i++) { + const key = $keys[i]; + const value = $values[i]; + keep(value); + this.tensorMap.set(key, value); + } + return this.handle; + }); + } + /** + * Looks up keys in a hash table, outputs the corresponding values. + * + * Performs batch lookups, for every element in the key tensor, `find` + * stacks the corresponding value into the return tensor. + * + * If an element is not present in the table, the given `defaultValue` is + * used. + * + * @param keys Keys to look up. Must have the same type as the keys of the + * table. + * @param defaultValue The scalar `defaultValue` is the value output for keys + * not present in the table. It must also be of the same type as the + * table values. + */ + async find(keys, defaultValue) { + this.checkKeyAndValueTensor(keys, defaultValue); + const $keys = await keys.data(); + return tidy(() => { + const result = []; + for (let i = 0; i < $keys.length; i++) { + const key = $keys[i]; + const value = this.findWithDefault(key, defaultValue); + result.push(value); + } + return stack(result); + }); + } + // tslint:disable-next-line: no-any + findWithDefault(key, defaultValue) { + const result = this.tensorMap.get(key); + return result != null ? result : defaultValue; + } + checkKeyAndValueTensor(key, value) { + if (key.dtype !== this.keyDType) { + throw new Error(`Expect key dtype ${this.keyDType}, but got ` + + `${key.dtype}`); + } + if (value.dtype !== this.valueDType) { + throw new Error(`Expect value dtype ${this.valueDType}, but got ` + + `${value.dtype}`); + } + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$c = async (node, tensorMap, context, resourceManager) => { + switch (node.op) { + case 'HashTable': + case 'HashTableV2': { + const existingTableHandle = resourceManager.getHashTableHandleByName(node.name); + // Table is shared with initializer. + if (existingTableHandle != null) { + return [existingTableHandle]; + } + else { + const keyDType = getParamValue('keyDType', node, tensorMap, context); + const valueDType = getParamValue('valueDType', node, tensorMap, context); + const hashTable = new HashTable(keyDType, valueDType); + resourceManager.addHashTable(node.name, hashTable); + return [hashTable.handle]; + } + } + case 'InitializeTable': + case 'InitializeTableV2': + case 'LookupTableImport': + case 'LookupTableImportV2': { + const handle = getParamValue('tableHandle', node, tensorMap, context, resourceManager); + const keys = getParamValue('keys', node, tensorMap, context); + const values = getParamValue('values', node, tensorMap, context); + const hashTable = resourceManager.getHashTableById(handle.id); + return [await hashTable.import(keys, values)]; + } + case 'LookupTableFind': + case 'LookupTableFindV2': { + const handle = getParamValue('tableHandle', node, tensorMap, context, resourceManager); + const keys = getParamValue('keys', node, tensorMap, context); + const defaultValue = getParamValue('defaultValue', node, tensorMap, context); + const hashTable = resourceManager.getHashTableById(handle.id); + return [await hashTable.find(keys, defaultValue)]; + } + case 'LookupTableSize': + case 'LookupTableSizeV2': { + const handle = getParamValue('tableHandle', node, tensorMap, context, resourceManager); + const hashTable = resourceManager.getHashTableById(handle.id); + return [hashTable.tensorSize()]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$b = 'hash_table'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$b = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'ResizeBilinear': { + const images = getParamValue('images', node, tensorMap, context); + const size = getParamValue('size', node, tensorMap, context); + const alignCorners = getParamValue('alignCorners', node, tensorMap, context); + const halfPixelCenters = getParamValue('halfPixelCenters', node, tensorMap, context); + return [ops.image.resizeBilinear(images, [size[0], size[1]], alignCorners, halfPixelCenters)]; + } + case 'ResizeNearestNeighbor': { + const images = getParamValue('images', node, tensorMap, context); + const size = getParamValue('size', node, tensorMap, context); + const alignCorners = getParamValue('alignCorners', node, tensorMap, context); + const halfPixelCenters = getParamValue('halfPixelCenters', node, tensorMap, context); + return [ops.image.resizeNearestNeighbor(images, [size[0], size[1]], alignCorners, halfPixelCenters)]; + } + case 'CropAndResize': { + const image = getParamValue('image', node, tensorMap, context); + const boxes = getParamValue('boxes', node, tensorMap, context); + const boxInd = getParamValue('boxInd', node, tensorMap, context); + const cropSize = getParamValue('cropSize', node, tensorMap, context); + const method = getParamValue('method', node, tensorMap, context); + const extrapolationValue = getParamValue('extrapolationValue', node, tensorMap, context); + return [ops.image.cropAndResize(image, boxes, boxInd, cropSize, method, extrapolationValue)]; + } + case 'ImageProjectiveTransformV3': { + const images = getParamValue('images', node, tensorMap, context); + const transforms = getParamValue('transforms', node, tensorMap, context); + const outputShape = getParamValue('outputShape', node, tensorMap, context); + const fillValue = getParamValue('fillValue', node, tensorMap, context); + const interpolation = getParamValue('interpolation', node, tensorMap, context); + const fillMode = getParamValue('fillMode', node, tensorMap, context); + return [ops.image.transform(images, transforms, interpolation.toLowerCase(), fillMode.toLowerCase(), fillValue, outputShape)]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$a = 'image'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$a = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'Equal': { + return [ops.equal(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'NotEqual': { + return [ops.notEqual(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'Greater': { + return [ops.greater(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'GreaterEqual': { + return [ops.greaterEqual(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'Less': { + return [ops.less(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'LessEqual': { + return [ops.lessEqual(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'LogicalAnd': { + return [ops.logicalAnd(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'LogicalNot': { + return [ops.logicalNot(getParamValue('a', node, tensorMap, context))]; + } + case 'LogicalOr': { + return [ops.logicalOr(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'Select': + case 'SelectV2': { + return [ops.where(getParamValue('condition', node, tensorMap, context), getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + case 'BitwiseAnd': { + return [ops.bitwiseAnd(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context))]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$9 = 'logical'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$9 = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'BatchMatMul': + case 'BatchMatMulV2': + case 'MatMul': + return [ops.matMul(getParamValue('a', node, tensorMap, context), getParamValue('b', node, tensorMap, context), getParamValue('transposeA', node, tensorMap, context), getParamValue('transposeB', node, tensorMap, context))]; + case 'Einsum': + return [ops.einsum(getParamValue('equation', node, tensorMap, context), ...getParamValue('tensors', node, tensorMap, context))]; + case 'Transpose': + return [ops.transpose(getParamValue('x', node, tensorMap, context), getParamValue('perm', node, tensorMap, context))]; + case '_FusedMatMul': + const [extraOp, activationFunc] = getParamValue('fusedOps', node, tensorMap, context); + const isBiasAdd = extraOp === 'biasadd'; + const isPrelu = activationFunc === 'prelu'; + const numArgs = getParamValue('numArgs', node, tensorMap, context); + const leakyreluAlpha = getParamValue('leakyreluAlpha', node, tensorMap, context); + if (isBiasAdd) { + if (isPrelu && numArgs !== 2) { + throw new Error('Fused MatMul with BiasAdd and Prelu must have two ' + + 'extra arguments: bias and alpha.'); + } + if (!isPrelu && numArgs !== 1) { + throw new Error('Fused MatMul with BiasAdd must have one extra argument: bias.'); + } + } + const [biasArg, preluArg] = getParamValue('args', node, tensorMap, context); + return [ops.fused.matMul({ + a: getParamValue('a', node, tensorMap, context), + b: getParamValue('b', node, tensorMap, context), + transposeA: getParamValue('transposeA', node, tensorMap, context), + transposeB: getParamValue('transposeB', node, tensorMap, context), + bias: biasArg, + activation: activationFunc, + preluActivationWeights: preluArg, + leakyreluAlpha + })]; + case 'MatrixBandPart': + return [ops.linalg.bandPart(getParamValue('a', node, tensorMap, context), getParamValue('numLower', node, tensorMap, context), getParamValue('numUpper', node, tensorMap, context))]; + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$8 = 'matrices'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$8 = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'EuclideanNorm': + return [ops.euclideanNorm(getParamValue('x', node, tensorMap, context), getParamValue('axis', node, tensorMap, context), getParamValue('keepDims', node, tensorMap, context))]; + case 'FusedBatchNorm': + case 'FusedBatchNormV2': { + return [ops.batchNorm(getParamValue('x', node, tensorMap, context), getParamValue('mean', node, tensorMap, context), getParamValue('variance', node, tensorMap, context), getParamValue('offset', node, tensorMap, context), getParamValue('scale', node, tensorMap, context), getParamValue('epsilon', node, tensorMap, context))]; + } + case 'FusedBatchNormV3': { + return [ops.batchNorm(getParamValue('x', node, tensorMap, context), getParamValue('mean', node, tensorMap, context), getParamValue('variance', node, tensorMap, context), getParamValue('offset', node, tensorMap, context), getParamValue('scale', node, tensorMap, context), getParamValue('epsilon', node, tensorMap, context))]; + } + case 'LRN': { + return [ops.localResponseNormalization(getParamValue('x', node, tensorMap, context), getParamValue('radius', node, tensorMap, context), getParamValue('bias', node, tensorMap, context), getParamValue('alpha', node, tensorMap, context), getParamValue('beta', node, tensorMap, context))]; + } + case 'Softmax': { + return [ops.softmax(getParamValue('x', node, tensorMap, context))]; + } + case 'LogSoftmax': { + return [ops.logSoftmax(getParamValue('x', node, tensorMap, context))]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$7 = 'normalization'; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$7 = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'RaggedGather': { + const { outputNestedSplits, outputDenseValues, } = ops.raggedGather(getParamValue('paramsNestedSplits', node, tensorMap, context), getParamValue('paramsDenseValues', node, tensorMap, context), getParamValue('indices', node, tensorMap, context), getParamValue('outputRaggedRank', node, tensorMap, context)); + return outputNestedSplits.concat(outputDenseValues); + } + case 'RaggedRange': { + const { rtNestedSplits, rtDenseValues } = ops.raggedRange(getParamValue('starts', node, tensorMap, context), getParamValue('limits', node, tensorMap, context), getParamValue('splits', node, tensorMap, context)); + return [rtNestedSplits, rtDenseValues]; + } + case 'RaggedTensorToTensor': { + return [ops.raggedTensorToTensor(getParamValue('shape', node, tensorMap, context), getParamValue('values', node, tensorMap, context), getParamValue('defaultValue', node, tensorMap, context), getParamValue('rowPartitionTensors', node, tensorMap, context), getParamValue('rowPartitionTypes', node, tensorMap, context))]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$6 = 'ragged'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$6 = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'Max': { + const axis = getParamValue('axis', node, tensorMap, context); + const keepDims = getParamValue('keepDims', node, tensorMap, context); + return [ops.max(getParamValue('x', node, tensorMap, context), axis, keepDims)]; + } + case 'Mean': { + const axis = getParamValue('axis', node, tensorMap, context); + const keepDims = getParamValue('keepDims', node, tensorMap, context); + return [ops.mean(getParamValue('x', node, tensorMap, context), axis, keepDims)]; + } + case 'Min': { + const axis = getParamValue('axis', node, tensorMap, context); + const keepDims = getParamValue('keepDims', node, tensorMap, context); + return [ops.min(getParamValue('x', node, tensorMap, context), axis, keepDims)]; + } + case 'Sum': { + const axis = getParamValue('axis', node, tensorMap, context); + const keepDims = getParamValue('keepDims', node, tensorMap, context); + return [ops.sum(getParamValue('x', node, tensorMap, context), axis, keepDims)]; + } + case 'All': { + const axis = getParamValue('axis', node, tensorMap, context); + const keepDims = getParamValue('keepDims', node, tensorMap, context); + return [ops.all(getParamValue('x', node, tensorMap, context), axis, keepDims)]; + } + case 'Any': { + const axis = getParamValue('axis', node, tensorMap, context); + const keepDims = getParamValue('keepDims', node, tensorMap, context); + return [ops.any(getParamValue('x', node, tensorMap, context), axis, keepDims)]; + } + case 'ArgMax': { + const axis = getParamValue('axis', node, tensorMap, context); + return [ops.argMax(getParamValue('x', node, tensorMap, context), axis)]; + } + case 'ArgMin': { + const axis = getParamValue('axis', node, tensorMap, context); + return [ops.argMin(getParamValue('x', node, tensorMap, context), axis)]; + } + case 'Prod': { + const axis = getParamValue('axis', node, tensorMap, context); + const keepDims = getParamValue('keepDims', node, tensorMap, context); + return [ops.prod(getParamValue('x', node, tensorMap, context), axis, keepDims)]; + } + case 'Cumprod': { + const axis = getParamValue('axis', node, tensorMap, context); + const exclusive = getParamValue('exclusive', node, tensorMap, context); + const reverse = getParamValue('reverse', node, tensorMap, context); + return [ops.cumprod(getParamValue('x', node, tensorMap, context), axis, exclusive, reverse)]; + } + case 'Cumsum': { + const axis = getParamValue('axis', node, tensorMap, context); + const exclusive = getParamValue('exclusive', node, tensorMap, context); + const reverse = getParamValue('reverse', node, tensorMap, context); + return [ops.cumsum(getParamValue('x', node, tensorMap, context), axis, exclusive, reverse)]; + } + case 'Bincount': + const x = getParamValue('x', node, tensorMap, context); + const weights = getParamValue('weights', node, tensorMap, context); + const size = getParamValue('size', node, tensorMap, context); + return [ops.bincount(x, weights, size)]; + case 'DenseBincount': { + const x = getParamValue('x', node, tensorMap, context); + const weights = getParamValue('weights', node, tensorMap, context); + const size = getParamValue('size', node, tensorMap, context); + const binaryOutput = getParamValue('binaryOutput', node, tensorMap, context); + return [ops.denseBincount(x, weights, size, binaryOutput)]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$5 = 'reduction'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$5 = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'ConcatV2': + case 'Concat': { + const n = getParamValue('n', node, tensorMap, context); + const axis = getParamValue('axis', node, tensorMap, context); + let inputs = getParamValue('tensors', node, tensorMap, context); + inputs = inputs.slice(0, n); + return [ops.concat(inputs, axis)]; + } + case 'Gather': { + const input = getParamValue('x', node, tensorMap, context); + const indices = getParamValue('indices', node, tensorMap, context); + return [ops.gather(input, ops.cast(indices, 'int32'), 0)]; + } + case 'GatherV2': { + const axis = getParamValue('axis', node, tensorMap, context); + const batchDims = getParamValue('batchDims', node, tensorMap, context); + const input = getParamValue('x', node, tensorMap, context); + const indices = getParamValue('indices', node, tensorMap, context); + return [ops.gather(input, ops.cast(indices, 'int32'), axis, batchDims)]; + } + case 'Reverse': { + const dims = getParamValue('dims', node, tensorMap, context); + const axis = []; + for (let i = 0; i < dims.length; i++) { + if (dims[i]) { + axis.push(i); + } + } + const input = getParamValue('x', node, tensorMap, context); + return [ops.reverse(input, axis)]; + } + case 'ReverseV2': { + const axis = getParamValue('axis', node, tensorMap, context); + const input = getParamValue('x', node, tensorMap, context); + return [ops.reverse(input, axis)]; + } + case 'Slice': { + // tslint:disable-next-line:no-any + const begin = getParamValue('begin', node, tensorMap, context); + // tslint:disable-next-line:no-any + const size = getParamValue('size', node, tensorMap, context); + return [ops.slice(getParamValue('x', node, tensorMap, context), begin, size)]; + } + case 'StridedSlice': { + const begin = getParamValue('begin', node, tensorMap, context); + const end = getParamValue('end', node, tensorMap, context); + const strides = getParamValue('strides', node, tensorMap, context); + const beginMask = getParamValue('beginMask', node, tensorMap, context); + const endMask = getParamValue('endMask', node, tensorMap, context); + const ellipsisMask = getParamValue('ellipsisMask', node, tensorMap, context); + const newAxisMask = getParamValue('newAxisMask', node, tensorMap, context); + const shrinkAxisMask = getParamValue('shrinkAxisMask', node, tensorMap, context); + const tensor = getParamValue('x', node, tensorMap, context); + return [ops.stridedSlice(tensor, begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask)]; + } + case 'Pack': { + return tidy(() => { + const axis = getParamValue('axis', node, tensorMap, context); + const tensors = getParamValue('tensors', node, tensorMap, context); + // Reshape the tensors to the first tensor's shape if they don't + // match. + const shape = tensors[0].shape; + const squeezedShape = ops.squeeze(tensors[0]).shape; + const mapped = tensors.map(tensor => { + const sameShape = arraysEqual(tensor.shape, shape); + if (!sameShape && + !arraysEqual(ops.squeeze(tensor).shape, squeezedShape)) { + throw new Error('the input tensors shape does not match'); + } + return sameShape ? tensor : ops.reshape(tensor, shape); + }); + return [ops.stack(mapped, axis)]; + }); + } + case 'Unpack': { + const axis = getParamValue('axis', node, tensorMap, context); + const tensor = getParamValue('tensor', node, tensorMap, context); + return ops.unstack(tensor, axis); + } + case 'Tile': { + const reps = getParamValue('reps', node, tensorMap, context); + return [ops.tile(getParamValue('x', node, tensorMap, context), reps)]; + } + case 'Split': + case 'SplitV': { + const axis = getParamValue('axis', node, tensorMap, context); + const numOrSizeSplits = getParamValue('numOrSizeSplits', node, tensorMap, context); + const tensor = getParamValue('x', node, tensorMap, context); + return ops.split(tensor, numOrSizeSplits, axis); + } + case 'ScatterNd': { + const indices = getParamValue('indices', node, tensorMap, context); + const values = getParamValue('values', node, tensorMap, context); + const shape = getParamValue('shape', node, tensorMap, context); + return [ops.scatterND(indices, values, shape)]; + } + case 'GatherNd': { + const x = getParamValue('x', node, tensorMap, context); + const indices = getParamValue('indices', node, tensorMap, context); + return [ops.gatherND(x, indices)]; + } + case 'SparseToDense': { + const indices = getParamValue('sparseIndices', node, tensorMap, context); + const shape = getParamValue('outputShape', node, tensorMap, context); + const sparseValues = getParamValue('sparseValues', node, tensorMap, context); + const defaultValue = getParamValue('defaultValue', node, tensorMap, context); + return [ops.sparseToDense(indices, sparseValues, shape, sparseValues.dtype === defaultValue.dtype ? + defaultValue : + ops.cast(defaultValue, sparseValues.dtype))]; + } + case 'TensorScatterUpdate': { + const indices = getParamValue('indices', node, tensorMap, context); + const values = getParamValue('values', node, tensorMap, context); + const tensor = getParamValue('tensor', node, tensorMap, context); + return [ops.tensorScatterUpdate(tensor, indices, values)]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$4 = 'slice_join'; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$4 = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'SparseFillEmptyRows': { + const { outputIndices, outputValues, emptyRowIndicator, reverseIndexMap } = ops.sparse.sparseFillEmptyRows(getParamValue('indices', node, tensorMap, context), getParamValue('values', node, tensorMap, context), getParamValue('denseShape', node, tensorMap, context), getParamValue('defaultValue', node, tensorMap, context)); + return [ + outputIndices, outputValues, emptyRowIndicator, reverseIndexMap + ]; + } + case 'SparseReshape': { + const { outputIndices, outputShape } = ops.sparse.sparseReshape(getParamValue('inputIndices', node, tensorMap, context), getParamValue('inputShape', node, tensorMap, context), getParamValue('newShape', node, tensorMap, context)); + return [outputIndices, outputShape]; + } + case 'SparseSegmentMean': { + const outputData = ops.sparse.sparseSegmentMean(getParamValue('data', node, tensorMap, context), getParamValue('indices', node, tensorMap, context), getParamValue('segmentIds', node, tensorMap, context)); + return [outputData]; + } + case 'SparseSegmentSum': { + const outputData = ops.sparse.sparseSegmentSum(getParamValue('data', node, tensorMap, context), getParamValue('indices', node, tensorMap, context), getParamValue('segmentIds', node, tensorMap, context)); + return [outputData]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$3 = 'sparse'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$3 = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'FFT': { + return [ops.fft(getParamValue('x', node, tensorMap, context))]; + } + case 'IFFT': { + return [ops.ifft(getParamValue('x', node, tensorMap, context))]; + } + case 'RFFT': { + return [ops.rfft(getParamValue('x', node, tensorMap, context))]; + } + case 'IRFFT': { + return [ops.irfft(getParamValue('x', node, tensorMap, context))]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$2 = 'spectral'; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$2 = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'StaticRegexReplace': { + return [ops.string.staticRegexReplace(getParamValue('input', node, tensorMap, context), getParamValue('pattern', node, tensorMap, context), getParamValue('rewrite', node, tensorMap, context), getParamValue('replaceGlobal', node, tensorMap, context))]; + } + case 'StringNGrams': { + const { nGrams, nGramsSplits } = ops.string.stringNGrams(getParamValue('data', node, tensorMap, context), getParamValue('dataSplits', node, tensorMap, context), getParamValue('separator', node, tensorMap, context), getParamValue('nGramWidths', node, tensorMap, context), getParamValue('leftPad', node, tensorMap, context), getParamValue('rightPad', node, tensorMap, context), getParamValue('padWidth', node, tensorMap, context), getParamValue('preserveShortSequences', node, tensorMap, context)); + return [nGrams, nGramsSplits]; + } + case 'StringSplit': { + const { indices, values, shape } = ops.string.stringSplit(getParamValue('input', node, tensorMap, context), getParamValue('delimiter', node, tensorMap, context), getParamValue('skipEmpty', node, tensorMap, context)); + return [indices, values, shape]; + } + case 'StringToHashBucketFast': { + const output = ops.string.stringToHashBucketFast(getParamValue('input', node, tensorMap, context), getParamValue('numBuckets', node, tensorMap, context)); + return [output]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY$1 = 'string'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const executeOp$1 = (node, tensorMap, context, ops = tfOps) => { + switch (node.op) { + case 'Cast': { + return [ops.cast(getParamValue('x', node, tensorMap, context), getParamValue('dtype', node, tensorMap, context))]; + } + case 'ExpandDims': { + const axis = getParamValue('axis', node, tensorMap, context); + return [ops.expandDims(getParamValue('x', node, tensorMap, context), axis)]; + } + case 'Squeeze': { + const axis = getParamValue('axis', node, tensorMap, context); + return [ops.squeeze(getParamValue('x', node, tensorMap, context), axis)]; + } + case 'Reshape': { + return [ops.reshape(getParamValue('x', node, tensorMap, context), getParamValue('shape', node, tensorMap, context))]; + } + case 'EnsureShape': { + return [ops.ensureShape(getParamValue('x', node, tensorMap, context), getParamValue('shape', node, tensorMap, context))]; + } + case 'MirrorPad': { + return [ops.mirrorPad(getParamValue('x', node, tensorMap, context), getParamValue('padding', node, tensorMap, context), getParamValue('mode', node, tensorMap, context))]; + } + case 'PadV2': + case 'Pad': { + return [ops.pad(getParamValue('x', node, tensorMap, context), getParamValue('padding', node, tensorMap, context), getParamValue('constantValue', node, tensorMap, context))]; + } + case 'SpaceToBatchND': { + const blockShape = getParamValue('blockShape', node, tensorMap, context); + const paddings = getParamValue('paddings', node, tensorMap, context); + return [ops.spaceToBatchND(getParamValue('x', node, tensorMap, context), blockShape, paddings)]; + } + case 'BatchToSpaceND': { + const blockShape = getParamValue('blockShape', node, tensorMap, context); + const crops = getParamValue('crops', node, tensorMap, context); + return [ops.batchToSpaceND(getParamValue('x', node, tensorMap, context), blockShape, crops)]; + } + case 'DepthToSpace': { + const blockSize = getParamValue('blockSize', node, tensorMap, context); + const dataFormat = getParamValue('dataFormat', node, tensorMap, context).toUpperCase(); + return [ops.depthToSpace(getParamValue('x', node, tensorMap, context), blockSize, dataFormat)]; + } + case 'BroadcastTo': { + return [ops.broadcastTo(getParamValue('x', node, tensorMap, context), getParamValue('shape', node, tensorMap, context))]; + } + case 'BroadcastArgs': { + return [ops.broadcastArgs(getParamValue('s0', node, tensorMap, context), getParamValue('s1', node, tensorMap, context))]; + } + default: + throw TypeError(`Node type ${node.op} is not implemented`); + } + }; + const CATEGORY = 'transformation'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Executes the op defined by the node object. + * @param node + * @param tensorMap contains tensors for executed nodes and weights + * @param context contains tensors and information for running the current node. + * @param resourceManager Optional. Contains global resources of the model. + */ + function executeOp(node, tensorMap, context, resourceManager, tidy$1 = tidy) { + const value = ((node, tensorMap, context) => { + switch (node.category) { + case 'arithmetic': + return tidy$1(() => executeOp$k(node, tensorMap, context)); + case 'basic_math': + return tidy$1(() => executeOp$j(node, tensorMap, context)); + case 'control': + return executeOp$i(node, tensorMap, context); + case 'convolution': + return tidy$1(() => executeOp$h(node, tensorMap, context)); + case 'creation': + return tidy$1(() => executeOp$g(node, tensorMap, context)); + case 'dynamic': + return executeOp$f(node, tensorMap, context); + case 'evaluation': + return tidy$1(() => executeOp$e(node, tensorMap, context)); + case 'image': + return tidy$1(() => executeOp$b(node, tensorMap, context)); + case 'graph': + return tidy$1(() => executeOp$d(node, tensorMap, context)); + case 'logical': + return tidy$1(() => executeOp$a(node, tensorMap, context)); + case 'matrices': + return tidy$1(() => executeOp$9(node, tensorMap, context)); + case 'normalization': + return tidy$1(() => executeOp$8(node, tensorMap, context)); + case 'ragged': + return tidy$1(() => executeOp$7(node, tensorMap, context)); + case 'reduction': + return tidy$1(() => executeOp$6(node, tensorMap, context)); + case 'slice_join': + return tidy$1(() => executeOp$5(node, tensorMap, context)); + case 'sparse': + return tidy$1(() => executeOp$4(node, tensorMap, context)); + case 'spectral': + return tidy$1(() => executeOp$3(node, tensorMap, context)); + case 'string': + return tidy$1(() => executeOp$2(node, tensorMap, context)); + case 'transformation': + return tidy$1(() => executeOp$1(node, tensorMap, context)); + case 'hash_table': + return executeOp$c(node, tensorMap, context, resourceManager); + case 'custom': + const opMapper = getRegisteredOp(node.op); + if (opMapper && opMapper.customExecutor) { + return opMapper.customExecutor(new NodeValueImpl(node, tensorMap, context)); + } + else { + throw TypeError(`Custom op ${node.op} is not registered.`); + } + default: + throw TypeError(`Unknown op '${node.op}'. File an issue at ` + + `https://github.com/tensorflow/tfjs/issues so we can add it` + + `, or register a custom execution with tf.registerOp()`); + } + })(node, tensorMap, context); + if (isPromise(value)) { + return value.then((data) => [].concat(data)); + } + return [].concat(value); + } + + /** + * ExecutionContext captures the runtime environment of the node. It keeps + * track of the current frame and iteration for the control flow ops. + * + * For example, typical Dynamic RNN model may contain loops, for which + * TensorFlow will generate graphs with Enter/Exit nodes to control the + * current execution frame, and NextIteration Nodes for iteration id increment. + * For model with branch logic, TensorFLow will generate Switch/Merge ops. + */ + class ExecutionContext { + constructor(weightMap = {}, tensorArrayMap = {}, tensorListMap = {}, functionMap = {}, parseNodeNameCache) { + this.weightMap = weightMap; + this.tensorArrayMap = tensorArrayMap; + this.tensorListMap = tensorListMap; + this.functionMap = functionMap; + this.parseNodeNameCache = parseNodeNameCache; + this.rootContext = { id: 0, frameName: '', iterationId: 0 }; + this.contexts = [this.rootContext]; + this.lastId = 0; + this.generateCurrentContextIds(); + } + newFrame(id, frameName) { + return { id, frameName, iterationId: 0 }; + } + /** + * Set the current context + * @param contexts: ExecutionContextInfo[] the current path of execution + * frames + */ + set currentContext(contexts) { + if (this.contexts !== contexts) { + this.contexts = contexts; + this.generateCurrentContextIds(); + } + } + get currentContext() { + return this.contexts; + } + /** + * Returns the current context in string format. + */ + get currentContextId() { + return this._currentContextIds[0]; + } + /** + * Returns the current context and all parent contexts in string format. + * This allow access to the nodes in the current and parent frames. + */ + get currentContextIds() { + return this._currentContextIds; + } + generateCurrentContextIds() { + const names = []; + for (let i = 0; i < this.contexts.length - 1; i++) { + const contexts = this.contexts.slice(0, this.contexts.length - i); + names.push(this.contextIdforContexts(contexts)); + } + names.push(''); + this._currentContextIds = names; + } + contextIdforContexts(contexts) { + return contexts ? + contexts + .map(context => (context.id === 0 && context.iterationId === 0) ? + '' : + `${context.frameName}-${context.iterationId}`) + .join('/') : + ''; + } + /** + * Enter a new frame, a new context is pushed on the current context list. + * @param frameId new frame id + */ + enterFrame(frameId) { + if (this.contexts) { + this.lastId++; + this.contexts = this.contexts.slice(); + this.contexts.push(this.newFrame(this.lastId, frameId)); + this._currentContextIds.unshift(this.contextIdforContexts(this.contexts)); + } + } + /** + * Exit the current frame, the last context is removed from the current + * context list. + */ + exitFrame() { + if (this.contexts && this.contexts.length > 1) { + this.contexts = this.contexts.slice(); + this.contexts.splice(-1); + this.currentContextIds.shift(); + } + else { + throw new Error('Cannot exit frame, the context is empty'); + } + } + /** + * Enter the next iteration of a loop, the iteration id of last context is + * increased. + */ + nextIteration() { + if (this.contexts && this.contexts.length > 0) { + this.contexts = this.contexts.slice(); + this.lastId++; + const context = Object.assign({}, this.contexts[this.contexts.length - 1]); + context.iterationId += 1; + context.id = this.lastId; + this.contexts.splice(-1, 1, context); + this._currentContextIds.splice(0, 1, this.contextIdforContexts(this.contexts)); + } + else { + throw new Error('Cannot increase frame iteration, the context is empty'); + } + } + getWeight(name) { + return this.weightMap[name]; + } + addTensorArray(tensorArray) { + this.tensorArrayMap[tensorArray.id] = tensorArray; + } + getTensorArray(id) { + return this.tensorArrayMap[id]; + } + addTensorList(tensorList) { + this.tensorListMap[tensorList.id] = tensorList; + } + getTensorList(id) { + return this.tensorListMap[id]; + } + dispose(keepIds) { + for (const key in this.tensorArrayMap) { + this.tensorArrayMap[key].clearAndClose(keepIds); + } + for (const key in this.tensorListMap) { + this.tensorListMap[key].clearAndClose(keepIds); + } + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Given graph inputs and desired outputs, find the minimal set of nodes + * to execute in order to compute the outputs. In addition return other useful + * info such: + * - Missing inputs needed to compute the output. + * - Whether the subgraph contains dynamic ops (control flow, dynamic shape). + * - Alternative inputs in order to avoid async (dynamic op) execution. + */ + function getExecutionSubgraph(inputs, outputs, weightMap, initNodes) { + const usedNodes = new Set(); + const missingInputs = []; + let dynamicNode = null; + let syncInputs = null; + // Start with the outputs, going backwards and find all the nodes that are + // needed to compute those outputs. + const seen = new Set(); + const inputNodeNames = new Set(Object.keys(inputs).map((name) => parseNodeName(name)[0])); + initNodes = initNodes || []; + const initNodeNames = new Set(initNodes.map((node) => parseNodeName(node.name)[0])); + const frontier = [...outputs]; + while (frontier.length > 0) { + const node = frontier.pop(); + if (isControlFlow(node) || isDynamicShape(node) || isHashTable(node)) { + if (dynamicNode == null) { + dynamicNode = node; + syncInputs = dynamicNode.children.map(child => child.name) + .filter(name => usedNodes.has(name)); + } + } + usedNodes.add(node.name); + // Weights are dead end since we already have their values. + if (weightMap[node.name] != null) { + continue; + } + // This node is a dead end since it's one of the user-provided inputs. + if (inputNodeNames.has(node.name)) { + continue; + } + // This node is a dead end since it doesn't have any inputs. + if (initNodeNames.has(node.name)) { + continue; + } + if (node.inputs.length === 0) { + missingInputs.push(node.name); + continue; + } + node.inputs.forEach(input => { + // Don't add to the frontier if it is already there. + if (seen.has(input.name)) { + return; + } + seen.add(input.name); + frontier.push(input); + }); + } + return { inputs, outputs, usedNodes, missingInputs, dynamicNode, syncInputs }; + } + /** + * Given the execution info, return a list of nodes in topological order that + * need to be executed to compute the output. + */ + function getNodesInTopologicalOrder(graph, executionInfo) { + const { usedNodes, inputs } = executionInfo; + const inputNodes = Object.keys(inputs) + .map(name => parseNodeName(name)[0]) + .map(name => graph.nodes[name]); + const initNodes = graph.initNodes || []; + const isUsed = (node) => usedNodes.has(typeof node === 'string' ? node : node.name); + function unique(nodes) { + return [...new Map(nodes.map((node) => [node.name, node])).values()]; + } + const predefinedNodes = unique([ + ...inputNodes, + ...graph.weights, + ...initNodes, + ]).filter(isUsed); + const allNodes = unique([ + ...predefinedNodes, + ...Object.values(graph.nodes), + ]).filter(isUsed); + const nameToNode = new Map(allNodes.map((node) => [node.name, node])); + const inCounts = {}; + for (const node of allNodes) { + inCounts[node.name] = inCounts[node.name] || 0; + for (const child of node.children) { + // When the child is unused, set in counts to infinity so that it will + // never be decreased to 0 and added to the execution list. + if (!isUsed(child)) { + inCounts[child.name] = Number.POSITIVE_INFINITY; + } + inCounts[child.name] = (inCounts[child.name] || 0) + 1; + } + } + // Build execution order for all used nodes regardless whether they are + // predefined or not. + const frontier = Object.entries(inCounts) + .filter(([, inCount]) => inCount === 0) + .map(([name]) => name); + const orderedNodeNames = [...frontier]; + while (frontier.length > 0) { + const nodeName = frontier.pop(); + const node = nameToNode.get(nodeName); + for (const child of node.children.filter(isUsed)) { + if (--inCounts[child.name] === 0) { + orderedNodeNames.push(child.name); + frontier.push(child.name); + } + } + } + const orderedNodes = orderedNodeNames.map((name) => nameToNode.get(name)); + const filteredOrderedNodes = filterPredefinedReachableNodes(orderedNodes, predefinedNodes); + // TODO: Turn validation on/off with tf env flag. + validateNodesExecutionOrder(filteredOrderedNodes, predefinedNodes); + return filteredOrderedNodes; + } + /** + * This is a helper function of `getNodesInTopologicalOrder`. + * Returns ordered nodes reachable by at least one predefined node. + * This can help us filter out redundant nodes from the returned node list. + * For example: + * If we have four nodes with dependencies like this: + * a --> b --> c --> d + * when node `c` is predefined (e.g. given as an input tensor), we can + * skip node `a` and `b` since their outputs will never be used. + * + * @param orderedNodes Graph nodes in execution order. + * @param predefinedNodes Graph inputs, weights, and init nodes. Nodes in this + * list must have distinct names. + */ + function filterPredefinedReachableNodes(orderedNodes, predefinedNodes) { + const nameToNode = new Map(orderedNodes.map((node) => [node.name, node])); + // TODO: Filter out more nodes when >=2 nodes are predefined in a path. + const stack = predefinedNodes.map((node) => node.name); + const predefinedReachableNodeNames = new Set(stack); + // Perform a DFS starting from the set of all predefined nodes + // to find the set of all nodes reachable from the predefined nodes. + while (stack.length > 0) { + const nodeName = stack.pop(); + const node = nameToNode.get(nodeName); + for (const child of node.children) { + if (!nameToNode.has(child.name) || + predefinedReachableNodeNames.has(child.name)) { + continue; + } + predefinedReachableNodeNames.add(child.name); + stack.push(child.name); + } + } + // Filter out unreachable nodes and build the ordered node list. + const filteredOrderedNodes = orderedNodes.filter((node) => predefinedReachableNodeNames.has(node.name)); + return filteredOrderedNodes; + } + class NodesExecutionOrderError extends Error { + constructor(message) { + super(`NodesExecutionOrderError: ${message}`); + } + } + /** + * This is a helper function of `getNodesInTopologicalOrder`. + * Validates property: given nodes `a` and `b`, Order(a) > Order(b) if `a` + * is a child of `b`. This function throws an error if validation fails. + * + * @param orderedNodes Graph nodes in execution order. + * @param predefinedNodes Graph inputs, weights, and init nodes. Nodes in this + * list must have distinct names. + */ + function validateNodesExecutionOrder(orderedNodes, predefinedNodes) { + const nodeNameToOrder = new Map(orderedNodes.map((node, order) => [node.name, order])); + const predefinedNodeNames = new Set(predefinedNodes.map((node) => node.name)); + const isPredefined = (node) => predefinedNodeNames.has(typeof node === 'string' ? node : node.name); + const willBeExecutedNodeNames = new Set(orderedNodes.map((node) => node.name)); + const willBeExecuted = (node) => willBeExecutedNodeNames.has(typeof node === 'string' ? node : node.name); + for (const node of orderedNodes) { + for (const child of node.children.filter(willBeExecuted)) { + if (!nodeNameToOrder.has(child.name)) { + throw new NodesExecutionOrderError(`Child ${child.name} of node ${node.name} is unreachable.`); + } + if (nodeNameToOrder.get(node.name) > nodeNameToOrder.get(child.name)) { + throw new NodesExecutionOrderError(`Node ${node.name} is scheduled to run after its child ${child.name}.`); + } + } + if (!isPredefined(node)) { + for (const input of node.inputs) { + if (!nodeNameToOrder.has(input.name)) { + throw new NodesExecutionOrderError(`Input ${input.name} of node ${node.name} is unreachable.`); + } + if (nodeNameToOrder.get(input.name) > nodeNameToOrder.get(node.name)) { + throw new NodesExecutionOrderError(`Node ${node.name} is scheduled to run before its input ${input.name}.`); + } + } + } + } + } + /** + * Given the execution info, return a map from node name to the disposable + * node name list after its execution. + * + * @returns A map from node name to disposable nodes after its + * execution. That is, for a node `x`, `nodeLiveUntilMap[x]` indicates + * all nodes which their intermediate tensors should be disposed after `x` + * being executed. + */ + function getNodeLiveUntilMap(orderedNodes) { + const nodeNameToOrder = new Map(orderedNodes.map((node, order) => [node.name, order])); + const INF_LIFE = Number.MAX_SAFE_INTEGER; + // Make control flow nodes (and consequently their direct parents) + // live forever since they're tricky to track correctly. + const selfLifespans = orderedNodes.map((node, nodeOrder) => isControlFlow(node) ? INF_LIFE : nodeOrder); + const getSelfLifeSpan = (node) => { + const selfLife = selfLifespans[nodeNameToOrder.get(node.name)]; + if (selfLife == null) { + // If nodeToOrder does not contain the node, it is unused or + // unreachable in graph. + return -1; + } + return selfLife; + }; + // `liveUntil[i]` points to the last node in the `orderedNodes` array that + // may depend on tensors from node `i`. It indicates that all the + // intermediate tensors from `orderedNodes[i]` should be disposed after + // `orderedNodes[liveUntil[i]]` is executed. + // A node lives long enough to pass on its tensors to its children. + // It lives until at least `max(node's position, children's positions)`. + const liveUntilOrders = orderedNodes.map((node, nodeOrder) => { + return node.children.map(getSelfLifeSpan) + .reduce((a, b) => Math.max(a, b), selfLifespans[nodeOrder]); + }); + // liveUntilMap: + // - Key: Name of a node `x` + // - Values: All nodes whose intermediate tensors should be disposed + // after `x` is executed. + const liveUntilMap = new Map(); + for (let nodeOrder = 0; nodeOrder < orderedNodes.length; ++nodeOrder) { + const liveUntilOrder = liveUntilOrders[nodeOrder]; + if (liveUntilOrder === INF_LIFE) { + continue; + } + const node = orderedNodes[nodeOrder]; + const liveUntilNode = orderedNodes[liveUntilOrder]; + if (!liveUntilMap.has(liveUntilNode.name)) { + liveUntilMap.set(liveUntilNode.name, []); + } + liveUntilMap.get(liveUntilNode.name).push(node); + } + return liveUntilMap; + } + const CONTROL_FLOW_OPS = new Set([ + 'Switch', 'Merge', 'Enter', 'Exit', 'NextIteration', 'StatelessIf', + 'StatelessWhile', 'if', 'While' + ]); + const DYNAMIC_SHAPE_OPS = new Set([ + 'NonMaxSuppressionV2', 'NonMaxSuppressionV3', 'NonMaxSuppressionV5', 'Where' + ]); + const HASH_TABLE_OPS = new Set([ + 'HashTable', 'HashTableV2', 'LookupTableImport', 'LookupTableImportV2', + 'LookupTableFind', 'LookupTableFindV2', 'LookupTableSize', 'LookupTableSizeV2' + ]); + function isControlFlow(node) { + return CONTROL_FLOW_OPS.has(node.op); + } + function isDynamicShape(node) { + return DYNAMIC_SHAPE_OPS.has(node.op); + } + function isHashTable(node) { + return HASH_TABLE_OPS.has(node.op); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class GraphExecutor { + get weightIds() { + return this.parent ? this.parent.weightIds : this._weightIds; + } + get functionExecutorMap() { + return this.parent ? this.parent.functionExecutorMap : + this._functionExecutorMap; + } + get weightMap() { + return this.parent ? this.parent.weightMap : this._weightMap; + } + set weightMap(weightMap) { + const weightIds = Object.keys(weightMap).map(key => weightMap[key].map(tensor => tensor.id)); + this._weightIds = [].concat(...weightIds); + this._weightMap = weightMap; + } + /** + * Set `ResourceManager` shared by executors of a model. + * @param resourceManager: `ResourceManager` of the `GraphModel`. + */ + set resourceManager(resourceManager) { + this._resourceManager = resourceManager; + } + get inputs() { + return this._inputs.map(node => { + return { + name: node.name, + shape: node.attrParams['shape'] ? + node.attrParams['shape'].value : + undefined, + dtype: node.attrParams['dtype'] ? + node.attrParams['dtype'].value : + undefined + }; + }); + } + get outputs() { + return this._outputs.map(node => { + return { + name: node.name, + shape: node.attrParams['shape'] ? + node.attrParams['shape'].value : + undefined, + dtype: node.attrParams['dtype'] ? + node.attrParams['dtype'].value : + undefined + }; + }); + } + get inputNodes() { + return this._inputs.map(node => node.signatureKey || node.name); + } + get outputNodes() { + return this._outputs.map((node) => { + const name = node.signatureKey || node.name; + return node.defaultOutput ? (`${name}:${node.defaultOutput}`) : name; + }); + } + get functions() { + return Object.keys(this._functions).reduce((map, key) => { + map[key] = this._functions[key].signature; + return map; + }, {}); + } + /** + * + * @param graph Graph the model or function graph to be executed. + * @param parent When building function exector you need to set the parent + * executor. Since the weights and function executor maps are set at parant + * level, that function executor can access the function maps and weight maps + * through the parent. + */ + constructor(graph, parent) { + this.graph = graph; + this.parent = parent; + this.compiledMap = new Map(); + this.parseNodeNameCache = new Map(); + this._weightMap = {}; + this.SEPARATOR = ','; + this._functions = {}; + this._functionExecutorMap = {}; + this.keepIntermediateTensors = false; + this._outputs = graph.outputs; + this._inputs = graph.inputs; + this._initNodes = graph.initNodes; + this._signature = graph.signature; + this._functions = graph.functions; + // create sub-graph executors + if (graph.functions != null) { + Object.keys(graph.functions).forEach(name => { + this._functionExecutorMap[name] = + new GraphExecutor(graph.functions[name], this); + }); + } + } + getCompilationKey(inputs, outputs) { + const sortedInputs = inputs.map(node => node.name).sort(); + const sortedOutputs = outputs.map(node => node.name).sort(); + return sortedInputs.join(this.SEPARATOR) + '--' + + sortedOutputs.join(this.SEPARATOR); + } + /** + * Compiles the inference graph and returns the minimal set of nodes that are + * required for execution, in the correct execution order. + * @returns {Object} compilation The compile result. + * @returns {Node[]} compilation.orderedNodes Nodes in the correct execution + * order. + * @returns {Map} compilation.nodeLiveUntilMap A map from node + * to disposable nodes after its execution. That is, for a node `x`, + * `nodeLiveUntilMap[x]` indicates all nodes whose intermediate + * tensors should be disposed after `x` is executed. + */ + compile(inputs, outputs) { + const executionInfo = getExecutionSubgraph(inputs, outputs, this.weightMap, this._initNodes); + const { missingInputs, dynamicNode, syncInputs } = executionInfo; + if (dynamicNode != null) { + throw new Error(`This execution contains the node '${dynamicNode.name}', which has ` + + `the dynamic op '${dynamicNode.op}'. Please use ` + + `model.executeAsync() instead. Alternatively, to avoid the ` + + `dynamic ops, specify the inputs [${syncInputs}]`); + } + if (missingInputs.length > 0) { + const outNames = outputs.map(n => n.name); + const inNames = Object.keys(inputs); + throw new Error(`Cannot compute the outputs [${outNames}] from the provided inputs ` + + `[${inNames}]. Missing the following inputs: [${missingInputs}]`); + } + const orderedNodes = getNodesInTopologicalOrder(this.graph, executionInfo); + const nodeLiveUntilMap = getNodeLiveUntilMap(orderedNodes); + return { orderedNodes, nodeLiveUntilMap }; + } + cloneAndKeepTensor(tensor) { + if (tensor == null) { + return null; + } + const clone = tensor.clone(); + // Keep the clone because`model.execute()` may be called within + // a `tidy()`, but the user may inspect these tensors after the + // tidy. + keep(clone); + return clone; + } + cloneTensorList(tensors) { + if (!tensors) { + return null; + } + const clonedTensor = tensors.map(tensor => { + return this.cloneAndKeepTensor(tensor); + }); + return clonedTensor; + } + cloneTensorMap(tensorsMap) { + return Object.fromEntries(Object.entries(tensorsMap).map(([name, tensorsList]) => { + return [name, this.cloneTensorList(tensorsList)]; + })); + } + /** + * Executes the inference for given input tensors. + * @param inputs Tensor map for the model inputs, keyed by the input node + * names. + * @param outputs Optional. output node name from the Tensorflow model, if + * no outputs are specified, the default outputs of the model would be used. + * You can inspect intermediate nodes of the model by adding them to the + * outputs array. + */ + execute(inputs, outputs) { + // Dispose any tensors from a prior run to avoid leaking them. + this.disposeIntermediateTensors(); + inputs = this.mapInputs(inputs); + const names = Object.keys(inputs).sort(); + this.checkInputs(inputs); + this.checkInputShapeAndType(inputs); + outputs = this.mapOutputs(outputs); + this.checkOutputs(outputs); + const inputNodes = names.map(name => this.graph.nodes[parseNodeName(name)[0]]); + const outputNodeNames = outputs.map(name => parseNodeName(name)[0]); + const outputNodeNameSet = new Set(outputNodeNames); + let outputNodes = outputNodeNames.map(name => this.graph.nodes[name]); + // If no outputs are specified, then use the default outputs of the model. + if (outputNodes.length === 0) { + outputNodes = this._outputs; + } + const compilationKey = this.getCompilationKey(inputNodes, outputNodes); + // Do nothing if the compiled graph cache contains the input. + let compilation = this.compiledMap.get(compilationKey); + if (compilation == null) { + compilation = this.compile(inputs, outputNodes); + this.compiledMap.set(compilationKey, compilation); + } + // Keep tensors if KEEP_INTERMEDIATE_TENSORS is on. + try { + this.keepIntermediateTensors = env().getBool('KEEP_INTERMEDIATE_TENSORS'); + } + catch (e) { + this.keepIntermediateTensors = false; + console.warn(e.message); + } + const tensorArrayMap = {}; + const tensorListMap = {}; + return tidy(() => { + const context = new ExecutionContext(this.weightMap, tensorArrayMap, tensorListMap, this.functionExecutorMap, this.parseNodeNameCache); + const tensorsMap = Object.assign({}, this.weightMap); + if (this.keepIntermediateTensors) { + this.clonedTensorsMap = this.cloneTensorMap(this.weightMap); + } + Object.keys(inputs).forEach(name => { + const [nodeName, index] = parseNodeName(name, context); + const tensors = []; + tensors[index] = inputs[name]; + tensorsMap[nodeName] = tensors; + if (this.keepIntermediateTensors) { + this.clonedTensorsMap[nodeName] = this.cloneTensorList(tensors); + } + }); + const tensorsToKeep = this.getFrozenTensorIds(tensorsMap); + const { orderedNodes, nodeLiveUntilMap } = compilation; + for (const node of orderedNodes) { + if (tensorsMap[node.name]) { + continue; + } + const tensors = executeOp(node, tensorsMap, context, this._resourceManager); + if (isPromise(tensors)) { + throw new Error(`The execution of the op '${node.op}' returned a promise. ` + + `Please use model.executeAsync() instead.`); + } + tensorsMap[node.name] = tensors; + if (this.keepIntermediateTensors) { + this.clonedTensorsMap[node.name] = this.cloneTensorList(tensors); + } + this.checkTensorForDisposalWithNodeLiveUntilInfo(node, tensorsMap, context, tensorsToKeep, outputNodeNameSet, nodeLiveUntilMap.get(node.name)); + } + // dispose the context for the root executor + if (this.parent == null) { + context.dispose(tensorsToKeep); + } + return outputs.map(name => getTensor(name, tensorsMap, context)); + }); + } + getFrozenTensorIds(tensorMap) { + const ids = [].concat.apply([], Object.keys(tensorMap) + .map(key => tensorMap[key]) + .map(tensors => tensors.map(tensor => tensor.id))); + return new Set(ids); + } + checkTensorForDisposal(nodeName, node, tensorMap, context, tensorsToKeep, outputNodeNameSet, intermediateTensorConsumerCount) { + // Skip output nodes and any control flow nodes, since its dependency is + // tricky to track correctly. + if (isControlFlow(node) || outputNodeNameSet.has(nodeName)) { + return; + } + for (const tensor of tensorMap[nodeName]) { + if (tensor == null) { + continue; + } + intermediateTensorConsumerCount[tensor.id] = + (intermediateTensorConsumerCount[tensor.id] || 0) + + node.children.length; + } + for (const input of node.inputs) { + // Skip any control flow nodes, since its dependency is tricky to track + // correctly. + if (isControlFlow(input)) { + continue; + } + const tensors = getTensorsForCurrentContext(input.name, tensorMap, context); + if (tensors == null) { + continue; + } + for (const tensor of tensors) { + if (!tensor || tensor.kept || tensorsToKeep.has(tensor.id)) { + continue; + } + // Only intermediate nodes' tensors have counts set, not marked as + // kept, and not in `tensorsToKeep`. + // Input and weight nodes' tensors should exist in `tensorsToKeep`. + // Output and control flow nodes' tensors should never have count set. + const count = intermediateTensorConsumerCount[tensor.id]; + if (count === 1) { + tensor.dispose(); + delete intermediateTensorConsumerCount[tensor.id]; + } + else if (count != null) { + intermediateTensorConsumerCount[tensor.id]--; + } + } + } + } + checkTensorForDisposalWithNodeLiveUntilInfo(node, tensorMap, context, tensorsToKeep, outputNodeNameSet, liveUntilNodes) { + function isNonDisposableNode(node) { + // Skip output nodes and any control flow nodes, since its dependency is + // tricky to track correctly. + return isControlFlow(node) || outputNodeNameSet.has(node.name); + } + if (isControlFlow(node) || liveUntilNodes == null) { + return; + } + for (const nodeToDispose of liveUntilNodes) { + if (isNonDisposableNode(nodeToDispose)) { + continue; + } + const tensors = getTensorsForCurrentContext(nodeToDispose.name, tensorMap, context); + for (const tensor of tensors) { + if (!tensor || tensor.kept || tensorsToKeep.has(tensor.id)) { + continue; + } + tensor.dispose(); + } + } + } + /** + * Executes the inference for given input tensors in Async fashion. + * @param inputs Tensor map for the model inputs, keyed by the input node + * names. + * @param outputs output node name from the Tensorflow model, if no outputs + * are specified, the default outputs of the model would be used. You can + * inspect intermediate nodes of the model by adding them to the outputs + * array. + */ + async executeAsync(inputs, outputs) { + return this._executeAsync(inputs, outputs); + } + disposeIntermediateTensors() { + if (!this.clonedTensorsMap) { + return; + } + Object.values(this.clonedTensorsMap).forEach(tensorsList => { + for (const tensor of tensorsList) { + if (tensor && !tensor.isDisposed) { + tensor.dispose(); + } + } + }); + this.clonedTensorsMap = null; + } + getIntermediateTensors() { + return this.clonedTensorsMap; + } + /** + * Executes the inference for given input tensors in Async fashion. + * @param inputs Tensor map for the model inputs, keyed by the input node + * names. + * @param outputs Optional. output node name from the Tensorflow model, + * if no outputs are specified, the default outputs of the model would be + * used. You can inspect intermediate nodes of the model by adding them to + * the outputs array. + * @param isFunctionExecution Optional. Flag for executing a function. + * @param tensorArrayMap Optional, global TensorArray map by id. Used for + * function execution. + * @param tensorArrayMap Optional global TensorList map by id. Used for + * function execution. + */ + async _executeAsync(inputs, outputs, isFunctionExecution = false, tensorArrayMap = {}, tensorListMap = {}) { + // Dispose any tensors from a prior run to avoid leaking them. + this.disposeIntermediateTensors(); + if (!isFunctionExecution) { + inputs = this.mapInputs(inputs); + this.checkInputs(inputs); + this.checkInputShapeAndType(inputs); + outputs = this.mapOutputs(outputs); + this.checkOutputs(outputs); + } + // Keep tensors if KEEP_INTERMEDIATE_TENSORS is on. + try { + this.keepIntermediateTensors = env().getBool('KEEP_INTERMEDIATE_TENSORS'); + } + catch (e) { + this.keepIntermediateTensors = false; + console.warn(e.message); + } + const context = new ExecutionContext(this.weightMap, tensorArrayMap, tensorListMap, this.functionExecutorMap, this.parseNodeNameCache); + if (this.keepIntermediateTensors) { + this.clonedTensorsMap = this.cloneTensorMap(this.weightMap); + } + // Graph with control flow op requires runtime evaluation of the execution + // order, while without control flow the execution order is pre-determined + // in the compile method. + const tensorsMap = await this.executeWithControlFlow(inputs, context, outputs, isFunctionExecution); + const results = outputs.map(name => getTensor(name, tensorsMap, context)); + // dispose all the intermediate tensors + const outputIds = results.map(t => t.id); + const inputIds = Object.keys(inputs).map(name => inputs[name].id); + const keepIds = new Set([...outputIds, ...inputIds, ...this.weightIds]); + Object.values(tensorsMap).forEach(tensorsList => { + tensorsList.forEach(tensor => { + if (tensor && !tensor.isDisposed && !keepIds.has(tensor.id)) { + tensor.dispose(); + } + }); + }); + // dispose the context for the root executor + if (this.parent == null) { + context.dispose(keepIds); + } + return results; + } + async executeFunctionAsync(inputs, tensorArrayMap, tensorListMap) { + const mappedInputs = inputs.reduce((map, tensor, index) => { + map[this.inputs[index].name] = tensor; + return map; + }, {}); + return this._executeAsync(mappedInputs, this.outputNodes, true, tensorArrayMap, tensorListMap); + } + /** + * When there are control flow nodes in the graph, the graph execution use + * ExecutionContext to keep track of the frames and loop iterators. + * @param inputs placeholder tensors for the graph. + * @param context the execution context object for current execution. + * @param outputNames Optional. output node name from the Tensorflow model, + * if no outputs are specified, the default outputs of the model would be + * used. You can inspect intermediate nodes of the model by adding them to + * the outputs array. + * @param isFunctionExecution Flag for executing a function. + */ + async executeWithControlFlow(inputs, context, outputNames, isFunctionExecution) { + const names = Object.keys(inputs); + const inputNodes = names.map(name => this.graph.nodes[parseNodeName(name)[0]]); + const outputNodeNames = outputNames.map(name => parseNodeName(name)[0]); + const outputNodeNameSet = new Set(outputNodeNames); + let outputNodes = outputNodeNames.map(name => this.graph.nodes[name]); + // If no outputs are specified, then use the default outputs of the model. + if (outputNodes.length === 0) { + outputNodes = this._outputs; + } + const { usedNodes, missingInputs, dynamicNode, syncInputs } = getExecutionSubgraph(inputs, outputNodes, this.weightMap, this._initNodes); + // First nodes to execute include inputNodes, weights, and initNodes. + const stack = [ + ...inputNodes, ...this.graph.weights, ...(this._initNodes || []) + ].map(node => { + return { node, contexts: context.currentContext }; + }); + const tensorsMap = Object.assign({}, this.weightMap); + Object.keys(inputs).forEach(name => { + const [nodeName, index] = parseNodeName(name); + const tensors = []; + tensors[index] = inputs[name]; + tensorsMap[nodeName] = tensors; + }); + const intermediateTensorConsumerCount = {}; + const tensorsToKeep = this.getFrozenTensorIds(tensorsMap); + const added = {}; + while (stack.length > 0) { + const promises = this.processStack(inputNodes, stack, context, tensorsMap, added, tensorsToKeep, outputNodeNameSet, intermediateTensorConsumerCount, usedNodes); + await Promise.all(promises); + } + if (dynamicNode == null && !isFunctionExecution) { + console.warn(`This model execution did not contain any nodes with control flow ` + + `or dynamic output shapes. You can use model.execute() instead.`); + } + const missingOutputs = outputNodes + .filter(node => !isControlFlow(node) && + !getTensor(node.name, tensorsMap, context)) + .map(node => node.name); + if (missingOutputs.length > 0) { + let alternativeMsg = ''; + if (dynamicNode != null) { + alternativeMsg = + `Alternatively, to avoid the dynamic ops, use model.execute() ` + + `and specify the inputs [${syncInputs}]`; + } + throw new Error(`Cannot compute the outputs [${missingOutputs}] from the provided ` + + `inputs [${names}]. Consider providing the following inputs: ` + + `[${missingInputs}]. ${alternativeMsg}`); + } + return tensorsMap; + } + processStack(inputNodes, stack, context, tensorMap, added, tensorsToKeep, outputNodeNameSet, intermediateTensorConsumerCount, usedNodes) { + const promises = []; + while (stack.length > 0) { + const item = stack.pop(); + context.currentContext = item.contexts; + let nodeName = ''; + // The tensor of the Enter op with isConstant set should be set + // in the parent scope, so it will be available as constant for the + // whole loop. + if (item.node.op === 'Enter' && + getParamValue('isConstant', item.node, tensorMap, context)) { + [nodeName] = getNodeNameAndIndex(item.node.name, context); + } + // only process nodes that are not in the tensorMap yet, this include + // inputNodes and internal initNodes. + if (tensorMap[item.node.name] == null) { + const tensors = executeOp(item.node, tensorMap, context, this._resourceManager); + if (!nodeName) { + [nodeName] = getNodeNameAndIndex(item.node.name, context); + } + const currentContext = context.currentContext; + if (isPromise(tensors)) { + promises.push(tensors.then(t => { + tensorMap[nodeName] = t; + if (this.keepIntermediateTensors) { + this.clonedTensorsMap[nodeName] = this.cloneTensorList(t); + } + context.currentContext = currentContext; + this.checkTensorForDisposal(nodeName, item.node, tensorMap, context, tensorsToKeep, outputNodeNameSet, intermediateTensorConsumerCount); + this.processChildNodes(item.node, stack, context, tensorMap, added, usedNodes); + return t; + })); + } + else { + tensorMap[nodeName] = tensors; + if (this.keepIntermediateTensors) { + this.clonedTensorsMap[nodeName] = this.cloneTensorList(tensors); + } + this.checkTensorForDisposal(nodeName, item.node, tensorMap, context, tensorsToKeep, outputNodeNameSet, intermediateTensorConsumerCount); + this.processChildNodes(item.node, stack, context, tensorMap, added, usedNodes); + } + } + else { + this.processChildNodes(item.node, stack, context, tensorMap, added, usedNodes); + } + } + return promises; + } + processChildNodes(node, stack, context, tensorMap, added, usedNodes) { + node.children.forEach((childNode) => { + const [nodeName,] = getNodeNameAndIndex(childNode.name, context); + if (added[nodeName] || !usedNodes.has(childNode.name)) { + return; + } + // Merge op can be pushed if any of its inputs has value. + if (childNode.op === 'Merge') { + if (childNode.inputNames.some(name => { + return !!getTensor(name, tensorMap, context); + })) { + added[nodeName] = true; + stack.push({ contexts: context.currentContext, node: childNode }); + } + } + else // Otherwise all inputs must to have value. + if (childNode.inputNames.every(name => { + return !!getTensor(name, tensorMap, context); + })) { + added[nodeName] = true; + stack.push({ contexts: context.currentContext, node: childNode }); + } + }); + } + /** + * Releases the memory used by the weight tensors. + */ + dispose() { + Object.keys(this.weightMap) + .forEach(key => this.weightMap[key].forEach(tensor => tensor.dispose())); + } + checkInputShapeAndType(inputs) { + Object.keys(inputs).forEach(name => { + const input = inputs[name]; + const [nodeName,] = parseNodeName(name); + const node = this.graph.nodes[nodeName]; + if (node.attrParams['shape'] && node.attrParams['shape'].value) { + const shape = node.attrParams['shape'].value; + const match = shape.length === input.shape.length && + input.shape.every((dim, index) => shape[index] === -1 || shape[index] === dim); + assert$1(match, () => `The shape of dict['${node.name}'] provided in ` + + `model.execute(dict) must be [${shape}], but was ` + + `[${input.shape}]`); + } + if (node.attrParams['dtype'] && node.attrParams['dtype'].value) { + assert$1(input.dtype === node.attrParams['dtype'].value, () => `The dtype of dict['${node.name}'] provided in ` + + `model.execute(dict) must be ` + + `${node.attrParams['dtype'].value}, but was ${input.dtype}`); + } + }); + } + mapInputs(inputs) { + var _a, _b; + const result = {}; + for (const inputName in inputs) { + const tensor = (_b = (_a = this._signature) === null || _a === void 0 ? void 0 : _a.inputs) === null || _b === void 0 ? void 0 : _b[inputName]; + if (tensor != null) { + result[tensor.name] = inputs[inputName]; + } + else { + result[inputName] = inputs[inputName]; + } + } + return result; + } + checkInputs(inputs) { + const notInGraph = Object.keys(inputs).filter(name => { + const [nodeName] = parseNodeName(name); + return this.graph.nodes[nodeName] == null; + }); + if (notInGraph.length > 0) { + throw new Error(`The dict provided in model.execute(dict) has ` + + `keys: [${notInGraph}] that are not part of graph`); + } + } + mapOutputs(outputs) { + return outputs.map(name => { + var _a, _b; + const tensor = (_b = (_a = this._signature) === null || _a === void 0 ? void 0 : _a.outputs) === null || _b === void 0 ? void 0 : _b[name]; + if (tensor != null) { + return tensor.name; + } + return name; + }, {}); + } + checkOutputs(outputs) { + outputs.forEach(name => { + const [normalizedName] = parseNodeName(name); + if (!this.graph.nodes[normalizedName]) { + throw new Error(`The output '${name}' is not found in the graph`); + } + }); + } + } + + /** + * Contains global resources of a model. + */ + class ResourceManager { + constructor(hashTableNameToHandle = {}, hashTableMap = {}) { + this.hashTableNameToHandle = hashTableNameToHandle; + this.hashTableMap = hashTableMap; + } + /** + * Register a `HashTable` in the resource manager. + * + * The `HashTable` can be retrieved by `resourceManager.getHashTableById`, + * where id is the table handle tensor's id. + * + * @param name Op node name that creates the `HashTable`. + * @param hashTable The `HashTable` to be added to resource manager. + */ + addHashTable(name, hashTable) { + this.hashTableNameToHandle[name] = hashTable.handle; + this.hashTableMap[hashTable.id] = hashTable; + } + /** + * Get the table handle by node name. + * @param name Op node name that creates the `HashTable`. This name is also + * used in the inputs list of lookup and import `HashTable` ops. + */ + getHashTableHandleByName(name) { + return this.hashTableNameToHandle[name]; + } + /** + * Get the actual `HashTable` by its handle tensor's id. + * @param id The id of the handle tensor. + */ + getHashTableById(id) { + return this.hashTableMap[id]; + } + /** + * Dispose `ResourceManager`, including its hashTables and tensors in them. + */ + dispose() { + for (const key in this.hashTableMap) { + this.hashTableMap[key].clearAndClose(); + delete this.hashTableMap[key]; + } + for (const name in this.hashTableNameToHandle) { + this.hashTableNameToHandle[name].dispose(); + delete this.hashTableNameToHandle[name]; + } + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const TFHUB_SEARCH_PARAM = '?tfjs-format=file'; + const DEFAULT_MODEL_NAME = 'model.json'; + /** + * A `tf.GraphModel` is a directed, acyclic graph built from a + * SavedModel GraphDef and allows inference execution. + * + * A `tf.GraphModel` can only be created by loading from a model converted from + * a [TensorFlow SavedModel](https://www.tensorflow.org/guide/saved_model) using + * the command line converter tool and loaded via `tf.loadGraphModel`. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + class GraphModel { + // Returns the version information for the tensorflow model GraphDef. + get modelVersion() { + return this.version; + } + get inputNodes() { + return this.executor.inputNodes; + } + get outputNodes() { + return this.executor.outputNodes; + } + get inputs() { + return this.executor.inputs; + } + get outputs() { + return this.executor.outputs; + } + get weights() { + return this.executor.weightMap; + } + get metadata() { + return this.artifacts.userDefinedMetadata; + } + get modelSignature() { + return this.signature; + } + get modelStructuredOutputKeys() { + return this.structuredOutputKeys; + } + /** + * @param modelUrl url for the model, or an `io.IOHandler`. + * @param weightManifestUrl url for the weight file generated by + * scripts/convert.py script. + * @param requestOption options for Request, which allows to send credentials + * and custom headers. + * @param onProgress Optional, progress callback function, fired periodically + * before the load is completed. + */ + constructor(modelUrl, loadOptions = {}, tfio = io) { + this.modelUrl = modelUrl; + this.loadOptions = loadOptions; + this.version = 'n/a'; + this.io = tfio; + if (loadOptions == null) { + this.loadOptions = {}; + } + this.resourceManager = new ResourceManager(); + } + findIOHandler() { + const path = this.modelUrl; + if (path.load != null) { + // Path is an IO Handler. + this.handler = path; + } + else if (this.loadOptions.requestInit != null) { + this.handler = this.io.browserHTTPRequest(path, this.loadOptions); + } + else { + const handlers = this.io.getLoadHandlers(path, this.loadOptions); + if (handlers.length === 0) { + // For backward compatibility: if no load handler can be found, + // assume it is a relative http path. + handlers.push(this.io.browserHTTPRequest(path, this.loadOptions)); + } + else if (handlers.length > 1) { + throw new Error(`Found more than one (${handlers.length}) load handlers for ` + + `URL '${[path]}'`); + } + this.handler = handlers[0]; + } + } + /** + * Loads the model and weight files, construct the in memory weight map and + * compile the inference graph. + */ + load() { + this.findIOHandler(); + if (this.handler.load == null) { + throw new Error('Cannot proceed with model loading because the IOHandler provided ' + + 'does not have the `load` method implemented.'); + } + const loadResult = this.handler.load(); + if (isPromise(loadResult)) { + return loadResult.then(artifacts => { + if (artifacts.getWeightStream == null) { + return this.loadSync(artifacts); + } + return this.loadStreaming(artifacts); + }); + } + return this.loadSync(loadResult); + } + /** + * Synchronously construct the in memory weight map and + * compile the inference graph. + * + * @doc {heading: 'Models', subheading: 'Classes', ignoreCI: true} + */ + loadSync(artifacts) { + const weightMap = this.io.decodeWeights(artifacts.weightData, artifacts.weightSpecs); + return this.loadWithWeightMap(artifacts, weightMap); + } + async loadStreaming(artifacts) { + if (artifacts.getWeightStream == null) { + throw new Error('Model artifacts missing streamWeights function'); + } + const weightMap = await decodeWeightsStream(artifacts.getWeightStream(), artifacts.weightSpecs); + return this.loadWithWeightMap(artifacts, weightMap); + } + loadWithWeightMap(artifacts, weightMap) { + this.artifacts = artifacts; + const graph = this.artifacts.modelTopology; + let signature = this.artifacts.signature; + if (this.artifacts.userDefinedMetadata != null) { + const metadata = this.artifacts.userDefinedMetadata; + if (metadata.signature != null) { + signature = metadata.signature; + } + if (metadata.structuredOutputKeys != null) { + this.structuredOutputKeys = metadata.structuredOutputKeys; + } + } + this.signature = signature; + this.version = `${graph.versions.producer}.${graph.versions.minConsumer}`; + this.executor = new GraphExecutor(OperationMapper.Instance.transformGraph(graph, this.signature)); + this.executor.weightMap = this.convertTensorMapToTensorsMap(weightMap); + // Attach a model-level resourceManager to each executor to share resources, + // such as `HashTable`. + this.executor.resourceManager = this.resourceManager; + if (artifacts.modelInitializer != null && + artifacts.modelInitializer.node != null) { + const initializer = OperationMapper.Instance.transformGraph(artifacts.modelInitializer); + this.initializer = new GraphExecutor(initializer); + this.initializer.weightMap = this.executor.weightMap; + // Attach a model-level resourceManager to the initializer, the + // hashTables created from when executing the initializer will be stored + // in the resourceManager. + this.initializer.resourceManager = this.resourceManager; + this.initializerSignature = artifacts.initializerSignature; + } + return true; + } + /** + * Save the configuration and/or weights of the GraphModel. + * + * An `IOHandler` is an object that has a `save` method of the proper + * signature defined. The `save` method manages the storing or + * transmission of serialized data ("artifacts") that represent the + * model's topology and weights onto or via a specific medium, such as + * file downloads, local storage, IndexedDB in the web browser and HTTP + * requests to a server. TensorFlow.js provides `IOHandler` + * implementations for a number of frequently used saving mediums, such as + * `tf.io.browserDownloads` and `tf.io.browserLocalStorage`. See `tf.io` + * for more details. + * + * This method also allows you to refer to certain types of `IOHandler`s + * as URL-like string shortcuts, such as 'localstorage://' and + * 'indexeddb://'. + * + * Example 1: Save `model`'s topology and weights to browser [local + * storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage); + * then load it back. + * + * ```js + * const modelUrl = + * 'https://storage.googleapis.com/tfjs-models/savedmodel/mobilenet_v2_1.0_224/model.json'; + * const model = await tf.loadGraphModel(modelUrl); + * const zeros = tf.zeros([1, 224, 224, 3]); + * model.predict(zeros).print(); + * + * const saveResults = await model.save('localstorage://my-model-1'); + * + * const loadedModel = await tf.loadGraphModel('localstorage://my-model-1'); + * console.log('Prediction from loaded model:'); + * model.predict(zeros).print(); + * ``` + * + * @param handlerOrURL An instance of `IOHandler` or a URL-like, + * scheme-based string shortcut for `IOHandler`. + * @param config Options for saving the model. + * @returns A `Promise` of `SaveResult`, which summarizes the result of + * the saving, such as byte sizes of the saved artifacts for the model's + * topology and weight values. + * + * @doc {heading: 'Models', subheading: 'Classes', ignoreCI: true} + */ + async save(handlerOrURL, config) { + if (typeof handlerOrURL === 'string') { + const handlers = this.io.getSaveHandlers(handlerOrURL); + if (handlers.length === 0) { + throw new Error(`Cannot find any save handlers for URL '${handlerOrURL}'`); + } + else if (handlers.length > 1) { + throw new Error(`Found more than one (${handlers.length}) save handlers for ` + + `URL '${handlerOrURL}'`); + } + handlerOrURL = handlers[0]; + } + if (handlerOrURL.save == null) { + throw new Error('GraphModel.save() cannot proceed because the IOHandler ' + + 'provided does not have the `save` attribute defined.'); + } + return handlerOrURL.save(this.artifacts); + } + addStructuredOutputNames(outputTensors) { + if (this.structuredOutputKeys) { + const outputTensorsArray = outputTensors instanceof Tensor ? [outputTensors] : outputTensors; + const outputTensorMap = {}; + outputTensorsArray.forEach((outputTensor, i) => outputTensorMap[this.structuredOutputKeys[i]] = + outputTensor); + return outputTensorMap; + } + return outputTensors; + } + /** + * Execute the inference for the input tensors. + * + * @param input The input tensors, when there is single input for the model, + * inputs param should be a `tf.Tensor`. For models with multiple inputs, + * inputs params should be in either `tf.Tensor`[] if the input order is + * fixed, or otherwise NamedTensorMap format. + * + * For model with multiple inputs, we recommend you use NamedTensorMap as the + * input type, if you use `tf.Tensor`[], the order of the array needs to + * follow the + * order of inputNodes array. @see {@link GraphModel.inputNodes} + * + * You can also feed any intermediate nodes using the NamedTensorMap as the + * input type. For example, given the graph + * InputNode => Intermediate => OutputNode, + * you can execute the subgraph Intermediate => OutputNode by calling + * model.execute('IntermediateNode' : tf.tensor(...)); + * + * This is useful for models that uses tf.dynamic_rnn, where the intermediate + * state needs to be fed manually. + * + * For batch inference execution, the tensors for each input need to be + * concatenated together. For example with mobilenet, the required input shape + * is [1, 244, 244, 3], which represents the [batch, height, width, channel]. + * If we are provide a batched data of 100 images, the input tensor should be + * in the shape of [100, 244, 244, 3]. + * + * @param config Prediction configuration for specifying the batch size. + * Currently the batch size option is ignored for graph model. + * + * @returns Inference result tensors. If the model is converted and it + * originally had structured_outputs in tensorflow, then a NamedTensorMap + * will be returned matching the structured_outputs. If no structured_outputs + * are present, the output will be single `tf.Tensor` if the model has single + * output node, otherwise Tensor[]. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + predict(inputs, config) { + const outputTensors = this.execute(inputs, this.outputNodes); + return this.addStructuredOutputNames(outputTensors); + } + /** + * Execute the inference for the input tensors in async fashion, use this + * method when your model contains control flow ops. + * + * @param input The input tensors, when there is single input for the model, + * inputs param should be a `tf.Tensor`. For models with mutliple inputs, + * inputs params should be in either `tf.Tensor`[] if the input order is + * fixed, or otherwise NamedTensorMap format. + * + * For model with multiple inputs, we recommend you use NamedTensorMap as the + * input type, if you use `tf.Tensor`[], the order of the array needs to + * follow the + * order of inputNodes array. @see {@link GraphModel.inputNodes} + * + * You can also feed any intermediate nodes using the NamedTensorMap as the + * input type. For example, given the graph + * InputNode => Intermediate => OutputNode, + * you can execute the subgraph Intermediate => OutputNode by calling + * model.execute('IntermediateNode' : tf.tensor(...)); + * + * This is useful for models that uses tf.dynamic_rnn, where the intermediate + * state needs to be fed manually. + * + * For batch inference execution, the tensors for each input need to be + * concatenated together. For example with mobilenet, the required input shape + * is [1, 244, 244, 3], which represents the [batch, height, width, channel]. + * If we are provide a batched data of 100 images, the input tensor should be + * in the shape of [100, 244, 244, 3]. + * + * @param config Prediction configuration for specifying the batch size. + * Currently the batch size option is ignored for graph model. + * + * @returns A Promise of inference result tensors. If the model is converted + * and it originally had structured_outputs in tensorflow, then a + * NamedTensorMap will be returned matching the structured_outputs. If no + * structured_outputs are present, the output will be single `tf.Tensor` if + * the model has single output node, otherwise Tensor[]. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + async predictAsync(inputs, config) { + const outputTensors = await this.executeAsync(inputs, this.outputNodes); + return this.addStructuredOutputNames(outputTensors); + } + normalizeInputs(inputs) { + var _a; + if (!(inputs instanceof Tensor) && !Array.isArray(inputs)) { + // The input is already a NamedTensorMap. + const signatureInputs = (_a = this.signature) === null || _a === void 0 ? void 0 : _a.inputs; + if (signatureInputs != null) { + for (const input in signatureInputs) { + const tensor = signatureInputs[input]; + if (tensor.resourceId != null) { + inputs[input] = this.resourceIdToCapturedInput[tensor.resourceId]; + } + } + } + return inputs; + } + inputs = Array.isArray(inputs) ? inputs : [inputs]; + const numCapturedInputs = Object.keys(this.resourceIdToCapturedInput).length; + if (inputs.length + numCapturedInputs !== this.inputNodes.length) { + throw new Error(`Input tensor count mismatch, the graph model has ${this.inputNodes.length - + numCapturedInputs} non-resource placeholders, while there are ${inputs.length} input tensors provided.`); + } + let inputIndex = 0; + return this.inputNodes.reduce((map, inputName) => { + var _a, _b, _c; + const resourceId = (_c = (_b = (_a = this.signature) === null || _a === void 0 ? void 0 : _a.inputs) === null || _b === void 0 ? void 0 : _b[inputName]) === null || _c === void 0 ? void 0 : _c.resourceId; + if (resourceId != null) { + map[inputName] = this.resourceIdToCapturedInput[resourceId]; + } + else { + map[inputName] = inputs[inputIndex++]; + } + return map; + }, {}); + } + normalizeOutputs(outputs) { + outputs = outputs || this.outputNodes; + return !Array.isArray(outputs) ? [outputs] : outputs; + } + executeInitializerGraph() { + if (this.initializer == null) { + return []; + } + if (this.initializerSignature == null) { + return this.initializer.execute({}, []); + } + else { + return this.initializer.execute({}, Object.keys(this.initializerSignature.outputs)); + } + } + async executeInitializerGraphAsync() { + if (this.initializer == null) { + return []; + } + if (this.initializerSignature == null) { + return this.initializer.executeAsync({}, []); + } + else { + return this.initializer.executeAsync({}, Object.keys(this.initializerSignature.outputs)); + } + } + setResourceIdToCapturedInput(outputs) { + this.resourceIdToCapturedInput = {}; + if (this.initializerSignature) { + const signatureOutputs = this.initializerSignature.outputs; + const outputNames = Object.keys(signatureOutputs); + for (let i = 0; i < outputNames.length; i++) { + const outputName = outputNames[i]; + const tensorInfo = signatureOutputs[outputName]; + this.resourceIdToCapturedInput[tensorInfo.resourceId] = outputs[i]; + } + } + } + /** + * Executes inference for the model for given input tensors. + * @param inputs tensor, tensor array or tensor map of the inputs for the + * model, keyed by the input node names. + * @param outputs output node name from the TensorFlow model, if no + * outputs are specified, the default outputs of the model would be used. + * You can inspect intermediate nodes of the model by adding them to the + * outputs array. + * + * @returns A single tensor if provided with a single output or no outputs + * are provided and there is only one default output, otherwise return a + * tensor array. The order of the tensor array is the same as the outputs + * if provided, otherwise the order of outputNodes attribute of the model. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + execute(inputs, outputs) { + if (this.resourceIdToCapturedInput == null) { + this.setResourceIdToCapturedInput(this.executeInitializerGraph()); + } + inputs = this.normalizeInputs(inputs); + outputs = this.normalizeOutputs(outputs); + const result = this.executor.execute(inputs, outputs); + return result.length > 1 ? result : result[0]; + } + /** + * Executes inference for the model for given input tensors in async + * fashion, use this method when your model contains control flow ops. + * @param inputs tensor, tensor array or tensor map of the inputs for the + * model, keyed by the input node names. + * @param outputs output node name from the TensorFlow model, if no outputs + * are specified, the default outputs of the model would be used. You can + * inspect intermediate nodes of the model by adding them to the outputs + * array. + * + * @returns A Promise of single tensor if provided with a single output or + * no outputs are provided and there is only one default output, otherwise + * return a tensor map. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + async executeAsync(inputs, outputs) { + if (this.resourceIdToCapturedInput == null) { + this.setResourceIdToCapturedInput(await this.executeInitializerGraphAsync()); + } + inputs = this.normalizeInputs(inputs); + outputs = this.normalizeOutputs(outputs); + const result = await this.executor.executeAsync(inputs, outputs); + return result.length > 1 ? result : result[0]; + } + /** + * Get intermediate tensors for model debugging mode (flag + * KEEP_INTERMEDIATE_TENSORS is true). + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + getIntermediateTensors() { + return this.executor.getIntermediateTensors(); + } + /** + * Dispose intermediate tensors for model debugging mode (flag + * KEEP_INTERMEDIATE_TENSORS is true). + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + disposeIntermediateTensors() { + this.executor.disposeIntermediateTensors(); + } + convertTensorMapToTensorsMap(map) { + return Object.keys(map).reduce((newMap, key) => { + newMap[key] = [map[key]]; + return newMap; + }, {}); + } + /** + * Releases the memory used by the weight tensors and resourceManager. + * + * @doc {heading: 'Models', subheading: 'Classes'} + */ + dispose() { + this.executor.dispose(); + if (this.initializer) { + this.initializer.dispose(); + if (this.resourceIdToCapturedInput) { + dispose(this.resourceIdToCapturedInput); + } + } + this.resourceManager.dispose(); + } + } + /** + * Load a graph model given a URL to the model definition. + * + * Example of loading MobileNetV2 from a URL and making a prediction with a + * zeros input: + * + * ```js + * const modelUrl = + * 'https://storage.googleapis.com/tfjs-models/savedmodel/mobilenet_v2_1.0_224/model.json'; + * const model = await tf.loadGraphModel(modelUrl); + * const zeros = tf.zeros([1, 224, 224, 3]); + * model.predict(zeros).print(); + * ``` + * + * Example of loading MobileNetV2 from a TF Hub URL and making a prediction + * with a zeros input: + * + * ```js + * const modelUrl = + * 'https://tfhub.dev/google/imagenet/mobilenet_v2_140_224/classification/2'; + * const model = await tf.loadGraphModel(modelUrl, {fromTFHub: true}); + * const zeros = tf.zeros([1, 224, 224, 3]); + * model.predict(zeros).print(); + * ``` + * @param modelUrl The url or an `io.IOHandler` that loads the model. + * @param options Options for the HTTP request, which allows to send + * credentials + * and custom headers. + * + * @doc {heading: 'Models', subheading: 'Loading'} + */ + async function loadGraphModel(modelUrl, options = {}, tfio = io) { + if (modelUrl == null) { + throw new Error('modelUrl in loadGraphModel() cannot be null. Please provide a url ' + + 'or an IOHandler that loads the model'); + } + if (options == null) { + options = {}; + } + if (options.fromTFHub && typeof modelUrl === 'string') { + modelUrl = getTFHubUrl(modelUrl); + } + const model = new GraphModel(modelUrl, options, tfio); + await model.load(); + return model; + } + /** + * Load a graph model given a synchronous IO handler with a 'load' method. + * + * @param modelSource The `io.IOHandlerSync` that loads the model, or the + * `io.ModelArtifacts` that encode the model, or a tuple of + * `[io.ModelJSON, ArrayBuffer]` of which the first element encodes the + * model and the second contains the weights. + * + * @doc {heading: 'Models', subheading: 'Loading'} + */ + function loadGraphModelSync(modelSource) { + if (modelSource == null) { + throw new Error('modelUrl in loadGraphModelSync() cannot be null. Please provide ' + + 'model artifacts or an IOHandler that loads the model'); + } + let ioHandler; + if (modelSource instanceof Array) { + const [modelJSON, weights] = modelSource; + if (!modelJSON) { + throw new Error('modelJSON must be the first element of the array'); + } + if (!weights || !(weights instanceof ArrayBuffer)) { + throw new Error('An ArrayBuffer of weights must be the second element of' + + ' the array'); + } + if (!('modelTopology' in modelJSON)) { + throw new Error('Model JSON is missing \'modelTopology\''); + } + if (!('weightsManifest' in modelJSON)) { + throw new Error('Model JSON is missing \'weightsManifest\''); + } + const weightSpecs = getWeightSpecs(modelJSON.weightsManifest); + const modelArtifacts = getModelArtifactsForJSONSync(modelJSON, weightSpecs, weights); + ioHandler = fromMemorySync(modelArtifacts); + } + else if ('load' in modelSource) { + // Then modelSource is already an IOHandlerSync. + ioHandler = modelSource; + } + else if ('modelTopology' in modelSource && 'weightSpecs' in modelSource && + 'weightData' in modelSource) { + // modelSource is of type ModelArtifacts. + ioHandler = fromMemorySync(modelSource); + } + else { + throw new Error('Unknown model format'); + } + const model = new GraphModel(ioHandler); + model.load(); + return model; + } + function getTFHubUrl(modelUrl) { + if (!modelUrl.endsWith('/')) { + modelUrl = (modelUrl) + '/'; + } + return `${modelUrl}${DEFAULT_MODEL_NAME}${TFHUB_SEARCH_PARAM}`; + } + + /** @license See the LICENSE file. */ + // This code is auto-generated, do not modify this file! + const version$5 = '4.22.0'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * Apply a mapping function to a nested structure in a recursive manner. + * + * The result of the mapping is an object with the same nested structure (i.e., + * of arrays and dicts) as the input, except that some subtrees are replaced, + * according to the results of the mapping function. + * + * Mappings are memoized. Thus, if the nested structure contains the same + * object in multiple positions, the output will contain the same mapped object + * in those positions. Cycles are not supported, however. + * + * @param input: The object to which to apply the mapping function. + * @param mapFn: A function that expects a single node of the object tree, and + * returns a `DeepMapResult`. The `DeepMapResult` either provides a + * replacement value for that node (i.e., replacing the subtree), or indicates + * that the node should be processed recursively. + */ + function deepMap(input, mapFn) { + return deepMapInternal(input, mapFn); + } + /** + * @param seen: A Map of known object mappings (i.e., memoized results of + * `mapFn()`) + * @param containedIn: An set containing objects on the reference path currently + * being processed (used to detect cycles). + */ + function deepMapInternal(input, mapFn, seen = new Map(), containedIn = new Set()) { + if (input == null) { + return null; + } + if (typeof Blob === 'function' && input instanceof Blob) { + return input.slice(); + } + if (containedIn.has(input)) { + throw new Error('Circular references are not supported.'); + } + if (seen.has(input)) { + return seen.get(input); + } + const result = mapFn(input); + if (result.recurse && result.value !== null) { + throw new Error('A deep map function may not return both a value and recurse=true.'); + } + if (!result.recurse) { + seen.set(input, result.value); + return result.value; + } + else if (isIterable(input)) { + // tslint:disable-next-line:no-any + const mappedIterable = Array.isArray(input) ? [] : {}; + containedIn.add(input); + for (const k in input) { + const child = input[k]; + const childResult = deepMapInternal(child, mapFn, seen, containedIn); + mappedIterable[k] = childResult; + } + containedIn.delete(input); + if (input.__proto__) { + mappedIterable.__proto__ = input.__proto__; + } + return mappedIterable; + } + else { + throw new Error(`Can't recurse into non-iterable type: ${input}`); + } + } + // TODO(soergel, kangyizhang) Reconsider naming of deepZip() to avoid confusion + // with zip() + /** + * Zip nested structures together in a recursive manner. + * + * This has the effect of transposing or pivoting data, e.g. converting it from + * a row-major representation to a column-major representation. + * + * For example, `deepZip([{a: 1, b: 2}, {a: 3, b: 4}])` returns + * `{a: [1, 3], b: [2, 4]}`. + * + * The inputs should all have the same nested structure (i.e., of arrays and + * dicts). The result is a single object with the same nested structure, where + * the leaves are arrays collecting the values of the inputs at that location + * (or, optionally, the result of a custom function applied to those arrays). + * + * @param inputs: An array of the objects to zip together. + * @param zipFn: (optional) A function that expects an array of elements at a + * single node of the object tree, and returns a `DeepMapResult`. The + * `DeepMapResult` either provides a result value for that node (i.e., + * representing the subtree), or indicates that the node should be processed + * recursively. The default zipFn recurses as far as possible and places + * arrays at the leaves. + */ + function deepZip(inputs, zipFn = zipToList) { + return deepZipInternal(inputs, zipFn); + } + /** + * @param containedIn: An set containing objects on the reference path currently + * being processed (used to detect cycles). + */ + function deepZipInternal(inputs, zipFn, containedIn = new Set()) { + // The recursion follows the structure of input 0; it's assumed that all the + // other inputs have the same structure. + const input = inputs[0]; + if (containedIn.has(input)) { + throw new Error('Circular references are not supported.'); + } + const result = zipFn(inputs); + if (result.recurse && result.value !== null) { + throw new Error('A deep zip function may not return both a value and recurse=true.'); + } + if (!result.recurse) { + return result.value; + } + else if (isIterable(input)) { + // tslint:disable-next-line:no-any + const mappedIterable = Array.isArray(input) ? [] : {}; + containedIn.add(input); + for (const k in input) { + const children = inputs.map(x => x[k]); + const childResult = deepZipInternal(children, zipFn, containedIn); + mappedIterable[k] = childResult; + } + containedIn.delete(input); + return mappedIterable; + } + else { + throw new Error(`Can't recurse into non-iterable type: ${input}`); + } + } + // tslint:disable-next-line:no-any + function zipToList(x) { + if (x === null) { + return null; + } + // TODO(soergel): validate array type? + if (isIterable(x[0])) { + return { value: null, recurse: true }; + } + else { + return { value: x, recurse: false }; + } + } + /** + * Apply an async mapping function to a nested structure in a recursive manner. + * + * This first creates a nested structure of Promises, and then awaits all of + * those, resulting in a single Promise for a resolved nested structure. + * + * The result of the mapping is an object with the same nested structure (i.e., + * of arrays and dicts) as the input, except that some subtrees are replaced, + * according to the results of the mapping function. + * + * Mappings are memoized. Thus, if the nested structure contains the same + * object in multiple positions, the output will contain the same mapped object + * in those positions. Cycles are not supported, however. + * + * @param input: The object to which to apply the mapping function. + * @param mapFn: A function that expects a single node of the object tree, and + * returns a `DeepMapAsyncResult`. The `DeepMapAsyncResult` either provides + * a `Promise` for a replacement value for that node (i.e., replacing the + * subtree), or indicates that the node should be processed recursively. Note + * that the decision whether or not to recurse must be made immediately; only + * the mapped value may be promised. + */ + async function deepMapAndAwaitAll(input, mapFn) { + const seen = new Map(); + // First do a normal deepMap, collecting Promises in 'seen' as a side effect. + deepMapInternal(input, mapFn, seen); + // Replace the Promises in 'seen' in place. + // Note TypeScript provides no async map iteration, and regular map iteration + // is broken too, so sadly we have to do Array.from() to make it work. + // (There's no advantage to Promise.all(), and that would be tricky anyway.) + for (const key of Array.from(seen.keys())) { + const value = seen.get(key); + if (isPromise(value)) { + const mappedValue = await value; + seen.set(key, mappedValue); + } + } + // Normal deepMap again, this time filling in the resolved values. + // It's unfortunate that we have to do two passes. + // TODO(soergel): test performance and think harder about a fast solution. + const result = deepMapInternal(input, mapFn, seen); + return result; + } + /** + * Determine whether the argument is iterable. + * + * @returns true if the argument is an array or any non-Tensor object. + */ + // tslint:disable-next-line:no-any + function isIterable(obj) { + let isTextDecoder = false; + if (env().get('IS_BROWSER')) { + isTextDecoder = obj instanceof TextDecoder; + } + else { + // tslint:disable-next-line:no-require-imports + const { StringDecoder } = require('string_decoder'); + isTextDecoder = obj instanceof StringDecoder; + } + return obj != null && (!ArrayBuffer.isView(obj)) && + (Array.isArray(obj) || + (typeof obj === 'object' && !(obj instanceof Tensor) && + !(obj instanceof Promise) && !isTextDecoder)); + } + /** + * Determine whether the argument can be converted to Tensor. + * + * Tensors, primitives, arrays, and TypedArrays all qualify; anything else does + * not. + * + * @returns true if the argument can be converted to Tensor. + */ + // tslint:disable-next-line:no-any + function canTensorify(obj) { + return obj == null || isPrimitive(obj) || Array.isArray(obj) || + (typeof obj === 'object' && (obj instanceof Tensor)) || + isTypedArray(obj); + } + /** + * Returns true if the given `value` is a primitive type. Otherwise returns + * false. This is equivalant to node util.isPrimitive + */ + function isPrimitive(value) { + return (value === null || + (typeof value !== 'object' && typeof value !== 'function')); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + function deepClone(container) { + return deepMap(container, cloneIfTensor); + } + // tslint:disable-next-line: no-any + function cloneIfTensor(item) { + if (item instanceof Tensor) { + return ({ value: item.clone(), recurse: false }); + } + else if (isIterable(item)) { + return { value: null, recurse: true }; + } + else { + return { value: item, recurse: false }; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * A ring buffer, providing O(1) FIFO, LIFO, and related operations. + */ + class RingBuffer { + /** + * Constructs a `RingBuffer`. + * @param capacity The number of items that the buffer can accomodate. + */ + constructor(capacity) { + this.capacity = capacity; + // Note we store the indices in the range 0 <= index < 2*capacity. + // This allows us to distinguish the full from the empty case. + // See https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/ + this.begin = 0; // inclusive + this.end = 0; // exclusive + if (capacity == null) { + throw new RangeError('Can\'t create a ring buffer of unknown capacity.'); + } + if (capacity < 1) { + throw new RangeError('Can\'t create ring buffer of capacity < 1.'); + } + this.data = new Array(capacity); + this.doubledCapacity = 2 * capacity; + } + /** + * Map any index into the range 0 <= index < 2*capacity. + */ + wrap(index) { + // don't trust % on negative numbers + while (index < 0) { + index += this.doubledCapacity; + } + return index % this.doubledCapacity; + } + get(index) { + if (index < 0) { + throw new RangeError('Can\'t get item at a negative index.'); + } + return this.data[index % this.capacity]; + } + set(index, value) { + if (index < 0) { + throw new RangeError('Can\'t set item at a negative index.'); + } + this.data[index % this.capacity] = value; + } + /** + * Returns the current number of items in the buffer. + */ + length() { + let length = this.end - this.begin; + if (length < 0) { + length = this.doubledCapacity + length; + } + return length; + } + /** + * Reports whether the buffer is full. + * @returns true if the number of items in the buffer equals its capacity, and + * false otherwise. + */ + isFull() { + return this.length() === this.capacity; + } + /** + * Reports whether the buffer is empty. + * @returns true if the number of items in the buffer equals zero, and + * false otherwise. + */ + isEmpty() { + return this.length() === 0; + } + /** + * Adds an item to the end of the buffer. + */ + push(value) { + if (this.isFull()) { + throw new RangeError('Ring buffer is full.'); + } + this.set(this.end, value); + this.end = this.wrap(this.end + 1); + } + /** + * Adds many items to the end of the buffer, in order. + */ + pushAll(values) { + for (const value of values) { + this.push(value); + } + } + /** + * Removes and returns the last item in the buffer. + */ + pop() { + if (this.isEmpty()) { + throw new RangeError('Ring buffer is empty.'); + } + this.end = this.wrap(this.end - 1); + const result = this.get(this.end); + this.set(this.end, undefined); + return result; + } + /** + * Adds an item to the beginning of the buffer. + */ + unshift(value) { + if (this.isFull()) { + throw new RangeError('Ring buffer is full.'); + } + this.begin = this.wrap(this.begin - 1); + this.set(this.begin, value); + } + /** + * Removes and returns the first item in the buffer. + */ + shift() { + if (this.isEmpty()) { + throw new RangeError('Ring buffer is empty.'); + } + const result = this.get(this.begin); + this.set(this.begin, undefined); + this.begin = this.wrap(this.begin + 1); + return result; + } + /** + * Removes and returns a specific item in the buffer, and moves the last item + * to the vacated slot. This is useful for implementing a shuffling stream. + * Note that this operation necessarily scrambles the original order. + * + * @param relativeIndex: the index of the item to remove, relative to the + * first item in the buffer (e.g., hiding the ring nature of the underlying + * storage). + */ + shuffleExcise(relativeIndex) { + if (this.isEmpty()) { + throw new RangeError('Ring buffer is empty.'); + } + const index = this.wrap(this.begin + relativeIndex); + const result = this.get(index); + this.set(index, this.pop()); + return result; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + class GrowingRingBuffer extends RingBuffer { + /** + * Constructs a `GrowingRingBuffer`. + */ + constructor() { + super(GrowingRingBuffer.INITIAL_CAPACITY); + } + isFull() { + return false; + } + push(value) { + if (super.isFull()) { + this.expand(); + } + super.push(value); + } + unshift(value) { + if (super.isFull()) { + this.expand(); + } + super.unshift(value); + } + /** + * Doubles the capacity of the buffer. + */ + expand() { + const newCapacity = this.capacity * 2; + const newData = new Array(newCapacity); + const len = this.length(); + // Rotate the buffer to start at index 0 again, since we can't just + // allocate more space at the end. + for (let i = 0; i < len; i++) { + newData[i] = this.get(this.wrap(this.begin + i)); + } + this.data = newData; + this.capacity = newCapacity; + this.doubledCapacity = 2 * this.capacity; + this.begin = 0; + this.end = len; + } + } + GrowingRingBuffer.INITIAL_CAPACITY = 32; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + // Here we implement a simple asynchronous iterator. + // This lets us avoid using either third-party stream libraries or + // recent TypeScript language support requiring polyfills. + /** + * Create a `LazyIterator` from an array of items. + */ + function iteratorFromItems(items) { + return new ArrayIterator(items); + } + /** + * Create a `LazyIterator` of incrementing integers. + */ + function iteratorFromIncrementing(start) { + let i = start; + return iteratorFromFunction(() => ({ value: i++, done: false })); + } + /** + * Create a `LazyIterator` from a function. + * + * ```js + * let i = -1; + * const func = () => + * ++i < 5 ? {value: i, done: false} : {value: null, done: true}; + * const iter = tf.data.iteratorFromFunction(func); + * await iter.forEachAsync(e => console.log(e)); + * ``` + * + * @param func A function that produces data on each call. + */ + function iteratorFromFunction(func) { + return new FunctionCallIterator(func); + } + /** + * Create a `LazyIterator` by concatenating underlying streams, which are + * themselves provided as a stream. + * + * This can also be thought of as a "stream flatten" operation. + * + * @param baseIterators A stream of streams to be concatenated. + * @param baseErrorHandler An optional function that can intercept `Error`s + * raised during a `next()` call on the base stream. This function can decide + * whether the error should be propagated, whether the error should be + * ignored, or whether the base stream should be terminated. + */ + function iteratorFromConcatenated(baseIterators, baseErrorHandler) { + return new ChainedIterator(baseIterators, baseErrorHandler); + } + /** + * Create a `LazyIterator` by concatenating streams produced by calling a + * stream-generating function a given number of times. + * + * Since a `LazyIterator` is read-once, it cannot be repeated, but this + * function can be used to achieve a similar effect: + * + * LazyIterator.ofConcatenatedFunction(() => new MyIterator(), 6); + * + * @param iteratorFunc: A function that produces a new stream on each call. + * @param count: The number of times to call the function. + * @param baseErrorHandler An optional function that can intercept `Error`s + * raised during a `next()` call on the base stream. This function can decide + * whether the error should be propagated, whether the error should be + * ignored, or whether the base stream should be terminated. + */ + function iteratorFromConcatenatedFunction(iteratorFunc, count, baseErrorHandler) { + return iteratorFromConcatenated(iteratorFromFunction(iteratorFunc).take(count), baseErrorHandler); + } + /** + * Create a `LazyIterator` by zipping together an array, dict, or nested + * structure of `LazyIterator`s (and perhaps additional constants). + * + * The underlying streams must provide elements in a consistent order such + * that they correspond. + * + * Typically, the underlying streams should have the same number of + * elements. If they do not, the behavior is determined by the + * `mismatchMode` argument. + * + * The nested structure of the `iterators` argument determines the + * structure of elements in the resulting iterator. + * + * @param iterators: An array or object containing LazyIterators at the + * leaves. + * @param mismatchMode: Determines what to do when one underlying iterator + * is exhausted before the others. `ZipMismatchMode.FAIL` (the default) + * causes an error to be thrown in this case. `ZipMismatchMode.SHORTEST` + * causes the zipped iterator to terminate with the furst underlying + * streams, so elements remaining on the longer streams are ignored. + * `ZipMismatchMode.LONGEST` causes the zipped stream to continue, filling + * in nulls for the exhausted streams, until all streams are exhausted. + */ + function iteratorFromZipped(iterators, mismatchMode = ZipMismatchMode.FAIL) { + return new ZipIterator(iterators, mismatchMode); + } + /** + * An asynchronous iterator, providing lazy access to a potentially + * unbounded stream of elements. + * + * Iterator can be obtained from a dataset: + * `const iter = await dataset.iterator();` + */ + class LazyIterator { + /** + * Collect all remaining elements of a bounded stream into an array. + * Obviously this will succeed only for small streams that fit in memory. + * Useful for testing. + * + * @returns A Promise for an array of stream elements, which will resolve + * when the stream is exhausted. + */ + async toArray() { + const result = []; + let x = await this.next(); + while (!x.done) { + result.push(x.value); + x = await this.next(); + } + return result; + } + /** + * Collect all elements of this dataset into an array with prefetching 100 + * elements. This is useful for testing, because the prefetch changes the + * order in which the Promises are resolved along the processing pipeline. + * This may help expose bugs where results are dependent on the order of + * Promise resolution rather than on the logical order of the stream (i.e., + * due to hidden mutable state). + * + * @returns A Promise for an array of stream elements, which will resolve + * when the stream is exhausted. + */ + async toArrayForTest() { + const stream = this.prefetch(100); + const result = []; + let x = await stream.next(); + while (!x.done) { + result.push(x.value); + x = await stream.next(); + } + return result; + } + /** + * Draw items from the stream until it is exhausted. + * + * This can be useful when the stream has side effects but no output. In + * that case, calling this function guarantees that the stream will be + * fully processed. + */ + async resolveFully() { + let x = await this.next(); + while (!x.done) { + x = await this.next(); + } + } + /** + * Draw items from the stream until it is exhausted, or a predicate fails. + * + * This can be useful when the stream has side effects but no output. In + * that case, calling this function guarantees that the stream will be + * fully processed. + */ + async resolveWhile(predicate) { + let x = await this.next(); + let shouldContinue = predicate(x.value); + while ((!x.done) && shouldContinue) { + x = await this.next(); + shouldContinue = predicate(x.value); + } + } + /** + * Handles errors thrown on this stream using a provided handler function. + * + * @param handler A function that handles any `Error` thrown during a `next()` + * call and returns true if the stream should continue (dropping the failed + * call) or false if the stream should quietly terminate. If the handler + * itself throws (or rethrows) an `Error`, that will be propagated. + * + * @returns A `LazyIterator` of elements passed through from upstream, + * possibly filtering or terminating on upstream `next()` calls that + * throw an `Error`. + */ + handleErrors(handler) { + return new ErrorHandlingLazyIterator(this, handler); + } + // TODO(soergel): Implement reduce() etc. + /** + * Filters this stream according to `predicate`. + * + * @param predicate A function mapping a stream element to a boolean or a + * `Promise` for one. + * + * @returns A `LazyIterator` of elements for which the predicate was true. + */ + filter(predicate) { + return new FilterIterator(this, predicate); + } + /** + * Maps this stream through a 1-to-1 transform. + * + * @param transform A function mapping a stream element to a transformed + * element. + * + * @returns A `LazyIterator` of transformed elements. + */ + map(transform) { + return new MapIterator(this, transform); + } + /** + * Maps this stream through an async 1-to-1 transform. + * + * @param transform A function mapping a stream element to a `Promise` for a + * transformed stream element. + * + * @returns A `LazyIterator` of transformed elements. + */ + mapAsync(transform) { + return new AsyncMapIterator(this, transform); + } + /** + * Maps this stream through a 1-to-1 transform, forcing serial execution. + * + * @param transform A function mapping a stream element to a transformed + * element. + * + * @returns A `LazyIterator` of transformed elements. + */ + serialMapAsync(transform) { + return new AsyncMapIterator(this, transform).serial(); + } + /** + * Maps this stream through a 1-to-many transform. + * + * @param transform A function mapping a stream element to an array of + * transformed elements. + * + * @returns A `DataStream` of transformed elements. + */ + flatmap(transform) { + return new FlatmapIterator(this, transform); + } + /** + * Apply a function to every element of the stream. + * + * @param f A function to apply to each stream element. + */ + async forEachAsync(f) { + return this.map(f).resolveFully(); + } + /** + * Apply a function to every element of the stream, forcing serial execution. + * + * @param f A function to apply to each stream element. Should return 'true' + * to indicate that the stream should continue, or 'false' to cause it to + * terminate. + */ + async serialForEach(f) { + return this.serialMapAsync(f).resolveWhile(x => (x === true)); + } + /** + * Groups elements into batches, represented as arrays of elements. + * + * We can think of the elements of this iterator as 'rows' (even if they are + * nested structures). By the same token, consecutive values for a given + * key within the elements form a 'column'. This matches the usual sense of + * 'row' and 'column' when processing tabular data (e.g., parsing a CSV). + * + * Thus, "Row-major" means that the resulting batch is simply a collection of + * rows: `[row1, row2, row3, ...]`. This is contrast to the column-major + * form, which is needed for vectorized computation. + * + * @param batchSize The number of elements desired per batch. + * @param smallLastBatch Whether to emit the final batch when it has fewer + * than batchSize elements. Default true. + * @returns A `LazyIterator` of batches of elements, represented as arrays + * of the original element type. + */ + rowMajorBatch(batchSize, smallLastBatch = true) { + return new RowMajorBatchIterator(this, batchSize, smallLastBatch); + } + /** + * Groups elements into batches, represented in column-major form. + * + * We can think of the elements of this iterator as 'rows' (even if they are + * nested structures). By the same token, consecutive values for a given + * key within the elements form a 'column'. This matches the usual sense of + * 'row' and 'column' when processing tabular data (e.g., parsing a CSV). + * + * Thus, "column-major" means that the resulting batch is a (potentially + * nested) structure representing the columns. Each column entry, then, + * contains a collection of the values found in that column for a range of + * input elements. This representation allows for vectorized computation, in + * contrast to the row-major form. + * + * The inputs should all have the same nested structure (i.e., of arrays and + * dicts). The result is a single object with the same nested structure, + * where the leaves are arrays collecting the values of the inputs at that + * location (or, optionally, the result of a custom function applied to those + * arrays). + * + * @param batchSize The number of elements desired per batch. + * @param smallLastBatch Whether to emit the final batch when it has fewer + * than batchSize elements. Default true. + * @param zipFn: (optional) A function that expects an array of elements at a + * single node of the object tree, and returns a `DeepMapResult`. The + * `DeepMapResult` either provides a result value for that node (i.e., + * representing the subtree), or indicates that the node should be processed + * recursively. The default zipFn recurses as far as possible and places + * arrays at the leaves. + * @returns A `LazyIterator` of batches of elements, represented as an object + * with collections at the leaves. + */ + columnMajorBatch(batchSize, smallLastBatch = true, + // tslint:disable-next-line:no-any + zipFn = zipToList) { + // First collect the desired number of input elements as a row-major batch. + const rowBatches = this.rowMajorBatch(batchSize, smallLastBatch); + // Now 'rotate' or 'pivot' the data, collecting all values from each column + // in the batch (i.e., for each key within the elements) into an array. + return rowBatches.map(x => deepZip(x, zipFn)); + } + /** + * Concatenate this `LazyIterator` with another. + * + * @param iterator A `LazyIterator` to be concatenated onto this one. + * @param baseErrorHandler An optional function that can intercept `Error`s + * raised during a `next()` call on the base stream. This function can + * decide whether the error should be propagated, whether the error should + * be ignored, or whether the base stream should be terminated. + * @returns A `LazyIterator`. + */ + concatenate(iterator, baseErrorHandler) { + return new ChainedIterator(iteratorFromItems([this, iterator]), baseErrorHandler); + } + /** + * Limits this stream to return at most `count` items. + * + * @param count The maximum number of items to provide from the stream. If + * a negative or undefined value is given, the entire stream is returned + * unaltered. + */ + take(count) { + if (count < 0 || count == null) { + return this; + } + return new TakeIterator(this, count); + } + /** + * Skips the first `count` items in this stream. + * + * @param count The number of items to skip. If a negative or undefined + * value is given, the entire stream is returned unaltered. + */ + skip(count) { + if (count < 0 || count == null) { + return this; + } + return new SkipIterator(this, count); + } + /** + * Prefetch the first `bufferSize` items in this stream. + * + * Note this prefetches Promises, but makes no guarantees about when those + * Promises resolve. + * + * @param bufferSize: An integer specifying the number of elements to be + * prefetched. + */ + prefetch(bufferSize) { + return new PrefetchIterator(this, bufferSize); + } + // TODO(soergel): deep sharded shuffle, where supported + /** + * Randomly shuffles the elements of this stream. + * + * @param bufferSize: An integer specifying the number of elements from + * this stream from which the new stream will sample. + * @param seed: (Optional.) An integer specifying the random seed that + * will be used to create the distribution. + */ + shuffle(windowSize, seed) { + return new ShuffleIterator(this, windowSize, seed); + } + /** + * Force an iterator to execute serially: each next() call will await the + * prior one, so that they cannot execute concurrently. + */ + serial() { + return new SerialIterator(this); + } + } + // ============================================================================ + // The following private classes serve to implement the chainable methods + // on LazyIterator. Unfortunately they can't be placed in separate files, + // due to resulting trouble with circular imports. + // ============================================================================ + // Iterators that just extend LazyIterator directly + // ============================================================================ + class ArrayIterator extends LazyIterator { + constructor(items) { + super(); + this.items = items; + this.trav = 0; + } + summary() { + return `Array of ${this.items.length} items`; + } + async next() { + if (this.trav >= this.items.length) { + return { value: null, done: true }; + } + const item = this.items[this.trav]; + this.trav++; + return { value: deepClone(item), done: false }; + } + } + class FunctionCallIterator extends LazyIterator { + constructor(nextFn) { + super(); + this.nextFn = nextFn; + } + summary() { + return `Function call`; + } + async next() { + try { + return this.nextFn(); + } + catch (e) { + // Modify the error message but leave the stack trace intact + e.message = + `Error thrown while iterating through a dataset: ${e.message}`; + throw e; + } + } + } + class SerialIterator extends LazyIterator { + constructor(upstream) { + super(); + this.upstream = upstream; + this.lastRead = Promise.resolve({ value: null, done: false }); + } + summary() { + return `${this.upstream.summary()} -> Serial`; + } + async next() { + // This sets this.lastRead to a new Promise right away, as opposed to + // saying `await this.lastRead; this.lastRead = this.serialNext();` which + // would not work because this.nextRead would be updated only after the + // promise resolves. + this.lastRead = this.lastRead.then(() => this.serialNext()); + return this.lastRead; + } + async serialNext() { + return this.upstream.next(); + } + } + class SkipIterator extends LazyIterator { + constructor(upstream, maxCount) { + super(); + this.upstream = upstream; + this.maxCount = maxCount; + // Local state that should not be clobbered by out-of-order execution. + this.count = 0; + this.lastRead = Promise.resolve({ value: null, done: false }); + } + summary() { + return `${this.upstream.summary()} -> Skip`; + } + async next() { + // This sets this.lastRead to a new Promise right away, as opposed to + // saying `await this.lastRead; this.lastRead = this.serialNext();` which + // would not work because this.nextRead would be updated only after the + // promise resolves. + this.lastRead = this.lastRead.then(() => this.serialNext()); + return this.lastRead; + } + async serialNext() { + // TODO(soergel): consider tradeoffs of reading in parallel, eg. + // collecting next() promises in an Array and then waiting for + // Promise.all() of those. Benefit: pseudo-parallel execution. Drawback: + // maybe delayed GC. + while (this.count++ < this.maxCount) { + const skipped = await this.upstream.next(); + // short-circuit if upstream is already empty + if (skipped.done) { + return skipped; + } + dispose(skipped.value); + } + return this.upstream.next(); + } + } + class TakeIterator extends LazyIterator { + constructor(upstream, maxCount) { + super(); + this.upstream = upstream; + this.maxCount = maxCount; + this.count = 0; + } + summary() { + return `${this.upstream.summary()} -> Take`; + } + async next() { + if (this.count++ >= this.maxCount) { + return { value: null, done: true }; + } + return this.upstream.next(); + } + } + // Note this batch just groups items into row-wise element arrays. + // Rotating these to a column-wise representation happens only at the dataset + // level. + class RowMajorBatchIterator extends LazyIterator { + constructor(upstream, batchSize, enableSmallLastBatch = true) { + super(); + this.upstream = upstream; + this.batchSize = batchSize; + this.enableSmallLastBatch = enableSmallLastBatch; + this.lastRead = Promise.resolve({ value: null, done: false }); + } + summary() { + return `${this.upstream.summary()} -> RowMajorBatch`; + } + async next() { + // This sets this.lastRead to a new Promise right away, as opposed to + // saying `await this.lastRead; this.lastRead = this.serialNext();` which + // would not work because this.nextRead would be updated only after the + // promise resolves. + this.lastRead = this.lastRead.then(() => this.serialNext()); + return this.lastRead; + } + async serialNext() { + const batch = []; + while (batch.length < this.batchSize) { + const item = await this.upstream.next(); + if (item.done) { + if (this.enableSmallLastBatch && batch.length > 0) { + return { value: batch, done: false }; + } + return { value: null, done: true }; + } + batch.push(item.value); + } + return { value: batch, done: false }; + } + } + class FilterIterator extends LazyIterator { + constructor(upstream, predicate) { + super(); + this.upstream = upstream; + this.predicate = predicate; + this.lastRead = Promise.resolve({ value: null, done: false }); + } + summary() { + return `${this.upstream.summary()} -> Filter`; + } + async next() { + // This sets this.lastRead to a new Promise right away, as opposed to + // saying `await this.lastRead; this.lastRead = this.serialNext();` which + // would not work because this.nextRead would be updated only after the + // promise resolves. + this.lastRead = this.lastRead.then(() => this.serialNext()); + return this.lastRead; + } + async serialNext() { + while (true) { + const item = await this.upstream.next(); + if (item.done || this.predicate(item.value)) { + return item; + } + dispose(item.value); + } + } + } + class MapIterator extends LazyIterator { + constructor(upstream, transform) { + super(); + this.upstream = upstream; + this.transform = transform; + } + summary() { + return `${this.upstream.summary()} -> Map`; + } + async next() { + const item = await this.upstream.next(); + if (item.done) { + return { value: null, done: true }; + } + const inputTensors = getTensorsInContainer(item.value); + // Careful: the transform may mutate the item in place. + // That's why we have to remember the input Tensors above, and then + // below dispose only those that were not passed through to the output. + // Note too that the transform function is responsible for tidying + // any intermediate Tensors. Here we are concerned only about the + // inputs. + const mapped = this.transform(item.value); + const outputTensors = getTensorsInContainer(mapped); + // TODO(soergel) faster intersection + // TODO(soergel) move to tf.disposeExcept(in, out)? + for (const t of inputTensors) { + if (!isTensorInList(t, outputTensors)) { + t.dispose(); + } + } + return { value: mapped, done: false }; + } + } + class ErrorHandlingLazyIterator extends LazyIterator { + constructor(upstream, handler) { + super(); + this.upstream = upstream; + this.handler = handler; + this.count = 0; + this.lastRead = Promise.resolve({ value: null, done: false }); + } + summary() { + return `${this.upstream.summary()} -> handleErrors`; + } + async next() { + // This sets this.lastRead to a new Promise right away, as opposed to + // saying `await this.lastRead; this.lastRead = this.serialNext();` which + // would not work because this.nextRead would be updated only after the + // promise resolves. + this.lastRead = this.lastRead.then(() => this.serialNext()); + return this.lastRead; + } + async serialNext() { + while (true) { + try { + return await this.upstream.next(); + } + catch (e) { + if (!this.handler(e)) { + return { value: null, done: true }; + } + // If the handler returns true, loop and fetch the next upstream item. + // If the upstream iterator throws an endless stream of errors, and if + // the handler says to ignore them, then we loop forever here. That is + // the correct behavior-- it's up to the handler to decide when to stop. + } + } + } + } + class AsyncMapIterator extends LazyIterator { + constructor(upstream, transform) { + super(); + this.upstream = upstream; + this.transform = transform; + } + summary() { + return `${this.upstream.summary()} -> AsyncMap`; + } + async next() { + const item = await this.upstream.next(); + if (item.done) { + return { value: null, done: true }; + } + const inputTensors = getTensorsInContainer(item.value); + // Careful: the transform may mutate the item in place. + // That's why we have to remember the input Tensors above, and then + // below dispose only those that were not passed through to the output. + // Note too that the transform function is responsible for tidying + // any intermediate Tensors. Here we are concerned only about the + // inputs. + const mapped = await this.transform(item.value); + const outputTensors = getTensorsInContainer(mapped); + // TODO(soergel) faster intersection + // TODO(soergel) move to tf.disposeExcept(in, out)? + for (const t of inputTensors) { + if (!isTensorInList(t, outputTensors)) { + t.dispose(); + } + } + return { value: mapped, done: false }; + } + } + // Iterators that maintain a queue of pending items + // ============================================================================ + /** + * A base class for transforming streams that operate by maintaining an + * output queue of elements that are ready to return via next(). This is + * commonly required when the transformation is 1-to-many: A call to next() + * may trigger a call to the underlying stream, which will produce many + * mapped elements of this stream-- of which we need to return only one, so + * we have to queue the rest. + */ + class OneToManyIterator extends LazyIterator { + constructor() { + super(); + this.outputQueue = new GrowingRingBuffer(); + this.lastRead = Promise.resolve({ value: null, done: false }); + } + async next() { + // This sets this.lastRead to a new Promise right away, as opposed to + // saying `await this.lastRead; this.lastRead = this.serialNext();` which + // would not work because this.nextRead would be updated only after the + // promise resolves. + this.lastRead = this.lastRead.then(() => this.serialNext()); + return this.lastRead; + } + async serialNext() { + // Fetch so that the queue contains at least one item if possible. + // If the upstream source is exhausted, AND there are no items left in + // the output queue, then this stream is also exhausted. + while (this.outputQueue.length() === 0) { + // TODO(soergel): consider parallel reads. + if (!await this.pump()) { + return { value: null, done: true }; + } + } + return { value: this.outputQueue.shift(), done: false }; + } + } + class FlatmapIterator extends OneToManyIterator { + constructor(upstream, transform) { + super(); + this.upstream = upstream; + this.transform = transform; + } + summary() { + return `${this.upstream.summary()} -> Flatmap`; + } + async pump() { + const item = await this.upstream.next(); + if (item.done) { + return false; + } + const inputTensors = getTensorsInContainer(item.value); + // Careful: the transform may mutate the item in place. + // that's why we have to remember the input Tensors above, and then + // below dispose only those that were not passed through to the output. + // Note too that the transform function is responsible for tidying any + // intermediate Tensors. Here we are concerned only about the inputs. + const mappedArray = this.transform(item.value); + const outputTensors = getTensorsInContainer(mappedArray); + this.outputQueue.pushAll(mappedArray); + // TODO(soergel) faster intersection, and deduplicate outputTensors + // TODO(soergel) move to tf.disposeExcept(in, out)? + for (const t of inputTensors) { + if (!isTensorInList(t, outputTensors)) { + t.dispose(); + } + } + return true; + } + } + /** + * Provides a `LazyIterator` that concatenates a stream of underlying + * streams. + * + * Doing this in a concurrency-safe way requires some trickery. In + * particular, we want this stream to return the elements from the + * underlying streams in the correct order according to when next() was + * called, even if the resulting Promises resolve in a different order. + */ + class ChainedIterator extends LazyIterator { + constructor(iterators, baseErrorHandler) { + super(); + this.baseErrorHandler = baseErrorHandler; + // Strict Promise execution order: + // a next() call may not even begin until the previous one completes. + this.lastRead = null; + // Local state that should not be clobbered by out-of-order execution. + this.iterator = null; + this.moreIterators = iterators; + } + summary() { + const upstreamSummaries = 'TODO: fill in upstream of chained summaries'; + return `${upstreamSummaries} -> Chained`; + } + async next() { + this.lastRead = this.readFromChain(this.lastRead); + return this.lastRead; + } + async readFromChain(lastRead) { + // Must await on the previous read since the previous read may have advanced + // the stream of streams, from which we need to read. + // This is unfortunate since we can't parallelize reads. Which means + // prefetching of chained streams is a no-op. + // One solution is to prefetch immediately upstream of this. + await lastRead; + if (this.iterator == null) { + const iteratorResult = await this.moreIterators.next(); + if (iteratorResult.done) { + // No more streams to stream from. + return { value: null, done: true }; + } + this.iterator = iteratorResult.value; + if (this.baseErrorHandler != null) { + this.iterator = this.iterator.handleErrors(this.baseErrorHandler); + } + } + const itemResult = await this.iterator.next(); + if (itemResult.done) { + this.iterator = null; + return this.readFromChain(lastRead); + } + return itemResult; + } + } + var ZipMismatchMode; + (function (ZipMismatchMode) { + ZipMismatchMode[ZipMismatchMode["FAIL"] = 0] = "FAIL"; + ZipMismatchMode[ZipMismatchMode["SHORTEST"] = 1] = "SHORTEST"; + ZipMismatchMode[ZipMismatchMode["LONGEST"] = 2] = "LONGEST"; // use nulls for exhausted streams; use up the longest stream. + })(ZipMismatchMode || (ZipMismatchMode = {})); + /** + * Provides a `LazyIterator` that zips together an array, dict, or nested + * structure of `LazyIterator`s (and perhaps additional constants). + * + * The underlying streams must provide elements in a consistent order such + * that they correspond. + * + * Typically, the underlying streams should have the same number of + * elements. If they do not, the behavior is determined by the + * `mismatchMode` argument. + * + * The nested structure of the `iterators` argument determines the + * structure of elements in the resulting iterator. + * + * Doing this in a concurrency-safe way requires some trickery. In + * particular, we want this stream to return the elements from the + * underlying streams in the correct order according to when next() was + * called, even if the resulting Promises resolve in a different order. + * + * @param iterators: An array or object containing LazyIterators at the + * leaves. + * @param mismatchMode: Determines what to do when one underlying iterator + * is exhausted before the others. `ZipMismatchMode.FAIL` (the default) + * causes an error to be thrown in this case. `ZipMismatchMode.SHORTEST` + * causes the zipped iterator to terminate with the furst underlying + * streams, so elements remaining on the longer streams are ignored. + * `ZipMismatchMode.LONGEST` causes the zipped stream to continue, filling + * in nulls for the exhausted streams, until all streams are exhausted. + */ + class ZipIterator extends LazyIterator { + constructor(iterators, mismatchMode = ZipMismatchMode.FAIL) { + super(); + this.iterators = iterators; + this.mismatchMode = mismatchMode; + this.count = 0; + this.currentPromise = null; + } + summary() { + const upstreamSummaries = 'TODO: fill in upstream of zip summaries'; + return `{${upstreamSummaries}} -> Zip`; + } + async nextState(afterState) { + // This chaining ensures that the underlying next() are not even called + // before the previous ones have resolved. + await afterState; + // Collect underlying iterator "done" signals as a side effect in + // getNext() + let numIterators = 0; + let iteratorsDone = 0; + function getNext(container) { + if (container instanceof LazyIterator) { + const result = container.next(); + return { + value: result.then(x => { + numIterators++; + if (x.done) { + iteratorsDone++; + } + return x.value; + }), + recurse: false + }; + } + else { + return { value: null, recurse: true }; + } + } + const mapped = await deepMapAndAwaitAll(this.iterators, getNext); + if (numIterators === iteratorsDone) { + // The streams have all ended. + return { value: null, done: true }; + } + if (iteratorsDone > 0) { + switch (this.mismatchMode) { + case ZipMismatchMode.FAIL: + throw new Error('Zipped streams should have the same length. ' + + `Mismatched at element ${this.count}.`); + case ZipMismatchMode.SHORTEST: + return { value: null, done: true }; + case ZipMismatchMode.LONGEST: + default: + // Continue. The exhausted streams already produced value: null. + } + } + this.count++; + return { value: mapped, done: false }; + } + async next() { + this.currentPromise = this.nextState(this.currentPromise); + return this.currentPromise; + } + } + // Iterators that maintain a ring buffer of pending promises + // ============================================================================ + /** + * A stream that prefetches a given number of items from an upstream source, + * returning them in FIFO order. + * + * Note this prefetches Promises, but makes no guarantees about when those + * Promises resolve. + */ + class PrefetchIterator extends LazyIterator { + constructor(upstream, bufferSize) { + super(); + this.upstream = upstream; + this.bufferSize = bufferSize; + this.buffer = new RingBuffer(bufferSize); + } + summary() { + return `${this.upstream.summary()} -> Prefetch`; + } + /** + * Refill the prefetch buffer. Returns only after the buffer is full, or + * the upstream source is exhausted. + */ + refill() { + while (!this.buffer.isFull()) { + const v = this.upstream.next(); + this.buffer.push(v); + } + } + next() { + this.refill(); + // This shift will never throw an error because the buffer is always + // full after a refill. If the stream is exhausted, the buffer will be + // full of Promises that will resolve to the end-of-stream signal. + return this.buffer.shift(); + } + } + /** + * A stream that performs a sliding-window random shuffle on an upstream + * source. This is like a `PrefetchIterator` except that the items are + * returned in randomized order. Mixing naturally improves as the buffer + * size increases. + */ + class ShuffleIterator extends PrefetchIterator { + constructor(upstream, windowSize, seed) { + super(upstream, windowSize); + this.upstream = upstream; + this.windowSize = windowSize; + // Local state that should not be clobbered by out-of-order execution. + this.upstreamExhausted = false; + this.random = seedrandom.alea(seed || now().toString()); + this.lastRead = Promise.resolve({ value: null, done: false }); + } + async next() { + // This sets this.lastRead to a new Promise right away, as opposed to + // saying `await this.lastRead; this.lastRead = this.serialNext();` which + // would not work because this.nextRead would be updated only after the + // promise resolves. + this.lastRead = this.lastRead.then(() => this.serialNext()); + return this.lastRead; + } + randomInt(max) { + return Math.floor(this.random() * max); + } + chooseIndex() { + return this.randomInt(this.buffer.length()); + } + async serialNext() { + // TODO(soergel): consider performance + if (!this.upstreamExhausted) { + this.refill(); + } + while (!this.buffer.isEmpty()) { + const chosenIndex = this.chooseIndex(); + const result = await this.buffer.shuffleExcise(chosenIndex); + if (result.done) { + this.upstreamExhausted = true; + } + else { + this.refill(); + return result; + } + } + return { value: null, done: true }; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + // TODO(soergel): consider vectorized operations within the pipeline. + /** + * Represents a potentially large list of independent data elements (typically + * 'samples' or 'examples'). + * + * A 'data example' may be a primitive, an array, a map from string keys to + * values, or any nested structure of these. + * + * A `Dataset` represents an ordered collection of elements, together with a + * chain of transformations to be performed on those elements. Each + * transformation is a method of `Dataset` that returns another `Dataset`, so + * these may be chained, e.g. + * `const processedDataset = rawDataset.filter(...).map(...).batch(...)`. + * + * Data loading and transformation is done in a lazy, streaming fashion. The + * dataset may be iterated over multiple times; each iteration starts the data + * loading anew and recapitulates the transformations. + * + * A `Dataset` is typically processed as a stream of unbatched examples -- i.e., + * its transformations are applied one example at a time. Batching produces a + * new `Dataset` where each element is a batch. Batching should usually come + * last in a pipeline, because data transformations are easier to express on a + * per-example basis than on a per-batch basis. + * + * The following code examples are calling `await dataset.forEachAsync(...)` to + * iterate once over the entire dataset in order to print out the data. + * + * @doc {heading: 'Data', subheading: 'Classes', namespace: 'data'} + */ + class Dataset { + constructor() { + this.size = null; + } + // TODO(soergel): Make Datasets report whether repeated iterator() calls + // produce the same result (e.g., reading from a file) or different results + // (e.g., from the webcam). Currently we don't make this distinction but it + // could be important for the user to know. + // abstract isDeterministic(): boolean; + /** + * Groups elements into batches. + * + * It is assumed that each of the incoming dataset elements has the same + * structure -- i.e. the same set of keys at each location in an object + * hierarchy. For each key, the resulting `Dataset` provides a batched + * element collecting all of the incoming values for that key. + * + * * Incoming primitives are grouped into a 1-D Tensor. + * * Incoming Tensors are grouped into a new Tensor where the 0th axis is + * the batch dimension. + * * Incoming arrays are converted to Tensor and then batched. + * * A nested array is interpreted as an n-D Tensor, so the batched result + * has n+1 dimensions. + * * An array that cannot be converted to Tensor produces an error. + * + * If an array should not be batched as a unit, it should first be converted + * to an object with integer keys. + * + * Here are a few examples: + * + * Batch a dataset of numbers: + * ```js + * const a = tf.data.array([1, 2, 3, 4, 5, 6, 7, 8]).batch(4); + * await a.forEachAsync(e => e.print()); + * ``` + * + * Batch a dataset of arrays: + * ```js + * const b = tf.data.array([[1], [2], [3], [4], [5], [6], [7], [8]]).batch(4); + * await b.forEachAsync(e => e.print()); + * ``` + * + * Batch a dataset of objects: + * ```js + * const c = tf.data.array([{a: 1, b: 11}, {a: 2, b: 12}, {a: 3, b: 13}, + * {a: 4, b: 14}, {a: 5, b: 15}, {a: 6, b: 16}, {a: 7, b: 17}, + * {a: 8, b: 18}]).batch(4); + * await c.forEachAsync(e => { + * console.log('{'); + * for(var key in e) { + * console.log(key+':'); + * e[key].print(); + * } + * console.log('}'); + * }) + * ``` + * + * @param batchSize The number of elements desired per batch. + * @param smallLastBatch Whether to emit the final batch when it has fewer + * than batchSize elements. Default true. + * @returns A `Dataset`, from which a stream of batches can be obtained. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + batch(batchSize, smallLastBatch = true) { + const base = this; + assert$1(batchSize > 0, () => `batchSize needs to be positive, but it is + ${batchSize}`); + let size; + if (this.size === Infinity || this.size == null) { + // If the size of this dataset is infinity or null, the new size keeps the + // same. + size = this.size; + } + else if (smallLastBatch) { + // If the size of this dataset is known and include small last batch, the + // new size is full batch count plus last batch. + size = Math.ceil(this.size / batchSize); + } + else { + // If the size of this dataset is known and not include small last batch, + // the new size is full batch count. + size = Math.floor(this.size / batchSize); + } + return datasetFromIteratorFn(async () => { + return (await base.iterator()) + .columnMajorBatch(batchSize, smallLastBatch, deepBatchConcat); + }, size); + } + /** + * Concatenates this `Dataset` with another. + * + * ```js + * const a = tf.data.array([1, 2, 3]); + * const b = tf.data.array([4, 5, 6]); + * const c = a.concatenate(b); + * await c.forEachAsync(e => console.log(e)); + * ``` + * + * @param dataset A `Dataset` to be concatenated onto this one. + * @returns A `Dataset`. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + concatenate(dataset) { + const base = this; + let size; + if (this.size === Infinity || dataset.size === Infinity) { + // If the size of any of these two dataset is infinity, new size is + // infinity. + size = Infinity; + } + else if (this.size != null && dataset.size != null) { + // If the size of both datasets are known and not infinity, new size is + // sum the size of these two datasets. + size = this.size + dataset.size; + } + else { + // If neither of these two datasets has infinite size and any of these two + // datasets' size is null, the new size is null. + size = null; + } + return datasetFromIteratorFn(async () => (await base.iterator()).concatenate(await dataset.iterator()), size); + } + /** + * Filters this dataset according to `predicate`. + * + * ```js + * const a = tf.data.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + * .filter(x => x%2 === 0); + * await a.forEachAsync(e => console.log(e)); + * ``` + * + * @param predicate A function mapping a dataset element to a boolean or a + * `Promise` for one. + * + * @returns A `Dataset` of elements for which the predicate was true. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + filter(predicate) { + const base = this; + let size; + if (this.size === Infinity) { + // If the size of this dataset is infinity, new size is infinity + size = Infinity; + } + else { + // If this dataset has limited elements, new size is null because it might + // exhausted randomly. + size = null; + } + return datasetFromIteratorFn(async () => { + return (await base.iterator()).filter(x => tidy(() => predicate(x))); + }, size); + } + /** + * Apply a function to every element of the dataset. + * + * After the function is applied to a dataset element, any Tensors contained + * within that element are disposed. + * + * ```js + * const a = tf.data.array([1, 2, 3]); + * await a.forEachAsync(e => console.log(e)); + * ``` + * + * @param f A function to apply to each dataset element. + * @returns A `Promise` that resolves after all elements have been processed. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + async forEachAsync(f) { + return (await this.iterator()).forEachAsync(f); + } + /** + * Maps this dataset through a 1-to-1 transform. + * + * ```js + * const a = tf.data.array([1, 2, 3]).map(x => x*x); + * await a.forEachAsync(e => console.log(e)); + * ``` + * + * @param transform A function mapping a dataset element to a transformed + * dataset element. + * + * @returns A `Dataset` of transformed elements. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + map(transform) { + const base = this; + return datasetFromIteratorFn(async () => { + return (await base.iterator()).map(x => tidy(() => transform(x))); + }, this.size); + } + /** + * Maps this dataset through an async 1-to-1 transform. + * + * ```js + * const a = + * tf.data.array([1, 2, 3]).mapAsync(x => new Promise(function(resolve){ + * setTimeout(() => { + * resolve(x * x); + * }, Math.random()*1000 + 500); + * })); + * console.log(await a.toArray()); + * ``` + * + * @param transform A function mapping a dataset element to a `Promise` for a + * transformed dataset element. This transform is responsible for disposing + * any intermediate `Tensor`s, i.e. by wrapping its computation in + * `tf.tidy()`; that cannot be automated here (as it is in the synchronous + * `map()` case). + * + * @returns A `Dataset` of transformed elements. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + mapAsync(transform) { + const base = this; + return datasetFromIteratorFn(async () => { + return (await base.iterator()).mapAsync(transform); + }, this.size); + } + /** + * Creates a `Dataset` that prefetches elements from this dataset. + * + * @param bufferSize: An integer specifying the number of elements to be + * prefetched. + * @returns A `Dataset`. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + prefetch(bufferSize) { + if (bufferSize == null) { + throw new RangeError('`Dataset.prefetch()` requires bufferSize to be specified.'); + } + const base = this; + return datasetFromIteratorFn(async () => (await base.iterator()).prefetch(bufferSize), this.size); + } + /** + * Repeats this dataset `count` times. + * + * NOTE: If this dataset is a function of global state (e.g. a random number + * generator), then different repetitions may produce different elements. + * + * ```js + * const a = tf.data.array([1, 2, 3]).repeat(3); + * await a.forEachAsync(e => console.log(e)); + * ``` + * + * @param count: (Optional) An integer, representing the number of times + * the dataset should be repeated. The default behavior (if `count` is + * `undefined` or negative) is for the dataset be repeated indefinitely. + * @returns A `Dataset`. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + repeat(count) { + const base = this; + let size; + if (this.size != null && count > 0) { + // If this dataset has size and count is positive, new size is current + // size multiply count. This also covers the case that current size is + // infinity. + size = this.size * count; + } + else if (count === 0) { + // If count is 0, new size is 0. + size = 0; + } + else if (this.size != null && (count === undefined || count < 0)) { + // If this dataset has size and count is undefined or negative, the + // dataset will be repeated indefinitely and new size is infinity. + size = Infinity; + } + else { + // If the size of this dataset is null, the new dataset's size is null. + size = null; + } + return datasetFromIteratorFn(async () => { + const iteratorIterator = iteratorFromFunction(async () => ({ value: await base.iterator(), done: false })); + return iteratorFromConcatenated(iteratorIterator.take(count)); + }, size); + } + /** + * Creates a `Dataset` that skips `count` initial elements from this dataset. + * + * ```js + * const a = tf.data.array([1, 2, 3, 4, 5, 6]).skip(3); + * await a.forEachAsync(e => console.log(e)); + * ``` + * + * @param count: The number of elements of this dataset that should be skipped + * to form the new dataset. If `count` is greater than the size of this + * dataset, the new dataset will contain no elements. If `count` + * is `undefined` or negative, skips the entire dataset. + * + * @returns A `Dataset`. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + skip(count) { + const base = this; + let size; + if (this.size != null && count >= 0 && this.size >= count) { + // If the size of this dataset is greater than count, the new dataset's + // size is current size minus skipped size.This also covers the case that + // current size is infinity. + size = this.size - count; + } + else if (this.size != null && + (this.size < count || count === undefined || count < 0)) { + // If the size of this dataset is smaller than count, or count is + // undefined or negative, skips the entire dataset and the new size is 0. + size = 0; + } + else { + // If the size of this dataset is null, the new dataset's size is null. + size = null; + } + return datasetFromIteratorFn(async () => (await base.iterator()).skip(count), size); + } + /** + * Pseudorandomly shuffles the elements of this dataset. This is done in a + * streaming manner, by sampling from a given number of prefetched elements. + * + * ```js + * const a = tf.data.array([1, 2, 3, 4, 5, 6]).shuffle(3); + * await a.forEachAsync(e => console.log(e)); + * ``` + * + * @param bufferSize: An integer specifying the number of elements from this + * dataset from which the new dataset will sample. + * @param seed: (Optional) An integer specifying the random seed that will + * be used to create the distribution. + * @param reshuffleEachIteration: (Optional) A boolean, which if true + * indicates that the dataset should be pseudorandomly reshuffled each time + * it is iterated over. If false, elements will be returned in the same + * shuffled order on each iteration. (Defaults to `true`.) + * @returns A `Dataset`. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + shuffle(bufferSize, seed, reshuffleEachIteration = true) { + if (bufferSize == null || bufferSize < 0) { + if (this.size == null) { + throw new RangeError('`Dataset.shuffle()` requires bufferSize to be specified.'); + } + else { + throw new RangeError('`Dataset.shuffle()` requires bufferSize to be specified. ' + + 'If your data fits in main memory (for regular JS objects), ' + + 'and/or GPU memory (for `tf.Tensor`s), consider setting ' + + `bufferSize to the dataset size (${this.size} elements)`); + } + } + const base = this; + const random = seedrandom.alea(seed || now().toString()); + return datasetFromIteratorFn(async () => { + let seed2 = random.int32(); + if (reshuffleEachIteration) { + seed2 += random.int32(); + } + return (await base.iterator()).shuffle(bufferSize, seed2.toString()); + }, this.size); + } + /** + * Creates a `Dataset` with at most `count` initial elements from this + * dataset. + * + * ```js + * const a = tf.data.array([1, 2, 3, 4, 5, 6]).take(3); + * await a.forEachAsync(e => console.log(e)); + * ``` + * + * @param count: The number of elements of this dataset that should be taken + * to form the new dataset. If `count` is `undefined` or negative, or if + * `count` is greater than the size of this dataset, the new dataset will + * contain all elements of this dataset. + * @returns A `Dataset`. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + take(count) { + const base = this; + let size; + if (this.size != null && this.size > count) { + // If the size of this dataset is greater than count, the new dataset's + // size is count. + size = count; + } + else if (this.size != null && this.size <= count) { + // If the size of this dataset is equal or smaller than count, the new + // dataset's size is the size of this dataset. + size = this.size; + } + else { + // If the size of this dataset is null, the new dataset's size is null. + size = null; + } + return datasetFromIteratorFn(async () => (await base.iterator()).take(count), size); + } + /** + * Collect all elements of this dataset into an array. + * + * Obviously this will succeed only for small datasets that fit in memory. + * Useful for testing and generally should be avoided if possible. + * + * ```js + * const a = tf.data.array([1, 2, 3, 4, 5, 6]); + * console.log(await a.toArray()); + * ``` + * + * @returns A Promise for an array of elements, which will resolve + * when a new stream has been obtained and fully consumed. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + async toArray() { + if (this.size === Infinity) { + throw new Error('Can not convert infinite data stream to array.'); + } + return (await this.iterator()).toArray(); + } + /** + * Collect all elements of this dataset into an array with prefetching 100 + * elements. This is useful for testing, because the prefetch changes the + * order in which the Promises are resolved along the processing pipeline. + * This may help expose bugs where results are dependent on the order of + * Promise resolution rather than on the logical order of the stream (i.e., + * due to hidden mutable state). + * + * @returns A Promise for an array of elements, which will resolve + * when a new stream has been obtained and fully consumed. + */ + async toArrayForTest() { + if (this.size === Infinity) { + throw new Error('Can not convert infinite data stream to array.'); + } + return (await this.iterator()).toArrayForTest(); + } + } + // TODO(soergel): deep sharded shuffle, where supported + Dataset.MAX_BUFFER_SIZE = 10000; + /** + * Create a `Dataset` defined by a provided iterator() function. + * + * ```js + * let i = -1; + * const func = () => + * ++i < 5 ? {value: i, done: false} : {value: null, done: true}; + * const iter = tf.data.iteratorFromFunction(func); + * const ds = tf.data.datasetFromIteratorFn(iter); + * await ds.forEachAsync(e => console.log(e)); + * ``` + */ + function datasetFromIteratorFn(iteratorFn, size = null) { + return new class extends Dataset { + constructor() { + super(...arguments); + this.size = size; + } + /* + * Provide a new stream of elements. Note this will also start new streams + * from any underlying `Dataset`s. + */ + async iterator() { + return iteratorFn(); + } + }(); + } + /** + * Create a `Dataset` from an array of elements. + * + * Create a Dataset from an array of objects: + * ```js + * const a = tf.data.array([{'item': 1}, {'item': 2}, {'item': 3}]); + * await a.forEachAsync(e => console.log(e)); + * ``` + * + * Create a Dataset from an array of numbers: + * ```js + * const a = tf.data.array([4, 5, 6]); + * await a.forEachAsync(e => console.log(e)); + * ``` + * @param items An array of elements that will be parsed as items in a dataset. + * + * @doc {heading: 'Data', subheading: 'Creation', namespace: 'data'} + */ + function array(items) { + return datasetFromIteratorFn(async () => iteratorFromItems(items), items.length); + } + /** + * Create a `Dataset` by zipping together an array, dict, or nested + * structure of `Dataset`s (and perhaps additional constants). + * The underlying datasets must provide elements in a consistent order such that + * they correspond. + * + * The number of elements in the resulting dataset is the same as the size of + * the smallest dataset in datasets. + * + * The nested structure of the `datasets` argument determines the + * structure of elements in the resulting iterator. + * + * Note this means that, given an array of two datasets that produce dict + * elements, the result is a dataset that produces elements that are arrays + * of two dicts: + * + * Zip an array of datasets: + * ```js + * console.log('Zip two datasets of objects:'); + * const ds1 = tf.data.array([{a: 1}, {a: 2}, {a: 3}]); + * const ds2 = tf.data.array([{b: 4}, {b: 5}, {b: 6}]); + * const ds3 = tf.data.zip([ds1, ds2]); + * await ds3.forEachAsync(e => console.log(JSON.stringify(e))); + * + * // If the goal is to merge the dicts in order to produce elements like + * // {a: ..., b: ...}, this requires a second step such as: + * console.log('Merge the objects:'); + * const ds4 = ds3.map(x => {return {a: x[0].a, b: x[1].b}}); + * await ds4.forEachAsync(e => console.log(e)); + * ``` + * + * Zip a dict of datasets: + * ```js + * const a = tf.data.array([{a: 1}, {a: 2}, {a: 3}]); + * const b = tf.data.array([{b: 4}, {b: 5}, {b: 6}]); + * const c = tf.data.zip({c: a, d: b}); + * await c.forEachAsync(e => console.log(JSON.stringify(e))); + * ``` + * + * @doc {heading: 'Data', subheading: 'Operations', namespace: 'data'} + */ + function zip(datasets) { + // manually type-check the argument for JS users + if (!isIterable(datasets)) { + throw new Error('The argument to zip() must be an object or array.'); + } + let size; + if (Array.isArray(datasets)) { + for (let i = 0; i < datasets.length; i++) { + size = size == null ? datasets[i].size : + Math.min(size, datasets[i].size); + } + } + else if (datasets instanceof Object) { + for (const ds in datasets) { + size = size == null ? datasets[ds].size : + Math.min(size, datasets[ds].size); + } + } + return datasetFromIteratorFn(async () => { + const streams = await deepMapAndAwaitAll(datasets, d => { + if (d instanceof Dataset) { + return { value: d.iterator(), recurse: false }; + } + else if (isIterable(d)) { + return { value: null, recurse: true }; + } + else { + throw new Error('Leaves of the structure passed to zip() must be Datasets, ' + + 'not primitives.'); + } + }); + return iteratorFromZipped(streams, ZipMismatchMode.SHORTEST); + }, size); + } + /** + * A zip function for use with deepZip, passed via the columnMajorBatch call. + * + * Accepts an array of identically-structured nested elements and either batches + * them (if they are primitives, numeric arrays, or Tensors) or requests + * recursion (if not). + */ + // tslint:disable-next-line:no-any + function deepBatchConcat(rows) { + if (rows === null) { + return null; + } + // use the first item to decide whether to recurse or batch here. + const exampleRow = rows[0]; + if (canTensorify(exampleRow)) { + // rows is an array of primitives, Tensors, or arrays. Batch them. + const value = batchConcat(rows); + return { value, recurse: false }; + } + // the example row is an object, so recurse into it. + return { value: null, recurse: true }; + } + /** + * Assembles a list of same-shaped numbers, number arrays, or Tensors + * into a single new Tensor where axis 0 is the batch dimension. + */ + function batchConcat(arrays) { + if (arrays.length === 0) { + // We can't return an empty Tensor because we don't know the element shape. + throw new Error('Can\'t make a batch of zero elements.'); + } + if (arrays[0] instanceof Tensor) { + // Input is an array of Tensors + return stack(arrays); + } + else { + // Input is a possibly-nested array of numbers. + return tensor(arrays); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * Represents a potentially large collection of text lines. + * + * The results are not batched. + */ + class TextLineDataset extends Dataset { + /** + * Create a `TextLineDataset`. + * + * @param input A `DataSource` providing a chunked, UTF8-encoded byte stream. + */ + constructor(input) { + super(); + this.input = input; + } + async iterator() { + const inputIterator = await this.input.iterator(); + const utf8Iterator = inputIterator.decodeUTF8(); + const lineIterator = utf8Iterator.split('\n').map(line => { + // Windows/DOS format text file has extra line breaker at the end of line. + if (line.endsWith('\r')) { + line = line.slice(0, -1); + } + return line; + }); + return lineIterator; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + const CODE_QUOTE = '"'; + const STATE_OUT = Symbol('out'); + const STATE_FIELD = Symbol('field'); + const STATE_QUOTE = Symbol('quote'); + const STATE_QUOTE_AFTER_QUOTE = Symbol('quoteafterquote'); + const STATE_WITHIN_QUOTE_IN_QUOTE = Symbol('quoteinquote'); + /** + * Represents a potentially large collection of delimited text records. + * + * The produced `TensorContainer`s each contain one key-value pair for + * every column of the table. When a field is empty in the incoming data, the + * resulting value is `undefined`, or throw error if it is required. Values + * that can be parsed as numbers are emitted as type `number`, other values + * are parsed as `string`. + * + * The results are not batched. + * + * @doc {heading: 'Data', subheading: 'Classes', namespace: 'data'} + */ + class CSVDataset extends Dataset { + /** + * Returns column names of the csv dataset. If `configuredColumnsOnly` is + * true, return column names in `columnConfigs`. If `configuredColumnsOnly` is + * false and `columnNames` is provided, `columnNames`. If + * `configuredColumnsOnly` is false and `columnNames` is not provided, return + * all column names parsed from the csv file. For example usage please go to + * `tf.data.csv`. + * + * @doc {heading: 'Data', subheading: 'Classes'} + */ + async columnNames() { + if (!this.columnNamesValidated) { + await this.setColumnNames(); + } + return this.configuredColumnsOnly ? Object.keys(this.columnConfigs) : + this.fullColumnNames; + } + /* 1) If `columnNames` is provided as string[], use this string[] as output + * keys in corresponding order. The length must match the number of inferred + * columns if `hasHeader` is true . + * 2) If `columnNames` is not provided, parse header line as `columnNames` if + * hasHeader is true. If `hasHeader` is false, throw an error. + * 3) If `columnConfigs` is provided, all the keys in `columnConfigs` must + * exist in parsed `columnNames`. + */ + async setColumnNames() { + const columnNamesFromFile = await this.maybeReadHeaderLine(); + if (!this.fullColumnNames && !columnNamesFromFile) { + // Throw an error if columnNames is not provided and no header line. + throw new Error('Column names must be provided if there is no header line.'); + } + else if (this.fullColumnNames && columnNamesFromFile) { + // Check provided columnNames match header line. + assert$1(columnNamesFromFile.length === this.fullColumnNames.length, () => 'The length of provided columnNames (' + + this.fullColumnNames.length.toString() + + ') does not match the length of the header line read from ' + + 'file (' + columnNamesFromFile.length.toString() + ').'); + } + if (!this.fullColumnNames) { + this.fullColumnNames = columnNamesFromFile; + } + // Check if there are duplicate column names. + const counts = this.fullColumnNames.reduce((countAcc, name) => { + countAcc[name] = (countAcc[name] + 1) || 1; + return countAcc; + }, {}); + const duplicateNames = Object.keys(counts).filter((name) => (counts[name] > 1)); + assert$1(duplicateNames.length === 0, () => 'Duplicate column names found: ' + duplicateNames.toString()); + // Check if keys in columnConfigs match columnNames. + if (this.columnConfigs) { + for (const key of Object.keys(this.columnConfigs)) { + const index = this.fullColumnNames.indexOf(key); + if (index === -1) { + throw new Error('The key "' + key + + '" provided in columnConfigs does not match any of the column ' + + 'names (' + this.fullColumnNames.toString() + ').'); + } + } + } + this.columnNamesValidated = true; + } + async maybeReadHeaderLine() { + if (this.hasHeader) { + const iter = await this.base.iterator(); + const firstElement = await iter.next(); + if (firstElement.done) { + throw new Error('No data was found for CSV parsing.'); + } + const firstLine = firstElement.value; + const headers = this.parseRow(firstLine, false); + return headers; + } + else { + return null; + } + } + /** + * Create a `CSVDataset`. + * + * @param input A `DataSource` providing a chunked, UTF8-encoded byte stream. + * @param csvConfig (Optional) A CSVConfig object that contains configurations + * of reading and decoding from CSV file(s). + * + * hasHeader: (Optional) A boolean value that indicates whether the first + * row of provided CSV file is a header line with column names, and should + * not be included in the data. Defaults to `true`. + * + * columnNames: (Optional) A list of strings that corresponds to + * the CSV column names, in order. If provided, it ignores the column + * names inferred from the header row. If not provided, infers the column + * names from the first row of the records. If hasHeader is false and + * columnNames is not provided, this method throws an error. + * + * columnConfigs: (Optional) A dictionary whose key is column names, value + * is an object stating if this column is required, column's data type, + * default value, and if this column is label. If provided, keys must + * correspond to names provided in columnNames or inferred from the file + * header lines. If isLabel is true any column, returns an array of two + * items: the first item is a dict of features key/value pairs, the second + * item is a dict of labels key/value pairs. If no feature is marked as + * label, returns a dict of features only. + * + * configuredColumnsOnly (Optional) If true, only columns provided in + * columnConfigs will be parsed and provided during iteration. + * + * delimiter (Optional) The string used to parse each line of the input + * file. Defaults to `,`. + */ + constructor(input, csvConfig) { + super(); + this.input = input; + this.hasHeader = true; + this.fullColumnNames = null; + this.columnNamesValidated = false; + this.columnConfigs = null; + this.configuredColumnsOnly = false; + this.delimiter = ','; + this.delimWhitespace = false; + this.base = new TextLineDataset(input); + if (!csvConfig) { + csvConfig = {}; + } + this.hasHeader = csvConfig.hasHeader === false ? false : true; + this.fullColumnNames = csvConfig.columnNames; + this.columnConfigs = csvConfig.columnConfigs; + this.configuredColumnsOnly = csvConfig.configuredColumnsOnly; + if (csvConfig.delimWhitespace) { + assert$1(csvConfig.delimiter == null, () => 'Delimiter should not be provided when delimWhitespace is true.'); + this.delimWhitespace = true; + this.delimiter = ' '; + } + else { + this.delimiter = csvConfig.delimiter ? csvConfig.delimiter : ','; + } + } + async iterator() { + if (!this.columnNamesValidated) { + await this.setColumnNames(); + } + let lines = await this.base.iterator(); + if (this.hasHeader) { + // We previously read the first line to get the columnNames. + // Now that we're providing data, skip it. + lines = lines.skip(1); + } + return lines.map(x => this.makeDataElement(x)); + } + makeDataElement(line) { + const values = this.parseRow(line); + const features = {}; + const labels = {}; + for (let i = 0; i < this.fullColumnNames.length; i++) { + const key = this.fullColumnNames[i]; + const config = this.columnConfigs ? this.columnConfigs[key] : null; + if (this.configuredColumnsOnly && !config) { + // This column is not selected. + continue; + } + else { + const value = values[i]; + let parsedValue = null; + if (value === '') { + // If default value is provided, use it. If default value is not + // provided, set as undefined. + if (config && config.default !== undefined) { + parsedValue = config.default; + } + else if (config && (config.required || config.isLabel)) { + throw new Error(`Required column ${key} is empty in this line: ${line}`); + } + else { + parsedValue = undefined; + } + } + else { + // A value is present, so parse it based on type + const valueAsNum = Number(value); + if (isNaN(valueAsNum)) { + // The value is a string and this column is declared as boolean + // in config, parse it as boolean. + if (config && config.dtype === 'bool') { + parsedValue = this.getBoolean(value); + } + else { + // Set value as string + parsedValue = value; + } + } + else if (!config || !config.dtype) { + // If this value is a number and no type config is provided, return + // it as number. + parsedValue = valueAsNum; + } + else { + // If this value is a number and data type is provided, parse it + // according to provided data type. + switch (config.dtype) { + case 'float32': + parsedValue = valueAsNum; + break; + case 'int32': + parsedValue = Math.floor(valueAsNum); + break; + case 'bool': + parsedValue = this.getBoolean(value); + break; + default: + parsedValue = valueAsNum; + } + } + } + // Check if this column is label. + (config && config.isLabel) ? labels[key] = parsedValue : + features[key] = parsedValue; + } + } + // If label exists, return an object of features and labels as {xs:features, + // ys:labels}, otherwise return features only. + if (Object.keys(labels).length === 0) { + return features; + } + else { + return { xs: features, ys: labels }; + } + } + getBoolean(value) { + if (value === '1' || value.toLowerCase() === 'true') { + return 1; + } + else { + return 0; + } + } + // adapted from https://beta.observablehq.com/@mbostock/streaming-csv + parseRow(line, validateElementCount = true) { + const result = []; + let readOffset = 0; + const readLength = line.length; + let currentState = STATE_OUT; + // Goes through the line to parse quote. + for (let i = 0; i < readLength; i++) { + switch (currentState) { + // Before enter a new field + case STATE_OUT: + switch (line.charAt(i)) { + // Enter a quoted field + case CODE_QUOTE: + readOffset = i + 1; + currentState = STATE_QUOTE; + break; + // Read an empty field + case this.delimiter: + readOffset = i + 1; + // If delimiter is white space and configured to collapse + // multiple white spaces, ignore this white space. + if (this.delimiter === ' ' && this.delimWhitespace) { + break; + } + result.push(''); + currentState = STATE_OUT; + break; + // Enter an unquoted field + default: + currentState = STATE_FIELD; + readOffset = i; + break; + } + break; + // In an unquoted field + case STATE_FIELD: + switch (line.charAt(i)) { + // Exit an unquoted field, add it to result + case this.delimiter: + result.push(line.substring(readOffset, i)); + currentState = STATE_OUT; + readOffset = i + 1; + break; + default: + } + break; + // In a quoted field + case STATE_QUOTE: + switch (line.charAt(i)) { + // Read a quote after a quote + case CODE_QUOTE: + currentState = STATE_QUOTE_AFTER_QUOTE; + break; + default: + } + break; + // This state means it's right after a second quote in a field + case STATE_QUOTE_AFTER_QUOTE: + switch (line.charAt(i)) { + // Finished a quoted field + case this.delimiter: + result.push(line.substring(readOffset, i - 1)); + currentState = STATE_OUT; + readOffset = i + 1; + break; + // Finished a quoted part in a quoted field + case CODE_QUOTE: + currentState = STATE_QUOTE; + break; + // In a quoted part in a quoted field + default: + currentState = STATE_WITHIN_QUOTE_IN_QUOTE; + break; + } + break; + case STATE_WITHIN_QUOTE_IN_QUOTE: + switch (line.charAt(i)) { + // Exit a quoted part in a quoted field + case CODE_QUOTE: + currentState = STATE_QUOTE; + break; + default: + } + break; + default: + } + } + // Adds last item based on if it is quoted. + if (currentState === STATE_QUOTE_AFTER_QUOTE) { + result.push(line.substring(readOffset, readLength - 1)); + } + else { + result.push(line.substring(readOffset)); + } + // Check if each row has the same number of elements as column names. + if (validateElementCount && result.length !== this.fullColumnNames.length) { + throw new Error(`Invalid row in csv file. Should have ${this.fullColumnNames.length} elements in a row, but got ${result}`); + } + return result; + } + } + // TODO(soergel): add more basic datasets for parity with tf.data + // tf.data.FixedLengthRecordDataset() + // tf.data.TFRecordDataset() + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * Provide a stream of tensors from microphone audio stream. The tensors are + * representing audio data as frequency-domain spectrogram generated with + * browser's native FFT. Tensors representing time-domain waveform is available + * based on configuration. Only works in browser environment. + */ + class MicrophoneIterator extends LazyIterator { + constructor(microphoneConfig) { + super(); + this.microphoneConfig = microphoneConfig; + this.isClosed = false; + this.fftSize = microphoneConfig.fftSize || 1024; + const fftSizeLog2 = Math.log2(this.fftSize); + if (this.fftSize < 0 || fftSizeLog2 < 4 || fftSizeLog2 > 14 || + !Number.isInteger(fftSizeLog2)) { + throw new Error(`Invalid fftSize: it must be a power of 2 between ` + + `2 to 4 and 2 to 14, but got ${this.fftSize}`); + } + this.numFrames = microphoneConfig.numFramesPerSpectrogram || 43; + this.sampleRateHz = microphoneConfig.sampleRateHz; + this.columnTruncateLength = + microphoneConfig.columnTruncateLength || this.fftSize; + this.audioTrackConstraints = microphoneConfig.audioTrackConstraints; + this.smoothingTimeConstant = microphoneConfig.smoothingTimeConstant || 0; + this.includeSpectrogram = + microphoneConfig.includeSpectrogram === false ? false : true; + this.includeWaveform = + microphoneConfig.includeWaveform === true ? true : false; + if (!this.includeSpectrogram && !this.includeWaveform) { + throw new Error('Both includeSpectrogram and includeWaveform are false. ' + + 'At least one type of data should be returned.'); + } + } + summary() { + return `microphone`; + } + // Construct a MicrophoneIterator and start the audio stream. + static async create(microphoneConfig = {}) { + if (!env().get('IS_BROWSER')) { + throw new Error('microphone API is only supported in browser environment.'); + } + const microphoneIterator = new MicrophoneIterator(microphoneConfig); + // Call async function start() to initialize the audio stream. + await microphoneIterator.start(); + return microphoneIterator; + } + // Start the audio stream and FFT. + async start() { + try { + this.stream = await navigator.mediaDevices.getUserMedia({ + audio: this.audioTrackConstraints == null ? true : + this.audioTrackConstraints, + video: false + }); + } + catch (e) { + throw new Error(`Error thrown while initializing video stream: ${e.message}`); + } + if (!this.stream) { + throw new Error('Could not obtain audio from microphone.'); + } + const ctxConstructor = + // tslint:disable-next-line:no-any + window.AudioContext || window.webkitAudioContext; + this.audioContext = new ctxConstructor(); + if (!this.sampleRateHz) { + // If sample rate is not provided, use the available sample rate on + // device. + this.sampleRateHz = this.audioContext.sampleRate; + } + else if (this.audioContext.sampleRate !== this.sampleRateHz) { + throw new Error(`Mismatch in sampling rate: ` + + `Expected: ${this.sampleRateHz}; ` + + `Actual: ${this.audioContext.sampleRate}`); + } + const streamSource = this.audioContext.createMediaStreamSource(this.stream); + this.analyser = this.audioContext.createAnalyser(); + this.analyser.fftSize = this.fftSize * 2; + this.analyser.smoothingTimeConstant = this.smoothingTimeConstant; + streamSource.connect(this.analyser); + this.freqData = new Float32Array(this.fftSize); + this.timeData = new Float32Array(this.fftSize); + return; + } + async next() { + if (this.isClosed) { + return { value: null, done: true }; + } + let spectrogramTensor; + let waveformTensor; + const audioDataQueue = await this.getAudioData(); + if (this.includeSpectrogram) { + const freqData = this.flattenQueue(audioDataQueue.freqDataQueue); + spectrogramTensor = this.getTensorFromAudioDataArray(freqData, [this.numFrames, this.columnTruncateLength, 1]); + } + if (this.includeWaveform) { + const timeData = this.flattenQueue(audioDataQueue.timeDataQueue); + waveformTensor = this.getTensorFromAudioDataArray(timeData, [this.numFrames * this.fftSize, 1]); + } + return { + value: { 'spectrogram': spectrogramTensor, 'waveform': waveformTensor }, + done: false + }; + } + // Capture one result from the audio stream, and extract the value from + // iterator.next() result. + async capture() { + return (await this.next()).value; + } + async getAudioData() { + const freqDataQueue = []; + const timeDataQueue = []; + let currentFrames = 0; + return new Promise(resolve => { + const intervalID = setInterval(() => { + if (this.includeSpectrogram) { + this.analyser.getFloatFrequencyData(this.freqData); + // If the audio stream is initializing, return empty queue. + if (this.freqData[0] === -Infinity) { + resolve({ freqDataQueue, timeDataQueue }); + } + freqDataQueue.push(this.freqData.slice(0, this.columnTruncateLength)); + } + if (this.includeWaveform) { + this.analyser.getFloatTimeDomainData(this.timeData); + timeDataQueue.push(this.timeData.slice()); + } + // Clean interval and return when all frames have been collected + if (++currentFrames === this.numFrames) { + clearInterval(intervalID); + resolve({ freqDataQueue, timeDataQueue }); + } + }, this.fftSize / this.sampleRateHz * 1e3); + }); + } + // Stop the audio stream and pause the iterator. + stop() { + if (!this.isClosed) { + this.isClosed = true; + this.analyser.disconnect(); + this.audioContext.close(); + if (this.stream != null && this.stream.getTracks().length > 0) { + this.stream.getTracks()[0].stop(); + } + } + } + // Override toArray() function to prevent collecting. + toArray() { + throw new Error('Can not convert infinite audio stream to array.'); + } + // Return audio sampling rate in Hz + getSampleRate() { + return this.sampleRateHz; + } + flattenQueue(queue) { + const frameSize = queue[0].length; + const freqData = new Float32Array(queue.length * frameSize); + queue.forEach((data, i) => freqData.set(data, i * frameSize)); + return freqData; + } + getTensorFromAudioDataArray(freqData, shape) { + const vals = new Float32Array(sizeFromShape(shape)); + // If the data is less than the output shape, the rest is padded with zeros. + vals.set(freqData, vals.length - freqData.length); + return tensor(vals, shape); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * Provide a stream of image tensors from webcam video stream. Only works in + * browser environment. + */ + class WebcamIterator extends LazyIterator { + constructor(webcamVideoElement, webcamConfig) { + super(); + this.webcamVideoElement = webcamVideoElement; + this.webcamConfig = webcamConfig; + this.isClosed = true; + this.resize = false; + if (this.needToResize()) { + this.resize = true; + this.cropSize = + [this.webcamConfig.resizeHeight, this.webcamConfig.resizeWidth]; + this.cropBoxInd = tensor1d([0], 'int32'); + if (this.webcamConfig.centerCrop) { + // Calculate the box based on resizing shape. + const widthCroppingRatio = this.webcamConfig.resizeWidth * 1.0 / this.webcamVideoElement.width; + const heightCroppingRatio = this.webcamConfig.resizeHeight * 1.0 / + this.webcamVideoElement.height; + const widthCropStart = (1 - widthCroppingRatio) / 2; + const heightCropStart = (1 - heightCroppingRatio) / 2; + const widthCropEnd = widthCropStart + widthCroppingRatio; + const heightCropEnd = heightCroppingRatio + heightCropStart; + this.cropBox = tensor2d([heightCropStart, widthCropStart, heightCropEnd, widthCropEnd], [1, 4]); + } + else { + this.cropBox = tensor2d([0, 0, 1, 1], [1, 4]); + } + } + } + summary() { + return `webcam`; + } + // Construct a WebcamIterator and start it's video stream. + static async create(webcamVideoElement, webcamConfig = {}) { + if (!env().get('IS_BROWSER')) { + throw new Error('tf.data.webcam is only supported in browser environment.'); + } + if (!webcamVideoElement) { + // If webcam video element is not provided, create a hidden video element + // with provided width and height. + webcamVideoElement = document.createElement('video'); + if (!webcamConfig.resizeWidth || !webcamConfig.resizeHeight) { + throw new Error('Please provide webcam video element, or resizeWidth and ' + + 'resizeHeight to create a hidden video element.'); + } + webcamVideoElement.width = webcamConfig.resizeWidth; + webcamVideoElement.height = webcamConfig.resizeHeight; + } + const webcamIterator = new WebcamIterator(webcamVideoElement, webcamConfig); + // Call async function to initialize the video stream. + await webcamIterator.start(); + return webcamIterator; + } + // Async function to start video stream. + async start() { + if (this.webcamConfig.facingMode) { + assert$1((this.webcamConfig.facingMode === 'user') || + (this.webcamConfig.facingMode === 'environment'), () => `Invalid webcam facing mode: ${this.webcamConfig.facingMode}. ` + + `Please provide 'user' or 'environment'`); + } + try { + this.stream = await navigator.mediaDevices.getUserMedia({ + video: { + deviceId: this.webcamConfig.deviceId, + facingMode: this.webcamConfig.facingMode ? + this.webcamConfig.facingMode : + 'user', + width: this.webcamVideoElement.width, + height: this.webcamVideoElement.height + } + }); + } + catch (e) { + // Modify the error message but leave the stack trace intact + e.message = `Error thrown while initializing video stream: ${e.message}`; + throw e; + } + if (!this.stream) { + throw new Error('Could not obtain video from webcam.'); + } + // Older browsers may not have srcObject + try { + this.webcamVideoElement.srcObject = this.stream; + } + catch (error) { + console.log(error); + this.webcamVideoElement.src = window.URL.createObjectURL(this.stream); + } + // Start the webcam video stream + this.webcamVideoElement.play(); + this.isClosed = false; + return new Promise(resolve => { + // Add event listener to make sure the webcam has been fully initialized. + this.webcamVideoElement.onloadedmetadata = () => { + resolve(); + }; + }); + } + async next() { + if (this.isClosed) { + return { value: null, done: true }; + } + let img; + try { + img = fromPixels$1(this.webcamVideoElement); + } + catch (e) { + throw new Error(`Error thrown converting video to pixels: ${JSON.stringify(e)}`); + } + if (this.resize) { + try { + return { value: this.cropAndResizeFrame(img), done: false }; + } + catch (e) { + throw new Error(`Error thrown cropping the video: ${e.message}`); + } + finally { + img.dispose(); + } + } + else { + return { value: img, done: false }; + } + } + needToResize() { + // If resizeWidth and resizeHeight are provided, and different from the + // width and height of original HTMLVideoElement, then resizing and cropping + // is required. + if (this.webcamConfig.resizeWidth && this.webcamConfig.resizeHeight && + (this.webcamVideoElement.width !== this.webcamConfig.resizeWidth || + this.webcamVideoElement.height !== this.webcamConfig.resizeHeight)) { + return true; + } + return false; + } + // Cropping and resizing each frame based on config + cropAndResizeFrame(img) { + return tidy(() => { + const expandedImage = expandDims$3(cast$3(img, 'float32'), (0)); + let resizedImage; + resizedImage = image$1.cropAndResize(expandedImage, this.cropBox, this.cropBoxInd, this.cropSize, 'bilinear'); + // Extract image from batch cropping. + const shape = resizedImage.shape; + return reshape$3(resizedImage, shape.slice(1)); + }); + } + // Capture one frame from the video stream, and extract the value from + // iterator.next() result. + async capture() { + return (await this.next()).value; + } + // Stop the video stream and pause webcam iterator. + stop() { + const tracks = this.stream.getTracks(); + tracks.forEach(track => track.stop()); + try { + this.webcamVideoElement.srcObject = null; + } + catch (error) { + console.log(error); + this.webcamVideoElement.src = null; + } + this.isClosed = true; + } + // Override toArray() function to prevent collecting. + toArray() { + throw new Error('Can not convert infinite video stream to array.'); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * Represents a data source readable as a stream of binary data chunks. + * + * Because `Dataset`s can be read repeatedly (via `Dataset.iterator()`), this + * provides a means to repeatedly create streams from the underlying data + * sources. + */ + class DataSource { + } + // TODO(soergel): consider convenience factory functions here + // in combination with chainable source->dataset above, e.g.: + // tf.data.url(...).asCsvDataset().shuffle().batch() + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + class StringIterator extends LazyIterator { + /** + * Splits a string stream on a given separator. + * + * It is assumed that the incoming chunk boundaries have no semantic meaning, + * so conceptually the incoming stream is treated simply as the concatenation + * of its elements. + * + * The outgoing stream provides chunks corresponding to the results of the + * standard string split() operation (even if such a chunk spanned incoming + * chunks). The separators are not included. + * + * A typical usage is to split a text file (represented as a stream with + * arbitrary chunk boundaries) into lines. + * + * @param upstream A readable stream of strings that can be treated as + * concatenated. + * @param separator A character to split on. + */ + split(separator) { + return new SplitIterator(this, separator); + } + } + // ============================================================================ + // The following private classes serve to implement the chainable methods + // on StringIterator. Unfortunately they can't be placed in separate files, due + // to resulting trouble with circular imports. + // ============================================================================ + // We wanted multiple inheritance, e.g. + // class SplitIterator extends QueueIterator, StringIterator + // but the TypeScript mixin approach is a bit hacky, so we take this adapter + // approach instead. + class SplitIterator extends StringIterator { + constructor(upstream, separator) { + super(); + this.upstream = upstream; + this.impl = new SplitIteratorImpl(upstream, separator); + } + summary() { + return this.impl.summary(); + } + async next() { + return this.impl.next(); + } + } + class SplitIteratorImpl extends OneToManyIterator { + constructor(upstream, separator) { + super(); + this.upstream = upstream; + this.separator = separator; + // A partial string at the end of an upstream chunk + this.carryover = ''; + } + summary() { + return `${this.upstream.summary()} -> Split('${this.separator}')`; + } + async pump() { + const chunkResult = await this.upstream.next(); + if (chunkResult.done) { + if (this.carryover === '') { + return false; + } + // Pretend that the pump succeeded in order to emit the small last batch. + // The next pump() call will actually fail. + this.outputQueue.push(this.carryover); + this.carryover = ''; + return true; + } + const lines = chunkResult.value.split(this.separator); + // Note the behavior: " ab ".split(' ') === ['', 'ab', ''] + // Thus the carryover may be '' if the separator falls on a chunk + // boundary; this produces the correct result. + lines[0] = this.carryover + lines[0]; + for (const line of lines.slice(0, -1)) { + this.outputQueue.push(line); + } + this.carryover = lines[lines.length - 1]; + return true; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + class ByteChunkIterator extends LazyIterator { + /** + * Decode a stream of UTF8-encoded byte arrays to a stream of strings. + * + * The byte arrays producetd from the ByteChunkIterator on which this is + * called will be interpreted as concatenated. No assumptions are made about + * the boundaries of the incoming chunks, so a multi-byte UTF8 encoding of a + * character may span the boundary between chunks. This naturally happens, + * for instance, when reading fixed-size byte arrays from a file. + */ + decodeUTF8() { + return new Utf8Iterator(this); + } + } + // ============================================================================ + // The following private classes serve to implement the chainable methods + // on ByteChunkIterator. Unfortunately they can't be placed in separate files, + // due to resulting trouble with circular imports. + // ============================================================================ + // We wanted multiple inheritance, e.g. + // class Utf8Iterator extends QueueIterator, StringIterator + // but the TypeScript mixin approach is a bit hacky, so we take this adapter + // approach instead. + class Utf8Iterator extends StringIterator { + constructor(upstream) { + super(); + this.upstream = upstream; + this.impl = new Utf8IteratorImpl(upstream); + } + summary() { + return this.impl.summary(); + } + async next() { + return this.impl.next(); + } + } + /** + * Decode a stream of UTF8-encoded byte arrays to a stream of strings. + * + * This is tricky because the incoming byte array boundaries may disrupt a + * multi-byte UTF8 character. Thus any incomplete character data at the end of + * a chunk must be carried over and prepended to the next chunk before + * decoding. Luckily with native decoder, TextDecoder in browser and + * string_decoder in node, byte array boundaries are handled automatically. + * + * In the context of an input pipeline for machine learning, UTF8 decoding is + * needed to parse text files containing training examples or prediction + * requests (e.g., formatted as CSV or JSON). We cannot use the built-in + * decoding provided by FileReader.readAsText() because here we are in a + * streaming context, which FileReader does not support. + * + * @param upstream A `LazyIterator` of `Uint8Arrays` containing UTF8-encoded + * text, which should be interpreted as concatenated. No assumptions are + * made about the boundaries of the incoming chunks, so a multi-byte UTF8 + * encoding of a character may span the boundary between chunks. This + * naturally happens, for instance, when reading fixed-size byte arrays from a + * file. + */ + class Utf8IteratorImpl extends OneToManyIterator { + constructor(upstream) { + super(); + this.upstream = upstream; + if (env().get('IS_BROWSER')) { + this.decoder = new TextDecoder('utf-8'); + } + else { + // tslint:disable-next-line:no-require-imports + const { StringDecoder } = require('string_decoder'); + this.decoder = new StringDecoder('utf8'); + } + } + summary() { + return `${this.upstream.summary()} -> Utf8`; + } + async pump() { + const chunkResult = await this.upstream.next(); + let chunk; + if (chunkResult.done) { + return false; + } + else { + chunk = chunkResult.value; + } + let text; + if (env().get('IS_BROWSER')) { + text = this.decoder.decode(chunk, { stream: true }); + } + else { + text = this.decoder.write(Buffer.from(chunk.buffer)); + } + this.outputQueue.push(text); + return true; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * Provide a stream of chunks from a File, Blob, or Uint8Array. + * @param file The source File, Blob or Uint8Array. + * @param options Optional settings controlling file reading. + * @returns a lazy Iterator of Uint8Arrays containing sequential chunks of the + * input File, Blob or Uint8Array. + */ + class FileChunkIterator extends ByteChunkIterator { + constructor(file, options = {}) { + super(); + this.file = file; + this.options = options; + assert$1((file instanceof Uint8Array) || + (env().get('IS_BROWSER') ? + (file instanceof File || file instanceof Blob) : + false), () => 'FileChunkIterator only supports File, Blob and Uint8Array ' + + 'right now.'); + this.offset = options.offset || 0; + // default 1MB chunk has tolerable perf on large files + this.chunkSize = options.chunkSize || 1024 * 1024; + } + summary() { + return `FileChunks ${this.file}`; + } + async next() { + if (this.offset >= ((this.file instanceof Uint8Array) ? + this.file.byteLength : + this.file.size)) { + return { value: null, done: true }; + } + const chunk = new Promise((resolve, reject) => { + const end = this.offset + this.chunkSize; + if (this.file instanceof Uint8Array) { + // Note if end > this.uint8Array.byteLength, we just get a small last + // chunk. + resolve(new Uint8Array(this.file.slice(this.offset, end))); + } + else { + // This branch assumes that this.file type is File or Blob, which + // means it is in the browser environment. + // TODO(soergel): is this a performance issue? + const fileReader = new FileReader(); + fileReader.onload = (event) => { + let data = fileReader.result; + // Not sure we can trust the return type of + // FileReader.readAsArrayBuffer See e.g. + // https://github.com/node-file-api/FileReader/issues/2 + if (data instanceof ArrayBuffer) { + data = new Uint8Array(data); + } + if (!(data instanceof Uint8Array)) { + return reject(new TypeError('FileReader returned unknown type.')); + } + resolve(data); + }; + fileReader.onabort = (event) => { + return reject(new Error('Aborted')); + }; + fileReader.onerror = (event) => { + return reject(new Error(event.type)); + }; + // TODO(soergel): better handle onabort, onerror + // Note if end > this.file.size, we just get a small last chunk. + const slice = this.file.slice(this.offset, end); + // We can't use readAsText here (even if we know the file is text) + // because the slice boundary may fall within a multi-byte character. + fileReader.readAsArrayBuffer(slice); + } + this.offset = end; + }); + return { value: (await chunk), done: false }; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * Provide a stream of chunks from a URL. + * + * Note this class first downloads the entire file into memory before providing + * the first element from the stream. This is because the Fetch API does not + * yet reliably provide a reader stream for the response body. + */ + async function urlChunkIterator(url, options = {}, fetchFunc) { + let urlString; + let requestInit; + if ((typeof url) === 'string') { + urlString = url; + } + else { + urlString = url.url; + requestInit = getRequestInitFromRequest(url); + } + const response = await (fetchFunc || fetch$1)(urlString, requestInit); + if (response.ok) { + const uint8Array = new Uint8Array(await response.arrayBuffer()); + return new FileChunkIterator(uint8Array, options); + } + else { + throw new Error(response.statusText); + } + } + // Generate RequestInit from Request to match tf.util.fetch signature. + const getRequestInitFromRequest = (request) => { + const init = { + method: request.method, + headers: request.headers, + body: request.body, + mode: request.mode, + credentials: request.credentials, + cache: request.cache, + redirect: request.redirect, + referrer: request.referrer, + integrity: request.integrity, + }; + return init; + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + // Skip tslint any type check cause this method is aiming to check type of + // input. + // tslint:disable-next-line:no-any + function isLocalPath(source) { + return (typeof source === 'string') && source.slice(0, 7) === 'file://'; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * Represents a file, blob, or Uint8Array readable as a stream of binary data + * chunks. + */ + class FileDataSource extends DataSource { + /** + * Create a `FileDataSource`. + * + * @param input Local file path, or `File`/`Blob`/`Uint8Array` object to + * read. Local file only works in node environment. + * @param options Options passed to the underlying `FileChunkIterator`s, + * such as {chunksize: 1024}. + */ + constructor(input, options = {}) { + super(); + this.input = input; + this.options = options; + } + async iterator() { + if (isLocalPath(this.input) && env().get('IS_NODE')) { + // tslint:disable-next-line:no-require-imports + const fs = require('fs'); + this.input = fs.readFileSync(this.input.slice(7)); + } + // TODO(kangyizhang): Add LocalFileChunkIterator to split local streaming + // with file in browser. + return new FileChunkIterator(this.input, this.options); + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /* + * Represents a URL readable as a stream of binary data chunks. + */ + class URLDataSource extends DataSource { + /** + * Create a `URLDataSource`. + * + * @param url A source URL string, or a `Request` object. + * @param options Options passed to the underlying `FileChunkIterator`s, + * such as {chunksize: 1024}. + */ + constructor(url, fileOptions = {}) { + super(); + this.url = url; + this.fileOptions = fileOptions; + } + // TODO(soergel): provide appropriate caching options. Currently this + // will download the URL anew for each call to iterator(). Since we have + // to treat the downloaded file as a blob/buffer anyway, we may as well retain + // it-- but that raises GC issues. Also we may want a persistent disk cache. + async iterator() { + if (isLocalPath(this.url)) { + return (new FileDataSource(this.url, this.fileOptions)) + .iterator(); + } + else { + return urlChunkIterator(this.url, this.fileOptions); + } + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============================================================================= + */ + /** + * Create a `CSVDataset` by reading and decoding CSV file(s) from provided URL + * or local path if it's in Node environment. + * + * Note: If isLabel in columnConfigs is `true` for at least one column, the + * element in returned `CSVDataset` will be an object of + * `{xs:features, ys:labels}`: xs is a dict of features key/value pairs, ys + * is a dict of labels key/value pairs. If no column is marked as label, + * returns a dict of features only. + * + * ```js + * const csvUrl = + * 'https://storage.googleapis.com/tfjs-examples/multivariate-linear-regression/data/boston-housing-train.csv'; + * + * async function run() { + * // We want to predict the column "medv", which represents a median value of + * // a home (in $1000s), so we mark it as a label. + * const csvDataset = tf.data.csv( + * csvUrl, { + * columnConfigs: { + * medv: { + * isLabel: true + * } + * } + * }); + * + * // Number of features is the number of column names minus one for the label + * // column. + * const numOfFeatures = (await csvDataset.columnNames()).length - 1; + * + * // Prepare the Dataset for training. + * const flattenedDataset = + * csvDataset + * .map(({xs, ys}) => + * { + * // Convert xs(features) and ys(labels) from object form (keyed by + * // column name) to array form. + * return {xs:Object.values(xs), ys:Object.values(ys)}; + * }) + * .batch(10); + * + * // Define the model. + * const model = tf.sequential(); + * model.add(tf.layers.dense({ + * inputShape: [numOfFeatures], + * units: 1 + * })); + * model.compile({ + * optimizer: tf.train.sgd(0.000001), + * loss: 'meanSquaredError' + * }); + * + * // Fit the model using the prepared Dataset + * return model.fitDataset(flattenedDataset, { + * epochs: 10, + * callbacks: { + * onEpochEnd: async (epoch, logs) => { + * console.log(epoch + ':' + logs.loss); + * } + * } + * }); + * } + * + * await run(); + * ``` + * + * @param source URL or local path to get CSV file. If it's a local path, it + * must have prefix `file://` and it only works in node environment. + * @param csvConfig (Optional) A CSVConfig object that contains configurations + * of reading and decoding from CSV file(s). + * + * @doc { + * heading: 'Data', + * subheading: 'Creation', + * namespace: 'data', + * configParamIndices: [1] + * } + */ + function csv(source, csvConfig = {}) { + return new CSVDataset(new URLDataSource(source), csvConfig); + } + /** + * Create a `Dataset` that produces each element by calling a provided function. + * + * Note that repeated iterations over this `Dataset` may produce different + * results, because the function will be called anew for each element of each + * iteration. + * + * Also, beware that the sequence of calls to this function may be out of order + * in time with respect to the logical order of the Dataset. This is due to the + * asynchronous lazy nature of stream processing, and depends on downstream + * transformations (e.g. .shuffle()). If the provided function is pure, this is + * no problem, but if it is a closure over a mutable state (e.g., a traversal + * pointer), then the order of the produced elements may be scrambled. + * + * ```js + * let i = -1; + * const func = () => + * ++i < 5 ? {value: i, done: false} : {value: null, done: true}; + * const ds = tf.data.func(func); + * await ds.forEachAsync(e => console.log(e)); + * ``` + * + * @param f A function that produces one data element on each call. + */ + function func(f) { + const iter = iteratorFromFunction(f); + return datasetFromIteratorFn(async () => iter); + } + /** + * Create a `Dataset` that produces each element from provided JavaScript + * generator, which is a function that returns a (potentially async) iterator. + * + * For more information on iterators and generators, see + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators . + * For the iterator protocol, see + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols . + * + * Example of creating a dataset from an iterator factory: + * ```js + * function makeIterator() { + * const numElements = 10; + * let index = 0; + * + * const iterator = { + * next: () => { + * let result; + * if (index < numElements) { + * result = {value: index, done: false}; + * index++; + * return result; + * } + * return {value: index, done: true}; + * } + * }; + * return iterator; + * } + * const ds = tf.data.generator(makeIterator); + * await ds.forEachAsync(e => console.log(e)); + * ``` + * + * Example of creating a dataset from a generator: + * ```js + * function* dataGenerator() { + * const numElements = 10; + * let index = 0; + * while (index < numElements) { + * const x = index; + * index++; + * yield x; + * } + * } + * + * const ds = tf.data.generator(dataGenerator); + * await ds.forEachAsync(e => console.log(e)); + * ``` + * + * @param generator A JavaScript function that returns + * a (potentially async) JavaScript iterator. + * + * @doc { + * heading: 'Data', + * subheading: 'Creation', + * namespace: 'data', + * configParamIndices: [1] + * } + */ + function generator(generator) { + return datasetFromIteratorFn(async () => { + const gen = await generator(); + return iteratorFromFunction(() => gen.next()); + }); + } + /** + * Create an iterator that generates `Tensor`s from webcam video stream. This + * API only works in Browser environment when the device has webcam. + * + * Note: this code snippet only works when the device has a webcam. It will + * request permission to open the webcam when running. + * ```js + * const videoElement = document.createElement('video'); + * videoElement.width = 100; + * videoElement.height = 100; + * const cam = await tf.data.webcam(videoElement); + * const img = await cam.capture(); + * img.print(); + * cam.stop(); + * ``` + * + * @param webcamVideoElement A `HTMLVideoElement` used to play video from + * webcam. If this element is not provided, a hidden `HTMLVideoElement` will + * be created. In that case, `resizeWidth` and `resizeHeight` must be + * provided to set the generated tensor shape. + * @param webcamConfig A `WebcamConfig` object that contains configurations of + * reading and manipulating data from webcam video stream. + * + * @doc { + * heading: 'Data', + * subheading: 'Creation', + * namespace: 'data', + * ignoreCI: true + * } + */ + async function webcam(webcamVideoElement, webcamConfig) { + return WebcamIterator.create(webcamVideoElement, webcamConfig); + } + /** + * Create an iterator that generates frequency-domain spectrogram `Tensor`s from + * microphone audio stream with browser's native FFT. This API only works in + * browser environment when the device has microphone. + * + * Note: this code snippet only works when the device has a microphone. It will + * request permission to open the microphone when running. + * ```js + * const mic = await tf.data.microphone({ + * fftSize: 1024, + * columnTruncateLength: 232, + * numFramesPerSpectrogram: 43, + * sampleRateHz:44100, + * includeSpectrogram: true, + * includeWaveform: true + * }); + * const audioData = await mic.capture(); + * const spectrogramTensor = audioData.spectrogram; + * spectrogramTensor.print(); + * const waveformTensor = audioData.waveform; + * waveformTensor.print(); + * mic.stop(); + * ``` + * + * @param microphoneConfig A `MicrophoneConfig` object that contains + * configurations of reading audio data from microphone. + * + * @doc { + * heading: 'Data', + * subheading: 'Creation', + * namespace: 'data', + * ignoreCI: true + * } + */ + async function microphone(microphoneConfig) { + return MicrophoneIterator.create(microphoneConfig); + } + + /** @license See the LICENSE file. */ + // This code is auto-generated, do not modify this file! + const version$4 = '4.22.0'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + var index = /*#__PURE__*/Object.freeze({ + __proto__: null, + CSVDataset: CSVDataset, + Dataset: Dataset, + FileDataSource: FileDataSource, + TextLineDataset: TextLineDataset, + URLDataSource: URLDataSource, + array: array, + csv: csv, + func: func, + generator: generator, + microphone: microphone, + version_data: version$4, + webcam: webcam, + zip: zip + }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function assertNotComplex$1(tensor, opName) { + if (!Array.isArray(tensor)) { + tensor = [tensor]; + } + tensor.forEach(t => { + if (t != null) { + assert$1(t.dtype !== 'complex64', () => `${opName} does not support complex64 tensors in the CPU backend.`); + } + }); + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const whereImpl$1 = whereImpl$2; + class MathBackendCPU extends KernelBackend { + nextDataId() { + return MathBackendCPU.nextDataId++; + } + constructor() { + super(); + this.blockSize = 48; + this.firstUse = true; + this.data = new DataStorage(this, engine()); + } + write(values, shape, dtype) { + if (this.firstUse) { + this.firstUse = false; + if (env().get('IS_NODE')) { + warn('\n============================\n' + + 'Hi, looks like you are running TensorFlow.js in ' + + 'Node.js. To speed things up dramatically, install our node ' + + 'backend, visit https://github.com/tensorflow/tfjs-node for more details. ' + + '\n============================'); + } + } + const dataId = { id: this.nextDataId() }; + this.data.set(dataId, { values, dtype, refCount: 1 }); + return dataId; + } + /** + * Create a data bucket in cpu backend. + * @param shape Shape of the `TensorInfo`. + * @param dtype DType of the `TensorInfo`. + * @param values The value of the `TensorInfo` stored as a flattened array. + */ + makeTensorInfo(shape, dtype, values) { + let outId; + if (dtype === 'string' && values != null && values.length > 0 && + isString(values[0])) { + const encodedValues = values.map(d => encodeString(d)); + outId = this.write(encodedValues, shape, dtype); + } + else { + outId = this.write(values, shape, dtype); + } + return { dataId: outId, shape, dtype }; + } + /** Return refCount of a `TensorData`. */ + refCount(dataId) { + if (this.data.has(dataId)) { + const tensorData = this.data.get(dataId); + return tensorData.refCount; + } + return 0; + } + /** Increase refCount of a `TensorData`. */ + incRef(dataId) { + const tensorData = this.data.get(dataId); + tensorData.refCount++; + } + /** Decrease refCount of a `TensorData`. */ + decRef(dataId) { + if (this.data.has(dataId)) { + const tensorData = this.data.get(dataId); + tensorData.refCount--; + } + } + move(dataId, values, shape, dtype, refCount) { + this.data.set(dataId, { values, dtype, refCount }); + } + numDataIds() { + return this.data.numDataIds(); + } + async read(dataId) { + return this.readSync(dataId); + } + readSync(dataId) { + const { dtype, complexTensorInfos } = this.data.get(dataId); + if (dtype === 'complex64') { + const realValues = this.readSync(complexTensorInfos.real.dataId); + const imagValues = this.readSync(complexTensorInfos.imag.dataId); + return mergeRealAndImagArrays(realValues, imagValues); + } + return convertBackendValuesAndArrayBuffer(this.data.get(dataId).values, dtype); + } + bufferSync(t) { + const data = this.readSync(t.dataId); + if (t.dtype === 'string') { + try { + // Decode the bytes into string. + const strings = data.map(d => decodeString(d)); + return buffer(t.shape, t.dtype, strings); + } + catch (_a) { + throw new Error('Failed to decode encoded string bytes into utf-8'); + } + } + return buffer(t.shape, t.dtype, data); + } + makeOutput(values, shape, dtype) { + return engine().makeTensorFromTensorInfo(this.makeTensorInfo(shape, dtype, values), this); + } + /** + * Dispose the memory if the dataId has 0 refCount. Return true if the memory + * is released or memory is not managed in this backend, false if memory is + * not cleared. + * @param dataId + * @oaram force Optional, remove the data regardless of refCount + */ + disposeData(dataId, force = false) { + if (this.data.has(dataId)) { + this.data.get(dataId).refCount--; + if (!force && this.data.get(dataId).refCount > 0) { + return false; + } + const { complexTensorInfos } = this.data.get(dataId); + if (complexTensorInfos != null) { + this.disposeData(complexTensorInfos.real.dataId, true); + this.disposeData(complexTensorInfos.imag.dataId, true); + } + this.data.delete(dataId); + } + return true; + } + disposeIntermediateTensorInfo(tensorInfo) { + this.disposeData(tensorInfo.dataId); + } + async time(f) { + const start = now(); + f(); + const kernelMs = now() - start; + return { kernelMs }; + } + memory() { + return { + // Unreliable due to automatic gc. The numbers above are cumulative. + unreliable: true, + reasons: ['The reported memory is an upper bound. Due to automatic garbage ' + + 'collection, the true allocated memory may be less.'] + }; + } + where(condition) { + assertNotComplex$1([condition], 'where'); + const condVals = this.readSync(condition.dataId); + return whereImpl$1(condition.shape, condVals); + } + dispose() { } + floatPrecision() { + return 32; + } + /** Returns the smallest representable number. */ + epsilon() { + return super.epsilon(); + } + } + MathBackendCPU.nextDataId = 0; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function simpleAbsImpl(vals) { + const resultValues = new Float32Array(vals.length); + for (let i = 0; i < vals.length; ++i) { + resultValues[i] = Math.abs(vals[i]); + } + return resultValues; + } + const abs$1 = (args) => { + const { x } = args.inputs; + const cpuBackend = args.backend; + assertNotComplex$1(x, 'abs'); + let resultValues = new Float32Array(sizeFromShape(x.shape)); + const values = cpuBackend.data.get(x.dataId).values; + resultValues = simpleAbsImpl(values); + return cpuBackend.makeOutput(resultValues, x.shape, x.dtype); + }; + const absConfig$1 = { + kernelName: Abs, + backendName: 'cpu', + kernelFunc: abs$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Template that creates implementation for binary ops. Supports broadcast. + */ + function createSimpleBinaryKernelImpl(op) { + return (aShape, bShape, aVals, bVals, dtype) => { + const newShape = assertAndGetBroadcastShape(aShape, bShape); + const resultRank = newShape.length; + const resultStrides = computeStrides(newShape); + const resultSize = sizeFromShape(newShape); + const result = getTypedArrayFromDType(dtype, resultSize); + const aRank = aShape.length; + const bRank = bShape.length; + const aStrides = computeStrides(aShape); + const bStrides = computeStrides(bShape); + const aBroadcastDims = getBroadcastDims$1(aShape, newShape); + const bBroadcastDims = getBroadcastDims$1(bShape, newShape); + if (aBroadcastDims.length + bBroadcastDims.length === 0) { + for (let i = 0; i < result.length; ++i) { + result[i] = op(aVals[i % aVals.length], bVals[i % bVals.length]); + } + } + else { + for (let i = 0; i < result.length; ++i) { + const loc = indexToLoc(i, resultRank, resultStrides); + const aLoc = loc.slice(-aRank); + aBroadcastDims.forEach(d => aLoc[d] = 0); + const aIndex = locToIndex(aLoc, aRank, aStrides); + const bLoc = loc.slice(-bRank); + bBroadcastDims.forEach(d => bLoc[d] = 0); + const bIndex = locToIndex(bLoc, bRank, bStrides); + result[i] = op(aVals[aIndex], bVals[bIndex]); + } + } + return [result, newShape]; + }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function complex$1(args) { + const { inputs, backend } = args; + const { real, imag } = inputs; + const realVals = backend.data.get(real.dataId).values; + const imagVals = backend.data.get(imag.dataId).values; + const complexInfo = backend.makeTensorInfo(real.shape, 'complex64'); + const complex = backend.data.get(complexInfo.dataId); + // The complex tensor owns the underlying real and imag tensorInfos, only the + // complex tensor tracks refCount, when complexData is disposed the + // underlying tensorData will be disposed. + complex.complexTensorInfos = { + real: backend.makeTensorInfo(real.shape, 'float32', realVals), + imag: backend.makeTensorInfo(imag.shape, 'float32', imagVals) + }; + return complexInfo; + } + const complexConfig$1 = { + kernelName: Complex, + backendName: 'cpu', + kernelFunc: complex$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Generates a tensorInfo with all zeros value. + * @param backend cpu backend. + * @param shape Shape for the zeros tensor. + * @param dtype Optional. If set, the result has this dtype. + */ + function zeros(backend, shape, dtype = 'float32') { + if (dtype === 'complex64') { + const real = zeros(backend, shape, 'float32'); + const imag = zeros(backend, shape, 'float32'); + return complex$1({ inputs: { real, imag }, backend }); + } + const values = makeZerosTypedArray(sizeFromShape(shape), dtype); + return backend.makeTensorInfo(shape, dtype, values); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function identity$1(args) { + const { inputs, backend } = args; + const { x } = inputs; + backend.incRef(x.dataId); + return { dataId: x.dataId, shape: x.shape, dtype: x.dtype }; + } + const identityConfig$1 = { + kernelName: Identity$1, + backendName: 'cpu', + kernelFunc: identity$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function real$1(args) { + const { inputs, backend } = args; + const { input } = inputs; + const real = backend.data.get(input.dataId).complexTensorInfos.real; + const realVal = backend.data.get(real.dataId).values; + // When complex tensor is disposed, its underlying parts will be disposed too. + // Make new tensor out of the real value of the complex. This makes sure the + // value is still accessible even if complex tensor is disposed. + return backend.makeTensorInfo(real.shape, real.dtype, realVal); + } + const realConfig$1 = { + kernelName: Real, + backendName: 'cpu', + kernelFunc: real$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function castImpl(values, shape, inputType, dtype) { + if (dtype === 'int32') { + const resultValues = Int32Array.from(values); + return [shape, 'int32', resultValues]; + } + if (dtype === 'bool') { + // This is essentially the result of notEqual(x, 0). We avoid using + // kernel notEqual to avoid circular dependency, i.e. binary_utils -> + // cast -> notEqual -> binary_utils. + const zero = toTypedArray([0], inputType); + const [resultData, resultShape] = createSimpleBinaryKernelImpl((a, b) => (a !== b) ? 1 : 0)(shape, [], values, zero, 'bool'); + return [resultShape, 'bool', resultData]; + } + throw new Error(`Error in Cast: failed to cast ${inputType} to ${dtype}`); + } + function cast$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { dtype } = attrs; + // Casting to complex64. + if (dtype === 'complex64') { + if (x.dtype === 'complex64') { + return identity$1({ inputs: { x }, backend }); + } + const zerosTensorInfo = zeros(backend, x.shape, x.dtype); + const floatX = cast$1({ inputs: { x }, backend, attrs: { dtype: 'float32' } }); + const result = complex$1({ inputs: { real: floatX, imag: zerosTensorInfo }, backend }); + backend.disposeIntermediateTensorInfo(zerosTensorInfo); + backend.disposeIntermediateTensorInfo(floatX); + return result; + } + // Casting from complex64 + if (x.dtype === 'complex64') { + const realPart = real$1({ inputs: { input: x }, backend }); + const result = cast$1({ inputs: { x: realPart }, backend, attrs: { dtype } }); + backend.disposeIntermediateTensorInfo(realPart); + return result; + } + if (!hasEncodingLoss(x.dtype, dtype)) { + // We don't change the underlying data, since we cast to higher + // precision. + const result = identity$1({ inputs: { x }, backend }); + return { dataId: result.dataId, shape: result.shape, dtype }; + } + const values = backend.data.get(x.dataId).values; + const [resultShape, resultType, resultData] = castImpl(values, x.shape, x.dtype, dtype); + return backend.makeTensorInfo(resultShape, resultType, resultData); + } + const castConfig$1 = { + kernelName: Cast, + backendName: 'cpu', + kernelFunc: cast$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Template that creates a `KernelFunc` for binary ops. + * @param name Kernel name. + * @param binaryKernelImpl A `SimpleBinaryKernelImpl` for the kernel. + * @param binaryKernelComplexImpl Optional. If exists, represents a + * `ComplexBinaryKernelImpl` for the kernel, will be used when input dtype + * is `complex64`. + * @param dtype Optional. If set, the result has this dtype. Otherwise, the + * result has the same dtype as the first input. This is mainly used in + * comparison kernels, such as Equal, Less, Greater, etc. + */ + function binaryKernelFunc$1(name, simpleImpl, complexImpl, dtype) { + if (complexImpl == null) { + return ({ inputs, backend }) => { + const { a, b } = inputs; + const cpuBackend = backend; + assertNotComplex$1([a, b], name); + const aVals = cpuBackend.data.get(a.dataId).values; + const bVals = cpuBackend.data.get(b.dataId).values; + const decodedAVals = a.dtype === 'string' ? + // tslint:disable-next-line: no-any + fromUint8ToStringArray(aVals) : + aVals; + const decodedBVals = a.dtype === 'string' ? + // tslint:disable-next-line: no-any + fromUint8ToStringArray(bVals) : + bVals; + const $dtype = dtype || a.dtype; + const [resultData, resultShape] = simpleImpl(a.shape, b.shape, decodedAVals, decodedBVals, $dtype); + return cpuBackend.makeTensorInfo(resultShape, $dtype, resultData); + }; + } + return ({ inputs, backend }) => { + const { a, b } = inputs; + const cpuBackend = backend; + if (a.dtype === 'complex64' || b.dtype === 'complex64') { + const $aComplex = cast$1({ inputs: { x: a }, backend: cpuBackend, attrs: { dtype: 'complex64' } }); + const $aComplexVals = cpuBackend.data.get($aComplex.dataId); + const aReal = $aComplexVals.complexTensorInfos.real; + const aImag = $aComplexVals.complexTensorInfos.imag; + const aRealVals = cpuBackend.data.get(aReal.dataId).values; + const aImagVals = cpuBackend.data.get(aImag.dataId).values; + const $bComplex = cast$1({ inputs: { x: b }, backend: cpuBackend, attrs: { dtype: 'complex64' } }); + const $bComplexVals = cpuBackend.data.get($bComplex.dataId); + const bReal = $bComplexVals.complexTensorInfos.real; + const bImag = $bComplexVals.complexTensorInfos.imag; + const bRealVals = cpuBackend.data.get(bReal.dataId).values; + const bImagVals = cpuBackend.data.get(bImag.dataId).values; + const [resultRealData, resultImagData, resultShape] = complexImpl(a.shape, b.shape, aRealVals, aImagVals, bRealVals, bImagVals); + const resultReal = cpuBackend.makeTensorInfo(resultShape, 'float32', resultRealData); + const resultImag = cpuBackend.makeTensorInfo(resultShape, 'float32', resultImagData); + const result = complex$1({ inputs: { real: resultReal, imag: resultImag }, backend: cpuBackend }); + cpuBackend.disposeIntermediateTensorInfo($aComplex); + cpuBackend.disposeIntermediateTensorInfo($bComplex); + cpuBackend.disposeIntermediateTensorInfo(resultReal); + cpuBackend.disposeIntermediateTensorInfo(resultImag); + return result; + } + else { + const aVals = cpuBackend.data.get(a.dataId).values; + const bVals = cpuBackend.data.get(b.dataId).values; + const $dtype = dtype || a.dtype; + const [resultData, resultShape] = simpleImpl(a.shape, b.shape, aVals, bVals, $dtype); + return cpuBackend.makeTensorInfo(resultShape, $dtype, resultData); + } + }; + } + /** + * Template that creates the complex type implementation for binary ops. + * Supports broadcast. + */ + function createComplexBinaryKernelImpl(op) { + return (aShape, bShape, aRealVals, aImagVals, bRealVals, bImagVals) => { + const resultShape = assertAndGetBroadcastShape(aShape, bShape); + const resultSize = sizeFromShape(resultShape); + const resultRank = resultShape.length; + const resultStrides = computeStrides(resultShape); + const resultRealVals = getTypedArrayFromDType('float32', resultSize); + const resultImagVals = getTypedArrayFromDType('float32', resultSize); + const aBroadcastDims = getBroadcastDims$1(aShape, resultShape); + const bBroadcastDims = getBroadcastDims$1(bShape, resultShape); + const aVals = mergeRealAndImagArrays(aRealVals, aImagVals); + const bVals = mergeRealAndImagArrays(bRealVals, bImagVals); + const aRank = aShape.length; + const aStrides = computeStrides(aShape); + const bRank = bShape.length; + const bStrides = computeStrides(bShape); + if (aBroadcastDims.length + bBroadcastDims.length === 0) { + for (let i = 0; i < resultRealVals.length; i++) { + const aIdx = i % aVals.length; + const bIdx = i % bVals.length; + const result = op(aVals[aIdx * 2], aVals[aIdx * 2 + 1], bVals[bIdx * 2], bVals[bIdx * 2 + 1]); + resultRealVals[i] = result.real; + resultImagVals[i] = result.imag; + } + } + else { + for (let i = 0; i < resultRealVals.length; i++) { + const loc = indexToLoc(i, resultRank, resultStrides); + const aLoc = loc.slice(-aRank); + aBroadcastDims.forEach(d => aLoc[d] = 0); + const aIndex = locToIndex(aLoc, aRank, aStrides); + const bLoc = loc.slice(-bRank); + bBroadcastDims.forEach(d => bLoc[d] = 0); + const bIndex = locToIndex(bLoc, bRank, bStrides); + const opResult = op(aVals[aIndex * 2], aVals[aIndex * 2 + 1], bVals[bIndex * 2], bVals[bIndex * 2 + 1]); + resultRealVals[i] = opResult.real; + resultImagVals[i] = opResult.imag; + } + } + return [resultRealVals, resultImagVals, resultShape]; + }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const addImpl = createSimpleBinaryKernelImpl(((a, b) => a + b)); + const addComplexImpl = createComplexBinaryKernelImpl(((aReal, aImag, bReal, bImag) => { + return { real: aReal + bReal, imag: aImag + bImag }; + })); + const add = binaryKernelFunc$1(Add$1, addImpl, addComplexImpl); + const addConfig$1 = { + kernelName: Add$1, + backendName: 'cpu', + kernelFunc: add + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function bincountImpl(xVals, weightsVals, weightsDtype, weightsShape, size) { + const weightsSize = sizeFromShape(weightsShape); + const outVals = makeZerosTypedArray(size, weightsDtype); + for (let i = 0; i < xVals.length; i++) { + const value = xVals[i]; + if (value < 0) { + throw new Error('Input x must be non-negative!'); + } + if (value >= size) { + continue; + } + if (weightsSize > 0) { + outVals[value] += weightsVals[i]; + } + else { + outVals[value] += 1; + } + } + return outVals; + } + function bincountReduceImpl(xBuf, weightsBuf, size, binaryOutput = false) { + const numRows = xBuf.shape[0]; + const numCols = xBuf.shape[1]; + const outBuf = buffer([numRows, size], weightsBuf.dtype); + for (let i = 0; i < numRows; i++) { + for (let j = 0; j < numCols; j++) { + const value = xBuf.get(i, j); + if (value < 0) { + throw new Error('Input x must be non-negative!'); + } + if (value >= size) { + continue; + } + if (binaryOutput) { + outBuf.set(1, i, value); + } + else { + if (weightsBuf.size > 0) { + outBuf.set(outBuf.get(i, value) + weightsBuf.get(i, j), i, value); + } + else { + outBuf.set(outBuf.get(i, value) + 1, i, value); + } + } + } + } + return outBuf; + } + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const bitwiseAndImpl = createSimpleBinaryKernelImpl(((a, b) => a & b)); + const bitwiseAnd$1 = binaryKernelFunc$1(BitwiseAnd, bitwiseAndImpl); + const bitwiseAndConfig$1 = { + kernelName: BitwiseAnd, + backendName: 'cpu', + kernelFunc: bitwiseAnd$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Template that creates implementation for unary op. + */ + function createSimpleUnaryImpl(op) { + return (values, dtype, attrs) => { + const newValues = getArrayFromDType(dtype, values.length); + for (let i = 0; i < values.length; ++i) { + newValues[i] = op(values[i], attrs); + } + return newValues; + }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Template that creates a `KernelFunc` for unary ops. + * @param name Kernel name. + * @param op A `SimpleUnaryOperation` for the kernel. + * @param dtype Optional. If set, the result has this dtype. Otherwise, the + * result has the same dtype as the input. This is mainly used in certain + * kernels that return bool type, such as isFinite, isInf, etc. + */ + function unaryKernelFunc$1(name, op, dtype) { + const impl = createSimpleUnaryImpl(op); + return unaryKernelFuncFromImpl(name, impl, dtype); + } + /** + * Template that creates a `KernelFunc` for unary ops from the given + * `SimpleUnaryImpl`.. + * @param name Kernel name. + * @param unaryImpl A `SimpleUnaryImpl` that implements the op. + * @param dtype Optional. If set, the result has this dtype. Otherwise, the + * result has the same dtype as the input. This is mainly used in certain + * kernels that return bool type, such as isFinite, isInf, etc. + */ + function unaryKernelFuncFromImpl(name, unaryImpl, dtype) { + return ({ inputs, attrs, backend }) => { + const { x } = inputs; + assertNotComplex$1(x, name); + const cpuBackend = backend; + const values = cpuBackend.data.get(x.dataId).values; + let decoded; + if (x.dtype === 'string') { + if (!Array.isArray(values)) { + throw new Error('String tensor\'s value was not an instance of Array'); + } + decoded = fromUint8ToStringArray(values); + } + else { + decoded = values; + } + const $dtype = dtype || x.dtype; + const newValues = unaryImpl(decoded, $dtype, attrs); + return cpuBackend.makeTensorInfo(x.shape, $dtype, newValues); + }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ceilImpl = createSimpleUnaryImpl((xi) => Math.ceil(xi)); + const ceil$1 = unaryKernelFuncFromImpl(Ceil, ceilImpl); + const ceilConfig$1 = { + kernelName: Ceil, + backendName: 'cpu', + kernelFunc: ceil$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function concatImpl$1(inputs, outShape, dtype, simplyConcat) { + const outVals = getArrayFromDType(dtype, sizeFromShape(outShape)); + if (simplyConcat && dtype !== 'string') { + // Use built-in TypedArray.set() method for speed. + let offset = 0; + inputs.forEach(input => { + const size = sizeFromShape(input.shape); + outVals.set(input.vals, offset); + offset += size; + }); + } + else { + let colOffset = 0; + inputs.forEach(input => { + const decodedData = dtype === 'string' ? + fromUint8ToStringArray(input.vals) : + input.vals; + let tIdx = 0; + for (let row = 0; row < input.shape[0]; ++row) { + const resIdx = row * outShape[1] + colOffset; + for (let col = 0; col < input.shape[1]; ++col) { + outVals[resIdx + col] = decodedData[tIdx++]; + } + } + colOffset += input.shape[1]; + }); + } + return outVals; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const equalImpl = createSimpleBinaryKernelImpl((a, b) => (a === b) ? 1 : 0); + const equal$1 = binaryKernelFunc$1(Equal, equalImpl, null /* complexImpl */, 'bool'); + const equalConfig$1 = { + kernelName: Equal, + backendName: 'cpu', + kernelFunc: equal$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const expImpl = createSimpleUnaryImpl((xi) => Math.exp(xi)); + const exp$1 = unaryKernelFuncFromImpl(Exp, expImpl, 'float32'); + const expConfig$1 = { + kernelName: Exp, + backendName: 'cpu', + kernelFunc: exp$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const expm1Impl = createSimpleUnaryImpl((xi) => Math.expm1(xi)); + const expm1$1 = unaryKernelFuncFromImpl(Expm1, expm1Impl); + const expm1Config$1 = { + kernelName: Expm1, + backendName: 'cpu', + kernelFunc: expm1$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const floorImpl = createSimpleUnaryImpl((xi) => Math.floor(xi)); + const floor$1 = unaryKernelFuncFromImpl(Floor, floorImpl); + const floorConfig$1 = { + kernelName: Floor, + backendName: 'cpu', + kernelFunc: floor$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const floorDivImpl = createSimpleBinaryKernelImpl((a, b) => Math.floor(a / b)); + const floorDiv$1 = binaryKernelFunc$1(FloorDiv, floorDivImpl, null /* complexImpl */, 'int32'); + const floorDivConfig$1 = { + kernelName: FloorDiv, + backendName: 'cpu', + kernelFunc: floorDiv$1 + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function gatherNdImpl(indicesData, paramsBuf, dtype, numSlices, sliceRank, sliceSize, strides, paramsShape, paramsSize) { + const outBuf = buffer([numSlices, sliceSize], dtype); + for (let i = 0; i < numSlices; i++) { + const index = []; + let flattenIndex = 0; + for (let j = 0; j < sliceRank; j++) { + const dim = indicesData[i * sliceRank + j]; + flattenIndex += dim * strides[j]; + index.push(dim); + } + if (flattenIndex < 0 || flattenIndex >= paramsSize / sliceSize) { + throw new Error(`Invalid indices: ${index} does not index into ${paramsShape}`); + } + for (let k = 0; k < sliceSize; k++) { + outBuf.values[i * sliceSize + k] = + paramsBuf.get(...paramsBuf.indexToLoc(flattenIndex * sliceSize + k)); + } + } + return outBuf; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function gatherV2Impl(xBuf, indicesBuf, flattenOutputShape) { + const outBuf = buffer(flattenOutputShape, xBuf.dtype); + for (let i = 0; i < outBuf.size; ++i) { + const newLoc = outBuf.indexToLoc(i); + const originalLoc = newLoc.slice(); + const batchIdx = originalLoc[0]; + const indicesIdx = originalLoc[2]; + const indicesIndex = indicesBuf.locToIndex([batchIdx, indicesIdx]); + originalLoc[2] = indicesBuf.values[indicesIndex]; + const originalIndex = xBuf.locToIndex(originalLoc); + if (0 <= originalIndex && originalIndex < xBuf.values.length) { + outBuf.values[i] = xBuf.values[originalIndex]; + } // Else, index is out of bounds, so leave the default zero val in outBuf. + } + return outBuf; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const greaterImpl = createSimpleBinaryKernelImpl((a, b) => (a > b) ? 1 : 0); + const greater$1 = binaryKernelFunc$1(Greater, greaterImpl, null /* complexImpl */, 'bool'); + const greaterConfig$1 = { + kernelName: Greater, + backendName: 'cpu', + kernelFunc: greater$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const greaterEqualImpl = createSimpleBinaryKernelImpl((a, b) => (a >= b) ? 1 : 0); + const greaterEqual$1 = binaryKernelFunc$1(GreaterEqual, greaterEqualImpl, null /* complexImpl */, 'bool'); + const greaterEqualConfig$1 = { + kernelName: GreaterEqual, + backendName: 'cpu', + kernelFunc: greaterEqual$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const lessImpl = createSimpleBinaryKernelImpl((a, b) => (a < b) ? 1 : 0); + const less$1 = binaryKernelFunc$1(Less, lessImpl, null /* complexImpl */, 'bool'); + const lessConfig$1 = { + kernelName: Less, + backendName: 'cpu', + kernelFunc: less$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const lessEqualImpl = createSimpleBinaryKernelImpl((a, b) => (a <= b) ? 1 : 0); + const lessEqual$1 = binaryKernelFunc$1(LessEqual, lessEqualImpl, null /* complexImpl */, 'bool'); + const lessEqualConfig$1 = { + kernelName: LessEqual, + backendName: 'cpu', + kernelFunc: lessEqual$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function linSpaceImpl(start, stop, num) { + const step = (stop - start) / (num - 1); + const values = makeZerosTypedArray(num, 'float32'); + values[0] = start; + for (let i = 1; i < values.length; i++) { + values[i] = values[i - 1] + step; + } + return values; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const logImpl = createSimpleUnaryImpl((xi) => Math.log(xi)); + const log$1 = unaryKernelFuncFromImpl(Log, logImpl); + const logConfig$1 = { + kernelName: Log, + backendName: 'cpu', + kernelFunc: log$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxImpl$1(aVals, reduceSize, outShape, dtype) { + const vals = getTypedArrayFromDType(dtype, sizeFromShape(outShape)); + for (let i = 0; i < vals.length; ++i) { + const offset = i * reduceSize; + let max = aVals[offset]; + for (let j = 0; j < reduceSize; ++j) { + const value = aVals[offset + j]; + if (Number.isNaN(value) || + value > max) { // comparison with NaN always return false + max = value; + } + } + vals[i] = max; + } + return vals; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const maximumImpl = createSimpleBinaryKernelImpl(((aValue, bValue) => Math.max(aValue, bValue))); + const maximum$1 = binaryKernelFunc$1(Maximum$1, maximumImpl); + const maximumConfig$1 = { + kernelName: Maximum$1, + backendName: 'cpu', + kernelFunc: maximum$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const minimumImpl = createSimpleBinaryKernelImpl(((aValue, bValue) => Math.min(aValue, bValue))); + const minimum$1 = binaryKernelFunc$1(Minimum$1, minimumImpl); + const minimumConfig$1 = { + kernelName: Minimum$1, + backendName: 'cpu', + kernelFunc: minimum$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const multiplyImpl = createSimpleBinaryKernelImpl(((aValue, bValue) => aValue * bValue)); + const multiplyComplexImpl = createComplexBinaryKernelImpl(((aReal, aImag, bReal, bImag) => { + return { + real: aReal * bReal - aImag * bImag, + imag: aReal * bImag + aImag * bReal + }; + })); + const multiply$1 = binaryKernelFunc$1(Multiply$1, multiplyImpl, multiplyComplexImpl); + const multiplyConfig$1 = { + kernelName: Multiply$1, + backendName: 'cpu', + kernelFunc: multiply$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function negImpl(xVals, xShape, xDtype) { + const minusOne = createScalarValue(-1, xDtype); + return multiplyImpl([], xShape, minusOne, xVals, xDtype); + } + function neg$1(args) { + const { inputs, backend } = args; + const { x } = inputs; + assertNotComplex$1(x, 'neg'); + const xVals = backend.data.get(x.dataId).values; + const [res, newShape] = negImpl(xVals, x.shape, x.dtype); + return backend.makeTensorInfo(newShape, x.dtype, res); + } + const negConfig$1 = { + kernelName: Neg, + backendName: 'cpu', + kernelFunc: neg$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const notEqualImpl = createSimpleBinaryKernelImpl(((a, b) => (a !== b) ? 1 : 0)); + const notEqual$1 = binaryKernelFunc$1(NotEqual, notEqualImpl, null /* complexOp */, 'bool'); + const notEqualConfig$1 = { + kernelName: NotEqual, + backendName: 'cpu', + kernelFunc: notEqual$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function transposeImpl$1(xVals, xShape, dtype, perm, newShape) { + const xRank = xShape.length; + const xSize = sizeFromShape(xShape); + const xStrides = computeStrides(xShape); + const newStrides = computeStrides(newShape); + const result = getTypedArrayFromDType(dtype, sizeFromShape(newShape)); + for (let i = 0; i < xSize; ++i) { + const loc = indexToLoc(i, xRank, xStrides); + // Permute location. + const newLoc = new Array(loc.length); + for (let i = 0; i < newLoc.length; i++) { + newLoc[i] = loc[perm[i]]; + } + const newIndex = locToIndex(newLoc, xRank, newStrides); + result[newIndex] = xVals[i]; + } + return result; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function transpose$1(args) { + const { inputs, attrs, backend } = args; + const { x } = inputs; + const { perm } = attrs; + assertNotComplex$1(x, 'transpose'); + const xRank = x.shape.length; + const newShape = new Array(xRank); + for (let i = 0; i < newShape.length; i++) { + newShape[i] = x.shape[perm[i]]; + } + const values = backend.data.get(x.dataId).values; + const result = transposeImpl$1(values, x.shape, x.dtype, perm, newShape); + const dataId = backend.write(result, newShape, x.dtype); + return { dataId, shape: newShape, dtype: x.dtype }; + } + const transposeConfig$1 = { + kernelName: Transpose, + backendName: 'cpu', + kernelFunc: transpose$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function prodImpl(xShape, xDtype, xVals, reductionAxes) { + const [outShape, reduceShape] = computeOutAndReduceShapes(xShape, reductionAxes); + const outDtype = upcastType(xDtype, 'int32'); + const outVals = makeZerosTypedArray(sizeFromShape(outShape), outDtype); + const reduceSize = sizeFromShape(reduceShape); + for (let i = 0; i < outVals.length; ++i) { + const offset = i * reduceSize; + let prod = 1; + for (let j = 0; j < reduceSize; ++j) { + prod *= xVals[offset + j]; + } + outVals[i] = prod; + } + return { outVals, outShape, outDtype }; + } + function prod$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + assertNotComplex$1(x, 'prod'); + const xRank = x.shape.length; + const axes = parseAxisParam(axis, x.shape); + const permutation = getAxesPermutation(axes, xRank); + let reductionAxes = axes; + let permutedX = x; + const intermediateTensorInfos = []; + if (permutation != null) { + permutedX = transpose$1({ inputs: { x }, backend, attrs: { perm: permutation } }); + intermediateTensorInfos.push(permutedX); + reductionAxes = getInnerMostAxes(reductionAxes.length, xRank); + } + const xVals = backend.data.get(permutedX.dataId).values; + const { outVals, outShape, outDtype } = prodImpl(permutedX.shape, permutedX.dtype, xVals, reductionAxes); + let resultShape = outShape; + if (keepDims) { + resultShape = expandShapeToKeepDim(outShape, axes); + } + intermediateTensorInfos.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return backend.makeTensorInfo(resultShape, outDtype, outVals); + } + const prodConfig$1 = { + kernelName: Prod, + backendName: 'cpu', + kernelFunc: prod$1 + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function validateIndices(indices, indicesShape, numParams) { + indices.forEach((index, i) => { + if (index < 0 || index >= numParams) { + const locString = indexToLoc(i, indicesShape.length, computeStrides(indicesShape)) + .join(','); + throw new Error(`indices[${locString}] = ${index} is not in [0, ${numParams})`); + } + }); + } + function validateSplits(paramsNestedSplits, numParamsDenseValues) { + // Validate + for (let dim = 0; dim < paramsNestedSplits.length; ++dim) { + const splits = paramsNestedSplits[dim]; + const lastSplit = (dim === paramsNestedSplits.length - 1) ? + numParamsDenseValues : + paramsNestedSplits[dim + 1].length; + if (splits.length === 0) { + throw new Error('Ragged splits may not be empty'); + } + if (splits[0] < 0) { + throw new Error('Ragged splits must be non-negative'); + } + if (splits[splits.length - 1] > lastSplit) { + throw new Error('Ragged splits must not point past values'); + } + for (let i = 1; i < splits.length; ++i) { + if (splits[i - 1] > splits[i]) { + throw new Error('Ragged splits must be sorted in ascending order'); + } + } + } + } + // Construct the `splits` output tensors, encoded using a nested vector. + // Also find the slices of values that need to be copied, and store them + // in `valueSlices`. The total number of values that will be copied (which + // we need for allocating the output values tensor) is stored in `numValues`. + function makeSplits(indices, indicesShape, paramsNestedSplits, numParamsDenseValues) { + const valueSlices = []; + let numValues = 0; + const numSplits = indicesShape.length - 1 + paramsNestedSplits.length; + const outSplits = new Array(numSplits).fill(null).map(() => [0]); + validateSplits(paramsNestedSplits, numParamsDenseValues); + // Add `splits` that come from all but the last dimension of the dense + // Tensor `indices`. In particular, for each dimension D, we add a + // splits tensor whose values are: + // range(reduceProd(splits.shape[:D]) + 1) * splits.shape[D+1] + // E.g., if indices.shape=[2, 3, 4] then we will add splits tensors: + // [0, 3, 6] # length=2+1, stride=3 + // [0, 4, 8, 12, 16, 20, 24] # length=2*3+1, stride=4 + let nrows = 1; + for (let dim = 0; dim < indicesShape.length - 1; ++dim) { + nrows *= indicesShape[dim]; + const rowLength = indicesShape[dim + 1]; + for (let i = 1; i < nrows + 1; ++i) { + outSplits[dim].push(i * rowLength); + } + } + // Add `splits` that come from `paramsNestedSplits`. Starting with the + // outermost ragged dimension (i.e., the first `splits` tensor), we work + // our way in, finding the range of values that should be copied. As we + // go, we update the output `splits` for each dimension with the appropriate + // values. In particular, the *lengths* of the slices from `param_splits` + // should be copied to generate corresponding slice lengths in the output + // splits. E.g., if we are copying a ragged row with length 4, then we + // should add a new split point to outSplits that is 4 greater than the + // previous split point in outSplits. + for (let i = 0; i < indices.length; ++i) { + let start = indices[i]; + let limit = indices[i] + 1; + // Copy splits. + for (let dim = 0; dim < paramsNestedSplits.length; ++dim) { + const splits = paramsNestedSplits[dim]; + const outDim = dim + indicesShape.length - 1; + if (outDim >= 0) { + const outSplitsOutDim = outSplits[outDim]; + const delta = outSplitsOutDim[outSplitsOutDim.length - 1] - splits[start]; + for (let j = start; j < limit; ++j) { + outSplits[outDim].push(splits[j + 1] + delta); + } + } + start = splits[start]; + limit = splits[limit]; + } + if (limit !== start) { + valueSlices.push([start, limit]); + numValues += limit - start; + } + } + return { outSplits, valueSlices, numValues }; + } + function getSplits(outSplits) { + const splitsOut = []; + for (let i = 0; i < outSplits.length; ++i) { + const numSplits = outSplits[i].length; + const splits = getArrayFromDType('int32', numSplits); + splitsOut.push(splits); + outSplits[i].forEach((value, j) => splits[j] = value); + } + return splitsOut; + } + function computeFlatOuterDims(orig, numOutDims) { + const outDims = orig.slice(0, numOutDims); + while (outDims.length < numOutDims) { + outDims.push(1); + } + for (let inDim = numOutDims; inDim < orig.length; inDim++) { + outDims[numOutDims - 1] *= orig[inDim]; + } + return outDims; + } + // For each slice in `(start, limit)` in `valueSlices`, append + // `paramsDenseValues[start,...,limit] to `values`. `valueSize` indicates + // the number of scalars contained in each value paramsDenseValues[i]. + function writeValueSlices(paramsDenseValues, paramsDenseValuesShape, valueSlices, valueSize, values, valuesShape) { + const denseM = computeFlatOuterDims(paramsDenseValuesShape, 2)[1]; + const valuesM = computeFlatOuterDims(valuesShape, 2)[1]; + let outPos = 0; + for (const slice of valueSlices) { + for (let i = slice[0]; i < slice[1]; ++i) { + for (let j = 0; j < valueSize; ++j) { + values[outPos * valuesM + j] = paramsDenseValues[i * denseM + j]; + } + ++outPos; + } + } + } + function getValues(paramsDenseValues, paramsDenseValuesShape, paramsDenseValuesDType, valueSlices, numValues) { + const valuesShape = paramsDenseValuesShape.slice(); + valuesShape[0] = numValues; + const valuesOut = getArrayFromDType(paramsDenseValuesDType, sizeFromShape(valuesShape)); + const numElements = paramsDenseValues.length; + const valueSize = numElements === 0 ? 0 : (numElements / paramsDenseValuesShape[0]); + writeValueSlices(paramsDenseValues, paramsDenseValuesShape, valueSlices, valueSize, valuesOut, valuesShape); + return [valuesOut, valuesShape]; + } + function raggedGatherImpl(paramsNestedSplits, paramsNestedSplitsShapes, paramsDenseValues, paramsDenseValuesShape, paramsDenseValuesDType, indices, indicesShape, outputRaggedRank) { + if (paramsNestedSplits.length === 0) { + throw new Error('paramsNestedSplits must be non empty'); + } + if (paramsNestedSplitsShapes[0].length === 0) { + throw new Error('Split tensors must not be scalars'); + } + const numParams = paramsNestedSplitsShapes[0][0] - 1; + validateIndices(indices, indicesShape, numParams); + if (paramsDenseValuesShape.length === 0) { + throw new Error('params.rank must be nonzero'); + } + const numParamsDenseValues = paramsDenseValuesShape[0]; + // Calculate the `splits`, and store the value slices that we need to + // copy in `valueSlices`. + const { outSplits, valueSlices, numValues } = makeSplits(indices, indicesShape, paramsNestedSplits, numParamsDenseValues); + // Write the output tensors. + const outputNestedSplits = getSplits(outSplits); + const outputDenseValues = getValues(paramsDenseValues, paramsDenseValuesShape, paramsDenseValuesDType, valueSlices, numValues); + return [outputNestedSplits, outputDenseValues[0], outputDenseValues[1]]; + } + + /** + * @license + * Copyright 2022 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const INT32_MAX = 2147483647; + function raggedRangeImpl(starts, startsShape, startsDType, limits, limitsShape, deltas, deltasShape) { + // Check input tensor shapes. + if (startsShape.length > 1) { + throw new Error('starts must be a scalar or vector'); + } + if (limitsShape.length > 1) { + throw new Error('limits must be a scalar or vector'); + } + if (deltasShape.length > 1) { + throw new Error('deltas must be a scalar or vector'); + } + // Determine which tensors we need to broadcast. + const broadcastStarts = startsShape.length === 0; + const broadcastLimits = limitsShape.length === 0; + const broadcastDeltas = deltasShape.length === 0; + // nRows (number of output rows) is the size of the non-broadcast inputs, + // or 1 if all inputs are scalars. + const inSizes = []; + if (!broadcastStarts) { + inSizes.push(startsShape[0]); + } + if (!broadcastLimits) { + inSizes.push(limitsShape[0]); + } + if (!broadcastDeltas) { + inSizes.push(deltasShape[0]); + } + for (let i = 1; i < inSizes.length; ++i) { + if (inSizes[i] !== inSizes[i - 1]) { + throw new Error('starts, limits, and deltas must have the same shape'); + } + } + const nRows = inSizes.length === 0 ? 1 : inSizes[0]; + // Construct the rtNestedSplits tensor. + const rtNestedSplits = getArrayFromDType('int32', nRows + 1); + rtNestedSplits[0] = 0; + for (let row = 0; row < nRows; ++row) { + const start = broadcastStarts ? starts[0] : starts[row]; + const limit = broadcastLimits ? limits[0] : limits[row]; + const delta = broadcastDeltas ? deltas[0] : deltas[row]; + if (delta === 0) { + throw new Error('Requires delta != 0'); + } + let size; // The number of elements in the specified range. + if (((delta > 0) && (limit < start)) || ((delta < 0) && (limit > start))) { + size = 0; + } + else { + size = Math.ceil(Math.abs((limit - start) / delta)); + if (size > INT32_MAX) { + throw new Error(`Requires ((limit - start) / delta) <= ${INT32_MAX}`); + } + } + rtNestedSplits[row + 1] = rtNestedSplits[row] + size; + } + const nVals = rtNestedSplits[nRows]; + // Construct the rtDenseValues tensor. + const rtDenseValues = getArrayFromDType(startsDType, nVals); + let valueIndex = 0; + for (let row = 0; row < nRows; ++row) { + const rowSize = rtNestedSplits[row + 1] - rtNestedSplits[row]; + let value = broadcastStarts ? starts[0] : starts[row]; + const delta = broadcastDeltas ? deltas[0] : deltas[row]; + for (let i = 0; i < rowSize; ++i) { + rtDenseValues[valueIndex++] = value; + value += delta; + } + } + return [rtNestedSplits, rtDenseValues]; + } + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + var RowPartitionType = RowPartitionType$1; + // Based on + // https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc + class RaggedTensorToTensorOp { + constructor(shape, shapeShape, values, valuesShape, valuesDType, defaultValue, defaultValueShape, rowPartitionValues, rowPartitionValuesShapes, rowPartitionTypeStrings) { + this.shape = shape; + this.shapeShape = shapeShape; + this.values = values; + this.valuesShape = valuesShape; + this.valuesDType = valuesDType; + this.defaultValue = defaultValue; + this.defaultValueShape = defaultValueShape; + this.rowPartitionValues = rowPartitionValues; + this.rowPartitionValuesShapes = rowPartitionValuesShapes; + this.rowPartitionTypes = + getRowPartitionTypesHelper(rowPartitionTypeStrings); + this.raggedRank = getRaggedRank(this.rowPartitionTypes); + } + getRowPartitionTypeByDimension(dimension) { + if (this.rowPartitionTypes[0] === RowPartitionType.FIRST_DIM_SIZE) { + return this.rowPartitionTypes[dimension + 1]; + } + else { + return this.rowPartitionTypes[dimension]; + } + } + // Returns the relationship between dimension and dimension + 1. + getRowPartitionTensor(dimension) { + if (this.rowPartitionTypes[0] === RowPartitionType.FIRST_DIM_SIZE) { + return this.rowPartitionValues[dimension + 1]; + } + else { + return this.rowPartitionValues[dimension]; + } + } + getMaxWidth(dimension) { + const rowPartitionTensor = this.getRowPartitionTensor(dimension - 1); + switch (this.getRowPartitionTypeByDimension(dimension - 1)) { + case RowPartitionType.VALUE_ROWIDS: + return RaggedTensorToTensorOp.getMaxWidthValueRowID(rowPartitionTensor); + case RowPartitionType.ROW_SPLITS: + return RaggedTensorToTensorOp.getMaxWidthRowSplit(rowPartitionTensor); + default: + throw new Error(`Cannot handle partition type ${RowPartitionType[this.getRowPartitionTypeByDimension(dimension - 1)]}`); + } + } + static getMaxWidthRowSplit(rowSplit) { + const tensorLength = rowSplit.length; + if (tensorLength === 0 || tensorLength === 1) { + return 0; + } + let maxWidth = 0; + for (let i = 0; i < tensorLength - 1; ++i) { + const currentWidth = rowSplit[i + 1] - rowSplit[i]; + if (currentWidth > maxWidth) { + maxWidth = currentWidth; + } + } + return maxWidth; + } + static getMaxWidthValueRowID(valueRowIds) { + const indexLength = valueRowIds.length; + if (indexLength === 0) { + return 0; + } + let firstEqualIndex = 0; + let firstEqualIndexValue = valueRowIds[0]; + let maxWidth = 0; + for (let i = 1; i < indexLength; ++i) { + const value = valueRowIds[i]; + if (value !== firstEqualIndexValue) { + firstEqualIndexValue = value; + maxWidth = Math.max(i - firstEqualIndex, maxWidth); + firstEqualIndex = i; + } + } + return Math.max(indexLength - firstEqualIndex, maxWidth); + } + tensorShapeFromTensor(t, tShape, isPartial = true) { + if (tShape.length === 0) { + if (t[0] === -1) { + return []; + } + throw new Error(`The only valid scalar shape tensor is the fully unknown shape specified as -1.`); + } + // MakePartialShape/MakeShapeHelper. + return makeShape(t, isPartial); + } + calculateOutputSize(firstDim) { + const valueShape = this.valuesShape; + const defaultValueShape = this.defaultValueShape; + validateDefaultValueShape(defaultValueShape, valueShape); + const shape = this.tensorShapeFromTensor(this.shape, this.shapeShape); + const outputShape = combineRaggedTensorToTensorShapes(this.raggedRank, shape, valueShape); + const result = outputShape; + if (result[0] < 0) { + result[0] = firstDim; + } + for (let i = 1; i <= this.raggedRank; ++i) { + if (result[i] < 0) { + result[i] = this.getMaxWidth(i); + } + } + return result; + } + /** + * The outputIndex represents the index in the output tensor + * where the first element of a particular dimension would be written. + * If it is -1, it indicates that the index is out of scope. + * Example, given firstDimension = 10, firstDimensionOutput = 6, + * and outputIndexMultiplier = 100: + * result = [0 100 200 300 400 500 -1 -1 -1 -1] + * If firstDimensionOutput = 11 instead, then: + * result = [0 100 200 300 400 500 600 700 800 900] + */ + calculateFirstParentOutputIndex(firstDimension, outputIndexMultiplier, firstDimensionOutput) { + const minDimension = Math.min(firstDimension, firstDimensionOutput); + const result = []; + let currentOutputIndex = 0; + for (let i = 0; i < minDimension; ++i, currentOutputIndex += outputIndexMultiplier) { + result.push(currentOutputIndex); + } + for (let i = minDimension; i < firstDimension; ++i) { + result.push(-1); + } + assert$1(result.length === firstDimension, () => 'Final length of result must be equal to firstDimension.'); + return result; + } + calculateOutputIndexRowSplit(rowSplit, parentOutputIndex, outputIndexMultiplier, outputSize) { + const rowSplitSize = rowSplit.length; + const result = []; + for (let i = 0; i < rowSplitSize - 1; ++i) { + const rowLength = rowSplit[i + 1] - rowSplit[i]; + let realLength = Math.min(outputSize, rowLength); + let parentOutputIndexCurrent = parentOutputIndex[i]; + if (parentOutputIndexCurrent === -1) { + realLength = 0; + } + for (let j = 0; j < realLength; ++j) { + result.push(parentOutputIndexCurrent); + parentOutputIndexCurrent += outputIndexMultiplier; + } + for (let j = 0; j < rowLength - realLength; ++j) { + result.push(-1); + } + } + if (rowSplitSize > 0 && result.length !== rowSplit[rowSplitSize - 1]) { + throw new Error('Invalid row split size.'); + } + return result; + } + // Calculate the output index of the first element of a list. + // The parentOutputIndex is the same computation for the previous list. + // -1 indicates an element or list that is out of range. + // The outputIndexMultiplier is the number of output indices one moves + // forward for each column. + // E.g., given: + // valueRowIds:[0 1 2 2 2 3 5 5 6] + // parentOutputIndex:[1000 1100 2000 2100 -1 3000 4000] + // outputIndexMultiplier: 10 + // outputSize: 2 + // You get: + // result = [1000 1100 2000 2010 -1 2100 -1 -1 3000] + // result[0] = parentOutputIndex[valueRowIds[0]] + // result[1] = parentOutputIndex[valueRowIds[1]] + // result[2] = parentOutputIndex[valueRowIds[2]] + // result[3] = parentOutputIndex[valueRowIds[2] + 10] + // result[4] = -1 because it is the third element the size is 2. + // result[5] = parentOutputIndex[valueRowIds[3]] + // result[6] = -1 because parentOutputIndex[valueRowIds[6]] == -1 + // result[7] = -1 because parentOutputIndex[valueRowIds[6]] == -1 + // result[8] = parentOutputIndex[valueRowIds[7]] + calculateOutputIndexValueRowID(valueRowIds, parentOutputIndex, outputIndexMultiplier, outputSize) { + const indexSize = valueRowIds.length; + const result = []; + if (indexSize === 0) { + return []; + } + let currentOutputColumn = 0; + let currentValueRowId = valueRowIds[0]; + if (currentValueRowId >= parentOutputIndex.length) { + throw new Error(`Got currentValueRowId=${currentValueRowId}, which is not less than ${parentOutputIndex.length}`); + } + let currentOutputIndex = parentOutputIndex[currentValueRowId]; + result.push(currentOutputIndex); + for (let i = 1; i < indexSize; ++i) { + const nextValueRowId = valueRowIds[i]; + if (nextValueRowId === currentValueRowId) { + if (currentOutputIndex >= 0) { + ++currentOutputColumn; + if (currentOutputColumn < outputSize) { + currentOutputIndex += outputIndexMultiplier; + } + else { + currentOutputIndex = -1; + } + } + } + else { + currentOutputColumn = 0; + currentValueRowId = nextValueRowId; + if (nextValueRowId >= parentOutputIndex.length) { + throw new Error(`Got nextValueRowId=${nextValueRowId} which is not less than ${parentOutputIndex.length}`); + } + currentOutputIndex = parentOutputIndex[nextValueRowId]; + } + result.push(currentOutputIndex); + } + if (result.length !== valueRowIds.length) { + throw new Error('Invalid row ids.'); + } + return result; + } + calculateOutputIndex(dimension, parentOutputIndex, outputIndexMultiplier, outputSize) { + const rowPartitionTensor = this.getRowPartitionTensor(dimension); + const partitionType = this.getRowPartitionTypeByDimension(dimension); + switch (partitionType) { + case RowPartitionType.VALUE_ROWIDS: + return this.calculateOutputIndexValueRowID(rowPartitionTensor, parentOutputIndex, outputIndexMultiplier, outputSize); + case RowPartitionType.ROW_SPLITS: + if (rowPartitionTensor.length - 1 > parentOutputIndex.length) { + throw new Error(`Row partition size is greater than output size: ${rowPartitionTensor.length - 1} > ${parentOutputIndex.length}`); + } + return this.calculateOutputIndexRowSplit(rowPartitionTensor, parentOutputIndex, outputIndexMultiplier, outputSize); + default: + throw new Error(`Unsupported partition type: ${RowPartitionType[partitionType]}`); + } + } + getFirstDimensionSize() { + const firstPartitionTensor = this.rowPartitionValues[0]; + if (this.rowPartitionTypes.length === 0) { + throw new Error('No row_partition_types given.'); + } + const firstPartitionType = this.rowPartitionTypes[0]; + switch (firstPartitionType) { + case RowPartitionType.FIRST_DIM_SIZE: + return firstPartitionTensor[0]; + case RowPartitionType.VALUE_ROWIDS: + throw new Error('Cannot handle VALUE_ROWIDS in first dimension.'); + case RowPartitionType.ROW_SPLITS: + return this.rowPartitionValuesShapes[0][0] - 1; + default: + throw new Error(`Cannot handle type ${RowPartitionType[firstPartitionType]}`); + } + } + compute() { + const firstPartitionTensor = this.rowPartitionValues[0]; + if (firstPartitionTensor.length <= 0) { + throw new Error('Invalid first partition input. ' + + 'Tensor requires at least one element.'); + } + const firstDimension = this.getFirstDimensionSize(); + const outputSize = this.calculateOutputSize(firstDimension); + const multiplier = new Array(this.raggedRank + 1); + multiplier[multiplier.length - 1] = 1; + for (let i = multiplier.length - 2; i >= 0; --i) { + multiplier[i] = multiplier[i + 1] * outputSize[i + 1]; + } + // Full size of the tensor. + const outputShape = makeShape(outputSize, false); + const outputTensor = getArrayFromDType(this.valuesDType, sizeFromShape(outputShape)); + const fullSize = multiplier[0] * outputSize[0]; + if (fullSize > 0) { + let outputIndex = this.calculateFirstParentOutputIndex(firstDimension, multiplier[0], outputSize[0]); + for (let i = 1; i <= this.raggedRank; ++i) { + const newOutputIndex = this.calculateOutputIndex(i - 1, outputIndex, multiplier[i], outputSize[i]); + outputIndex = newOutputIndex; + } + this.setOutput(this.raggedRank, outputIndex, outputTensor, outputShape); + } + return [outputShape, outputTensor]; + } + setOutput(raggedRank, outputIndex, outputTensor, outputShape) { + if (outputTensor.length === 0) { + return; + } + const valuesBase = this.values; + const outputBase = outputTensor; + let elementShape = outputShape.slice(); + elementShape = elementShape.slice(raggedRank + 1); + const valueElementSize = sizeFromShape(elementShape); + const outputIndexSize = outputIndex.length; + // Broadcast the default value to value_element_size. (We can skip this + // if defaultValueTensor.size == 1, since we use fill when that's true.) + let defaultValue = this.defaultValue; + if (defaultValue.length !== valueElementSize && defaultValue.length !== 1) { + const srcShape = this.defaultValueShape; + tidy(() => { + const defaultValueTensor = reshape$3(defaultValue, srcShape); + const bCastDefault = broadcastTo(defaultValueTensor, elementShape); + defaultValue = bCastDefault.dataSync(); + }); + } + // Loop through the outputIndex array, finding contiguous regions that + // should be copied. Once we find the end of a contiguous region, copy it + // and add any necessary padding (with defaultValue). + let srcStart = 0; // Start of contiguous region (in values) + let dstStart = 0; // Destination for contiguous region (in output) + let dstEnd = 0; // Destination for contiguous region (in output) + for (let srcI = 0; srcI <= outputIndexSize; ++srcI) { + // dstI is the destination where the value at srcI should be copied. + let dstI = srcI < outputIndexSize ? outputIndex[srcI] : -1; + // If we're still in a contiguous region, then update dstEnd go to the + // next srcI. + if (dstI === dstEnd) { + ++dstEnd; + continue; + } + // We found the end of contiguous region. This can be because we found + // a gap (dstI > dstEnd), or a source value that shouldn't be copied + // because it's out-of-bounds (dstI == -1), or the end of the tensor + // (dstI === -1). + if (dstStart < dstEnd) { + // Copy the contiguous region. + const src = valuesBase.subarray(srcStart * valueElementSize); + const dst = outputBase.subarray(dstStart * valueElementSize); + const nVals = (dstEnd - dstStart) * valueElementSize; + copyArray(dst, src, nVals); + } + // Add any necessary padding (w/ defaultValue). + if (srcI >= outputIndexSize) { + // We reached the end of values: pad to the end of output. + const outputSize = outputTensor.length; + dstI = Math.floor(outputSize / valueElementSize); + } + if (dstI > dstEnd) { + if (this.defaultValue.length === 1) { + outputBase + .subarray(dstEnd * valueElementSize, dstI * valueElementSize) + .fill(this.defaultValue[0]); + dstEnd = dstI; + } + else { + while (dstI > dstEnd) { + const dst = outputBase.slice(dstEnd * valueElementSize); + copyArray(dst, defaultValue, valueElementSize); + ++dstEnd; + } + } + } + // Update indices. + if (dstI < 0) { + // srcI should be skipped -- leave it out of the contiguous region. + srcStart = srcI + 1; + dstStart = dstEnd; + } + else { + // srcI should be copied -- include it in the contiguous region. + srcStart = srcI; + dstStart = dstEnd; + dstEnd = dstStart + 1; + } + } + } + } + function copyArray(dst, src, size) { + for (let i = 0; i < size; i++) { + dst[i] = src[i]; + } + } + function makeShape(shape, isPartial) { + const out = []; + for (let dim of shape) { + if (dim < 0) { + if (!isPartial) { + throw new Error(`Dimension ${dim} must be >= 0`); + } + if (dim < -1) { + throw new Error(`Dimension ${dim} must be >= -1`); + } + dim = -1; + } + out.push(dim); + } + return out; + } + function raggedTensorToTensorImpl(shape, shapesShape, values, valuesShape, valuesDType, defaultValue, defaultValueShape, rowPartitionValues, rowPartitionValuesShapes, rowPartitionTypes) { + return new RaggedTensorToTensorOp(shape, shapesShape, values, valuesShape, valuesDType, defaultValue, defaultValueShape, rowPartitionValues, rowPartitionValuesShapes, rowPartitionTypes) + .compute(); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function rangeImpl(start, stop, step, dtype) { + const sameStartStop = start === stop; + const increasingRangeNegativeStep = start < stop && step < 0; + const decreasingRangePositiveStep = stop < start && step > 1; + if (sameStartStop || increasingRangeNegativeStep || + decreasingRangePositiveStep) { + return makeZerosTypedArray(0, dtype); + } + const numElements = Math.abs(Math.ceil((stop - start) / step)); + const values = makeZerosTypedArray(numElements, dtype); + if (stop < start && step === 1) { + // Auto adjust the step's sign if it hasn't been set + // (or was set to 1) + step = -1; + } + values[0] = start; + for (let i = 1; i < values.length; i++) { + values[i] = values[i - 1] + step; + } + return values; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const rsqrtImpl = createSimpleUnaryImpl((xi) => 1 / Math.sqrt(xi)); + const rsqrt$1 = unaryKernelFuncFromImpl(Rsqrt, rsqrtImpl); + const rsqrtConfig$1 = { + kernelName: Rsqrt, + backendName: 'cpu', + kernelFunc: rsqrt$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function scatterImpl(indices, updates, shape, outputSize, sliceSize, numUpdates, sliceRank, strides, defaultValue, sumDupeIndices) { + const flattenShape = [outputSize / sliceSize, sliceSize]; + const indicesData = indices.values; + const updatesData = updates.values; + if (outputSize === 0) { + return buffer(shape, updates.dtype); + } + const outBuf = (defaultValue instanceof TensorBuffer) ? + defaultValue : + buffer(flattenShape, updates.dtype); + if (typeof defaultValue === 'string') { + outBuf.values.fill(defaultValue); + } + else if (typeof defaultValue === 'number') { + outBuf.values.fill(defaultValue); + } + else if (typeof defaultValue === 'boolean') { + outBuf.values.fill(+defaultValue); + } + for (let i = 0; i < numUpdates; i++) { + const index = []; + let flattenIndex = 0; + for (let j = 0; j < sliceRank; j++) { + const dim = indicesData[i * sliceRank + j]; + index.push(dim); + flattenIndex += dim * strides[j]; + } + if (flattenIndex < 0 || flattenIndex >= outputSize / sliceSize) { + throw new Error(`Invalid indices: ${index} does not index into ${shape}`); + } + for (let k = 0; k < sliceSize; k++) { + if (sumDupeIndices) { + outBuf.values[flattenIndex * sliceSize + k] += + updatesData[i * sliceSize + k]; + } + else { + outBuf.values[flattenIndex * sliceSize + k] = updates.rank === 0 ? + updatesData[0] : + updatesData[i * sliceSize + k]; + } + } + } + return outBuf; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sigmoidImpl = createSimpleUnaryImpl((xi) => 1 / (1 + Math.exp(-xi))); + const sigmoid$1 = unaryKernelFunc$1(Sigmoid$1, (xi) => 1 / (1 + Math.exp(-xi))); + const sigmoidConfig$1 = { + kernelName: Sigmoid$1, + backendName: 'cpu', + kernelFunc: sigmoid$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sliceImpl(vals, begin, size, shape, dtype) { + const isContinous = isSliceContinous(shape, begin, size); + const length = sizeFromShape(size); + const xStrides = computeStrides(shape); + if (isContinous) { + const flatOffset = computeFlatOffset(begin, xStrides); + if (dtype === 'string') { + return vals.slice(flatOffset, flatOffset + length); + } + return vals.subarray(flatOffset, flatOffset + length); + } + const decodedData = dtype === 'string' ? + fromUint8ToStringArray(vals) : + vals; + const inBuf = buffer(shape, dtype, decodedData); + const outBuf = buffer(size, dtype); + for (let i = 0; i < outBuf.size; ++i) { + const outLoc = outBuf.indexToLoc(i); + const inLoc = outLoc.map((idx, j) => idx + begin[j]); + outBuf.set(inBuf.get(...inLoc), ...outLoc); + } + if (dtype === 'string') { + return fromStringArrayToUint8(outBuf.values); + } + return outBuf.values; + } + function slice$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { begin, size } = attrs; + assertNotComplex$1(x, 'slice'); + const [$begin, $size] = parseSliceParams(x, begin, size); + assertParamsValid(x, $begin, $size); + const vals = backend.data.get(x.dataId).values; + const outVals = sliceImpl(vals, $begin, $size, x.shape, x.dtype); + return backend.makeTensorInfo($size, x.dtype, outVals); + } + const sliceConfig$1 = { + kernelName: Slice, + backendName: 'cpu', + kernelFunc: slice$1 + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseFillEmptyRowsImpl(indices, indicesShape, indicesDType, values, valuesDType, denseShape, defaultValue) { + const indicesCount = indicesShape[0]; + const denseRows = denseShape[0]; + const emptyRowIndicator = new Array(denseRows); + const reverseIndexMap = new Array(indicesCount); + const rank = indicesShape[1]; + if (denseRows === 0) { + if (indicesCount !== 0) { + throw new Error(getSparseFillEmptyRowsIndicesDenseShapeMismatch(indicesCount)); + } + const outputIndices = getArrayFromDType(indicesDType, 0); + const outputValues = getArrayFromDType(valuesDType, 0); + return [ + outputIndices, [0, rank], outputValues, emptyRowIndicator, reverseIndexMap + ]; + } + let rowsAreOrdered = true; + let lastIndicesRow = 0; + const csrOffset = new Array(denseRows).fill(0); + for (let i = 0; i < indicesCount; ++i) { + // indices is a 2d tensor with shape of [N, rank] + const row = indices[i * rank]; + if (row < 0) { + throw new Error(getSparseFillEmptyRowsNegativeIndexErrorMessage(i, row)); + } + if (row >= denseRows) { + throw new Error(getSparseFillEmptyRowsOutOfRangeIndexErrorMessage(i, row, denseRows)); + } + ++csrOffset[row]; + rowsAreOrdered = rowsAreOrdered && (row >= lastIndicesRow); + lastIndicesRow = row; + } + let allRowsFull = true; + for (let row = 0; row < denseRows; ++row) { + // csrOffset here describes the number of elements in this dense row + const rowEmpty = (csrOffset[row] === 0); + emptyRowIndicator[row] = rowEmpty; + allRowsFull = allRowsFull && !rowEmpty; + // In filled version, each row has at least one element. + csrOffset[row] = Math.max(csrOffset[row], 1); + // Update csrOffset to represent the number of elements up to and + // including denseRows + 1: + // csrOffset[0] == #{elements of row 0} + // csrOffset[1] == #{elements of row 1} + #{elements of row 0} + // .. + // csrOffset[i] == starting index for elements in row i + 1. + if (row > 0) { + csrOffset[row] += csrOffset[row - 1]; + } + } + if (allRowsFull && rowsAreOrdered) { + const outputIndices = indices; + const outputValues = values; + for (let i = 0; i < indicesCount; ++i) { + reverseIndexMap[i] = i; + } + return [ + outputIndices, [indicesCount, rank], outputValues, emptyRowIndicator, + reverseIndexMap + ]; + } + else { + const fullIndicesCount = csrOffset[denseRows - 1]; + const outputIndices = getArrayFromDType(indicesDType, fullIndicesCount * rank); + const outputValues = getArrayFromDType(valuesDType, fullIndicesCount); + const filledCount = new Array(denseRows).fill(0); + // Fill in values for rows that are not missing + for (let i = 0; i < indicesCount; ++i) { + // indices is a 2d tensor with shape of [N, rank] + const row = indices[i * rank]; + const offset = filledCount[row]; + const outputI = ((row === 0) ? 0 : csrOffset[row - 1]) + offset; + filledCount[row]++; // Increment the filled count for this row. + for (let j = 0; j < rank; ++j) { + // indices and outputIndices are 2d tensors with shape of [N, rank] + outputIndices[outputI * rank + j] = indices[i * rank + j]; + } + outputValues[outputI] = values[i]; + // We'll need this reverse index map to backprop correctly. + reverseIndexMap[i] = outputI; + } + // Fill in values for rows that are missing + for (let row = 0; row < denseRows; ++row) { + const rowCount = filledCount[row]; + if (rowCount === 0) { // We haven't filled this row + const startingIndex = (row === 0) ? 0 : csrOffset[row - 1]; + // Remaining index values were set to zero already. + // Just need to set the row index in the right location. + // outputIndices is a 2d tensor with shape of [N, rank] + outputIndices[startingIndex * rank + 0] = row; + for (let col = 1; col < rank; ++col) { + outputIndices[startingIndex * rank + col] = 0; + } + outputValues[startingIndex] = defaultValue; + } + } + return [ + outputIndices, [fullIndicesCount, rank], outputValues, emptyRowIndicator, + reverseIndexMap + ]; + } + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseReshapeImpl(inputIndices, inputIndicesShape, inputDType, inputShape, targetShape) { + const denseSize = sizeFromShape(inputShape); + const nnz = inputIndicesShape[0]; + const outputRank = targetShape.length; + // Compute the output shape. Determine product of specified dimensions, and + // find the index of the unspecified one. + const outputShape = []; + let product = 1; + let unknownIndex = -1; + for (let d = 0; d < outputRank; ++d) { + const size = targetShape[d]; + if (size === -1) { + if (unknownIndex !== -1) { + throw new Error(getSparseReshapeMultipleNegativeOneOutputDimErrorMessage(unknownIndex, d)); + } + unknownIndex = d; + outputShape.push(1); + } + else { + if (size < 0) { + throw new Error(getSparseReshapeNegativeOutputDimErrorMessage(d, size)); + } + product *= size; + outputShape.push(size); + } + } + if (unknownIndex !== -1) { + if (product <= 0) { + throw new Error(getSparseReshapeEmptyTensorZeroOutputDimErrorMessage()); + } + const missing = Math.trunc(denseSize / product); + if (product * missing !== denseSize) { + throw new Error(getSparseReshapeInputOutputMultipleErrorMessage(inputShape, outputShape)); + } + outputShape[unknownIndex] = missing; + } + const outputSize = sizeFromShape(outputShape); + if (outputSize !== denseSize) { + throw new Error(getSparseReshapeInputOutputMismatchErrorMessage(inputShape, outputShape)); + } + const inputRank = inputShape.length; + const inputStrides = []; + if (inputRank > 0) { + inputStrides[inputRank - 1] = 1; + for (let d = inputRank - 2; d >= 0; --d) { + inputStrides[d] = inputStrides[d + 1] * inputShape[d + 1]; + } + } + const outputStrides = []; + if (outputRank > 0) { + outputStrides[outputRank - 1] = 1; + for (let d = outputRank - 2; d >= 0; --d) { + outputStrides[d] = outputStrides[d + 1] * outputShape[d + 1]; + } + } + const newIndices = getArrayFromDType(inputDType, nnz * outputRank); + for (let i = 0; i < nnz; ++i) { + let id = 0; + for (let j = 0; j < inputRank; ++j) { + // inputIndices is a 2d tensor with shape of [nnz, inputRank] + id += inputIndices[i * inputRank + j] * inputStrides[j]; + } + for (let j = 0; j < outputRank; ++j) { + // newIndices is a 2d tensor with shape of [nnz, outputRank] + newIndices[i * outputRank + j] = Math.trunc(id / outputStrides[j]); + id %= outputStrides[j]; + } + } + return [newIndices, [nnz, outputRank], outputShape]; + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseSegmentReductionImpl(input, inputShape, inputDType, indices, segmentIds, isMean = false, defaultValue = 0) { + const numIndices = indices.length; + // Flatten the array to two dimensions + const inputFlat = [inputShape[0], input.length / inputShape[0]]; + const numCol = inputFlat[1]; + // Note that the current implementation assumes that segmentIds values are + // sorted. + const lastSegmentIdPlusOne = numIndices > 0 ? segmentIds[numIndices - 1] + 1 : 0; + const outputRows = lastSegmentIdPlusOne; + if (outputRows < 0) { + throw new Error(getSparseSegmentReductionNegativeSegmentIdsErrorMessage()); + } + const outputShape = inputShape.slice(); + outputShape[0] = outputRows; + const outputLength = outputShape.reduce((product, value) => product * value, 1); + // Output array is initialized with the value 0 by default. + const output = getArrayFromDType(inputDType, outputLength); + // Note that we do not initialize the output buffer with a default value, so + // we need to explicitly set missing indices to the default value. + if (numIndices === 0) { + if (outputRows > 0) { + output.fill(defaultValue); + } + return [output, outputShape]; + } + if (outputRows <= 0) { + throw new Error(getSparseSegmentReductionNegativeSegmentIdsErrorMessage()); + } + let start = 0, end = 1; + // Index from which the output is not initialized. + let uninitializedIndex = 0; + let outIndex = segmentIds[start]; + while (true) { + // We initialize nextIndex to 0 to avoid may be uninitialized warning + let nextIndex = 0; + if (end < numIndices) { + nextIndex = segmentIds[end]; + if (outIndex === nextIndex) { + ++end; + continue; + } + // We have a new segment here. Verify that the segment ids are growing. + if (outIndex >= nextIndex) { + throw new Error(getSparseSegmentReductionNonIncreasingSegmentIdsErrorMessage()); + } + } + if (outIndex < 0 || outIndex >= outputRows) { + throw new Error(getSparseSegmentReductionSegmentIdOutOfRangeErrorMessage(outIndex, outputRows)); + } + // If there is a gap between two indices, we need to set that gap to the + // default value. + if (outIndex > uninitializedIndex) { + output.fill(defaultValue, uninitializedIndex * numCol, outIndex * numCol); + } + for (let i = start; i < end; ++i) { + const index = indices[i]; + if (index < 0 || index >= inputFlat[0]) { + throw new Error(getSparseSegmentReductionIndicesOutOfRangeErrorMessage(i, indices[i], inputFlat[0])); + } + for (let j = 0; j < numCol; j++) { + output[outIndex * numCol + j] += input[index * numCol + j]; + } + } + if (isMean) { + for (let j = 0; j < numCol; j++) { + output[outIndex * numCol + j] /= end - start; + } + } + start = end; + ++end; + uninitializedIndex = outIndex + 1; + outIndex = nextIndex; + if (end > numIndices) { + break; + } + } + // Fill the gap at the end with the default value. + if (uninitializedIndex < outputRows) { + output.fill(defaultValue, uninitializedIndex * numCol, outputRows * numCol); + } + return [output, outputShape]; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sqrtImpl = createSimpleUnaryImpl((xi) => Math.sqrt(xi)); + const sqrt$1 = unaryKernelFunc$1(Sqrt, (xi) => Math.sqrt(xi)); + const sqrtConfig$1 = { + kernelName: Sqrt, + backendName: 'cpu', + kernelFunc: sqrt$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const squaredDifferenceImpl = createSimpleBinaryKernelImpl(((a, b) => { + const diff = a - b; + return diff * diff; + })); + const squaredDifference$1 = binaryKernelFunc$1(SquaredDifference, squaredDifferenceImpl); + const squaredDifferenceConfig$1 = { + kernelName: SquaredDifference, + backendName: 'cpu', + kernelFunc: squaredDifference$1 + }; + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const staticRegexReplaceImpl = createSimpleUnaryImpl((x, attrs) => { + const { pattern, replaceGlobal, rewrite } = attrs; + // TODO(mattSoulanille): Don't create a regex each time. + return x.replace(new RegExp(pattern, replaceGlobal ? 'g' : ''), rewrite); + }); + const staticRegexReplace$1 = unaryKernelFuncFromImpl(StaticRegexReplace, staticRegexReplaceImpl); + const staticRegexReplaceConfig$1 = { + kernelName: StaticRegexReplace, + backendName: 'cpu', + kernelFunc: staticRegexReplace$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stridedSliceImpl(outShape, xBuf, strides, begin) { + const outBuf = buffer(outShape, xBuf.dtype); + for (let i = 0; i < outBuf.size; i++) { + const loc = outBuf.indexToLoc(i); + const newLoc = new Array(loc.length); + for (let j = 0; j < newLoc.length; j++) { + newLoc[j] = loc[j] * strides[j] + begin[j]; + } + outBuf.set(xBuf.get(...newLoc), ...loc); + } + return outBuf; + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * The StringNGramsOp class creates ngrams from ragged string data. + * The constructor contains all attributes related to the operation such as + * padding widths and strings, and the compute function can be used to + * compute the ngrams for different ragged tensor inputs. + */ + class StringNGramsOp { + constructor(separator, nGramWidths, leftPad, rightPad, padWidth, preserveShortSequences) { + this.separator = encodeString(separator); + this.nGramWidths = nGramWidths; + this.leftPad = encodeString(leftPad); + this.rightPad = encodeString(rightPad); + this.padWidth = padWidth; + this.preserveShort = preserveShortSequences; + } + getPadWidth(nGramWidth) { + // Ngrams can be padded with either a fixed pad width or a dynamic pad + // width depending on the 'padWidth' arg, but in no case should the padding + // ever be wider than 'nGramWidth' - 1. + return Math.min(this.padWidth < 0 ? nGramWidth - 1 : this.padWidth, nGramWidth - 1); + } + getNumNGrams(length, nGramWidth) { + const padWidth = this.getPadWidth(nGramWidth); + return Math.max(0, ((length + 2 * padWidth) - nGramWidth) + 1); + } + createNGrams(data, splitIndex, output, outputStartIndex, numNGrams, nGramWidth) { + for (let nGramIndex = 0; nGramIndex < numNGrams; ++nGramIndex) { + const padWidth = this.getPadWidth(nGramWidth); + const leftPadding = Math.max(0, padWidth - nGramIndex); + const rightPadding = Math.max(0, padWidth - (numNGrams - (nGramIndex + 1))); + const numTokens = nGramWidth - (leftPadding + rightPadding); + const dataStartIndex = splitIndex + (leftPadding > 0 ? 0 : nGramIndex - padWidth); + // Calculate the total expected size of the nGram so we can reserve the + // correct amount of space in the string. + let nGramSize = 0; + // Size of the left padding. + nGramSize += leftPadding * this.leftPad.length; + // Size of the tokens. + for (let n = 0; n < numTokens; ++n) { + nGramSize += data[dataStartIndex + n].length; + } + // Size of the right padding. + nGramSize += rightPadding * this.rightPad.length; + // Size of the separators. + const numSeparators = leftPadding + rightPadding + numTokens - 1; + nGramSize += numSeparators * this.separator.length; + // Build the nGram. + output[outputStartIndex + nGramIndex] = new Uint8Array(nGramSize); + const nGram = output[outputStartIndex + nGramIndex]; + let nextNGramIndex = 0; + const appendToNGram = (str) => str.forEach((value) => nGram[nextNGramIndex++] = value); + for (let n = 0; n < leftPadding; ++n) { + appendToNGram(this.leftPad); + appendToNGram(this.separator); + } + // Only output first numTokens - 1 pairs of data and separator + for (let n = 0; n < numTokens - 1; ++n) { + appendToNGram(data[dataStartIndex + n]); + appendToNGram(this.separator); + } + // Handle case when there are no tokens or no right padding as these + // can result in consecutive separators. + if (numTokens > 0) { + // If we have tokens, then output last and then pair each separator + // with the right padding that follows, to ensure nGram ends either with + // the token or with the right pad. + appendToNGram(data[dataStartIndex + numTokens - 1]); + for (let n = 0; n < rightPadding; ++n) { + appendToNGram(this.separator); + appendToNGram(this.rightPad); + } + } + else { + // If we don't have tokens, then the last item inserted into the nGram + // has been the separator from the left padding loop above. Hence, + // output right pad and separator and make sure to finish with a + // padding, not a separator. + for (let n = 0; n < rightPadding - 1; ++n) { + appendToNGram(this.rightPad); + appendToNGram(this.separator); + } + appendToNGram(this.rightPad); + } + } + } + // Data and splits together form the definition of the ragged tensor, + // where data is 1 dimensional and contains the values of the tensor + // and splits denotes the indices at which each row starts. + compute(data, splits) { + // Validate that the splits are valid indices into data, only if there are + // splits specified. + const inputDataSize = data.length; + const splitsSize = splits.length; + if (splitsSize > 0) { + let prevSplit = splits[0]; + if (prevSplit !== 0) { + throw new Error(`First split value must be 0, got ${prevSplit}`); + } + for (let i = 1; i < splitsSize; ++i) { + let validSplits = splits[i] >= prevSplit; + validSplits = validSplits && (splits[i] <= inputDataSize); + if (!validSplits) { + throw new Error(`Invalid split value ${splits[i]}, must be in [${prevSplit}, ${inputDataSize}]`); + } + prevSplit = splits[i]; + } + if (prevSplit !== inputDataSize) { + throw new Error(`Last split value must be data size. Expected ${inputDataSize}, got ${prevSplit}`); + } + } + const numBatchItems = splitsSize - 1; + const nGramsSplits = getArrayFromDType('int32', splitsSize); + // If there is no data or size, return an empty ragged tensor. + if (inputDataSize === 0 || splitsSize === 0) { + const empty = new Array(inputDataSize); + for (let i = 0; i <= numBatchItems; ++i) { + nGramsSplits[i] = 0; + } + return [empty, nGramsSplits]; + } + nGramsSplits[0] = 0; + for (let i = 1; i <= numBatchItems; ++i) { + const length = splits[i] - splits[i - 1]; + let numNGrams = 0; + this.nGramWidths.forEach((nGramWidth) => { + numNGrams += this.getNumNGrams(length, nGramWidth); + }); + if (this.preserveShort && length > 0 && numNGrams === 0) { + numNGrams = 1; + } + nGramsSplits[i] = nGramsSplits[i - 1] + numNGrams; + } + const nGrams = new Array(nGramsSplits[numBatchItems]); + for (let i = 0; i < numBatchItems; ++i) { + const splitIndex = splits[i]; + let outputStartIdx = nGramsSplits[i]; + this.nGramWidths.forEach((nGramWidth) => { + const length = splits[i + 1] - splits[i]; + const numNGrams = this.getNumNGrams(length, nGramWidth); + this.createNGrams(data, splitIndex, nGrams, outputStartIdx, numNGrams, nGramWidth); + outputStartIdx += numNGrams; + }); + // If we're preserving short sequences, check to see if no sequence was + // generated by comparing the current output start idx to the original + // one (nGramSplitsdata). If no ngrams were generated, then they will + // be equal (since we increment outputStartIdx by numNGrams every + // time we create a set of ngrams.) + if (this.preserveShort && outputStartIdx === nGramsSplits[i]) { + const dataLength = splits[i + 1] - splits[i]; + // One legitimate reason to not have any ngrams when this.preserveShort + // is true is if the sequence itself is empty. In that case, move on. + if (dataLength === 0) { + continue; + } + // We don't have to worry about dynamic padding sizes here: if padding + // was dynamic, every sequence would have had sufficient padding to + // generate at least one nGram. + const nGramWidth = dataLength + 2 * this.padWidth; + const numNGrams = 1; + this.createNGrams(data, splitIndex, nGrams, outputStartIdx, numNGrams, nGramWidth); + } + } + return [nGrams, nGramsSplits]; + } + } + function stringNGramsImpl(data, dataSplits, separator, nGramWidths, leftPad, rightPad, padWidth, preserveShortSequences) { + return new StringNGramsOp(separator, nGramWidths, leftPad, rightPad, padWidth, preserveShortSequences) + .compute(data, dataSplits); + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function split(str, delimiters, skipEmpty, result) { + if (!str.length) { + return; + } + // When the delimiter is empty, the input is split into individual characters. + if (delimiters.length === 0) { + for (let i = 0; i < str.length; ++i) { + result.push(str.subarray(i, i + 1)); + } + return; + } + // When there is one delimiter, the input is split only at that delimiter. + if (delimiters.length === 1) { + const delimiter = delimiters[0]; + let f = str.indexOf(delimiter); + while (f !== -1) { + const token = str.subarray(0, f); + if (!skipEmpty || token.length !== 0) { + result.push(token); + } + str = str.subarray(f + 1); + f = str.indexOf(delimiter); + } + if (!skipEmpty || str.length !== 0) { + result.push(str); + } + return; + } + // When there are multiple delimiters, the input is split at every instance + // one of the delimiters appears. + let tokenStart = 0; + for (let i = 0; i < str.length + 1; i++) { + if ((i === str.length) || (delimiters.indexOf(str[i]) !== -1)) { + const token = str.subarray(tokenStart, i); + if (!skipEmpty || token.length !== 0) { + result.push(token); + } + tokenStart = i + 1; + } + } + } + function stringSplitImpl(input, delimiter, skipEmpty) { + const batchSize = input.length; + // Empty delimiter means split the input character by character. + const tokens = []; + let outputSize = 0; + let maxNumEntries = 0; + const numIndices = new Array(batchSize); + for (let i = 0; i < batchSize; ++i) { + const prevTokensLength = tokens.length; + split(input[i], delimiter, skipEmpty, tokens); + const nEntries = tokens.length - prevTokensLength; + numIndices[i] = nEntries; + outputSize += nEntries; + maxNumEntries = Math.max(maxNumEntries, nEntries); + } + const indices = getArrayFromDType('int32', outputSize * 2); + const values = new Array(outputSize); + const shape = [batchSize, maxNumEntries]; + let c = 0; + for (let i = 0; i < batchSize; ++i) { + for (let j = 0; j < numIndices[i]; ++j) { + // indices is a 2d tensor with shape of [outputSize, 2] + indices[c * 2] = i; + indices[c * 2 + 1] = j; + values[c] = tokens[c]; + ++c; + } + } + return [indices, values, shape]; + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stringToHashBucketFastImpl(input, numBuckets) { + const output = getArrayFromDType('int32', input.length); + for (let i = 0; i < input.length; ++i) { + output[i] = + fingerPrint64(input[i]).modulo(numBuckets).getLowBitsUnsigned(); + } + return output; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const subImpl = createSimpleBinaryKernelImpl(((aValue, bValue) => aValue - bValue)); + const subComplexImpl = createComplexBinaryKernelImpl(((aReal, aImag, bReal, bImag) => { + return { real: aReal - bReal, imag: aImag - bImag }; + })); + const sub$1 = binaryKernelFunc$1(Sub, subImpl, subComplexImpl); + const subConfig$1 = { + kernelName: Sub, + backendName: 'cpu', + kernelFunc: sub$1 + }; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * An implementation of the tile kernel shared between webgl and cpu for string + * tensors only. + */ + function tileImpl(xBuf, reps) { + const newShape = new Array(xBuf.rank); + for (let i = 0; i < newShape.length; i++) { + newShape[i] = xBuf.shape[i] * reps[i]; + } + const result = buffer(newShape, xBuf.dtype); + for (let i = 0; i < result.values.length; ++i) { + const newLoc = result.indexToLoc(i); + const originalLoc = new Array(xBuf.rank); + for (let j = 0; j < originalLoc.length; j++) { + originalLoc[j] = newLoc[j] % xBuf.shape[j]; + } + const originalIndex = xBuf.locToIndex(originalLoc); + result.values[i] = xBuf.values[originalIndex]; + } + return result; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const comparePair = (a, b) => { + const valueDiff = b.value - a.value; + return valueDiff === 0 ? a.index - b.index : valueDiff; + }; + /** + * Partitions array where all elements smaller than the (k+1) smallest element + * are found to the left of it, and all larger to the right of it. + * Based on the Floyd-Rivest Algorithm, ref: + * https://en.wikipedia.org/wiki/Floyd%E2%80%93Rivest_algorithm + * @param array: Array to partition + * @param left: Left index for the interval + * @param right: Right index for the interval + * @param k: Desired index value, where array[k] is the (k+1)th smallest element + * when left = 0 + */ + function select$2(array, k, left = 0, right = array.length - 1) { + while (right > left) { + // Use select recursively to sample a smaller set of size s + // the arbitrary constants 600 and 0.5 are used in the original + // version to minimize execution time. + if (right - left > 600) { + const n = right - left + 1; + const i = k - left + 1; + const z = Math.log(n); + const s = 0.5 * Math.exp(2 * z / 3); + const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * Math.sign(i - n / 2); + const newLeft = Math.max(left, Math.floor(k - i * s / n + sd)); + const newRight = Math.min(right, Math.floor(k + (n - i) * s / n + sd)); + select$2(array, k, newLeft, newRight); + } + // partition the elements between left and right around t + const t = array[k]; + let i = left; + let j = right; + swap(array, left, k); + if (comparePair(array[right], t) > 0) { + swap(array, left, right); + } + while (i < j) { + swap(array, i, j); + i++; + j--; + while (comparePair(array[i], t) < 0) { + i = i + 1; + } + while (comparePair(array[j], t) > 0) { + j = j - 1; + } + } + if (comparePair(array[left], t) === 0) { + swap(array, left, j); + } + else { + j = j + 1; + swap(array, j, right); + } + // Adjust left and right towards the boundaries of the subset + // containing the (k - left + 1)th smallest element. + if (j <= k) { + left = j + 1; + } + if (k <= j) { + right = j - 1; + } + } + } + function topKImpl(x, xShape, xDtype, k, sorted) { + // Reshape into a 2d tensor [batch, lastDim] and compute topk along lastDim. + const lastDim = xShape[xShape.length - 1]; + const [batch, size] = [x.length / lastDim, lastDim]; + const allTopKVals = getTypedArrayFromDType(xDtype, batch * k); + const allTopKIndices = getTypedArrayFromDType('int32', batch * k); + for (let b = 0; b < batch; b++) { + const offset = b * size; + const vals = x.subarray(offset, offset + size); + let valAndInd = new Array(vals.length); + vals.forEach((value, index) => valAndInd[index] = { value, index }); + if (k < valAndInd.length) { + select$2(valAndInd, k); + valAndInd = valAndInd.slice(0, k); + } + if (sorted) { + valAndInd.sort(comparePair); + } + const outOffset = b * k; + const topKVals = allTopKVals.subarray(outOffset, outOffset + k); + const topKIndices = allTopKIndices.subarray(outOffset, outOffset + k); + for (let i = 0; i < k; i++) { + topKVals[i] = valAndInd[i].value; + topKIndices[i] = valAndInd[i].index; + } + } + // Reshape back to the original input shape, except that the last + // dimension is k. + const outputShape = xShape.slice(); + outputShape[outputShape.length - 1] = k; + return [ + buffer(outputShape, xDtype, allTopKVals), + buffer(outputShape, 'int32', allTopKIndices) + ]; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function uniqueImpl(values, axis, shape, dtype) { + // Normalize and validate axis. + const $axis = parseAxisParam(axis, shape)[0]; + // Calculate the new shape that is suitable for extracting data along the + // given axis. + // + // The rank is 3. + // The size of the 1st dimension is the size of all the axes < the given axis. + // The size of the 2nd dimension is the same as the size of the given axis. + // The size of the 3rd dimension is the size of all the axes > the given axis. + // + // For example, for a 4D tensor with shape=[2, 3, 5, 4] and axis=2, the + // newShape would be: [2*3, 5, 4]. + // + // Note that this is not the final output shape. This will be the shape for an + // intermediate TensorBuffer (see inputBuffer below) to allow us to extract + // values along the given axis. To demonstrate how it works, consider the + // following example: + // + // Input: a 3D tensor, with shape [1, 2, 3] + // [ + // [ + // [1,2,3], + // [4,5,6] + // ] + // ] + // Axis: 2 (the last axis). + // Along axis 2, we expect to extract 3 tensors: [1,4], [2,5], [3,6]. + // + // For this example, newShape would be: [2, 3, 1], where 2 is calculated from + // 1*2. The re-shaped data would look like: + // + // [ + // [ + // [1], [2], [3] + // ], + // [ + // [4], [5], [6] + // ] + // ] + // + // Then, we can construct a 3-level nested loop by the following dimension + // order to extract the values along the axis (dimension1): + // i: dimension1 // 0,1,2 (newShape[1]) + // m: dimension0 // 0,1 (newShape[0]) + // n: dimension2 // 0 (newShape[2]) + // + // m, i, n + // --------- + // Iteration 0: data at [0, 0, 0] => "1" + // Iteration 1: data at [1, 0, 0] => "4" + // We got [1,4]. + // Iteration 2: data at [0, 1, 0] => "2" + // Iteration 3: data at [1, 1, 0] => "5" + // We got [2,5]. + // Iteration 4: data at [0, 2, 0] => "3" + // Iteration 5: data at [1, 2, 0] => "6" + // We got [3,6]. + const newShape = [1, shape[0], 1]; + for (let i = 0; i < $axis; i++) { + newShape[0] *= shape[i]; + } + newShape[1] = shape[$axis]; + for (let i = $axis + 1; i < shape.length; i++) { + newShape[2] *= shape[i]; + } + // A map from unique elements (their string representations) to their values + // in "indices" (below). + const uniqueElements = new Map(); + // The indices of each unique element in the original tensor along the given + // axis. It is 1D and has the same size as the given axis. + const indices = new Int32Array(shape[$axis]); + // Create a buffer so we can easily extract value at a given location. + const inputBuffer = new TensorBuffer(newShape, dtype, values); + // The indices along the given axis that have unique elements. This is a + // de-duped version of "indices" above. + const uniqueIndices = []; + const is1DTensor = newShape[0] === 1 && newShape[2] === 1; + for (let i = 0; i < shape[$axis]; i++) { + // Extract values along the axis. + let element; + if (is1DTensor) { + // Fast path for 1D tensor input. + element = values[i].toString(); + } + else { + const axisValues = []; + for (let m = 0; m < newShape[0]; m++) { + for (let n = 0; n < newShape[2]; n++) { + axisValues.push(inputBuffer.get(m, i, n)); + } + } + element = axisValues.join(','); + } + // Dedup and update various indices. + const existingIndex = uniqueElements.get(element); + if (existingIndex != null) { + indices[i] = existingIndex; + } + else { + const uniqueIndex = uniqueElements.size; + uniqueElements.set(element, uniqueIndex); + indices[i] = uniqueIndex; + uniqueIndices.push(i); + } + } + // Now we know where each of the unique elements are located along the axis + // (uniqueIndices). Extract them from input buffer and store them in the + // output buffer. + const outputTmpShape = newShape.slice(); + outputTmpShape[1] = uniqueElements.size; + const outputBuffer = new TensorBuffer(outputTmpShape, dtype); + uniqueIndices.forEach((uniqueElementIndex, i) => { + for (let m = 0; m < newShape[0]; m++) { + for (let n = 0; n < newShape[2]; n++) { + outputBuffer.set(inputBuffer.get(m, uniqueElementIndex, n), m, i, n); + } + } + }); + // The output shape can be calculated from the input shape with the size of + // the given axis replaced by the number of unique elements along that axis. + const outputShape = shape.slice(); + outputShape[$axis] = outputTmpShape[1]; + return { + outputValues: outputBuffer.values, + outputShape, + indices, + }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + var shared = /*#__PURE__*/Object.freeze({ + __proto__: null, + addImpl: addImpl, + bincountImpl: bincountImpl, + bincountReduceImpl: bincountReduceImpl, + bitwiseAndImpl: bitwiseAndImpl, + castImpl: castImpl, + ceilImpl: ceilImpl, + concatImpl: concatImpl$1, + equalImpl: equalImpl, + expImpl: expImpl, + expm1Impl: expm1Impl, + floorDivImpl: floorDivImpl, + floorImpl: floorImpl, + gatherNdImpl: gatherNdImpl, + gatherV2Impl: gatherV2Impl, + greaterEqualImpl: greaterEqualImpl, + greaterImpl: greaterImpl, + lessEqualImpl: lessEqualImpl, + lessImpl: lessImpl, + linSpaceImpl: linSpaceImpl, + logImpl: logImpl, + maxImpl: maxImpl$1, + maximumImpl: maximumImpl, + minimumImpl: minimumImpl, + multiplyImpl: multiplyImpl, + negImpl: negImpl, + notEqualImpl: notEqualImpl, + prodImpl: prodImpl, + raggedGatherImpl: raggedGatherImpl, + raggedRangeImpl: raggedRangeImpl, + raggedTensorToTensorImpl: raggedTensorToTensorImpl, + rangeImpl: rangeImpl, + rsqrtImpl: rsqrtImpl, + scatterImpl: scatterImpl, + sigmoidImpl: sigmoidImpl, + simpleAbsImpl: simpleAbsImpl, + sliceImpl: sliceImpl, + sparseFillEmptyRowsImpl: sparseFillEmptyRowsImpl, + sparseReshapeImpl: sparseReshapeImpl, + sparseSegmentReductionImpl: sparseSegmentReductionImpl, + sqrtImpl: sqrtImpl, + squaredDifferenceImpl: squaredDifferenceImpl, + staticRegexReplaceImpl: staticRegexReplaceImpl, + stridedSliceImpl: stridedSliceImpl, + stringNGramsImpl: stringNGramsImpl, + stringSplitImpl: stringSplitImpl, + stringToHashBucketFastImpl: stringToHashBucketFastImpl, + subImpl: subImpl, + tileImpl: tileImpl, + topKImpl: topKImpl, + transposeImpl: transposeImpl$1, + uniqueImpl: uniqueImpl + }); + + /** @license See the LICENSE file. */ + // This code is auto-generated, do not modify this file! + const version$3 = '4.22.0'; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Side effects for default initialization of MathBackendCPU + registerBackend('cpu', () => new MathBackendCPU(), 1 /* priority */); + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const elu$1 = unaryKernelFunc$1(Elu$1, (xi) => xi >= 0 ? xi : (Math.exp(xi) - 1)); + const eluConfig$1 = { + kernelName: Elu$1, + backendName: 'cpu', + kernelFunc: elu$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function leakyRelu$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { alpha } = attrs; + assertNotComplex$1([x], 'leakyRelu'); + const xSize = sizeFromShape(x.shape); + const xVals = backend.data.get(x.dataId).values; + const outVals = getTypedArrayFromDType('float32', xSize); + for (let i = 0; i < xVals.length; i++) { + outVals[i] = xVals[i] < 0 ? alpha * xVals[i] : xVals[i]; + } + return backend.makeTensorInfo(x.shape, 'float32', outVals); + } + const leakyReluConfig$1 = { + kernelName: LeakyRelu, + backendName: 'cpu', + kernelFunc: leakyRelu$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const preluImpl = createSimpleBinaryKernelImpl((xValue, aValue) => xValue < 0 ? aValue * xValue : xValue); + function prelu$1(args) { + const { inputs, backend } = args; + const { x, alpha } = inputs; + assertNotComplex$1([x, alpha], 'prelu'); + const aVals = backend.data.get(x.dataId).values; + const bVals = backend.data.get(alpha.dataId).values; + const [resultData, resultShape] = preluImpl(x.shape, alpha.shape, aVals, bVals, 'float32'); + return backend.makeTensorInfo(resultShape, 'float32', resultData); + } + const preluConfig$1 = { + kernelName: Prelu, + backendName: 'cpu', + kernelFunc: prelu$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const relu$1 = unaryKernelFunc$1(Relu$1, (xi) => Math.max(0, xi)); + const reluConfig$1 = { + kernelName: Relu$1, + backendName: 'cpu', + kernelFunc: relu$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const relu6$1 = unaryKernelFunc$1(Relu6$1, (xi) => Math.min(Math.max(0, xi), 6)); + const relu6Config$1 = { + kernelName: Relu6$1, + backendName: 'cpu', + kernelFunc: relu6$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function applyActivation(backend, x, activation, preluActivationWeights, leakyreluAlpha) { + if (activation === 'linear') { + return identity$1({ inputs: { x }, backend }); + } + else if (activation === 'relu') { + return relu$1({ inputs: { x }, backend }); + } + else if (activation === 'elu') { + return elu$1({ inputs: { x }, backend }); + } + else if (activation === 'relu6') { + return relu6$1({ inputs: { x }, backend }); + } + else if (activation === 'prelu') { + return prelu$1({ inputs: { x, alpha: preluActivationWeights }, backend }); + } + else if (activation === 'leakyrelu') { + return leakyRelu$1({ inputs: { x }, backend, attrs: { alpha: leakyreluAlpha } }); + } + else if (activation === 'sigmoid') { + return sigmoid$1({ inputs: { x }, backend }); + } + throw new Error(`Activation ${activation} has not been implemented for the CPU backend.`); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function reshape$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { shape } = attrs; + const xSize = sizeFromShape(x.shape); + const $shape = inferFromImplicitShape(shape, xSize); + const $xSize = sizeFromShape($shape); + assert$1(xSize === $xSize, () => `The new shape (${$shape}) has ${$xSize} elements and the old ` + + `shape (${x.shape}) has ${xSize} elements. The new shape and old ` + + `shape must have the same number of elements.`); + backend.incRef(x.dataId); + const xData = backend.data.get(x.dataId); + if (xData.complexTensorInfos != null) { + const real = xData.complexTensorInfos.real; + const imag = xData.complexTensorInfos.imag; + real.shape = $shape; + imag.shape = $shape; + } + return { dataId: x.dataId, shape: $shape, dtype: x.dtype }; + } + const reshapeConfig$1 = { + kernelName: Reshape$1, + backendName: 'cpu', + kernelFunc: reshape$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function batchMatMul$1(args) { + const { inputs, backend, attrs } = args; + const { a, b } = inputs; + const { transposeA, transposeB } = attrs; + assertNotComplex$1([a, b], 'matMul'); + const aRank = a.shape.length; + const bRank = b.shape.length; + const innerShapeA = transposeA ? a.shape[aRank - 2] : a.shape[aRank - 1]; + const innerShapeB = transposeB ? b.shape[bRank - 1] : b.shape[bRank - 2]; + const outerShapeA = transposeA ? a.shape[aRank - 1] : a.shape[aRank - 2]; + const outerShapeB = transposeB ? b.shape[bRank - 2] : b.shape[bRank - 1]; + const outerDimsA = a.shape.slice(0, -2); + const outerDimsB = b.shape.slice(0, -2); + const batchDimA = sizeFromShape(outerDimsA); + const batchDimB = sizeFromShape(outerDimsB); + const outShapeOuterDims = assertAndGetBroadcastShape(a.shape.slice(0, -2), b.shape.slice(0, -2)); + const outShape = outShapeOuterDims.concat([outerShapeA, outerShapeB]); + assert$1(innerShapeA === innerShapeB, () => `Error in matMul: inner shapes (${innerShapeA}) and (` + + `${innerShapeB}) of Tensors with shapes ${a.shape} and ` + + `${b.shape} and transposeA=${transposeA}` + + ` and transposeB=${transposeB} must match.`); + const a3dShape = transposeA ? [batchDimA, innerShapeA, outerShapeA] : + [batchDimA, outerShapeA, innerShapeA]; + const b3dShape = transposeB ? [batchDimB, outerShapeB, innerShapeB] : + [batchDimB, innerShapeB, outerShapeB]; + // The rest of the implementation is designed to operate on rank-3 tensors + const a3d = reshape$1({ inputs: { x: a }, backend, attrs: { shape: a3dShape } }); + const b3d = reshape$1({ inputs: { x: b }, backend, attrs: { shape: b3dShape } }); + const sharedDim = transposeA ? a3d.shape[1] : a3d.shape[2]; + const leftDim = transposeA ? a3d.shape[2] : a3d.shape[1]; + const rightDim = transposeB ? b3d.shape[1] : b3d.shape[2]; + const batchDim = Math.max(batchDimA, batchDimB); + const a3dValues = backend.data.get(a3d.dataId).values; + const b3dValues = backend.data.get(b3d.dataId).values; + const a3dStrides = computeStrides(a3d.shape); + const b3dStrides = computeStrides(b3d.shape); + const [aBatch, aOuterStep, aInnerStep] = transposeA ? + [a3dStrides[0], 1, a3dStrides[1]] : + [a3dStrides[0], a3dStrides[1], 1]; + const [bInnerStep, bOuterStep, bBatch] = transposeB ? + [1, b3dStrides[1], b3dStrides[0]] : + [b3dStrides[1], 1, b3dStrides[0]]; + const size = leftDim * rightDim; + const result = buffer([batchDim, leftDim, rightDim], a3d.dtype); + const resVals = result.values; + const blockSize = backend.blockSize; + for (let bi = 0; bi < batchDim; bi++) { + const batchIndexA = bi % batchDimA; + const batchIndexB = bi % batchDimB; + for (let i0 = 0; i0 < leftDim; i0 += blockSize) { + // for when blockSize doesn't evenly divide the input + const iBlock = Math.min(i0 + blockSize, leftDim); + for (let j0 = 0; j0 < rightDim; j0 += blockSize) { + const jBlock = Math.min(j0 + blockSize, rightDim); + for (let k0 = 0; k0 < sharedDim; k0 += blockSize) { + const kBlock = Math.min(k0 + blockSize, sharedDim); + for (let i = i0; i < iBlock; i++) { + for (let j = j0; j < jBlock; j++) { + let sum = 0.0; + for (let k = k0; k < kBlock; k++) { + const aVal = + // tslint:disable-next-line: max-line-length + a3dValues[batchIndexA * aBatch + i * aOuterStep + k * aInnerStep]; + const bVal = + // tslint:disable-next-line: max-line-length + b3dValues[k * bInnerStep + j * bOuterStep + batchIndexB * bBatch]; + sum += aVal * bVal; + } + resVals[bi * size + (i * rightDim + j)] += sum; + } + } + } + } + } + } + backend.disposeIntermediateTensorInfo(a3d); + backend.disposeIntermediateTensorInfo(b3d); + // set correct shape on output. + return backend.makeTensorInfo(outShape, result.dtype, result.values); + } + const batchMatMulConfig$1 = { + kernelName: BatchMatMul, + backendName: 'cpu', + kernelFunc: batchMatMul$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function _fusedMatMul$1(args) { + const { inputs, backend, attrs } = args; + const { a, b, bias, preluActivationWeights } = inputs; + const { transposeA, transposeB, activation, leakyreluAlpha } = attrs; + let current; + let addRes; + let activationRes; + const intermediates = []; + const matMulRes = batchMatMul$1({ inputs: { a, b }, attrs: { transposeA, transposeB }, backend }); + current = matMulRes; + if (bias) { + addRes = add({ inputs: { a: current, b: bias }, backend }); + intermediates.push(current); + current = addRes; + } + if (activation) { + activationRes = applyActivation(backend, current, activation, preluActivationWeights, leakyreluAlpha); + intermediates.push(current); + current = activationRes; + } + for (const i of intermediates) { + backend.disposeIntermediateTensorInfo(i); + } + return current; + } + const _fusedMatMulConfig$1 = { + kernelName: _FusedMatMul, + backendName: 'cpu', + kernelFunc: _fusedMatMul$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const acos$1 = unaryKernelFunc$1(Acos, (xi) => Math.acos(xi)); + const acosConfig$1 = { + kernelName: Acos, + backendName: 'cpu', + kernelFunc: acos$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const acosh$1 = unaryKernelFunc$1(Acosh, (xi) => Math.acosh(xi)); + const acoshConfig$1 = { + kernelName: Acosh, + backendName: 'cpu', + kernelFunc: acosh$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function addN$1(args) { + const { inputs, backend } = args; + const tensors = inputs; + assertNotComplex$1(inputs, 'addN'); + const vals = tensors.map(t => backend.data.get(t.dataId).values); + const outBuf = buffer(tensors[0].shape, tensors[0].dtype); + const outVals = outBuf.values; + for (let i = 0; i < tensors.length; i++) { + const currVals = vals[i]; + for (let j = 0; j < outVals.length; j++) { + outVals[j] += currVals[j]; + } + } + return backend.makeTensorInfo(outBuf.shape, outBuf.dtype, outBuf.values); + } + const addNConfig$1 = { + kernelName: AddN, + backendName: 'cpu', + kernelFunc: addN$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function all$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + assertNotComplex$1(x, 'all'); + const origAxes = parseAxisParam(axis, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, x.shape.length); + let $x = x; + if (permutedAxes != null) { + $x = transpose$1({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + axes = getInnerMostAxes(axes.length, x.shape.length); + } + assertAxesAreInnerMostDims('all', axes, $x.shape.length); + const [outShape, reduceShape] = computeOutAndReduceShapes($x.shape, axes); + const reduceSize = sizeFromShape(reduceShape); + const vals = makeZerosTypedArray(sizeFromShape(outShape), $x.dtype); + const aVals = backend.data.get($x.dataId).values; + for (let i = 0; i < vals.length; ++i) { + const offset = i * reduceSize; + let all = aVals[offset]; + for (let j = 0; j < reduceSize; ++j) { + const value = aVals[offset + j]; + all = all && value; + } + vals[i] = all; + } + if (permutedAxes != null) { + backend.disposeIntermediateTensorInfo($x); + } + const result = backend.makeTensorInfo(outShape, $x.dtype, vals); + if (keepDims) { + const expandedShape = expandShapeToKeepDim(outShape, origAxes); + const reshapedResult = reshape$1({ inputs: { x: result }, backend, attrs: { shape: expandedShape } }); + backend.disposeIntermediateTensorInfo(result); + return reshapedResult; + } + return result; + } + const allConfig$1 = { + kernelName: All, + backendName: 'cpu', + kernelFunc: all$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function any$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + assertNotComplex$1(x, 'any'); + const origAxes = parseAxisParam(axis, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, x.shape.length); + let $x = x; + if (permutedAxes != null) { + $x = transpose$1({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + axes = getInnerMostAxes(axes.length, x.shape.length); + } + assertAxesAreInnerMostDims('any', axes, $x.shape.length); + const [outShape, reduceShape] = computeOutAndReduceShapes($x.shape, axes); + const reduceSize = sizeFromShape(reduceShape); + const vals = makeZerosTypedArray(sizeFromShape(outShape), $x.dtype); + const aVals = backend.data.get($x.dataId).values; + for (let i = 0; i < vals.length; ++i) { + const offset = i * reduceSize; + let anyVal = aVals[offset]; + for (let j = 0; j < reduceSize; ++j) { + const value = aVals[offset + j]; + anyVal = anyVal || value; + } + vals[i] = anyVal; + } + if (permutedAxes != null) { + backend.disposeIntermediateTensorInfo($x); + } + const result = backend.makeTensorInfo(outShape, $x.dtype, vals); + if (keepDims) { + const expandedShape = expandShapeToKeepDim(outShape, origAxes); + const reshapedResult = reshape$1({ inputs: { x: result }, backend, attrs: { shape: expandedShape } }); + backend.disposeIntermediateTensorInfo(result); + return reshapedResult; + } + return result; + } + const anyConfig$1 = { + kernelName: Any, + backendName: 'cpu', + kernelFunc: any$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function argMax$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis } = attrs; + assertNotComplex$1(x, 'argMax'); + let axes = parseAxisParam(axis, x.shape); + const permutedAxes = getAxesPermutation(axes, x.shape.length); + let $x = x; + const intermediateTensorInfos = []; + if (permutedAxes != null) { + $x = transpose$1({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + intermediateTensorInfos.push($x); + axes = getInnerMostAxes(axes.length, $x.shape.length); + } + axes = [axes[0]]; + assertAxesAreInnerMostDims('argMax', axes, $x.shape.length); + const [outShape, reduceShape] = computeOutAndReduceShapes($x.shape, axes); + const outSize = sizeFromShape(outShape); + const vals = makeZerosTypedArray(outSize, 'int32'); + const reduceSize = sizeFromShape(reduceShape); + const aVals = backend.data.get($x.dataId).values; + for (let i = 0; i < vals.length; ++i) { + const offset = i * reduceSize; + let max = aVals[offset]; + let maxIndex = 0; + for (let j = 0; j < reduceSize; ++j) { + const value = aVals[offset + j]; + if (value > max) { + max = value; + maxIndex = j; + } + } + vals[i] = maxIndex; + } + intermediateTensorInfos.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return backend.makeTensorInfo(outShape, 'int32', vals); + } + const argMaxConfig$1 = { + kernelName: ArgMax, + backendName: 'cpu', + kernelFunc: argMax$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function argMin$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis } = attrs; + assertNotComplex$1(x, 'argMin'); + let axes = parseAxisParam(axis, x.shape); + const permutedAxes = getAxesPermutation(axes, x.shape.length); + let $x = x; + const intermediateTensorInfos = []; + if (permutedAxes != null) { + $x = transpose$1({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + intermediateTensorInfos.push($x); + axes = getInnerMostAxes(axes.length, $x.shape.length); + } + axes = [axes[0]]; + assertAxesAreInnerMostDims('argMin', axes, $x.shape.length); + const [outShape, reduceShape] = computeOutAndReduceShapes($x.shape, axes); + const outSize = sizeFromShape(outShape); + const vals = makeZerosTypedArray(outSize, 'int32'); + const reduceSize = sizeFromShape(reduceShape); + const aVals = backend.data.get($x.dataId).values; + for (let i = 0; i < vals.length; ++i) { + const offset = i * reduceSize; + let min = aVals[offset]; + let minIndex = 0; + for (let j = 0; j < reduceSize; ++j) { + const value = aVals[offset + j]; + if (value < min) { + min = value; + minIndex = j; + } + } + vals[i] = minIndex; + } + intermediateTensorInfos.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return backend.makeTensorInfo(outShape, 'int32', vals); + } + const argMinConfig$1 = { + kernelName: ArgMin, + backendName: 'cpu', + kernelFunc: argMin$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const asin$1 = unaryKernelFunc$1(Asin, (xi) => Math.asin(xi)); + const asinConfig$1 = { + kernelName: Asin, + backendName: 'cpu', + kernelFunc: asin$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const asinh$1 = unaryKernelFunc$1(Asinh, (xi) => Math.asinh(xi)); + const asinhConfig$1 = { + kernelName: Asinh, + backendName: 'cpu', + kernelFunc: asinh$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const atan$1 = unaryKernelFunc$1(Atan, (xi) => Math.atan(xi)); + const atanConfig$1 = { + kernelName: Atan, + backendName: 'cpu', + kernelFunc: atan$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const atan2Impl = createSimpleBinaryKernelImpl((aValue, bValue) => Math.atan2(aValue, bValue)); + const atan2$1 = binaryKernelFunc$1(Atan2, atan2Impl); + const atan2Config$1 = { + kernelName: Atan2, + backendName: 'cpu', + kernelFunc: atan2$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const atanh$1 = unaryKernelFunc$1(Atanh, (xi) => Math.atanh(xi)); + const atanhConfig$1 = { + kernelName: Atanh, + backendName: 'cpu', + kernelFunc: atanh$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function pool(xValues, xShape, dtype, strides, convInfo, poolType) { + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + const initialValue = (poolType === 'max' ? Number.NEGATIVE_INFINITY : + Number.POSITIVE_INFINITY); + const output = buffer(convInfo.outShape, dtype); + const outputVals = output.values; + const outputBatchStrides = convInfo.outShape[1] * convInfo.outShape[2] * convInfo.outShape[3]; + const outputRowStrides = convInfo.outShape[2] * convInfo.outShape[3]; + const outputColStrides = convInfo.outShape[3]; + for (let b = 0; b < convInfo.batchSize; ++b) { + const outputBatchOffset = b * outputBatchStrides; + const inputBatchOffset = b * strides[0]; + for (let d = 0; d < convInfo.inChannels; ++d) { + for (let yR = 0; yR < convInfo.outHeight; ++yR) { + const xRCorner = yR * strideHeight - padTop; + const xRMin = Math.max(0, xRCorner); + const xRMax = Math.min(convInfo.inHeight, effectiveFilterHeight + xRCorner); + const outputRowOffset = outputBatchOffset + yR * outputRowStrides; + for (let yC = 0; yC < convInfo.outWidth; ++yC) { + const xCCorner = yC * strideWidth - padLeft; + const xCMin = Math.max(0, xCCorner); + const xCMax = Math.min(convInfo.inWidth, effectiveFilterWidth + xCCorner); + let minMaxValue = initialValue; + let avgValue = 0; + let count = 0; + for (let xR = xRMin; xR < xRMax; xR += dilationHeight) { + const xROffset = inputBatchOffset + xR * strides[1]; + for (let xC = xCMin; xC < xCMax; xC += dilationWidth) { + const xCOffset = xROffset + xC * strides[2]; + const pixel = xValues[xCOffset + d]; + if ((poolType === 'max' && pixel > minMaxValue)) { + minMaxValue = pixel; + } + else if (poolType === 'avg') { + avgValue += pixel; + count++; + } + } + if (isNaN(minMaxValue)) { + break; + } + } + const outputOffset = outputRowOffset + yC * outputColStrides + d; + outputVals[outputOffset] = + poolType === 'avg' ? avgValue / count : minMaxValue; + } + } + } + } + return output; + } + function maxPoolPositions(xValues, xShape, dtype, convInfo, flattenPositions = false, includeBatchInIndex = false) { + const maxPositions = buffer(convInfo.outShape, 'int32'); + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + const xBuf = buffer(xShape, dtype, xValues); + for (let b = 0; b < convInfo.batchSize; ++b) { + for (let d = 0; d < convInfo.inChannels; ++d) { + for (let yR = 0; yR < convInfo.outHeight; ++yR) { + const xRCorner = yR * strideHeight - padTop; + let xRMin = xRCorner; + while (xRMin < 0) { + xRMin += dilationHeight; + } + // const xRMin = Math.max(0, xRCorner); + const xRMax = Math.min(convInfo.inHeight, effectiveFilterHeight + xRCorner); + for (let yC = 0; yC < convInfo.outWidth; ++yC) { + const xCCorner = yC * strideWidth - padLeft; + let xCMin = xCCorner; + while (xCMin < 0) { + xCMin += dilationWidth; + } + const xCMax = Math.min(convInfo.inWidth, effectiveFilterWidth + xCCorner); + let maxValue = Number.NEGATIVE_INFINITY; + let maxPosition = -1; + for (let xR = xRMin; xR < xRMax; xR += dilationHeight) { + const wR = xR - xRCorner; + for (let xC = xCMin; xC < xCMax; xC += dilationWidth) { + const wC = xC - xCCorner; + // For some reason, disable-next-line is not working + // TODO(mattsoulanille): Remove this when switching to TS5. + /* tslint:disable: no-unnecessary-type-assertion */ + const pixel = xBuf.get(b, xR, xC, d); + if (pixel > maxValue) { + maxValue = pixel; + if (flattenPositions) { + maxPosition = includeBatchInIndex ? + ((b * convInfo.inHeight + xR) * convInfo.inWidth + xC) * + convInfo.inChannels + + d : + (xR * convInfo.inWidth + xC) * convInfo.inChannels + d; + } + else { + maxPosition = wR * effectiveFilterWidth + wC; + } + } + } + } + maxPositions.set(maxPosition, b, yR, yC, d); + } + } + } + } + return maxPositions; + } + function pool3d(xValues, xShape, dtype, strides, convInfo, poolType) { + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationDepth = convInfo.dilationDepth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterDepth = convInfo.effectiveFilterDepth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padFront = convInfo.padInfo.front; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + const initialValue = (poolType === 'max' ? Number.NEGATIVE_INFINITY : + Number.POSITIVE_INFINITY); + const output = buffer(convInfo.outShape, dtype); + const outputVals = output.values; + const outputBatchStrides = convInfo.outShape[1] * convInfo.outShape[2] * + convInfo.outShape[3] * convInfo.outShape[4]; + const outputDepthStrides = convInfo.outShape[2] * convInfo.outShape[3] * convInfo.outShape[4]; + const outputRowStrides = convInfo.outShape[3] * convInfo.outShape[4]; + const outputColStrides = convInfo.outShape[4]; + for (let batch = 0; batch < convInfo.batchSize; ++batch) { + const outputBatchOffset = batch * outputBatchStrides; + const inputBatchOffset = batch * strides[0]; + for (let channel = 0; channel < convInfo.inChannels; ++channel) { + for (let yDepth = 0; yDepth < convInfo.outDepth; ++yDepth) { + const xDepthCorner = yDepth * strideDepth - padFront; + let xDepthMin = xDepthCorner; + while (xDepthMin < 0) { + xDepthMin += dilationDepth; + } + const xDepthMax = Math.min(convInfo.inDepth, effectiveFilterDepth + xDepthCorner); + const outputDepthOffset = outputBatchOffset + yDepth * outputDepthStrides; + for (let yRow = 0; yRow < convInfo.outHeight; ++yRow) { + const xRowCorner = yRow * strideHeight - padTop; + let xRowMin = xRowCorner; + while (xRowMin < 0) { + xRowMin += dilationHeight; + } + const xRowMax = Math.min(convInfo.inHeight, effectiveFilterHeight + xRowCorner); + const outputRowOffset = outputDepthOffset + yRow * outputRowStrides; + for (let yCol = 0; yCol < convInfo.outWidth; ++yCol) { + const xColCorner = yCol * strideWidth - padLeft; + let xColMin = xColCorner; + while (xColMin < 0) { + xColMin += dilationWidth; + } + const xColMax = Math.min(convInfo.inWidth, effectiveFilterWidth + xColCorner); + // Shader code begins + const outputColOffset = outputRowOffset + yCol * outputColStrides; + let minMaxValue = initialValue; + let avgValue = 0; + let count = 0; + for (let xDepth = xDepthMin; xDepth < xDepthMax; xDepth += dilationDepth) { + const xDepthOffset = inputBatchOffset + xDepth * strides[1]; + for (let xRow = xRowMin; xRow < xRowMax; xRow += dilationHeight) { + const xRowOffset = xDepthOffset + xRow * strides[2]; + for (let xCol = xColMin; xCol < xColMax; xCol += dilationWidth) { + const xColOffset = xRowOffset + xCol * strides[3]; + const pixel = xValues[xColOffset + channel]; + if ((poolType === 'max' && pixel > minMaxValue)) { + minMaxValue = pixel; + } + else if (poolType === 'avg') { + avgValue += pixel; + count++; + } + if (isNaN(minMaxValue)) { + break; + } + } + if (isNaN(minMaxValue)) { + break; + } + } + if (isNaN(minMaxValue)) { + break; + } + } + const outputOffset = outputColOffset + channel; + outputVals[outputOffset] = poolType === 'avg' ? + avgValue / Math.max(count, 1) : + minMaxValue; + } + } + } + } + } + return output; + } + function maxPool3dPositions(xBuf, convInfo) { + const maxPositions = buffer(convInfo.outShape, 'int32'); + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationDepth = convInfo.dilationDepth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterDepth = convInfo.effectiveFilterDepth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padFront = convInfo.padInfo.front; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + for (let batch = 0; batch < convInfo.batchSize; ++batch) { + for (let channel = 0; channel < convInfo.inChannels; ++channel) { + for (let yDepth = 0; yDepth < convInfo.outDepth; ++yDepth) { + const xDepthCorner = yDepth * strideDepth - padFront; + let xDepthMin = xDepthCorner; + while (xDepthMin < 0) { + xDepthMin += dilationDepth; + } + const xDepthMax = Math.min(convInfo.inDepth, effectiveFilterDepth + xDepthCorner); + for (let yRow = 0; yRow < convInfo.outHeight; ++yRow) { + const xRowCorner = yRow * strideHeight - padTop; + let xRowMin = xRowCorner; + while (xRowMin < 0) { + xRowMin += dilationHeight; + } + const xRowMax = Math.min(convInfo.inHeight, effectiveFilterHeight + xRowCorner); + for (let yCol = 0; yCol < convInfo.outWidth; ++yCol) { + const xColCorner = yCol * strideWidth - padLeft; + let xColMin = xColCorner; + while (xColMin < 0) { + xColMin += dilationWidth; + } + const xColMax = Math.min(convInfo.inWidth, effectiveFilterWidth + xColCorner); + // Shader code begins + let maxValue = Number.NEGATIVE_INFINITY; + let maxPosition = -1; + for (let xDepth = xDepthMin; xDepth < xDepthMax; xDepth += dilationDepth) { + const wDepth = xDepth - xDepthCorner; + for (let xRow = xRowMin; xRow < xRowMax; xRow += dilationHeight) { + const wRow = xRow - xRowCorner; + for (let xCol = xColMin; xCol < xColMax; xCol += dilationWidth) { + const wCol = xCol - xColCorner; + const pixel = xBuf.get(batch, xDepth, xRow, xCol, channel); + if (pixel >= maxValue) { + maxValue = pixel; + maxPosition = + wDepth * effectiveFilterHeight * effectiveFilterWidth + + wRow * effectiveFilterHeight + wCol; + } + } + } + } + maxPositions.set(maxPosition, batch, yDepth, yRow, yCol, channel); + } + } + } + } + } + return maxPositions; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function avgPool$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + assertNotComplex$1(x, 'avgPool'); + const { filterSize, strides, pad, dimRoundingMode } = attrs; + const dilations = 1; + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in avgPool: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + const convInfo = computePool2DInfo(x.shape, filterSize, strides, dilations, pad, dimRoundingMode); + let res; + if (convInfo.filterWidth === 1 && convInfo.filterHeight === 1 && + arraysEqual(convInfo.inShape, convInfo.outShape)) { + res = identity$1({ inputs: { x }, backend }); + } + else { + const xValues = backend.data.get(x.dataId).values; + const strides = computeStrides(x.shape); + const buffer = pool(xValues, x.shape, x.dtype, strides, convInfo, 'avg'); + res = backend.makeTensorInfo(convInfo.outShape, x.dtype, buffer.values); + } + return res; + } + const avgPoolConfig$1 = { + kernelName: AvgPool, + backendName: 'cpu', + kernelFunc: avgPool$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function avgPool3D$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { filterSize, strides, pad, dimRoundingMode, dataFormat } = attrs; + assertNotComplex$1(x, 'avgPool3d'); + const convInfo = computePool3DInfo(x.shape, filterSize, strides, 1 /* dilations */, pad, dimRoundingMode, dataFormat); + const xValues = backend.data.get(x.dataId).values; + const outBuf = pool3d(xValues, x.shape, x.dtype, computeStrides(x.shape), convInfo, 'avg'); + return backend.makeTensorInfo(outBuf.shape, 'float32', outBuf.values); + } + const avgPool3DConfig$1 = { + kernelName: AvgPool3D, + backendName: 'cpu', + kernelFunc: avgPool3D$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function avgPool3DGrad$1(args) { + const { inputs, backend, attrs } = args; + const { dy, input } = inputs; + const { filterSize, strides, pad, dimRoundingMode } = attrs; + assertNotComplex$1([dy, input], 'avgPool3DGrad'); + const convInfo = computePool3DInfo(input.shape, filterSize, strides, 1 /* dilations */, pad, dimRoundingMode); + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const filterDepth = convInfo.filterDepth; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const dilationDepth = convInfo.dilationDepth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterDepth = convInfo.effectiveFilterDepth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padFront = effectiveFilterDepth - 1 - convInfo.padInfo.front; + const padLeft = effectiveFilterWidth - 1 - convInfo.padInfo.left; + const padTop = effectiveFilterHeight - 1 - convInfo.padInfo.top; + const dx = buffer(input.shape, 'float32'); + const avgMultiplier = 1 / (filterDepth * filterHeight * filterWidth); + const dyBuf = backend.bufferSync(dy); + for (let batch = 0; batch < convInfo.batchSize; ++batch) { + for (let channel = 0; channel < convInfo.inChannels; ++channel) { + for (let dxDepth = 0; dxDepth < convInfo.inDepth; ++dxDepth) { + for (let dxRow = 0; dxRow < convInfo.inHeight; ++dxRow) { + for (let dxCol = 0; dxCol < convInfo.inWidth; ++dxCol) { + // Shader code begins. + const dyDepthCorner = dxDepth - padFront; + const dyRowCorner = dxRow - padTop; + const dyColCorner = dxCol - padLeft; + let dotProd = 0; + for (let wDepth = 0; wDepth < effectiveFilterDepth; wDepth += dilationDepth) { + const dyDepth = (dyDepthCorner + wDepth) / strideDepth; + if (dyDepth < 0 || dyDepth >= convInfo.outDepth || + Math.floor(dyDepth) !== dyDepth) { + continue; + } + for (let wRow = 0; wRow < effectiveFilterHeight; wRow += dilationHeight) { + const dyRow = (dyRowCorner + wRow) / strideHeight; + if (dyRow < 0 || dyRow >= convInfo.outHeight || + Math.floor(dyRow) !== dyRow) { + continue; + } + for (let wCol = 0; wCol < effectiveFilterWidth; wCol += dilationWidth) { + const dyCol = (dyColCorner + wCol) / strideWidth; + if (dyCol < 0 || dyCol >= convInfo.outWidth || + Math.floor(dyCol) !== dyCol) { + continue; + } + const pixel = dyBuf.get(batch, dyDepth, dyRow, dyCol, channel); + dotProd += pixel; + } + } + } + dx.set(dotProd * avgMultiplier, batch, dxDepth, dxRow, dxCol, channel); + } + } + } + } + } + return backend.makeTensorInfo(dx.shape, dx.dtype, dx.values); + } + const avgPool3DGradConfig$1 = { + kernelName: AvgPool3DGrad, + backendName: 'cpu', + kernelFunc: avgPool3DGrad$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function avgPoolGrad$1(args) { + const { inputs, backend, attrs } = args; + const { dy, input } = inputs; + const x = input; + assertNotComplex$1([dy, input], 'avgPoolGrad'); + const { filterSize, strides, pad } = attrs; + const convInfo = computePool2DInfo(x.shape, filterSize, strides, 1 /* dilations */, pad); + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padLeft = effectiveFilterWidth - 1 - convInfo.padInfo.left; + const padTop = effectiveFilterHeight - 1 - convInfo.padInfo.top; + const dx = buffer(x.shape, 'float32'); + const avgMultiplier = 1 / (filterHeight * filterWidth); + const dyData = backend.data.get(dy.dataId).values; + const dyBuf = buffer(dy.shape, 'float32', dyData); + for (let b = 0; b < convInfo.batchSize; ++b) { + for (let d = 0; d < convInfo.inChannels; ++d) { + for (let dxR = 0; dxR < convInfo.inHeight; ++dxR) { + for (let dxC = 0; dxC < convInfo.inWidth; ++dxC) { + // Shader code begins. + const dyRCorner = dxR - padTop; + const dyCCorner = dxC - padLeft; + let dotProd = 0; + for (let wR = 0; wR < effectiveFilterHeight; wR += dilationHeight) { + const dyR = (dyRCorner + wR) / strideHeight; + if (dyR < 0 || dyR >= convInfo.outHeight || + Math.floor(dyR) !== dyR) { + continue; + } + for (let wC = 0; wC < effectiveFilterWidth; wC += dilationWidth) { + const dyC = (dyCCorner + wC) / strideWidth; + if (dyC < 0 || dyC >= convInfo.outWidth || + Math.floor(dyC) !== dyC) { + continue; + } + const pixel = dyBuf.get(b, dyR, dyC, d); + dotProd += pixel; + } + } + dx.set(dotProd * avgMultiplier, b, dxR, dxC, d); + } + } + } + } + return backend.makeTensorInfo(dx.shape, dx.dtype, dx.values); + } + const avgPoolGradConfig$1 = { + kernelName: AvgPoolGrad, + backendName: 'cpu', + kernelFunc: avgPoolGrad$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function batchNorm$1(args) { + const { inputs, backend, attrs } = args; + const { x, scale, offset, mean, variance } = inputs; + assert$1(mean.shape.length === variance.shape.length, () => 'Batch normalization gradient requires mean and variance to have ' + + 'equal ranks.'); + assert$1(offset == null || mean.shape.length === offset.shape.length, () => 'Batch normalization gradient requires mean and offset to have ' + + 'equal ranks.'); + assert$1(scale == null || mean.shape.length === scale.shape.length, () => 'Batch normalization gradient requires mean and scale to have ' + + 'equal ranks.'); + assertNotComplex$1([x, mean, variance, scale, offset], 'batchNorm'); + let { varianceEpsilon } = attrs; + if (varianceEpsilon == null) { + varianceEpsilon = 0.001; + } + const xVals = backend.data.get(x.dataId).values; + const mVals = backend.data.get(mean.dataId).values; + const varVals = backend.data.get(variance.dataId).values; + const sVals = scale ? backend.data.get(scale.dataId).values : + new Float32Array([1]); + const offVals = offset ? + backend.data.get(offset.dataId).values : + new Float32Array([0]); + const outVals = new Float32Array(xVals.length); + const offValsLength = offVals.length; + const sValsLength = sVals.length; + const varValsLength = varVals.length; + const mValsLength = mVals.length; + let offi = 0; + let mi = 0; + let si = 0; + let vi = 0; + for (let i = 0; i < xVals.length; ++i) { + outVals[i] = offVals[offi++] + + (xVals[i] - mVals[mi++]) * sVals[si++] / + Math.sqrt(varVals[vi++] + varianceEpsilon); + if (offi >= offValsLength) { + offi = 0; + } + if (mi >= mValsLength) { + mi = 0; + } + if (si >= sValsLength) { + si = 0; + } + if (vi >= varValsLength) { + vi = 0; + } + } + return backend.makeTensorInfo(x.shape, x.dtype, outVals); + } + const batchNormConfig$1 = { + kernelName: FusedBatchNorm, + backendName: 'cpu', + kernelFunc: batchNorm$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function batchToSpaceND$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { blockShape, crops } = attrs; + assertNotComplex$1([x], 'batchToSpaceND'); + const prod = blockShape.reduce((a, b) => a * b); + const reshaped = getReshaped(x.shape, blockShape, prod); + const permuted = getPermuted(reshaped.length, blockShape.length); + const reshapedPermuted = getReshapedPermuted(x.shape, blockShape, prod); + const sliceBeginCoords = getSliceBeginCoords(crops, blockShape.length); + const sliceSize = getSliceSize(reshapedPermuted, crops, blockShape.length); + const xReshaped = reshape$1({ inputs: { x }, backend, attrs: { shape: reshaped } }); + const xTransposed = transpose$1({ inputs: { x: xReshaped }, backend, attrs: { perm: permuted } }); + const xTransposedReshaped = reshape$1({ inputs: { x: xTransposed }, backend, attrs: { shape: reshapedPermuted } }); + const result = slice$1({ + inputs: { x: xTransposedReshaped }, + backend, + attrs: { begin: sliceBeginCoords, size: sliceSize } + }); + backend.disposeIntermediateTensorInfo(xReshaped); + backend.disposeIntermediateTensorInfo(xTransposed); + backend.disposeIntermediateTensorInfo(xTransposedReshaped); + return result; + } + const batchToSpaceNDConfig$1 = { + kernelName: BatchToSpaceND, + backendName: 'cpu', + kernelFunc: batchToSpaceND$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function bincount$1(args) { + const { inputs, backend, attrs } = args; + const { x, weights } = inputs; + const { size } = attrs; + const xVals = backend.data.get(x.dataId).values; + const weightsVals = backend.data.get(weights.dataId).values; + const outVals = bincountImpl(xVals, weightsVals, weights.dtype, weights.shape, size); + return backend.makeTensorInfo([size], weights.dtype, outVals); + } + const bincountConfig$1 = { + kernelName: Bincount, + backendName: 'cpu', + kernelFunc: bincount$1 + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function broadcastArgs$1(args) { + const { inputs, backend } = args; + const { s0, s1 } = inputs; + const s0Vals = backend.data.get(s0.dataId).values; + const s1Vals = backend.data.get(s1.dataId).values; + const broadcastShape = assertAndGetBroadcastShape(Array.from(s0Vals), Array.from(s1Vals)); + return backend.makeTensorInfo([broadcastShape.length], 'int32', Int32Array.from(broadcastShape)); + } + const broadcastArgsConfig$1 = { + kernelName: BroadcastArgs, + backendName: 'cpu', + kernelFunc: broadcastArgs$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const clipByValue$1 = unaryKernelFunc$1(ClipByValue, (xi, attrs) => { + const clipAttrs = attrs; + if (xi > clipAttrs.clipValueMax) { + return clipAttrs.clipValueMax; + } + return xi < clipAttrs.clipValueMin ? clipAttrs.clipValueMin : xi; + }); + const clipByValueConfig$1 = { + kernelName: ClipByValue, + backendName: 'cpu', + kernelFunc: clipByValue$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const complexAbs$1 = (args) => { + const { x } = args.inputs; + const cpuBackend = args.backend; + const resultValues = new Float32Array(sizeFromShape(x.shape)); + const complexVals = cpuBackend.data.get(x.dataId); + const real = complexVals.complexTensorInfos.real; + const imag = complexVals.complexTensorInfos.imag; + const realVals = cpuBackend.data.get(real.dataId).values; + const imagVals = cpuBackend.data.get(imag.dataId).values; + for (let i = 0; i < realVals.length; i++) { + const real = realVals[i]; + const imag = imagVals[i]; + resultValues[i] = Math.hypot(real, imag); + } + return cpuBackend.makeOutput(resultValues, x.shape, 'float32'); + }; + const complexAbsConfig$1 = { + kernelName: ComplexAbs, + backendName: 'cpu', + kernelFunc: complexAbs$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function imag$1(args) { + const { inputs, backend } = args; + const { input } = inputs; + const imag = backend.data.get(input.dataId).complexTensorInfos.imag; + const imagVal = backend.data.get(imag.dataId).values; + // When complex tensor is disposed, its underlying parts will be disposed too. + // Make new tensor out of the imag value of the complex. This makes sure the + // value is still accessible even if complex tensor is disposed. + return backend.makeTensorInfo(imag.shape, imag.dtype, imagVal); + } + const imagConfig$1 = { + kernelName: Imag, + backendName: 'cpu', + kernelFunc: imag$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function concat$1(args) { + const { inputs, backend, attrs } = args; + const { axis } = attrs; + const $axis = parseAxisParam(axis, inputs[0].shape)[0]; + const shapes = inputs.map(t => t.shape); + assertParamsConsistent(shapes, $axis); + let outShape = computeOutShape$1(inputs.map(t => t.shape), $axis); + if (sizeFromShape(outShape) === 0) { + return backend.makeTensorInfo(outShape, inputs[0].dtype, []); + } + // Keep only non-empty tensors (ignore tensors with 0 in their shape). + const $inputs = inputs.filter(t => sizeFromShape(t.shape) > 0); + if ($inputs.length === 1) { + return identity$1({ inputs: { x: $inputs[0] }, backend }); + } + if ($inputs[0].dtype === 'complex64') { + const reals = $inputs.map((t) => real$1({ inputs: { input: t }, backend })); + const imags = $inputs.map((t) => imag$1({ inputs: { input: t }, backend })); + const realConcated = concat$1({ inputs: reals, backend, attrs: { axis: $axis } }); + const imagConcated = concat$1({ inputs: imags, backend, attrs: { axis: $axis } }); + const result = complex$1({ inputs: { real: realConcated, imag: imagConcated }, backend }); + reals.forEach(r => backend.disposeIntermediateTensorInfo(r)); + imags.forEach(i => backend.disposeIntermediateTensorInfo(i)); + backend.disposeIntermediateTensorInfo(realConcated); + backend.disposeIntermediateTensorInfo(imagConcated); + return result; + } + // Any concat of n-dimensional tensors across any axis can be reduced to + // a concatenation of two-dimensional tensors across the axis 1 by first + // partitioning the axes of the original tensors into those less than the + // axis to be concatenated and the rest. Then reshape the tensors + // into a two-dimensional tensor by collapsing these two sets of axes and + // concatenate the resulting matrices across the axis 1, finally reshaping + // the result to have the proper shape. + const inputs2D = $inputs.map(t => { + const innerSize = sizeFromShape(t.shape.slice($axis)); + const shape = [-1, innerSize]; + return reshape$1({ inputs: { x: t }, backend, attrs: { shape } }); + }); + const inputsValShapes = inputs2D.map(t => { + return { vals: backend.data.get(t.dataId).values, shape: t.shape }; + }); + // Concats 2d tensors along axis=1. + outShape = + computeOutShape$1(inputs2D.map(t => t.shape), 1 /* axis */); + const simplyConcat = inputs2D[0].shape[0] === 1; + const outVals = concatImpl$1(inputsValShapes, outShape, inputs[0].dtype, simplyConcat); + const finalOutShape = computeOutShape$1($inputs.map(t => t.shape), $axis); + const outInfo = backend.makeTensorInfo(finalOutShape, inputs[0].dtype, outVals); + inputs2D.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return outInfo; + } + const concatConfig$1 = { + kernelName: Concat, + backendName: 'cpu', + kernelFunc: concat$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv2D(args) { + const { inputs, backend, attrs } = args; + const { x, filter } = inputs; + const { strides, pad, dataFormat, dilations, dimRoundingMode } = attrs; + assertNotComplex$1([x, filter], 'conv2d'); + const $dataFormat = convertConv2DDataFormat(dataFormat); + const convInfo = computeConv2DInfo(x.shape, filter.shape, strides, dilations, pad, dimRoundingMode, false /* depthwise */, $dataFormat); + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const padLeft = convInfo.padInfo.left; + const padTop = convInfo.padInfo.top; + const isChannelsLast = convInfo.dataFormat === 'channelsLast'; + const y = new TensorBuffer(convInfo.outShape, x.dtype); + const xStrides = computeStrides(x.shape); + const filterStrides = computeStrides(filter.shape); + const xBatchStride = xStrides[0]; + const xRowStride = isChannelsLast ? xStrides[1] : xStrides[2]; + const xColStride = isChannelsLast ? xStrides[2] : 1; + const xChannelStride = isChannelsLast ? 1 : xStrides[1]; + const yBatchStride = y.strides[0]; + const yRowStride = isChannelsLast ? y.strides[1] : y.strides[2]; + const yColStride = isChannelsLast ? y.strides[2] : 1; + const yChannelStride = isChannelsLast ? 1 : y.strides[1]; + const xVals = backend.data.get(x.dataId).values; + const wVals = backend.data.get(filter.dataId).values; + const yVals = y.values; + for (let b = 0; b < convInfo.batchSize; ++b) { + const xOffset1 = b * xBatchStride; + const yOffset1 = b * yBatchStride; + for (let yR = 0; yR < convInfo.outHeight; ++yR) { + const yOffset2 = yOffset1 + yR * yRowStride; + const xRCorner = yR * convInfo.strideHeight - padTop; + for (let wR = 0; wR < filterHeight; ++wR) { + const xR = xRCorner + wR * dilationHeight; + if (xR < 0 || xR >= convInfo.inHeight) { + continue; + } + const wOffset1 = wR * filterStrides[0]; + const xOffset2 = xOffset1 + xR * xRowStride; + for (let yC = 0; yC < convInfo.outWidth; ++yC) { + const yOffset3 = yOffset2 + yC * yColStride; + const xCCorner = yC * convInfo.strideWidth - padLeft; + for (let wC = 0; wC < filterWidth; ++wC) { + const xC = xCCorner + wC * dilationWidth; + if (xC < 0 || xC >= convInfo.inWidth) { + continue; + } + const wOffset2 = wOffset1 + wC * filterStrides[1]; + const xOffset3 = xOffset2 + xC * xColStride; + let wOffset3 = wOffset2; + for (let d1 = 0; d1 < convInfo.inChannels; ++d1) { + const xVal = xVals[xOffset3 + d1 * xChannelStride]; + for (let d2 = 0; d2 < convInfo.outChannels; ++d2) { + yVals[yOffset3 + d2 * yChannelStride] += + xVal * wVals[wOffset3 + d2]; + } + wOffset3 += convInfo.outChannels; + } + } + } + } + } + } + return backend.makeTensorInfo(y.shape, y.dtype, yVals); + } + const conv2DConfig$1 = { + kernelName: Conv2D$1, + backendName: 'cpu', + kernelFunc: conv2D + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv2DBackpropFilter$1(args) { + const { inputs, backend, attrs } = args; + const { x, dy } = inputs; + const { strides, pad, dataFormat, dimRoundingMode, filterShape } = attrs; + assertNotComplex$1([x, dy], 'conv2dBackpropFilter'); + const $dataFormat = convertConv2DDataFormat(dataFormat); + const convInfo = computeConv2DInfo(x.shape, filterShape, strides, 1 /* dilations */, pad, dimRoundingMode, false /* depthwise */, $dataFormat); + const { strideHeight, strideWidth, filterHeight, filterWidth } = convInfo; + const isChannelsLast = convInfo.dataFormat === 'channelsLast'; + const dW = new TensorBuffer(convInfo.filterShape, 'float32'); + const leftPad = convInfo.padInfo.left; + const topPad = convInfo.padInfo.top; + const xVals = backend.data.get(x.dataId).values; + const dyVals = backend.data.get(dy.dataId).values; + const xBuf = new TensorBuffer(x.shape, x.dtype, xVals); + const dyBuf = new TensorBuffer(dy.shape, dy.dtype, dyVals); + for (let wR = 0; wR < filterHeight; ++wR) { + const yRMin = Math.max(0, Math.ceil((topPad - wR) / strideHeight)); + const yRMax = Math.min(convInfo.outHeight, (convInfo.inHeight + topPad - wR) / strideHeight); + for (let wC = 0; wC < filterWidth; ++wC) { + const yCMin = Math.max(0, Math.ceil((leftPad - wC) / strideWidth)); + const yCMax = Math.min(convInfo.outWidth, (convInfo.inWidth + leftPad - wC) / strideWidth); + for (let d1 = 0; d1 < convInfo.inChannels; ++d1) { + for (let d2 = 0; d2 < convInfo.outChannels; ++d2) { + let dotProd = 0; + for (let b = 0; b < convInfo.batchSize; ++b) { + for (let yR = yRMin; yR < yRMax; ++yR) { + const xR = wR + yR * strideHeight - topPad; + for (let yC = yCMin; yC < yCMax; ++yC) { + const xC = wC + yC * strideWidth - leftPad; + if (isChannelsLast) { + dotProd += xBuf.get(b, xR, xC, d1) * + dyBuf.get(b, yR, yC, d2); + } + else { + dotProd += xBuf.get(b, d1, xR, xC) * + dyBuf.get(b, d2, yR, yC); + } + } + } + } + dW.set(dotProd, wR, wC, d1, d2); + } + } + } + } + return backend.makeTensorInfo(dW.shape, dW.dtype, dW.values); + } + const conv2DBackpropFilterConfig$1 = { + kernelName: Conv2DBackpropFilter, + backendName: 'cpu', + kernelFunc: conv2DBackpropFilter$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv2DBackpropInput$1(args) { + const { inputs, backend, attrs } = args; + const { dy, filter } = inputs; + const { inputShape, strides, pad, dataFormat, dimRoundingMode } = attrs; + assertNotComplex$1([dy, filter], 'conv2dBackpropInput'); + const filterStrides = computeStrides(filter.shape); + const dyStrides = computeStrides(dy.shape); + let $dataFormat = convertConv2DDataFormat(dataFormat); + const convInfo = computeConv2DInfo(inputShape, filter.shape, strides, 1 /* dilations */, pad, dimRoundingMode, false, $dataFormat); + const dx = new TensorBuffer(convInfo.inShape, 'float32'); + const dxValues = dx.values; + const dyValues = backend.data.get(dy.dataId).values; + const fltValues = backend.data.get(filter.dataId).values; + const [fltS0, fltS1, fltS2] = filterStrides; + const { batchSize, filterHeight, filterWidth, inChannels, inHeight, inWidth, outChannels, outHeight, outWidth, strideHeight, strideWidth } = convInfo; + $dataFormat = convInfo.dataFormat; + const topPad = filterHeight - 1 - convInfo.padInfo.top; + const leftPad = filterWidth - 1 - convInfo.padInfo.left; + const isChannelsLast = $dataFormat === 'channelsLast'; + const xBatchStride = dx.strides[0]; + const xRowStride = isChannelsLast ? dx.strides[1] : dx.strides[2]; + const xColStride = isChannelsLast ? dx.strides[2] : 1; + const xChannelStride = isChannelsLast ? 1 : dx.strides[1]; + const yBatchStride = dyStrides[0]; + const yRowStride = isChannelsLast ? dyStrides[1] : dyStrides[2]; + const yColStride = isChannelsLast ? dyStrides[2] : 1; + const yChannelStride = isChannelsLast ? 1 : dyStrides[1]; + for (let b = 0; b < batchSize; ++b) { + for (let d1 = 0; d1 < inChannels; ++d1) { + for (let xR = 0; xR < inHeight; ++xR) { + const xRCorner = xR - topPad; + const xRMin = Math.max(0, Math.ceil(xRCorner / strideHeight)); + const yRMax = Math.min(outHeight, (filterHeight + xRCorner) / strideHeight); + for (let xC = 0; xC < inWidth; ++xC) { + const xCCorner = xC - leftPad; + const xCMin = Math.max(0, Math.ceil(xCCorner / strideWidth)); + const yCMax = Math.min(outWidth, (filterWidth + xCCorner) / strideWidth); + let dotProd = 0; + for (let yR = xRMin; yR < yRMax; ++yR) { + const wR = yR * strideHeight - xRCorner; + for (let yC = xCMin; yC < yCMax; ++yC) { + const wC = yC * strideWidth - xCCorner; + const dyOffset = yBatchStride * b + yRowStride * yR + yColStride * yC; + const fltOffset = fltS0 * (filterHeight - 1 - wR) + + fltS1 * (filterWidth - 1 - wC) + fltS2 * d1; + for (let d2 = 0; d2 < outChannels; ++d2) { + const pixel = dyValues[dyOffset + yChannelStride * d2]; + const weight = fltValues[fltOffset + d2]; + dotProd += pixel * weight; + } + } + } + const dxOffset = xBatchStride * b + xRowStride * xR + + xColStride * xC + xChannelStride * d1; + dxValues[dxOffset] = dotProd; + } + } + } + } + return backend.makeTensorInfo(dx.shape, dx.dtype, dx.values); + } + const conv2DBackpropInputConfig$1 = { + kernelName: Conv2DBackpropInput, + backendName: 'cpu', + kernelFunc: conv2DBackpropInput$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv3D$1(args) { + const { inputs, backend, attrs } = args; + const { x, filter } = inputs; + const { strides, pad, dilations } = attrs; + assertNotComplex$1([x, filter], 'conv3d'); + const convInfo = computeConv3DInfo(x.shape, filter.shape, strides, dilations, pad); + const { filterDepth, filterHeight, filterWidth, dilationDepth, dilationHeight, dilationWidth, padInfo } = convInfo; + const padFront = padInfo.front; + const padLeft = padInfo.left; + const padTop = padInfo.top; + const y = new TensorBuffer(convInfo.outShape, x.dtype); + const xVals = backend.data.get(x.dataId).values; + const wVals = backend.data.get(filter.dataId).values; + const yVals = y.values; + const xStrides = computeStrides(x.shape); + const filterStrides = computeStrides(filter.shape); + for (let b = 0; b < convInfo.batchSize; ++b) { + const xOffset1 = b * xStrides[0]; + const yOffset1 = b * y.strides[0]; + for (let yF = 0; yF < convInfo.outDepth; ++yF) { + const yOffset2 = yOffset1 + yF * y.strides[1]; + const xFCorner = yF * convInfo.strideDepth - padFront; + for (let wF = 0; wF < filterDepth; ++wF) { + const xF = xFCorner + wF * dilationDepth; + if (xF < 0 || xF >= convInfo.inDepth) { + continue; + } + const wOffset1 = wF * filterStrides[0]; + const xOffset2 = xOffset1 + xF * xStrides[1]; + for (let yR = 0; yR < convInfo.outHeight; ++yR) { + const yOffset3 = yOffset2 + yR * y.strides[2]; + const xRCorner = yR * convInfo.strideHeight - padTop; + for (let wR = 0; wR < filterHeight; ++wR) { + const xR = xRCorner + wR * dilationHeight; + if (xR < 0 || xR >= convInfo.inHeight) { + continue; + } + const wOffset2 = wOffset1 + wR * filterStrides[1]; + const xOffset3 = xOffset2 + xR * xStrides[2]; + for (let yC = 0; yC < convInfo.outWidth; ++yC) { + const yOffset4 = yOffset3 + yC * convInfo.outChannels; + const xCCorner = yC * convInfo.strideWidth - padLeft; + for (let wC = 0; wC < filterWidth; ++wC) { + const xC = xCCorner + wC * dilationWidth; + if (xC < 0 || xC >= convInfo.inWidth) { + continue; + } + const wOffset3 = wOffset2 + wC * filterStrides[2]; + const xOffset4 = xOffset3 + xC * convInfo.inChannels; + let wOffset4 = wOffset3; + for (let d1 = 0; d1 < convInfo.inChannels; ++d1) { + const xVal = xVals[xOffset4 + d1]; + for (let d2 = 0; d2 < convInfo.outChannels; ++d2) { + yVals[yOffset4 + d2] += xVal * wVals[wOffset4 + d2]; + } + wOffset4 += convInfo.outChannels; + } + } + } + } + } + } + } + } + return backend.makeTensorInfo(y.shape, y.dtype, y.values); + } + const conv3DConfig$1 = { + kernelName: Conv3D$1, + backendName: 'cpu', + kernelFunc: conv3D$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv3DBackpropFilterV2$1(args) { + const { inputs, backend, attrs } = args; + const { x, dy } = inputs; + const { strides, pad, filterShape } = attrs; + assertNotComplex$1([x, dy], 'conv3dBackpropFilterV2'); + const xStrides = computeStrides(x.shape); + const dyStrides = computeStrides(dy.shape); + const convInfo = computeConv3DInfo(x.shape, filterShape, strides, 1 /* dilations */, pad); + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const filterDepth = convInfo.filterDepth; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const dw = new TensorBuffer(convInfo.filterShape, 'float32'); + const dwValues = dw.values; + const [dwS0, dwS1, dwS2, dwS3] = dw.strides; + const dyValues = backend.data.get(dy.dataId).values; + const [dyS0, dyS1, dyS2, dyS3] = dyStrides; + const xValues = backend.data.get(x.dataId).values; + const [xS0, xS1, xS2, xS3] = xStrides; + const frontPad = convInfo.padInfo.front; + const leftPad = convInfo.padInfo.left; + const topPad = convInfo.padInfo.top; + for (let wF = 0; wF < filterDepth; ++wF) { + const yFMin = Math.max(0, Math.ceil((frontPad - wF) / strideDepth)); + const yFMax = Math.min(convInfo.outDepth, (convInfo.inDepth + frontPad - wF) / strideDepth); + const wOffset1 = wF * dwS0; + for (let wR = 0; wR < filterHeight; ++wR) { + const yRMin = Math.max(0, Math.ceil((topPad - wR) / strideHeight)); + const yRMax = Math.min(convInfo.outHeight, (convInfo.inHeight + topPad - wR) / strideHeight); + const wOffset2 = wR * dwS1 + wOffset1; + for (let wC = 0; wC < filterWidth; ++wC) { + const yCMin = Math.max(0, Math.ceil((leftPad - wC) / strideWidth)); + const yCMax = Math.min(convInfo.outWidth, (convInfo.inWidth + leftPad - wC) / strideWidth); + const wOffset3 = wC * dwS2 + wOffset2; + for (let d1 = 0; d1 < convInfo.inChannels; ++d1) { + const wOffset4 = d1 * dwS3 + wOffset3; + for (let d2 = 0; d2 < convInfo.outChannels; ++d2) { + let dotProd = 0; + for (let b = 0; b < convInfo.batchSize; ++b) { + const xOffset1 = b * xS0; + const yOffset1 = b * dyS0; + for (let yF = yFMin; yF < yFMax; ++yF) { + const xF = wF + yF * strideDepth - frontPad; + const xOffset2 = xF * xS1 + xOffset1; + const yOffset2 = yF * dyS1 + yOffset1; + for (let yR = yRMin; yR < yRMax; ++yR) { + const xR = wR + yR * strideHeight - topPad; + const xOffset3 = xR * xS2 + xOffset2; + const yOffset3 = yR * dyS2 + yOffset2; + for (let yC = yCMin; yC < yCMax; ++yC) { + const xC = wC + yC * strideWidth - leftPad; + const xOffset4 = xC * xS3 + xOffset3; + const yOffset4 = yC * dyS3 + yOffset3; + dotProd += xValues[xOffset4 + d1] * dyValues[yOffset4 + d2]; + } + } + } + } + dwValues[wOffset4 + d2] = dotProd; + } + } + } + } + } + return backend.makeTensorInfo(dw.shape, dw.dtype, dw.values); + } + const conv3DBackpropFilterV2Config$1 = { + kernelName: Conv3DBackpropFilterV2, + backendName: 'cpu', + kernelFunc: conv3DBackpropFilterV2$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv3DBackpropInputV2(args) { + const { inputs, backend, attrs } = args; + const { dy, filter } = inputs; + const { pad, strides, inputShape } = attrs; + assertNotComplex$1([dy], 'conv3dBackpropInputV2'); + const dyStrides = computeStrides(dy.shape); + const filterStrides = computeStrides(filter.shape); + const convInfo = computeConv3DInfo(inputShape, filter.shape, strides, 1 /* dilations */, pad); + const dx = new TensorBuffer(convInfo.inShape, 'float32'); + const dxValues = dx.values; + const [dxS0, dxS1, dxS2, dxS3] = dx.strides; + const dyValues = backend.data.get(dy.dataId).values; + const [dyS0, dyS1, dyS2, dyS3] = dyStrides; + const fltValues = backend.data.get(filter.dataId).values; + const [fltS0, fltS1, fltS2, fltS3] = filterStrides; + const { batchSize, filterDepth, filterHeight, filterWidth, inChannels, inDepth, inHeight, inWidth, outChannels, outDepth, outHeight, outWidth, strideDepth, strideHeight, strideWidth } = convInfo; + const frontPad = filterDepth - 1 - convInfo.padInfo.front; + const topPad = filterHeight - 1 - convInfo.padInfo.top; + const leftPad = filterWidth - 1 - convInfo.padInfo.left; + for (let b = 0; b < batchSize; ++b) { + for (let d1 = 0; d1 < inChannels; ++d1) { + // Frames of depth + for (let xF = 0; xF < inDepth; ++xF) { + const xFCorner = xF - frontPad; + const xFMin = Math.max(0, Math.ceil(xFCorner / strideDepth)); + const yFMax = Math.min(outDepth, (filterDepth + xFCorner) / strideDepth); + // Rows as per standard 2d matrix notation + for (let xR = 0; xR < inHeight; ++xR) { + const xRCorner = xR - topPad; + const xRMin = Math.max(0, Math.ceil(xRCorner / strideHeight)); + const yRMax = Math.min(outHeight, (filterHeight + xRCorner) / strideHeight); + // Columns as per standard 2d matrix notation + for (let xC = 0; xC < inWidth; ++xC) { + const xCCorner = xC - leftPad; + const xCMin = Math.max(0, Math.ceil(xCCorner / strideWidth)); + const yCMax = Math.min(outWidth, (filterWidth + xCCorner) / strideWidth); + let dotProd = 0; + for (let yF = xFMin; yF < yFMax; ++yF) { + const wF = yF * strideDepth - xFCorner; + for (let yR = xRMin; yR < yRMax; ++yR) { + const wR = yR * strideHeight - xRCorner; + for (let yC = xCMin; yC < yCMax; ++yC) { + const wC = yC * strideWidth - xCCorner; + const dyOffset = dyS0 * b + dyS1 * yF + dyS2 * yR + dyS3 * yC; + const fltOffset = fltS0 * (filterDepth - 1 - wF) + + fltS1 * (filterHeight - 1 - wR) + + fltS2 * (filterWidth - 1 - wC) + fltS3 * d1; + for (let d2 = 0; d2 < outChannels; ++d2) { + const pixel = dyValues[dyOffset + d2]; + const weight = fltValues[fltOffset + d2]; + dotProd += pixel * weight; + } + } + } + } + dxValues[dxS0 * b + dxS1 * xF + dxS2 * xR + dxS3 * xC + d1] = + dotProd; + } + } + } + } + } + return backend.makeTensorInfo(dx.shape, dx.dtype, dx.values); + } + const conv3DBackpropInputV2Config = { + kernelName: Conv3DBackpropInputV2, + backendName: 'cpu', + kernelFunc: conv3DBackpropInputV2 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const cos$1 = unaryKernelFunc$1(Cos, (xi) => Math.cos(xi)); + const cosConfig$1 = { + kernelName: Cos, + backendName: 'cpu', + kernelFunc: cos$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const cosh$1 = unaryKernelFunc$1(Cosh, (xi) => Math.cosh(xi)); + const coshConfig$1 = { + kernelName: Cosh, + backendName: 'cpu', + kernelFunc: cosh$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function cropAndResize$1(args) { + const { inputs, backend, attrs } = args; + const { image, boxes, boxInd } = inputs; + const { cropSize, method, extrapolationValue } = attrs; + const [batch, imageHeight, imageWidth, numChannels] = image.shape; + const numBoxes = boxes.shape[0]; + const [cropHeight, cropWidth] = cropSize; + const output = buffer([numBoxes, cropHeight, cropWidth, numChannels], 'float32'); + const boxVals = backend.data.get(boxes.dataId).values; + const boxIndVals = backend.data.get(boxInd.dataId).values; + const imageVals = backend.data.get(image.dataId).values; + const inStride = computeStrides(image.shape); // to calculate flat indexes into image + const outStride = computeStrides(output.shape); // to calculate flat indexes into output + // Reference implementation + // tslint:disable-next-line:max-line-length + // https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/crop_and_resize_op.cc + for (let b = 0; b < numBoxes; b++) { + const startInd = b * 4; + const y1 = boxVals[startInd]; + const x1 = boxVals[startInd + 1]; + const y2 = boxVals[startInd + 2]; + const x2 = boxVals[startInd + 3]; + const bInd = boxIndVals[b]; + if (bInd >= batch) { + continue; + } + const heightScale = (cropHeight > 1) ? (y2 - y1) * (imageHeight - 1) / (cropHeight - 1) : 0; + const widthScale = (cropWidth > 1) ? (x2 - x1) * (imageWidth - 1) / (cropWidth - 1) : 0; + for (let y = 0; y < cropHeight; y++) { + const yInd = (cropHeight > 1) ? + y1 * (imageHeight - 1) + y * (heightScale) : + 0.5 * (y1 + y2) * (imageHeight - 1); + if (yInd < 0 || yInd > imageHeight - 1) { + for (let x = 0; x < cropWidth; x++) { + for (let c = 0; c < numChannels; c++) { + const ind = c + x * outStride[2] + y * outStride[1] + b * outStride[0]; + output.values[ind] = extrapolationValue; + } + } + continue; + } + if (method === 'bilinear') { + const topInd = Math.floor(yInd); + const bottomInd = Math.ceil(yInd); + const yLerp = yInd - topInd; + for (let x = 0; x < cropWidth; x++) { + const xInd = (cropWidth > 1) ? + x1 * (imageWidth - 1) + x * widthScale : + 0.5 * (x1 + x2) * (imageWidth - 1); + if (xInd < 0 || xInd > imageWidth - 1) { + for (let c = 0; c < numChannels; c++) { + const ind = c + x * outStride[2] + y * outStride[1] + b * outStride[0]; + output.values[ind] = extrapolationValue; + } + continue; + } + const leftInd = Math.floor(xInd); + const rightInd = Math.ceil(xInd); + const xLerp = xInd - leftInd; + for (let c = 0; c < numChannels; c++) { + let ind = c + leftInd * inStride[2] + topInd * inStride[1] + + bInd * inStride[0]; + const topLeft = imageVals[ind]; + ind = c + rightInd * inStride[2] + topInd * inStride[1] + + bInd * inStride[0]; + const topRight = imageVals[ind]; + ind = c + leftInd * inStride[2] + bottomInd * inStride[1] + + bInd * inStride[0]; + const bottomLeft = imageVals[ind]; + ind = c + rightInd * inStride[2] + bottomInd * inStride[1] + + bInd * inStride[0]; + const bottomRight = imageVals[ind]; + const top = topLeft + (topRight - topLeft) * xLerp; + const bottom = bottomLeft + (bottomRight - bottomLeft) * xLerp; + ind = c + x * outStride[2] + y * outStride[1] + b * outStride[0]; + output.values[ind] = top + ((bottom - top) * yLerp); + } + } + } + else { // method == "nearest" + for (let x = 0; x < cropWidth; ++x) { + const xInd = (cropWidth > 1) ? + x1 * (imageWidth - 1) + x * widthScale : + 0.5 * (x1 + x2) * (imageWidth - 1); + if (xInd < 0 || xInd > imageWidth - 1) { + for (let c = 0; c < numChannels; c++) { + const ind = c + x * outStride[2] + y * outStride[1] + b * outStride[0]; + output.values[ind] = extrapolationValue; + } + continue; + } + const closestX = Math.round(xInd); + const closestY = Math.round(yInd); + for (let c = 0; c < numChannels; c++) { + const inInd = c + closestX * inStride[2] + closestY * inStride[1] + + bInd * inStride[0]; + const outInd = c + x * outStride[2] + y * outStride[1] + b * outStride[0]; + output.values[outInd] = imageVals[inInd]; + } + } + } + } + } + return backend.makeTensorInfo(output.shape, output.dtype, output.values); + } + const cropAndResizeConfig$1 = { + kernelName: CropAndResize, + backendName: 'cpu', + kernelFunc: cropAndResize$1 + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function cumprod$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, exclusive, reverse } = attrs; + assertNotComplex$1(x, 'cumprod'); + const permutation = getAxesPermutation([axis], x.shape.length); + let $x = x; + if (permutation != null) { + $x = transpose$1({ inputs: { x }, backend, attrs: { perm: permutation } }); + } + const permutedAxis = getInnerMostAxes(1, x.shape.length)[0]; + if (permutedAxis !== $x.shape.length - 1) { + throw new Error(`backend.cumprod in CPU expects an inner-most ` + + `axis=${$x.shape.length - 1} but got axis=${permutedAxis}`); + } + const resultDtype = upcastType($x.dtype, 'int32'); + const vals = makeOnesTypedArray(sizeFromShape($x.shape), resultDtype); + const aVals = backend.data.get($x.dataId).values; + const finalDim = $x.shape[$x.shape.length - 1]; + const indexAdjuster = reverse ? + (i, j) => i + finalDim - j - 1 : + (i, j) => i + j; + for (let i = 0; i < aVals.length; i += finalDim) { + for (let j = 0; j < finalDim; j++) { + const idx = indexAdjuster(i, j); + if (j === 0) { + vals[idx] = exclusive ? 1 : aVals[idx]; + } + else { + const prevIdx = indexAdjuster(i, j - 1); + vals[idx] = exclusive ? aVals[prevIdx] * vals[prevIdx] : + aVals[idx] * vals[prevIdx]; + } + } + } + const result = backend.makeTensorInfo($x.shape, resultDtype, vals); + if (permutation != null) { + const reversePermutation = getUndoAxesPermutation(permutation); + const reverseTransposedResult = transpose$1({ inputs: { x: result }, backend, attrs: { perm: reversePermutation } }); + backend.disposeIntermediateTensorInfo(result); + backend.disposeIntermediateTensorInfo($x); + return reverseTransposedResult; + } + return result; + } + const cumprodConfig$1 = { + kernelName: Cumprod, + backendName: 'cpu', + kernelFunc: cumprod$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function cumsum$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, exclusive, reverse } = attrs; + assertNotComplex$1(x, 'cumsum'); + const permutation = getAxesPermutation([axis], x.shape.length); + let $x = x; + if (permutation != null) { + $x = transpose$1({ inputs: { x }, backend, attrs: { perm: permutation } }); + } + const permutedAxis = getInnerMostAxes(1, x.shape.length)[0]; + if (permutedAxis !== $x.shape.length - 1) { + throw new Error(`backend.cumsum in CPU expects an inner-most ` + + `axis=${$x.shape.length - 1} but got axis=${permutedAxis}`); + } + const resultDtype = upcastType($x.dtype, 'int32'); + const vals = makeZerosTypedArray(sizeFromShape($x.shape), resultDtype); + const aVals = backend.data.get($x.dataId).values; + const finalDim = $x.shape[$x.shape.length - 1]; + const indexAdjuster = reverse ? + (i, j) => i + finalDim - j - 1 : + (i, j) => i + j; + for (let i = 0; i < aVals.length; i += finalDim) { + for (let j = 0; j < finalDim; j++) { + const idx = indexAdjuster(i, j); + if (j === 0) { + vals[idx] = exclusive ? 0 : aVals[idx]; + } + else { + const prevIdx = indexAdjuster(i, j - 1); + vals[idx] = exclusive ? aVals[prevIdx] + vals[prevIdx] : + aVals[idx] + vals[prevIdx]; + } + } + } + const result = backend.makeTensorInfo($x.shape, resultDtype, vals); + if (permutation != null) { + const reversePermutation = getUndoAxesPermutation(permutation); + const reverseTransposedResult = transpose$1({ inputs: { x: result }, backend, attrs: { perm: reversePermutation } }); + backend.disposeIntermediateTensorInfo(result); + backend.disposeIntermediateTensorInfo($x); + return reverseTransposedResult; + } + return result; + } + const cumsumConfig$1 = { + kernelName: Cumsum, + backendName: 'cpu', + kernelFunc: cumsum$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function denseBincount$1(args) { + const { inputs, backend, attrs } = args; + const { x, weights } = inputs; + const { size, binaryOutput } = attrs; + if (x.shape.length === 1) { + const xVals = backend.data.get(x.dataId).values; + const weightsVals = backend.data.get(weights.dataId).values; + const outVals = bincountImpl(xVals, weightsVals, weights.dtype, weights.shape, size); + return backend.makeTensorInfo([size], weights.dtype, outVals); + } + else if (x.shape.length === 2) { + const xBuf = backend.bufferSync(x); + const weightsBuf = backend.bufferSync(weights); + const outBuf = bincountReduceImpl(xBuf, weightsBuf, size, binaryOutput); + return backend.makeTensorInfo(outBuf.shape, weights.dtype, outBuf.values); + } + throw new Error(`Error in denseBincount: input must be at most rank 2, but got rank` + + `${x.shape.length}.`); + } + const denseBincountConfig$1 = { + kernelName: DenseBincount, + backendName: 'cpu', + kernelFunc: denseBincount$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthToSpace$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { blockSize, dataFormat } = attrs; + assert$1(dataFormat === 'NHWC', () => `Only NHWC dataFormat supported on CPU for depthToSpace. Got ${dataFormat}`); + const batchSize = x.shape[0]; + const inputHeight = x.shape[1]; + const inputWidth = x.shape[2]; + const inputDepth = x.shape[3]; + const outputHeight = inputHeight * blockSize; + const outputWidth = inputWidth * blockSize; + const outputDepth = inputDepth / (blockSize * blockSize); + const xValues = backend.data.get(x.dataId).values; + const result = new Float32Array(batchSize * outputHeight * outputWidth * outputDepth); + let outputIdx = 0; + for (let b = 0; b < batchSize; ++b) { + for (let h = 0; h < outputHeight; ++h) { + const inH = Math.floor(h / blockSize); + const offsetH = (h % blockSize); + for (let w = 0; w < outputWidth; ++w) { + const inW = Math.floor(w / blockSize); + const offsetW = (w % blockSize); + const offsetD = (offsetH * blockSize + offsetW) * outputDepth; + for (let d = 0; d < outputDepth; ++d) { + const inD = d + offsetD; + const inputIdx = inD + inputDepth * (inW + inputWidth * (inH + inputHeight * b)); + result[outputIdx++] = xValues[inputIdx]; + } + } + } + } + return backend.makeTensorInfo([batchSize, outputHeight, outputWidth, outputDepth], x.dtype, result); + } + const depthToSpaceConfig$1 = { + kernelName: DepthToSpace, + backendName: 'cpu', + kernelFunc: depthToSpace$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthwiseConv2dNative$1(args) { + const { inputs, backend, attrs } = args; + const { x, filter } = inputs; + const { strides, pad, dilations, dimRoundingMode } = attrs; + assertNotComplex$1([x, filter], 'depthwiseConv2DNative'); + const xStrides = computeStrides(x.shape); + const filterStrides = computeStrides(filter.shape); + let $dilations = dilations; + if ($dilations == null) { + $dilations = [1, 1]; + } + assert$1(eitherStridesOrDilationsAreOne(strides, $dilations), () => 'Error in depthwiseConv2d: Either strides or dilations must be ' + + `1. Got strides ${strides} and dilations '${$dilations}'`); + const convInfo = computeConv2DInfo(x.shape, filter.shape, strides, $dilations, pad, dimRoundingMode, true /* depthwise */); + const { filterHeight, filterWidth, dilationHeight, dilationWidth, padInfo } = convInfo; + const padLeft = padInfo.left; + const padTop = padInfo.top; + const chMul = convInfo.outChannels / convInfo.inChannels; + const y = new TensorBuffer(convInfo.outShape, x.dtype); + const xVals = backend.data.get(x.dataId).values; + const wVals = backend.data.get(filter.dataId).values; + const yVals = y.values; + for (let b = 0; b < convInfo.batchSize; ++b) { + const xOffset1 = b * xStrides[0]; + const yOffset1 = b * y.strides[0]; + for (let yR = 0; yR < convInfo.outHeight; ++yR) { + const yOffset2 = yOffset1 + yR * y.strides[1]; + const xRCorner = yR * convInfo.strideHeight - padTop; + for (let wR = 0; wR < filterHeight; ++wR) { + const xR = xRCorner + wR * dilationHeight; + if (xR < 0 || xR >= convInfo.inHeight) { + continue; + } + const wOffset1 = wR * filterStrides[0]; + const xOffset2 = xOffset1 + xR * xStrides[1]; + for (let yC = 0; yC < convInfo.outWidth; ++yC) { + const yOffset3 = yOffset2 + yC * y.strides[2]; + const xCCorner = yC * convInfo.strideWidth - padLeft; + for (let wC = 0; wC < filterWidth; ++wC) { + const xC = xCCorner + wC * dilationWidth; + if (xC < 0 || xC >= convInfo.inWidth) { + continue; + } + const wOffset2 = wOffset1 + wC * filterStrides[1]; + const xOffset3 = xOffset2 + xC * convInfo.inChannels; + let yOffset4 = yOffset3; + let wOffset3 = wOffset2; + for (let d1 = 0; d1 < convInfo.inChannels; ++d1) { + const xVal = xVals[xOffset3 + d1]; + for (let q = 0; q < chMul; ++q) { + yVals[yOffset4 + q] += xVal * wVals[wOffset3 + q]; + } + yOffset4 += chMul; + wOffset3 += chMul; + } + } + } + } + } + } + return backend.makeTensorInfo(y.shape, y.dtype, y.values); + } + const depthwiseConv2dNativeConfig$1 = { + kernelName: DepthwiseConv2dNative, + backendName: 'cpu', + kernelFunc: depthwiseConv2dNative$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthwiseConv2dNativeBackpropFilter$1(args) { + const { inputs, backend, attrs } = args; + const { x, dy } = inputs; + const { strides, dilations, pad, dimRoundingMode, filterShape } = attrs; + assertNotComplex$1([x, dy], 'depthwiseConv2dNativeBackpropFilter'); + const convInfo = computeConv2DInfo(x.shape, filterShape, strides, dilations, pad, dimRoundingMode, true /* depthwise */); + const { strideHeight, strideWidth, filterHeight, filterWidth } = convInfo; + const dW = new TensorBuffer(convInfo.filterShape, 'float32'); + const leftPad = convInfo.padInfo.left; + const topPad = convInfo.padInfo.top; + const chMul = convInfo.outChannels / convInfo.inChannels; + const xVals = backend.data.get(x.dataId).values; + const xBuf = new TensorBuffer(x.shape, x.dtype, xVals); + const dyVals = backend.data.get(dy.dataId).values; + const dyBuf = new TensorBuffer(dy.shape, dy.dtype, dyVals); + for (let wR = 0; wR < filterHeight; ++wR) { + const yRMin = Math.max(0, Math.ceil((topPad - wR) / strideHeight)); + const yRMax = Math.min(convInfo.outHeight, (convInfo.inHeight + topPad - wR) / strideHeight); + for (let wC = 0; wC < filterWidth; ++wC) { + const yCMin = Math.max(0, Math.ceil((leftPad - wC) / strideWidth)); + const yCMax = Math.min(convInfo.outWidth, (convInfo.inWidth + leftPad - wC) / strideWidth); + for (let d2 = 0; d2 < convInfo.outChannels; ++d2) { + const d1 = Math.trunc(d2 / chMul); + const dm = d2 % chMul; + let dotProd = 0; + for (let b = 0; b < convInfo.batchSize; ++b) { + for (let yR = yRMin; yR < yRMax; ++yR) { + const xR = wR + yR * strideHeight - topPad; + for (let yC = yCMin; yC < yCMax; ++yC) { + const xC = wC + yC * strideWidth - leftPad; + dotProd += xBuf.get(b, xR, xC, d1) * + dyBuf.get(b, yR, yC, d2); + } + } + } + dW.set(dotProd, wR, wC, d1, dm); + } + } + } + return backend.makeTensorInfo(dW.shape, dW.dtype, dW.values); + } + const depthwiseConv2dNativeBackpropFilterConfig$1 = { + kernelName: DepthwiseConv2dNativeBackpropFilter, + backendName: 'cpu', + kernelFunc: depthwiseConv2dNativeBackpropFilter$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthwiseConv2dNativeBackpropInput$1(args) { + const { inputs, backend, attrs } = args; + const { dy, filter } = inputs; + const { strides, dilations, pad, dimRoundingMode, inputShape } = attrs; + assertNotComplex$1([dy, filter], 'depthwiseConv2DNativeBackpropInput'); + const dyStrides = computeStrides(dy.shape); + const filterStrides = computeStrides(filter.shape); + const convInfo = computeConv2DInfo(inputShape, filter.shape, strides, dilations, pad, dimRoundingMode, true /* depthwise */); + const dx = new TensorBuffer(convInfo.inShape, 'float32'); + const dxValues = dx.values; + const [dxS0, dxS1, dxS2] = dx.strides; + const dyValues = backend.data.get(dy.dataId).values; + const [dyS0, dyS1, dyS2] = dyStrides; + const fltValues = backend.data.get(filter.dataId).values; + const [fltS0, fltS1, fltS2] = filterStrides; + const { batchSize, filterHeight, filterWidth, inChannels, inHeight, inWidth, outChannels, outHeight, outWidth, strideHeight, strideWidth } = convInfo; + const topPad = filterHeight - 1 - convInfo.padInfo.top; + const leftPad = filterWidth - 1 - convInfo.padInfo.left; + const chMul = outChannels / inChannels; + for (let b = 0; b < batchSize; ++b) { + for (let d1 = 0; d1 < inChannels; ++d1) { + for (let xR = 0; xR < inHeight; ++xR) { + const xRCorner = xR - topPad; + const xRMin = Math.max(0, Math.ceil(xRCorner / strideHeight)); + const yRMax = Math.min(outHeight, (filterHeight + xRCorner) / strideHeight); + for (let xC = 0; xC < inWidth; ++xC) { + const xCCorner = xC - leftPad; + const xCMin = Math.max(0, Math.ceil(xCCorner / strideWidth)); + const yCMax = Math.min(outWidth, (filterWidth + xCCorner) / strideWidth); + let dotProd = 0; + for (let yR = xRMin; yR < yRMax; ++yR) { + const wR = yR * strideHeight - xRCorner; + for (let yC = xCMin; yC < yCMax; ++yC) { + const wC = yC * strideWidth - xCCorner; + const dyOffset = dyS0 * b + dyS1 * yR + dyS2 * yC; + const fltOffset = fltS0 * (filterHeight - 1 - wR) + + fltS1 * (filterWidth - 1 - wC) + fltS2 * d1; + for (let dm = 0; dm < chMul; ++dm) { + const d2 = d1 * chMul + dm; + const pixel = dyValues[dyOffset + d2]; + const weight = fltValues[fltOffset + dm]; + dotProd += pixel * weight; + } + } + } + dxValues[dxS0 * b + dxS1 * xR + dxS2 * xC + d1] = dotProd; + } + } + } + } + return backend.makeTensorInfo(dx.shape, dx.dtype, dx.values); + } + const depthwiseConv2dNativeBackpropInputConfig$1 = { + kernelName: DepthwiseConv2dNativeBackpropInput, + backendName: 'cpu', + kernelFunc: depthwiseConv2dNativeBackpropInput$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function diag$1(args) { + const { inputs, backend } = args; + const { x } = inputs; + const xSize = sizeFromShape(x.shape); + const xVals = backend.data.get(x.dataId).values; + const outBuf = buffer([xSize, xSize], x.dtype); + const vals = outBuf.values; + for (let i = 0; i < xVals.length; i++) { + vals[i * xSize + i] = xVals[i]; + } + const outShape = [...x.shape, ...x.shape]; + return backend.makeTensorInfo(outShape, outBuf.dtype, outBuf.values); + } + const diagConfig$1 = { + kernelName: Diag, + backendName: 'cpu', + kernelFunc: diag$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const dilation2DConfig$1 = { + kernelName: Dilation2D, + backendName: 'cpu', + kernelFunc: ({ inputs, backend, attrs }) => { + const { x, filter } = inputs; + const { strides, pad, dilations } = attrs; + const cpuBackend = backend; + const xVals = cpuBackend.data.get(x.dataId).values; + const xRank = x.shape.length; + const filterVals = cpuBackend.data.get(filter.dataId).values; + const filterRank = filter.shape.length; + const { batchSize, inHeight, inWidth, inChannels, outHeight, outWidth, padInfo, strideHeight, strideWidth, filterHeight, filterWidth, dilationHeight, dilationWidth, outShape } = computeDilation2DInfo(x.shape, filter.shape, strides, pad, 'NHWC' /* dataFormat */, dilations); + const outSize = sizeFromShape(outShape); + const outRank = outShape.length; + const outputVals = getArrayFromDType(x.dtype, outSize); + // Upsampling the input by fill in `dilation size - 1` values between each + // input value. + // This implementation follows the TF c++ implementation: + // https://github.com/tensorflow/tensorflow/blob/d9a3a849edc198e90172bc58eb293de457f9d986/tensorflow/core/kernels/dilation_ops.cc + for (let b = 0; b < batchSize; ++b) { + for (let hOut = 0; hOut < outHeight; ++hOut) { + const hBeg = hOut * strideHeight - padInfo.top; + for (let wOut = 0; wOut < outWidth; ++wOut) { + const wBeg = wOut * strideWidth - padInfo.left; + for (let d = 0; d < inChannels; ++d) { + let curVal = Number.MIN_SAFE_INTEGER; + for (let h = 0; h < filterHeight; ++h) { + const hIn = hBeg + h * dilationHeight; + if (hIn >= 0 && hIn < inHeight) { + for (let w = 0; w < filterWidth; ++w) { + const wIn = wBeg + w * dilationWidth; + if (wIn >= 0 && wIn < inWidth) { + const xIndex = locToIndex([b, hIn, wIn, d], xRank, computeStrides(x.shape)); + const filterIndex = locToIndex([h, w, d], filterRank, computeStrides(filter.shape)); + const val = xVals[xIndex] + filterVals[filterIndex]; + if (val > curVal) { + curVal = val; + } + } + } + } + } + const outputIndex = locToIndex([b, hOut, wOut, d], outRank, computeStrides(outShape)); + outputVals[outputIndex] = curVal; + } + } + } + } + const dataId = cpuBackend.write(toTypedArray(outputVals, x.dtype), outShape, x.dtype); + return { dataId, shape: outShape, dtype: x.dtype }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const dilation2DBackpropFilterConfig = { + kernelName: Dilation2DBackpropFilter, + backendName: 'cpu', + kernelFunc: ({ inputs, backend, attrs }) => { + const { x, filter, dy } = inputs; + const { strides, pad, dilations } = attrs; + const cpuBackend = backend; + const $x = toNestedArray(x.shape, cpuBackend.data.get(x.dataId).values); + const $filter = toNestedArray(filter.shape, cpuBackend.data.get(filter.dataId).values); + const { batchSize, inHeight, inWidth, inChannels, outHeight, outWidth, padInfo, strideHeight, strideWidth, filterHeight, filterWidth, dilationHeight, dilationWidth, outShape } = computeDilation2DInfo(x.shape, filter.shape, strides, pad, 'NHWC' /* dataFormat */, dilations); + assert$1(dy.rank === outShape.length, () => `Error in ${Dilation2DBackpropFilter}, dy ` + + `must have the same rank as output ${outShape.length}, but got ` + + `${dy.rank}`); + const $dy = toNestedArray(outShape, cpuBackend.data.get(dy.dataId).values); + // The computed filter gradients has the same dimensions as the filter: + // [filterHeight, filterWidth, depth] + const gradients = makeZerosNestedTypedArray(filter.shape, filter.dtype); + // In the case of multiple argmax branches, we only back-propagate along the + // last branch, i.e., the one with largest value of `h * filter_cols + w`, + // similarly to the max-pooling backward routines. + // This implementation follows the TF c++ implementation: + // https://github.com/tensorflow/tensorflow/blob/d9a3a849edc198e90172bc58eb293de457f9d986/tensorflow/core/kernels/dilation_ops.cc + for (let b = 0; b < batchSize; ++b) { + for (let hOut = 0; hOut < outHeight; ++hOut) { + const hBeg = hOut * strideHeight - padInfo.top; + for (let wOut = 0; wOut < outWidth; ++wOut) { + const wBeg = wOut * strideWidth - padInfo.left; + for (let d = 0; d < inChannels; ++d) { + let curVal = Number.MIN_SAFE_INTEGER; + let hMax = 0; + let wMax = 0; + for (let h = 0; h < filterHeight; ++h) { + const hIn = hBeg + h * dilationHeight; + if (hIn >= 0 && hIn < inHeight) { + for (let w = 0; w < filterWidth; ++w) { + const wIn = wBeg + w * dilationWidth; + if (wIn >= 0 && wIn < inWidth) { + const val = $x[b][hIn][wIn][d] + $filter[h][w][d]; + if (val > curVal) { + curVal = val; + hMax = h; + wMax = w; + } + } + } + } + } + gradients[hMax][wMax][d] += $dy[b][hOut][wOut][d]; + } + } + } + } + const dataId = cpuBackend.write(toTypedArray(gradients, x.dtype), filter.shape, filter.dtype); + return { dataId, shape: filter.shape, dtype: filter.dtype }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const dilation2DBackpropInputConfig = { + kernelName: Dilation2DBackpropInput, + backendName: 'cpu', + kernelFunc: ({ inputs, backend, attrs }) => { + const { x, filter, dy } = inputs; + const { strides, pad, dilations } = attrs; + const cpuBackend = backend; + const $x = toNestedArray(x.shape, cpuBackend.data.get(x.dataId).values); + const $filter = toNestedArray(filter.shape, cpuBackend.data.get(filter.dataId).values); + const { batchSize, inHeight, inWidth, inChannels, outHeight, outWidth, padInfo, strideHeight, strideWidth, filterHeight, filterWidth, dilationHeight, dilationWidth, outShape } = computeDilation2DInfo(x.shape, filter.shape, strides, pad, 'NHWC' /* dataFormat */, dilations); + assert$1(dy.rank === outShape.length, () => `Error in ${Dilation2DBackpropInput}, dy ` + + `must have the same rank as output ${outShape.length}, but got ` + + `${dy.rank}`); + const $dy = toNestedArray(outShape, cpuBackend.data.get(dy.dataId).values); + // The computed gradients has the same dimensions as the input: + // [batch, inputHeight, inputCols, inChannel] + const gradients = makeZerosNestedTypedArray(x.shape, x.dtype); + // In the case of multiple argmax branches, we only back-propagate along the + // last branch, i.e., the one with largest value of `h * filter_cols + w`, + // similarly to the max-pooling backward routines. + // This implementation follows the TF c++ implementation: + // https://github.com/tensorflow/tensorflow/blob/d9a3a849edc198e90172bc58eb293de457f9d986/tensorflow/core/kernels/dilation_ops.cc + for (let b = 0; b < batchSize; ++b) { + for (let hOut = 0; hOut < outHeight; ++hOut) { + const hBeg = hOut * strideHeight - padInfo.top; + for (let wOut = 0; wOut < outWidth; ++wOut) { + const wBeg = wOut * strideWidth - padInfo.left; + for (let d = 0; d < inChannels; ++d) { + let curVal = Number.MIN_SAFE_INTEGER; + let hInMax = (hBeg < 0) ? 0 : hBeg; + let wInMax = (wBeg < 0) ? 0 : wBeg; + for (let h = 0; h < filterHeight; ++h) { + const hIn = hBeg + h * dilationHeight; + if (hIn >= 0 && hIn < inHeight) { + for (let w = 0; w < filterWidth; ++w) { + const wIn = wBeg + w * dilationWidth; + if (wIn >= 0 && wIn < inWidth) { + const val = $x[b][hIn][wIn][d] + $filter[h][w][d]; + if (val > curVal) { + curVal = val; + hInMax = hIn; + wInMax = wIn; + } + } + } + } + } + gradients[b][hInMax][wInMax][d] += $dy[b][hOut][wOut][d]; + } + } + } + } + const dataId = cpuBackend.write(toTypedArray(gradients, x.dtype), x.shape, x.dtype); + return { dataId, shape: x.shape, dtype: x.dtype }; + } + }; + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function draw(args) { + const { inputs, backend, attrs } = args; + const { image } = inputs; + const { canvas, options } = attrs; + const { contextOptions, imageOptions } = options || {}; + const alpha = (imageOptions === null || imageOptions === void 0 ? void 0 : imageOptions.alpha) || 1; + const contextType = (contextOptions === null || contextOptions === void 0 ? void 0 : contextOptions.contextType) || '2d'; + if (contextType !== '2d') { + throw new Error(`Context type ${contextOptions.contextType} is not supported by the CPU backend.`); + } + const ctx = canvas.getContext(contextType, (contextOptions === null || contextOptions === void 0 ? void 0 : contextOptions.contextAttributes) || {}); + if (ctx == null) { + throw new Error(`Could not get the context with ${contextType} type.`); + } + const [height, width] = image.shape.slice(0, 2); + const depth = image.shape.length === 2 ? 1 : image.shape[2]; + const data = backend.data.get(image.dataId).values; + const multiplier = image.dtype === 'float32' ? 255 : 1; + const bytes = new Uint8ClampedArray(width * height * 4); + for (let i = 0; i < height * width; ++i) { + const rgba = [0, 0, 0, 255 * alpha]; + for (let d = 0; d < depth; d++) { + const value = data[i * depth + d]; + if (image.dtype === 'float32') { + if (value < 0 || value > 1) { + throw new Error(`Tensor values for a float32 Tensor must be in the ` + + `range [0 - 1] but encountered ${value}.`); + } + } + else if (image.dtype === 'int32') { + if (value < 0 || value > 255) { + throw new Error(`Tensor values for a int32 Tensor must be in the ` + + `range [0 - 255] but encountered ${value}.`); + } + } + if (depth === 1) { + rgba[0] = value * multiplier; + rgba[1] = value * multiplier; + rgba[2] = value * multiplier; + } + else { + rgba[d] = value * multiplier; + } + } + const j = i * 4; + bytes[j + 0] = Math.round(rgba[0]); + bytes[j + 1] = Math.round(rgba[1]); + bytes[j + 2] = Math.round(rgba[2]); + bytes[j + 3] = Math.round(rgba[3]); + } + canvas.width = width; + canvas.height = height; + const imageData = new ImageData(bytes, width, height); + ctx.putImageData(imageData, 0, 0); + return image; + } + const drawConfig = { + kernelName: Draw, + backendName: 'cpu', + kernelFunc: draw + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sum$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + assertNotComplex$1(x, 'sum'); + let $x; + if (x.dtype === 'bool') { + $x = cast$1({ inputs: { x }, backend, attrs: { dtype: 'int32' } }); + } + else { + $x = identity$1({ inputs: { x }, backend }); + } + const xRank = $x.shape.length; + const axes = parseAxisParam(axis, $x.shape); + const permutation = getAxesPermutation(axes, xRank); + let reductionAxes = axes; + let permutedX = $x; + if (permutation != null) { + permutedX = + transpose$1({ inputs: { x: $x }, backend, attrs: { perm: permutation } }); + reductionAxes = getInnerMostAxes(reductionAxes.length, xRank); + } + assertAxesAreInnerMostDims('sum', reductionAxes, permutedX.shape.length); + const [outShape, reduceShape] = computeOutAndReduceShapes(permutedX.shape, reductionAxes); + const resultDtype = upcastType(permutedX.dtype, 'int32'); + let result = zeros(backend, outShape, resultDtype); + const reduceSize = sizeFromShape(reduceShape); + const vals = backend.data.get(result.dataId).values; + const aVals = backend.data.get(permutedX.dataId).values; + for (let i = 0; i < vals.length; ++i) { + const offset = i * reduceSize; + let sum = 0; + for (let j = 0; j < reduceSize; ++j) { + sum += aVals[offset + j]; + } + vals[i] = sum; + } + if (keepDims) { + const newShape = expandShapeToKeepDim(result.shape, axes); + const oldResult = result; + result = reshape$1({ inputs: { x: result }, backend, attrs: { shape: newShape } }); + backend.disposeIntermediateTensorInfo(oldResult); + } + backend.disposeIntermediateTensorInfo($x); + if (permutation != null) { + backend.disposeIntermediateTensorInfo(permutedX); + } + return result; + } + const sumConfig$1 = { + kernelName: Sum, + backendName: 'cpu', + kernelFunc: sum$1 + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function einsum$1(args) { + const { inputs, backend, attrs } = args; + const { equation } = attrs; + const tensors = inputs; + const { allDims, summedDims, idDims } = decodeEinsumEquation(equation, tensors.length); + checkEinsumDimSizes(allDims.length, idDims, tensors); + const { path, steps } = getEinsumComputePath(summedDims, idDims); + const nSteps = steps.length; + let out = null; + let numDimsRemaining = allDims.length; + const tensorsToDispose = []; + for (let i = 0; i < nSteps; ++i) { + for (const idTerm of steps[i]) { + const { permutationIndices: perm, expandDims: dimsToExpand } = getEinsumPermutation(numDimsRemaining, idDims[idTerm]); + let x; + if (isIdentityPermutation(perm)) { + x = tensors[idTerm]; + } + else { + x = transpose$1({ inputs: { x: tensors[idTerm] }, backend, attrs: { perm } }); + tensorsToDispose.push(x); + } + const targetShape = x.shape.slice(); + for (let k = 0; k < dimsToExpand.length; ++k) { + targetShape.splice(dimsToExpand[k], 0, 1); + } + if (!arraysEqual(x.shape, targetShape)) { + x = reshape$1({ inputs: { x }, backend, attrs: { shape: targetShape } }); + tensorsToDispose.push(x); + } + if (out === null) { + out = x; + } + else { + // tslint:disable-next-line: no-unnecessary-type-assertion + out = multiply$1({ inputs: { a: x, b: out }, backend }); + tensorsToDispose.push(out); + } + } + if (i < nSteps - 1) { + if (path[i] >= 0) { + out = sum$1({ + inputs: { x: out }, + backend, + attrs: { + axis: path[i] - (allDims.length - numDimsRemaining), + keepDims: false + } + }); + tensorsToDispose.push(out); + } + numDimsRemaining--; + } + } + // Clean up intermediate tensors. + for (const tensorInfo of tensorsToDispose) { + if (tensorInfo === out) { + continue; + } + backend.disposeIntermediateTensorInfo(tensorInfo); + } + return out; + } + const einsumConfig$1 = { + kernelName: Einsum, + backendName: 'cpu', + kernelFunc: einsum$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function eluGrad$1(args) { + const { inputs, backend } = args; + const { dy, y } = inputs; + assertNotComplex$1([dy, y], 'eluGrad'); + const resultValues = new Float32Array(sizeFromShape(y.shape)); + const values = backend.data.get(y.dataId).values; + const dyValues = backend.data.get(dy.dataId).values; + for (let i = 0; i < values.length; ++i) { + const v = values[i]; + if (v >= 0) { + resultValues[i] = dyValues[i]; + } + else { + resultValues[i] = dyValues[i] * (v + 1); + } + } + return backend.makeTensorInfo(y.shape, 'float32', resultValues); + } + const eluGradConfig$1 = { + kernelName: EluGrad, + backendName: 'cpu', + kernelFunc: eluGrad$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const p = ERF_P; + const a1 = ERF_A1; + const a2 = ERF_A2; + const a3 = ERF_A3; + const a4 = ERF_A4; + const a5 = ERF_A5; + const erf$1 = unaryKernelFunc$1(Erf, (xi) => { + const sign = Math.sign(xi); + const v = Math.abs(xi); + const t = 1.0 / (1.0 + p * v); + return sign * + (1.0 - + (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * + Math.exp(-v * v)); + }); + const erfConfig$1 = { + kernelName: Erf, + backendName: 'cpu', + kernelFunc: erf$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function expandDims$1(args) { + const { inputs, backend, attrs } = args; + const { input } = inputs; + const { dim } = attrs; + const inputRank = input.shape.length; + const newShape = input.shape.slice(); + let $dim = dim; + if (dim < 0) { + // Negative value is counted from the tail of rank. + assert$1(-(inputRank + 1) <= dim, () => `Axis must be in the interval [${-(inputRank + 1)}, ${inputRank}]`); + $dim = inputRank + dim + 1; + } + newShape.splice($dim, 0, 1); + return reshape$1({ inputs: { x: input }, backend, attrs: { shape: newShape } }); + } + const expandDimsConfig$1 = { + kernelName: ExpandDims, + backendName: 'cpu', + kernelFunc: expandDims$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const realDivImpl = createSimpleBinaryKernelImpl((a, b) => a / b); + const div = binaryKernelFunc$1(RealDiv, realDivImpl); + const realDivConfig$1 = { + kernelName: RealDiv, + backendName: 'cpu', + kernelFunc: div + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Calculate FFT of inner most elements of batch tensor. + */ + function fftBatch(input, inverse, cpuBackend) { + const inputShape = input.shape; + const batch = inputShape[0]; + const innerDim = inputShape[1]; + const inputVals = cpuBackend.data.get(input.dataId); + const real2D = inputVals.complexTensorInfos.real; + const imag2D = inputVals.complexTensorInfos.imag; + // Collects real and imaginary values separately. + const resultShape = [batch, innerDim]; + const resultSize = sizeFromShape(resultShape); + const resultReal = getTypedArrayFromDType('float32', resultSize); + const resultImag = getTypedArrayFromDType('float32', resultSize); + for (let b = 0; b < batch; b++) { + // TODO: Support slice ops for complex type. + const r = slice$1({ + inputs: { x: real2D }, + backend: cpuBackend, + attrs: { begin: [b, 0], size: [1, innerDim] } + }); + const i = slice$1({ + inputs: { x: imag2D }, + backend: cpuBackend, + attrs: { begin: [b, 0], size: [1, innerDim] } + }); + const input = complex$1({ inputs: { real: r, imag: i }, backend: cpuBackend }); + // Run FFT by batch element. + const { real, imag } = fftImpl$1(input, inverse, cpuBackend); + const res = mergeRealAndImagArrays(real, imag); + for (let d = 0; d < innerDim; d++) { + const c = getComplexWithIndex(res, d); + resultReal[b * innerDim + d] = c.real; + resultImag[b * innerDim + d] = c.imag; + } + cpuBackend.disposeIntermediateTensorInfo(r); + cpuBackend.disposeIntermediateTensorInfo(i); + cpuBackend.disposeIntermediateTensorInfo(input); + } + const $realInfo = cpuBackend.makeTensorInfo(resultShape, 'float32', resultReal); + const $imagInfo = cpuBackend.makeTensorInfo(resultShape, 'float32', resultImag); + const result = complex$1({ inputs: { real: $realInfo, imag: $imagInfo }, backend: cpuBackend }); + cpuBackend.disposeIntermediateTensorInfo($realInfo); + cpuBackend.disposeIntermediateTensorInfo($imagInfo); + return result; + } + function fftImpl$1(input, inverse, cpuBackend) { + const inputSize = sizeFromShape(input.shape); + const inputVals = cpuBackend.data.get(input.dataId); + const realVals = cpuBackend.data.get(inputVals.complexTensorInfos.real.dataId).values; + const imagVals = cpuBackend.data.get(inputVals.complexTensorInfos.imag.dataId).values; + if (isExponentOf2(inputSize)) { + const result = fftRadix2(realVals, imagVals, inputSize, inverse, cpuBackend); + const resultShape = [input.shape[0], input.shape[1]]; + if (inverse) { + const realInfo = cpuBackend.makeTensorInfo(resultShape, 'float32', result.real); + const imagInfo = cpuBackend.makeTensorInfo(resultShape, 'float32', result.imag); + const sizeInfo = cpuBackend.makeTensorInfo([], 'float32', createScalarValue(inputSize, 'float32')); + const sizeInfoCopy = identity$1({ inputs: { x: sizeInfo }, backend: cpuBackend }); + const divRealInfo = realDivConfig$1.kernelFunc({ inputs: { a: realInfo, b: sizeInfo }, backend: cpuBackend }); + const divImagInfo = realDivConfig$1.kernelFunc({ inputs: { a: imagInfo, b: sizeInfoCopy }, backend: cpuBackend }); + const divRealVals = cpuBackend.data.get(divRealInfo.dataId).values; + const divImagVals = cpuBackend.data.get(divImagInfo.dataId).values; + cpuBackend.disposeIntermediateTensorInfo(realInfo); + cpuBackend.disposeIntermediateTensorInfo(imagInfo); + cpuBackend.disposeIntermediateTensorInfo(sizeInfo); + cpuBackend.disposeIntermediateTensorInfo(sizeInfoCopy); + cpuBackend.disposeIntermediateTensorInfo(divRealInfo); + cpuBackend.disposeIntermediateTensorInfo(divImagInfo); + return { real: divRealVals, imag: divImagVals }; + } + return result; + } + else { + const data = mergeRealAndImagArrays(realVals, imagVals); + const rawOutput = fourierTransformByMatmul(data, inputSize, inverse); + return splitRealAndImagArrays(rawOutput); + } + } + function isExponentOf2(size) { + return (size & size - 1) === 0; + } + // FFT using Cooley-Tukey algorithm on radix 2 dimensional input. + function fftRadix2(realVals, imagVals, size, inverse, cpuBackend) { + if (size === 1) { + return { real: realVals, imag: imagVals }; + } + const data = mergeRealAndImagArrays(realVals, imagVals); + const half = size / 2; + const evenComplex = complexWithEvenIndex(data); + const evenRealVals = evenComplex.real; + const evenImagVals = evenComplex.imag; + const evenShape = [evenRealVals.length]; + const evenRealInfo = cpuBackend.makeTensorInfo(evenShape, 'float32', evenRealVals); + const evenImagInfo = cpuBackend.makeTensorInfo(evenShape, 'float32', evenImagVals); + const evenTensorInfo = complex$1({ inputs: { real: evenRealInfo, imag: evenImagInfo }, backend: cpuBackend }); + const oddComplex = complexWithOddIndex(data); + const oddRealVals = oddComplex.real; + const oddImagVals = oddComplex.imag; + const oddShape = [oddRealVals.length]; + const oddRealInfo = cpuBackend.makeTensorInfo(oddShape, 'float32', oddRealVals); + const oddImagInfo = cpuBackend.makeTensorInfo(oddShape, 'float32', oddImagVals); + const oddTensorInfo = complex$1({ inputs: { real: oddRealInfo, imag: oddImagInfo }, backend: cpuBackend }); + // Recursive call for half part of original input. + const $evenComplex = fftRadix2(evenRealVals, evenImagVals, half, inverse, cpuBackend); + const $evenRealVals = $evenComplex.real; + const $evenImagVals = $evenComplex.imag; + const $evenShape = [$evenRealVals.length]; + const $evenRealInfo = cpuBackend.makeTensorInfo($evenShape, 'float32', $evenRealVals); + const $evenImagInfo = cpuBackend.makeTensorInfo($evenShape, 'float32', $evenImagVals); + const $evenTensorInfo = complex$1({ + inputs: { real: $evenRealInfo, imag: $evenImagInfo }, + backend: cpuBackend + }); + const $oddComplex = fftRadix2(oddRealVals, oddImagVals, half, inverse, cpuBackend); + const $oddRealVals = $oddComplex.real; + const $oddImagVals = $oddComplex.imag; + const $oddShape = [$oddRealVals.length]; + const $oddRealInfo = cpuBackend.makeTensorInfo($oddShape, 'float32', $oddRealVals); + const $oddImagInfo = cpuBackend.makeTensorInfo($oddShape, 'float32', $oddImagVals); + const $oddTensorInfo = complex$1({ inputs: { real: $oddRealInfo, imag: $oddImagInfo }, backend: cpuBackend }); + const e = exponents(size, inverse); + const eShape = [e.real.length]; + const eRealInfo = cpuBackend.makeTensorInfo(eShape, 'float32', e.real); + const eImagInfo = cpuBackend.makeTensorInfo(eShape, 'float32', e.imag); + const complexInfo = complex$1({ inputs: { real: eRealInfo, imag: eImagInfo }, backend: cpuBackend }); + const exponentInfo = multiply$1({ inputs: { a: complexInfo, b: $oddTensorInfo }, backend: cpuBackend }); + const addPart = add({ + inputs: { a: $evenTensorInfo, b: exponentInfo }, + backend: cpuBackend + }); + const subPart = sub$1({ + inputs: { a: $evenTensorInfo, b: exponentInfo }, + backend: cpuBackend + }); + const addPartReal = real$1({ inputs: { input: addPart }, backend: cpuBackend }); + const subPartReal = real$1({ inputs: { input: subPart }, backend: cpuBackend }); + const addPartImag = imag$1({ inputs: { input: addPart }, backend: cpuBackend }); + const subPartImag = imag$1({ inputs: { input: subPart }, backend: cpuBackend }); + const $real = concat$1({ + inputs: [addPartReal, subPartReal], + backend: cpuBackend, + attrs: { axis: 0 } + }); + const $imag = concat$1({ + inputs: [addPartImag, subPartImag], + backend: cpuBackend, + attrs: { axis: 0 } + }); + const $realVals = cpuBackend.data.get($real.dataId).values; + const $imagVals = cpuBackend.data.get($imag.dataId).values; + cpuBackend.disposeIntermediateTensorInfo(evenRealInfo); + cpuBackend.disposeIntermediateTensorInfo(evenImagInfo); + cpuBackend.disposeIntermediateTensorInfo(evenTensorInfo); + cpuBackend.disposeIntermediateTensorInfo(oddRealInfo); + cpuBackend.disposeIntermediateTensorInfo(oddImagInfo); + cpuBackend.disposeIntermediateTensorInfo(oddTensorInfo); + cpuBackend.disposeIntermediateTensorInfo($evenRealInfo); + cpuBackend.disposeIntermediateTensorInfo($evenImagInfo); + cpuBackend.disposeIntermediateTensorInfo($evenTensorInfo); + cpuBackend.disposeIntermediateTensorInfo($oddRealInfo); + cpuBackend.disposeIntermediateTensorInfo($oddImagInfo); + cpuBackend.disposeIntermediateTensorInfo($oddTensorInfo); + cpuBackend.disposeIntermediateTensorInfo(eRealInfo); + cpuBackend.disposeIntermediateTensorInfo(eImagInfo); + cpuBackend.disposeIntermediateTensorInfo(complexInfo); + cpuBackend.disposeIntermediateTensorInfo(exponentInfo); + cpuBackend.disposeIntermediateTensorInfo(addPart); + cpuBackend.disposeIntermediateTensorInfo(subPart); + cpuBackend.disposeIntermediateTensorInfo(addPartReal); + cpuBackend.disposeIntermediateTensorInfo(addPartImag); + cpuBackend.disposeIntermediateTensorInfo(subPartReal); + cpuBackend.disposeIntermediateTensorInfo(subPartImag); + cpuBackend.disposeIntermediateTensorInfo($real); + cpuBackend.disposeIntermediateTensorInfo($imag); + return { real: $realVals, imag: $imagVals }; + } + // Calculate fourier transform by multplying sinusoid matrix. + function fourierTransformByMatmul(data, size, inverse) { + const ret = new Float32Array(size * 2); + // TODO: Use matmul instead once it supports complex64 type. + for (let r = 0; r < size; r++) { + let real = 0.0; + let imag = 0.0; + for (let c = 0; c < size; c++) { + const e = exponent(r * c, size, inverse); + const term = getComplexWithIndex(data, c); + real += term.real * e.real - term.imag * e.imag; + imag += term.real * e.imag + term.imag * e.real; + } + if (inverse) { + real /= size; + imag /= size; + } + assignToTypedArray(ret, real, imag, r); + } + return ret; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fft$1(args) { + const { inputs, backend } = args; + const { input } = inputs; + const inputSize = sizeFromShape(input.shape); + // Collapse all outer dimensions to a single batch dimension. + const innerDimensionSize = input.shape[input.shape.length - 1]; + const batch = inputSize / innerDimensionSize; + const input2D = reshape$1({ + inputs: { x: input }, + backend, + attrs: { shape: [batch, innerDimensionSize] } + }); + const result = fftBatch(input2D, false, backend); + const resultReshaped = reshape$1({ inputs: { x: result }, backend, attrs: { shape: input.shape } }); + backend.disposeIntermediateTensorInfo(input2D); + backend.disposeIntermediateTensorInfo(result); + return resultReshaped; + } + const fftConfig$1 = { + kernelName: FFT, + backendName: 'cpu', + kernelFunc: fft$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fill$1(args) { + const { backend, attrs } = args; + const { shape, value, dtype } = attrs; + const $dtype = dtype || inferDtype(value); + const values = getArrayFromDType($dtype, sizeFromShape(shape)); + fillValues(values, value, $dtype); + return backend.makeTensorInfo(shape, $dtype, values); + } + const fillConfig$1 = { + kernelName: Fill, + backendName: 'cpu', + kernelFunc: fill$1 + }; + function fillValues(values, value, dtype) { + if (dtype === 'string') { + values.fill(value); + } + else { + values.fill(value); + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const flipLeftRightConfig$1 = { + kernelName: FlipLeftRight, + backendName: 'cpu', + kernelFunc: ({ inputs, attrs, backend }) => { + const { image } = inputs; + const cpuBackend = backend; + const output = getTypedArrayFromDType(image.dtype, sizeFromShape(image.shape)); + const [batch, imageHeight, imageWidth, numChannels] = image.shape; + const imageVals = cpuBackend.data.get(image.dataId).values; + for (let batchIdx = 0; batchIdx < batch; batchIdx++) { + const batchOffset = batchIdx * imageWidth * imageHeight * numChannels; + for (let row = 0; row < imageHeight; row++) { + const rowOffset = row * (imageWidth * numChannels); + for (let col = 0; col < imageWidth; col++) { + const colOffset = col * numChannels; + for (let channel = 0; channel < numChannels; channel++) { + const coordX = Math.round(imageWidth - col - 1); + const outIdx = batchOffset + rowOffset + colOffset + channel; + let outputValue = imageVals[outIdx]; + // If the coordinate position falls within the image boundaries... + if (coordX >= 0 && coordX < imageWidth) { + // set the output to the image value at the coordinate position. + const rotatedColOffset = coordX * numChannels; + const imageIdx = batchOffset + rowOffset + rotatedColOffset + channel; + outputValue = imageVals[imageIdx]; + } + output[outIdx] = outputValue; + } + } + } + } + const dataId = cpuBackend.write(output, image.shape, image.dtype); + return { dataId, shape: image.shape, dtype: image.dtype }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fusedConv2D(args) { + const { inputs, backend, attrs } = args; + const { x, filter, bias, preluActivationWeights } = inputs; + const { strides, pad, dataFormat, dilations, dimRoundingMode, activation, leakyreluAlpha } = attrs; + let result = conv2D({ + inputs: { x, filter }, + backend, + attrs: { strides, pad, dataFormat, dilations, dimRoundingMode } + }); + if (bias) { + const resultOld = result; + // For NCHW format, if bias is a 1-D tensor, it is supposed to be aligned + // to the channel of the conv2d's result; if the bias is a scalar, the + // bias_add is computed as if the bias was broadcasted to the shape of the + // conv2d's result. + if (dataFormat === 'NCHW' && bias.shape.length === 1 && + bias.shape[0] !== 1) { + const reshapedBias = reshape$1({ inputs: { x: bias }, backend, attrs: { shape: [bias.shape[0], 1, 1] } }); + result = + add({ inputs: { a: result, b: reshapedBias }, backend }); + backend.disposeIntermediateTensorInfo(reshapedBias); + } + else { + // This condition handles NHWC and NCHW (scalar case). The only other case + // for NCHW (1D case) is handled above. + result = add({ inputs: { a: result, b: bias }, backend }); + } + backend.disposeIntermediateTensorInfo(resultOld); + } + if (activation) { + const resultOld = result; + // For NCHW format, if PReLu activation weights is a 1-D tensor, it is + // supposed to be aligned with the channel of the conv2d's result. For other + // cases, whether NCHW or NHWC data format, the conv2d result is + // already aligned with the activation weights. + if (dataFormat === 'NCHW' && activation === 'prelu' && + preluActivationWeights.shape.length === 1 && + preluActivationWeights.shape[0] !== 1) { + const reshapedAlpha = reshape$1({ + inputs: { x: preluActivationWeights }, + backend, + attrs: { shape: [preluActivationWeights.shape[0], 1, 1] } + }); + result = applyActivation(backend, result, activation, reshapedAlpha, leakyreluAlpha); + backend.disposeIntermediateTensorInfo(reshapedAlpha); + } + else { + result = applyActivation(backend, result, activation, preluActivationWeights, leakyreluAlpha); + } + backend.disposeIntermediateTensorInfo(resultOld); + } + return result; + } + const fusedConv2DConfig$1 = { + kernelName: FusedConv2D, + backendName: 'cpu', + kernelFunc: fusedConv2D + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fusedDepthwiseConv2D$1(args) { + const { inputs, backend, attrs } = args; + const { x, filter, bias, preluActivationWeights } = inputs; + const { strides, pad, dataFormat, dilations, dimRoundingMode, activation, leakyreluAlpha } = attrs; + let result = depthwiseConv2dNative$1({ + inputs: { x, filter }, + backend, + attrs: { strides, pad, dataFormat, dilations, dimRoundingMode } + }); + if (bias) { + const oldResult = result; + result = add({ inputs: { a: result, b: bias }, backend }); + backend.disposeIntermediateTensorInfo(oldResult); + } + if (activation) { + const oldResult = result; + result = applyActivation(backend, result, activation, preluActivationWeights, leakyreluAlpha); + backend.disposeIntermediateTensorInfo(oldResult); + } + return result; + } + const fusedDepthwiseConv2DConfig$1 = { + kernelName: FusedDepthwiseConv2D, + backendName: 'cpu', + kernelFunc: fusedDepthwiseConv2D$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function gatherNd$1(args) { + const { inputs, backend } = args; + const { params, indices } = inputs; + const paramsSize = sizeFromShape(params.shape); + const indicesShape = indices.shape; + const sliceRank = indicesShape[indicesShape.length - 1]; + const [resultShape, numSlices, sliceSize, strides] = prepareAndValidate(params, indices); + if (numSlices === 0) { + return backend.makeTensorInfo(resultShape, params.dtype, []); + } + const indicesData = backend.data.get(indices.dataId).values; + const paramsBuf = backend.bufferSync(params); + const outBuf = gatherNdImpl(indicesData, paramsBuf, params.dtype, numSlices, sliceRank, sliceSize, strides, params.shape, paramsSize); + return backend.makeTensorInfo(resultShape, params.dtype, outBuf.values); + } + const gatherNdConfig$1 = { + kernelName: GatherNd, + backendName: 'cpu', + kernelFunc: gatherNd$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function gatherV2$1(args) { + const { inputs, backend, attrs } = args; + const { x, indices } = inputs; + const { axis, batchDims } = attrs; + assertNotComplex$1([x, indices], 'gatherV2'); + // Throw error when any index is out of bound. + const parsedAxis = parseAxisParam(axis, x.shape)[0]; + const indicesVals = backend.data.get(indices.dataId).values; + const axisDim = x.shape[parsedAxis]; + for (let i = 0; i < indicesVals.length; ++i) { + const index = indicesVals[i]; + assert$1(index <= axisDim - 1 && index >= 0, () => `GatherV2: the index value ${index} is not in [0, ${axisDim - 1}]`); + } + let $batchDims = batchDims; + if (batchDims == null) { + $batchDims = 0; + } + const indicesSize = sizeFromShape(indices.shape); + const shapeInfo = collectGatherOpShapeInfo(x, indices, parsedAxis, $batchDims); + const flattenX = reshape$1({ + inputs: { x }, + backend, + attrs: { + shape: [ + shapeInfo.batchSize, shapeInfo.outerSize, shapeInfo.dimSize, + shapeInfo.sliceSize + ] + } + }); + const flattenIndex = reshape$1({ + inputs: { x: indices }, + backend, + attrs: { shape: [shapeInfo.batchSize, indicesSize / shapeInfo.batchSize] } + }); + const flattenOutputShape = [ + shapeInfo.batchSize, shapeInfo.outerSize, indicesSize / shapeInfo.batchSize, + shapeInfo.sliceSize + ]; + const indicesBuf = backend.bufferSync(flattenIndex); + const xBuf = backend.bufferSync(flattenX); + const outBuf = gatherV2Impl(xBuf, indicesBuf, flattenOutputShape); + backend.disposeIntermediateTensorInfo(flattenX); + backend.disposeIntermediateTensorInfo(flattenIndex); + return backend.makeTensorInfo(shapeInfo.outputShape, outBuf.dtype, outBuf.values); + } + const gatherV2Config$1 = { + kernelName: GatherV2, + backendName: 'cpu', + kernelFunc: gatherV2$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function ifft$1(args) { + const { inputs, backend } = args; + const { input } = inputs; + const inputSize = sizeFromShape(input.shape); + // Collapse all outer dimensions to a single batch dimension. + const innerDimensionSize = input.shape[input.shape.length - 1]; + const batch = inputSize / innerDimensionSize; + const input2D = reshape$1({ + inputs: { x: input }, + backend, + attrs: { shape: [batch, innerDimensionSize] } + }); + const result = fftBatch(input2D, true, backend); + const resultReshaped = reshape$1({ inputs: { x: result }, backend, attrs: { shape: input.shape } }); + backend.disposeIntermediateTensorInfo(input2D); + backend.disposeIntermediateTensorInfo(result); + return resultReshaped; + } + const ifftConfig$1 = { + kernelName: IFFT, + backendName: 'cpu', + kernelFunc: ifft$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const isFinite$2 = unaryKernelFunc$1(IsFinite, (xi) => Number.isFinite(xi) ? 1 : 0, 'bool'); + const isFiniteConfig$1 = { + kernelName: IsFinite, + backendName: 'cpu', + kernelFunc: isFinite$2, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const isInf$1 = unaryKernelFunc$1(IsInf, (xi) => Math.abs(xi) === Infinity ? 1 : 0, 'bool'); + const isInfConfig$1 = { + kernelName: IsInf, + backendName: 'cpu', + kernelFunc: isInf$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const isNaN$2 = unaryKernelFunc$1(IsNan, (xi) => Number.isNaN(xi) ? 1 : 0, 'bool'); + const isNaNConfig$1 = { + kernelName: IsNan, + backendName: 'cpu', + kernelFunc: isNaN$2, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function linSpace$1(args) { + const { backend, attrs } = args; + const { start, stop, num } = attrs; + const outVals = linSpaceImpl(start, stop, num); + return backend.makeTensorInfo([outVals.length], 'float32', outVals); + } + const linSpaceConfig$1 = { + kernelName: LinSpace, + backendName: 'cpu', + kernelFunc: linSpace$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const log1p$1 = unaryKernelFunc$1(Log1p, (xi) => Math.log1p(xi)); + const log1pConfig$1 = { + kernelName: Log1p, + backendName: 'cpu', + kernelFunc: log1p$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const logicalAndImpl = createSimpleBinaryKernelImpl((a, b) => a && b); + const logicalAnd$1 = binaryKernelFunc$1(LogicalAnd, logicalAndImpl, null /* complexImpl */, 'bool'); + const logicalAndConfig$1 = { + kernelName: LogicalAnd, + backendName: 'cpu', + kernelFunc: logicalAnd$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const logicalNot$1 = unaryKernelFunc$1(LogicalNot, (xi) => xi ? 0 : 1, 'bool'); + const logicalNotConfig$1 = { + kernelName: LogicalNot, + backendName: 'cpu', + kernelFunc: logicalNot$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const logicalOrImpl = createSimpleBinaryKernelImpl((a, b) => a || b); + const logicalOr$1 = binaryKernelFunc$1(LogicalOr, logicalOrImpl, null /* complexImpl */, 'bool'); + const logicalOrConfig$1 = { + kernelName: LogicalOr, + backendName: 'cpu', + kernelFunc: logicalOr$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function lRN(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { depthRadius, bias, alpha, beta } = attrs; + assertNotComplex$1(x, 'LRN'); + const channels = x.shape[3]; + const maxD = channels - 1; + const xValues = backend.data.get(x.dataId).values; + const size = sizeFromShape(x.shape); + const result = new Float32Array(size); + function sumAcrossChannels(offset) { + const currentChannel = offset % channels; + let beginSumOffset = offset - currentChannel + Math.max(0, currentChannel - depthRadius); + const endSumOffset = offset - currentChannel + Math.min(currentChannel + depthRadius, maxD); + let sum = 0.0; + for (; beginSumOffset <= endSumOffset; beginSumOffset++) { + const z = xValues[beginSumOffset]; + sum += z * z; + } + return sum; + } + for (let offset = 0; offset < size; offset++) { + const sum = sumAcrossChannels(offset); + const val = xValues[offset] * Math.pow(bias + alpha * sum, -beta); + result[offset] = val; + } + return backend.makeTensorInfo(x.shape, x.dtype, result); + } + // tslint:disable-next-line: variable-name + const LRNConfig$1 = { + kernelName: LRN, + backendName: 'cpu', + kernelFunc: lRN + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function lRNGrad(args) { + const { inputs, backend, attrs } = args; + const { x, y, dy } = inputs; + const { depthRadius, bias, alpha, beta } = attrs; + assertNotComplex$1(dy, 'LRNGrad'); + const dySize = sizeFromShape(dy.shape); + const channels = dy.shape[3]; + const dyValues = backend.data.get(dy.dataId).values; + const xValues = backend.data.get(x.dataId).values; + const yValues = backend.data.get(y.dataId).values; + const result = new Float32Array(dySize); + const size = dySize; + for (let offset = 0; offset < size; offset++) { + const currentChannel = offset % channels; + const depthBegin = (offset - currentChannel) + Math.max(0, currentChannel - depthRadius); + const depthEnd = (offset - currentChannel) + + Math.min(channels, currentChannel + depthRadius + 1); + let norm = 0; + for (let k = depthBegin; k < depthEnd; k++) { + norm += Math.pow(xValues[k], 2); + } + norm = alpha * norm + bias; + for (let k = depthBegin; k < depthEnd; k++) { + let dyi = -2 * alpha * beta * xValues[k] * yValues[offset] / norm; + if (offset === k) { + dyi += Math.pow(norm, -beta); + } + dyi *= dyValues[offset]; + result[k] += dyi; + } + } + return backend.makeTensorInfo(dy.shape, x.dtype, result); + } + // tslint:disable-next-line: variable-name + const LRNGradConfig$1 = { + kernelName: LRNGrad, + backendName: 'cpu', + kernelFunc: lRNGrad + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function max$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { reductionIndices, keepDims } = attrs; + const cpuBackend = backend; + let xShape = x.shape; + const xRank = xShape.length; + const origAxes = parseAxisParam(reductionIndices, xShape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, xRank); + let xVals = cpuBackend.data.get(x.dataId).values; + if (permutedAxes != null) { + const newShape = new Array(xRank); + for (let i = 0; i < newShape.length; i++) { + newShape[i] = xShape[permutedAxes[i]]; + } + xVals = transposeImpl$1(xVals, xShape, x.dtype, permutedAxes, newShape); + axes = getInnerMostAxes(axes.length, xRank); + xShape = newShape; + } + assertNotComplex$1(x, 'max'); + assertAxesAreInnerMostDims('max', axes, xRank); + const [maxOutShape, reduceShape] = computeOutAndReduceShapes(xShape, axes); + const reduceSize = sizeFromShape(reduceShape); + const result = maxImpl$1(xVals, reduceSize, maxOutShape, x.dtype); + const dataId = cpuBackend.write(result, maxOutShape, x.dtype); + let outShape = maxOutShape; + if (keepDims) { + // reshape + const newShape = expandShapeToKeepDim(maxOutShape, origAxes); + outShape = newShape; + } + return { dataId, shape: outShape, dtype: x.dtype }; + } + const maxConfig$1 = { + kernelName: Max, + backendName: 'cpu', + kernelFunc: max$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPool$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + assertNotComplex$1(x, 'maxPool'); + const { filterSize, strides, pad, dimRoundingMode } = attrs; + const dilations = 1; + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in maxPool: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + const convInfo = computePool2DInfo(x.shape, filterSize, strides, dilations, pad, dimRoundingMode); + let res; + if (convInfo.filterWidth === 1 && convInfo.filterHeight === 1 && + arraysEqual(convInfo.inShape, convInfo.outShape)) { + res = identity$1({ inputs: { x }, backend }); + } + else { + const xValues = backend.data.get(x.dataId).values; + const strides = computeStrides(x.shape); + const buffer = pool(xValues, x.shape, x.dtype, strides, convInfo, 'max'); + res = backend.makeTensorInfo(convInfo.outShape, x.dtype, buffer.values); + } + return res; + } + const maxPoolConfig$1 = { + kernelName: MaxPool, + backendName: 'cpu', + kernelFunc: maxPool$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPool3D(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { filterSize, strides, pad, dimRoundingMode, dataFormat } = attrs; + assertNotComplex$1(x, 'maxPool3d'); + const convInfo = computePool3DInfo(x.shape, filterSize, strides, 1 /* dilations */, pad, dimRoundingMode, dataFormat); + const xValues = backend.data.get(x.dataId).values; + const outBuf = pool3d(xValues, x.shape, x.dtype, computeStrides(x.shape), convInfo, 'max'); + return backend.makeTensorInfo(outBuf.shape, 'float32', outBuf.values); + } + const maxPool3DConfig$1 = { + kernelName: MaxPool3D, + backendName: 'cpu', + kernelFunc: maxPool3D + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPool3DGrad$1(args) { + const { inputs, backend, attrs } = args; + const { dy, input } = inputs; + const { filterSize, strides, pad, dimRoundingMode } = attrs; + assertNotComplex$1([dy, input], 'maxPool3DGrad'); + const convInfo = computePool3DInfo(input.shape, filterSize, strides, 1 /* dilations */, pad, dimRoundingMode); + const inputBuf = backend.bufferSync(input); + const maxPosBuf = maxPool3dPositions(inputBuf, convInfo); + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationDepth = convInfo.dilationDepth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterDepth = convInfo.effectiveFilterDepth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padFront = effectiveFilterDepth - 1 - convInfo.padInfo.front; + const padLeft = effectiveFilterWidth - 1 - convInfo.padInfo.left; + const padTop = effectiveFilterHeight - 1 - convInfo.padInfo.top; + const dx = buffer(input.shape, 'float32'); + const dyBuf = backend.bufferSync(dy); + for (let batch = 0; batch < convInfo.batchSize; ++batch) { + for (let channel = 0; channel < convInfo.inChannels; ++channel) { + for (let dxDepth = 0; dxDepth < convInfo.inDepth; ++dxDepth) { + for (let dxRow = 0; dxRow < convInfo.inHeight; ++dxRow) { + for (let dxCol = 0; dxCol < convInfo.inWidth; ++dxCol) { + // Shader code begins + const dyDepthCorner = dxDepth - padFront; + const dyRowCorner = dxRow - padTop; + const dyColCorner = dxCol - padLeft; + let dotProd = 0; + for (let wDepth = 0; wDepth < effectiveFilterDepth; wDepth += dilationDepth) { + const dyDepth = (dyDepthCorner + wDepth) / strideDepth; + if (dyDepth < 0 || dyDepth >= convInfo.outDepth || + Math.floor(dyDepth) !== dyDepth) { + continue; + } + for (let wRow = 0; wRow < effectiveFilterHeight; wRow += dilationHeight) { + const dyRow = (dyRowCorner + wRow) / strideHeight; + if (dyRow < 0 || dyRow >= convInfo.outHeight || + Math.floor(dyRow) !== dyRow) { + continue; + } + for (let wCol = 0; wCol < effectiveFilterWidth; wCol += dilationWidth) { + const dyCol = (dyColCorner + wCol) / strideWidth; + if (dyCol < 0 || dyCol >= convInfo.outWidth || + Math.floor(dyCol) !== dyCol) { + continue; + } + const maxPos = effectiveFilterDepth * effectiveFilterHeight * + effectiveFilterWidth - + 1 - + maxPosBuf.get(batch, dyDepth, dyRow, dyCol, channel); + const curPos = wDepth * effectiveFilterHeight * effectiveFilterWidth + + wRow * effectiveFilterWidth + wCol; + const mask = maxPos === curPos ? 1 : 0; + if (mask === 0) { + continue; + } + const pixel = dyBuf.get(batch, dyDepth, dyRow, dyCol, channel); + dotProd += pixel * mask; + } + } + } + dx.set(dotProd, batch, dxDepth, dxRow, dxCol, channel); + } + } + } + } + } + return backend.makeTensorInfo(dx.shape, dx.dtype, dx.values); + } + const maxPool3DGradConfig$1 = { + kernelName: MaxPool3DGrad, + backendName: 'cpu', + kernelFunc: maxPool3DGrad$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPoolGrad$1(args) { + const { inputs, backend, attrs } = args; + const { dy, input, output } = inputs; + const x = input; + assertNotComplex$1([input, output], 'maxPoolGrad'); + const { filterSize, strides, pad, dimRoundingMode } = attrs; + const convInfo = computePool2DInfo(x.shape, filterSize, strides, 1 /* dilations */, pad, dimRoundingMode); + const xValues = backend.data.get(x.dataId).values; + const maxPosBuf = buffer(convInfo.outShape, x.dtype, maxPoolPositions(xValues, x.shape, x.dtype, convInfo).values); + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padLeft = effectiveFilterWidth - 1 - convInfo.padInfo.left; + const padTop = effectiveFilterHeight - 1 - convInfo.padInfo.top; + const dx = buffer(x.shape, 'float32'); + const dyData = backend.data.get(dy.dataId).values; + const dyBuf = buffer(dy.shape, 'float32', dyData); + for (let b = 0; b < convInfo.batchSize; ++b) { + for (let d = 0; d < convInfo.inChannels; ++d) { + for (let dxR = 0; dxR < convInfo.inHeight; ++dxR) { + for (let dxC = 0; dxC < convInfo.inWidth; ++dxC) { + // Shader code begins. + const dyRCorner = dxR - padTop; + const dyCCorner = dxC - padLeft; + let dotProd = 0; + for (let wR = 0; wR < effectiveFilterHeight; wR += dilationHeight) { + const dyR = (dyRCorner + wR) / strideHeight; + if (dyR < 0 || dyR >= convInfo.outHeight || + Math.floor(dyR) !== dyR) { + continue; + } + for (let wC = 0; wC < effectiveFilterWidth; wC += dilationWidth) { + const dyC = (dyCCorner + wC) / strideWidth; + if (dyC < 0 || dyC >= convInfo.outWidth || + Math.floor(dyC) !== dyC) { + continue; + } + const maxPos = effectiveFilterHeight * effectiveFilterWidth - 1 - + maxPosBuf.get(b, dyR, dyC, d); + const curPos = wR * effectiveFilterWidth + wC; + const mask = maxPos === curPos ? 1 : 0; + if (mask === 0) { + continue; + } + const pixel = dyBuf.get(b, dyR, dyC, d); + dotProd += pixel * mask; + } + } + dx.set(dotProd, b, dxR, dxC, d); + } + } + } + } + return backend.makeTensorInfo(dx.shape, dx.dtype, dx.values); + } + const maxPoolGradConfig$1 = { + kernelName: MaxPoolGrad, + backendName: 'cpu', + kernelFunc: maxPoolGrad$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPoolWithArgmaxImpl$1(xValues, xShape, dtype, includeBatchInIndex, convInfo) { + const strides = computeStrides(xShape); + const maxPools = pool(xValues, xShape, dtype, strides, convInfo, 'max'); + const maxPositions = maxPoolPositions(xValues, xShape, dtype, convInfo, true, includeBatchInIndex); + return [maxPools.values, maxPositions.values]; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const maxPoolWithArgmaxConfig$1 = { + kernelName: MaxPoolWithArgmax, + backendName: 'cpu', + kernelFunc: ({ inputs, attrs, backend }) => { + const { x } = inputs; + const { filterSize, strides, pad, includeBatchInIndex } = attrs; + const cpuBackend = backend; + assertNotComplex$1(x, 'MaxPoolWithArgmax'); + const values = cpuBackend.data.get(x.dataId).values; + const convInfo = computePool2DInfo(x.shape, filterSize, strides, [1, 1], pad); + const [pooled, indexes] = maxPoolWithArgmaxImpl$1(values, x.shape, x.dtype, includeBatchInIndex, convInfo); + const pooledDataId = cpuBackend.write(pooled, convInfo.outShape, x.dtype); + const indexesDataId = cpuBackend.write(indexes, convInfo.outShape, x.dtype); + return [ + { dataId: pooledDataId, shape: convInfo.outShape, dtype: x.dtype }, + { dataId: indexesDataId, shape: convInfo.outShape, dtype: 'int32' } + ]; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function mean(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + const axes = parseAxisParam(axis, x.shape); + const shapes = computeOutAndReduceShapes(x.shape, axes); + const reduceShape = shapes[1]; + const reduceSize = sizeFromShape(reduceShape); + const toDispose = []; + const reduceSizeScalar = backend.makeTensorInfo([], 'float32', new Float32Array([reduceSize])); + toDispose.push(reduceSizeScalar); + const $x = cast$1({ inputs: { x }, backend, attrs: { dtype: 'float32' } }); + toDispose.push($x); + const res = div({ inputs: { a: $x, b: reduceSizeScalar }, backend }); + toDispose.push(res); + const result = sum$1({ inputs: { x: res }, backend, attrs: { axis, keepDims } }); + toDispose.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return result; + } + const meanConfig$1 = { + kernelName: Mean, + backendName: 'cpu', + kernelFunc: mean + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function min$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + assertNotComplex$1(x, 'min'); + const origAxes = parseAxisParam(axis, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, x.shape.length); + let $x = x; + if (permutedAxes != null) { + $x = transpose$1({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + axes = getInnerMostAxes(axes.length, x.shape.length); + } + assertAxesAreInnerMostDims('min', axes, $x.shape.length); + const [outShape, reduceShape] = computeOutAndReduceShapes($x.shape, axes); + const reduceSize = sizeFromShape(reduceShape); + const vals = makeZerosTypedArray(sizeFromShape(outShape), $x.dtype); + const aVals = backend.data.get($x.dataId).values; + for (let i = 0; i < vals.length; ++i) { + const offset = i * reduceSize; + let min = aVals[offset]; + for (let j = 0; j < reduceSize; ++j) { + const value = aVals[offset + j]; + if (Number.isNaN(value) || + value < min) { // comparison with NaN always return false + min = value; + } + } + vals[i] = min; + } + if (permutedAxes != null) { + backend.disposeIntermediateTensorInfo($x); + } + const result = backend.makeTensorInfo(outShape, $x.dtype, vals); + if (keepDims) { + const expandedShape = expandShapeToKeepDim(outShape, origAxes); + const reshapedResult = reshape$1({ inputs: { x: result }, backend, attrs: { shape: expandedShape } }); + backend.disposeIntermediateTensorInfo(result); + return reshapedResult; + } + return result; + } + const minConfig$1 = { + kernelName: Min, + backendName: 'cpu', + kernelFunc: min$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function mirrorPad(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { paddings, mode } = attrs; + assertNotComplex$1(x, 'mirrorPad'); + const outShape = paddings.map((p, i) => p[0] /* beforePad */ + x.shape[i] + p[1] /* afterPad */); + const start = paddings.map(p => p[0]); + const end = paddings.map((p, i) => p[0] + x.shape[i]); + const offset = mode === 'reflect' ? 0 : 1; + const xVals = backend.data.get(x.dataId).values; + const xRank = x.shape.length; + const xStrides = computeStrides(x.shape); + const resultSize = sizeFromShape(outShape); + const resultRank = outShape.length; + const resultStrides = computeStrides(outShape); + const resVals = getTypedArrayFromDType(x.dtype, resultSize); + for (let i = 0; i < resultSize; i++) { + let coords = indexToLoc(i, resultRank, resultStrides); + for (let i = 0; i < resultRank; i++) { + if (coords[i] < start[i]) { + coords[i] = start[i] * 2 - coords[i] - offset; + } + else if (coords[i] >= end[i]) { + coords[i] = (end[i] - 1) * 2 - coords[i] + offset; + } + } + coords = coords.map((c, i) => c - start[i]); + const inIndex = locToIndex(coords, xRank, xStrides); + resVals[i] = xVals[inIndex]; + } + const outId = backend.write(resVals, outShape, x.dtype); + return { dataId: outId, shape: outShape, dtype: x.dtype }; + } + const mirrorPadConfig$1 = { + kernelName: MirrorPad, + backendName: 'cpu', + kernelFunc: mirrorPad + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const modImpl = createSimpleBinaryKernelImpl(((aValue, bValue) => { + const rem = aValue % bValue; + if ((aValue < 0 && bValue < 0) || (aValue >= 0 && bValue >= 0)) { + return rem; + } + else { + return (rem + bValue) % bValue; + } + })); + const mod$1 = binaryKernelFunc$1(Mod, modImpl); + const modConfig$1 = { + kernelName: Mod, + backendName: 'cpu', + kernelFunc: mod$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function softmax$1(args) { + const { inputs, backend, attrs } = args; + const { logits } = inputs; + const { dim } = attrs; + const logitsRank = logits.shape.length; + let $dim = dim; + if ($dim === -1) { + $dim = logitsRank - 1; + } + if ($dim !== logitsRank - 1) { + throw Error('Softmax along a non-last dimension is not yet supported. ' + + `Logits was rank ${logitsRank} and dim was ${$dim}`); + } + const axes = parseAxisParam([$dim], logits.shape); + const maxLogit = max$1({ + inputs: { x: logits }, + backend, + attrs: { reductionIndices: axes, keepDims: false } + }); + const expandedShape = expandShapeToKeepDim(maxLogit.shape, axes); + const maxLogitReshaped = reshape$1({ inputs: { x: maxLogit }, backend, attrs: { shape: expandedShape } }); + const a = sub$1({ inputs: { a: logits, b: maxLogitReshaped }, backend }); + const b = exp$1({ inputs: { x: a }, backend }); + const sumExp = sum$1({ inputs: { x: b }, backend, attrs: { axis: axes, keepDims: false } }); + const sumReshaped = reshape$1({ inputs: { x: sumExp }, backend, attrs: { shape: expandedShape } }); + const result = div({ inputs: { a: b, b: sumReshaped }, backend }); + backend.disposeIntermediateTensorInfo(maxLogit); + backend.disposeIntermediateTensorInfo(maxLogitReshaped); + backend.disposeIntermediateTensorInfo(a); + backend.disposeIntermediateTensorInfo(b); + backend.disposeIntermediateTensorInfo(sumExp); + backend.disposeIntermediateTensorInfo(sumReshaped); + return result; + } + const softmaxConfig$1 = { + kernelName: Softmax$2, + backendName: 'cpu', + kernelFunc: softmax$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function multinomial$1(args) { + const { inputs, backend, attrs } = args; + const { logits } = inputs; + const { numSamples, seed, normalized } = attrs; + assertNotComplex$1(logits, 'multinomial'); + const probabilities = normalized ? + logits : + softmax$1({ inputs: { logits }, backend, attrs: { dim: -1 } }); + const batchSize = probabilities.shape[0]; + const numEvents = probabilities.shape[1]; + const probVals = backend.data.get(probabilities.dataId).values; + const resShape = [batchSize, numSamples]; + const resVals = makeZerosTypedArray(sizeFromShape(resShape), 'int32'); + for (let b = 0; b < batchSize; ++b) { + const offset = b * numEvents; + // The cdf won't include the last event. It will be implicit if no other + // event happened. + const cdf = new Float32Array(numEvents - 1); + cdf[0] = probVals[offset]; + for (let event = 1; event < cdf.length; ++event) { + cdf[event] = cdf[event - 1] + probVals[offset + event]; + } + const random = seedrandom.alea(seed.toString()); + const outOffset = b * numSamples; + for (let sampleId = 0; sampleId < numSamples; ++sampleId) { + const r = random(); + // Assume last event happened by default. + resVals[outOffset + sampleId] = cdf.length; + for (let event = 0; event < cdf.length; event++) { + if (r < cdf[event]) { + resVals[outOffset + sampleId] = event; + break; + } + } + } + } + if (!normalized) { + backend.disposeIntermediateTensorInfo(probabilities); + } + return backend.makeTensorInfo(resShape, 'int32', resVals); + } + const multinomialConfig$1 = { + kernelName: Multinomial, + backendName: 'cpu', + kernelFunc: multinomial$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const nonMaxSuppressionV3Impl$1 = nonMaxSuppressionV3Impl$2; + function nonMaxSuppressionV3$1(args) { + const { inputs, backend, attrs } = args; + const { boxes, scores } = inputs; + const { maxOutputSize, iouThreshold, scoreThreshold } = attrs; + assertNotComplex$1(boxes, 'NonMaxSuppression'); + const boxesVals = backend.data.get(boxes.dataId).values; + const scoresVals = backend.data.get(scores.dataId).values; + const { selectedIndices } = nonMaxSuppressionV3Impl$1(boxesVals, scoresVals, maxOutputSize, iouThreshold, scoreThreshold); + return backend.makeTensorInfo([selectedIndices.length], 'int32', new Int32Array(selectedIndices)); + } + const nonMaxSuppressionV3Config$1 = { + kernelName: NonMaxSuppressionV3, + backendName: 'cpu', + kernelFunc: nonMaxSuppressionV3$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const nonMaxSuppressionV4Impl$1 = nonMaxSuppressionV4Impl$2; + function nonMaxSuppressionV4$1(args) { + const { inputs, backend, attrs } = args; + const { boxes, scores } = inputs; + const { maxOutputSize, iouThreshold, scoreThreshold, padToMaxOutputSize } = attrs; + assertNotComplex$1(boxes, 'NonMaxSuppressionPadded'); + const boxesVals = backend.data.get(boxes.dataId).values; + const scoresVals = backend.data.get(scores.dataId).values; + const { selectedIndices, validOutputs } = nonMaxSuppressionV4Impl$1(boxesVals, scoresVals, maxOutputSize, iouThreshold, scoreThreshold, padToMaxOutputSize); + return [ + backend.makeTensorInfo([selectedIndices.length], 'int32', new Int32Array(selectedIndices)), + backend.makeTensorInfo([], 'int32', new Int32Array([validOutputs])) + ]; + } + const nonMaxSuppressionV4Config$1 = { + kernelName: NonMaxSuppressionV4, + backendName: 'cpu', + kernelFunc: nonMaxSuppressionV4$1 + }; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const nonMaxSuppressionV5Impl$1 = nonMaxSuppressionV5Impl$2; + function nonMaxSuppressionV5$1(args) { + const { inputs, backend, attrs } = args; + const { boxes, scores } = inputs; + const { maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma } = attrs; + assertNotComplex$1(boxes, 'NonMaxSuppressionWithScore'); + const boxesVals = backend.data.get(boxes.dataId).values; + const scoresVals = backend.data.get(scores.dataId).values; + const maxOutputSizeVal = maxOutputSize; + const iouThresholdVal = iouThreshold; + const scoreThresholdVal = scoreThreshold; + const softNmsSigmaVal = softNmsSigma; + const { selectedIndices, selectedScores } = nonMaxSuppressionV5Impl$1(boxesVals, scoresVals, maxOutputSizeVal, iouThresholdVal, scoreThresholdVal, softNmsSigmaVal); + return [ + backend.makeTensorInfo([selectedIndices.length], 'int32', new Int32Array(selectedIndices)), + backend.makeTensorInfo([selectedScores.length], 'float32', new Float32Array(selectedScores)) + ]; + } + const nonMaxSuppressionV5Config$1 = { + kernelName: NonMaxSuppressionV5, + backendName: 'cpu', + kernelFunc: nonMaxSuppressionV5$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function oneHot$1(args) { + const { inputs, backend, attrs } = args; + const { indices } = inputs; + const { dtype, depth, onValue, offValue } = attrs; + assertNotComplex$1(indices, 'oneHot'); + const indicesSize = sizeFromShape(indices.shape); + const res = new Float32Array(indicesSize * depth); + res.fill(offValue); + const indicesVal = backend.data.get(indices.dataId).values; + for (let event = 0; event < indicesSize; ++event) { + if (indicesVal[event] >= 0 && indicesVal[event] < depth) { + res[event * depth + indicesVal[event]] = onValue; + } + } + return backend.makeTensorInfo([...indices.shape, depth], dtype, res); + } + const oneHotConfig$1 = { + kernelName: OneHot, + backendName: 'cpu', + kernelFunc: oneHot$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function zerosLike$1(args) { + const { inputs, backend } = args; + const { x } = inputs; + if (x.dtype === 'string') { + throw new Error('zerosLike is not supported for string tensors'); + } + else if (x.dtype === 'complex64') { + const realPart = real$1({ inputs: { input: x }, backend }); + const r = zerosLike$1({ inputs: { x: realPart }, backend }); + const imagPart = imag$1({ inputs: { input: x }, backend }); + const i = zerosLike$1({ inputs: { x: imagPart }, backend }); + const result = complex$1({ inputs: { real: r, imag: i }, backend }); + backend.disposeIntermediateTensorInfo(realPart); + backend.disposeIntermediateTensorInfo(r); + backend.disposeIntermediateTensorInfo(imagPart); + backend.disposeIntermediateTensorInfo(i); + return result; + } + else { + return fill$1({ backend, attrs: { shape: x.shape, value: 0, dtype: x.dtype } }); + } + } + const zerosLikeConfig$1 = { + kernelName: ZerosLike, + backendName: 'cpu', + kernelFunc: zerosLike$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function onesLike$1(args) { + const { inputs, backend } = args; + const { x } = inputs; + if (x.dtype === 'string') { + throw new Error('onesLike is not supported for string tensors'); + } + else if (x.dtype === 'complex64') { + const realPart = real$1({ inputs: { input: x }, backend }); + const r = onesLike$1({ inputs: { x: realPart }, backend }); + const imagPart = imag$1({ inputs: { input: x }, backend }); + const i = zerosLike$1({ inputs: { x: imagPart }, backend }); + const result = complex$1({ inputs: { real: r, imag: i }, backend }); + backend.disposeIntermediateTensorInfo(realPart); + backend.disposeIntermediateTensorInfo(r); + backend.disposeIntermediateTensorInfo(imagPart); + backend.disposeIntermediateTensorInfo(i); + return result; + } + else { + return fill$1({ backend, attrs: { shape: x.shape, value: 1, dtype: x.dtype } }); + } + } + const onesLikeConfig$1 = { + kernelName: OnesLike, + backendName: 'cpu', + kernelFunc: onesLike$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function pack$1(args) { + const { inputs, backend, attrs } = args; + const { axis } = attrs; + if (inputs.length === 1) { + return expandDims$1({ inputs: { input: inputs[0] }, backend, attrs: { dim: axis } }); + } + const shape = inputs[0].shape; + const dtype = inputs[0].dtype; + inputs.forEach(t => { + assertShapesMatch(shape, t.shape, 'All tensors passed to stack must have matching shapes'); + assert$1(dtype === t.dtype, () => 'All tensors passed to stack must have matching dtypes'); + }); + const intermediateTensorInfos = []; + const expandedTensors = inputs.map(t => { + const expandedT = expandDims$1({ inputs: { input: t }, backend, attrs: { dim: axis } }); + intermediateTensorInfos.push(expandedT); + return expandedT; + }); + const result = concat$1({ inputs: expandedTensors, backend, attrs: { axis } }); + intermediateTensorInfos.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return result; + } + const packConfig$1 = { + kernelName: Pack, + backendName: 'cpu', + kernelFunc: pack$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function padV2$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { paddings, constantValue } = attrs; + assertNotComplex$1(x, 'pad'); + const outShape = paddings.map((p, i) => p[0] /* beforePad */ + x.shape[i] + p[1] /* afterPad */); + const start = paddings.map(p => p[0]); + const xVals = backend.data.get(x.dataId).values; + const xSize = sizeFromShape(x.shape); + const xRank = x.shape.length; + const xStrides = computeStrides(x.shape); + const resultSize = sizeFromShape(outShape); + const resultRank = outShape.length; + const resultStrides = computeStrides(outShape); + const resVals = getTypedArrayFromDType(x.dtype, resultSize); + if (constantValue !== 0) { + resVals.fill(constantValue); + } + for (let i = 0; i < xSize; i++) { + const coords = indexToLoc(i, xRank, xStrides); + const outCoords = coords.map((c, i) => c + start[i]); + const outIndex = locToIndex(outCoords, resultRank, resultStrides); + resVals[outIndex] = xVals[i]; + } + const outId = backend.write(resVals, outShape, x.dtype); + return { dataId: outId, shape: outShape, dtype: x.dtype }; + } + const padV2Config$1 = { + kernelName: PadV2, + backendName: 'cpu', + kernelFunc: padV2$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const powImpl = createSimpleBinaryKernelImpl((a, b) => Math.pow(a, b)); + const pow$1 = binaryKernelFunc$1(Pow, powImpl); + const powConfig$1 = { + kernelName: Pow, + backendName: 'cpu', + kernelFunc: pow$1 + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function raggedGather$1(args) { + const { inputs, backend, attrs } = args; + const { paramsNestedSplits, paramsDenseValues, indices } = inputs; + const { outputRaggedRank } = attrs; + const $paramsNestedSplits = paramsNestedSplits.map(t => backend.data.get(t.dataId).values); + const $paramsNestedSplitsShapes = paramsNestedSplits.map(t => t.shape); + const $paramsDenseValues = backend.data.get(paramsDenseValues.dataId).values; + const $indices = backend.data.get(indices.dataId).values; + const [outputNestedSplits, outputDenseValues, outputDenseValuesShape] = raggedGatherImpl($paramsNestedSplits, $paramsNestedSplitsShapes, $paramsDenseValues, paramsDenseValues.shape, paramsDenseValues.dtype, $indices, indices.shape, outputRaggedRank); + const outputNestedSplitsTensors = outputNestedSplits.map((splits) => backend.makeTensorInfo([splits.length], 'int32', splits)); + const outputDenseValuesTensor = backend.makeTensorInfo(outputDenseValuesShape, paramsDenseValues.dtype, outputDenseValues); + return outputNestedSplitsTensors.concat([outputDenseValuesTensor]); + } + const raggedGatherConfig$1 = { + kernelName: RaggedGather, + backendName: 'cpu', + kernelFunc: raggedGather$1, + }; + + /** + * @license + * Copyright 2022 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function raggedRange$1(args) { + const { inputs, backend } = args; + const { starts, limits, deltas } = inputs; + const $starts = backend.data.get(starts.dataId).values; + const $limits = backend.data.get(limits.dataId).values; + const $deltas = backend.data.get(deltas.dataId).values; + const [rtNestedSplitsData, rtDenseValuesData] = raggedRangeImpl($starts, starts.shape, starts.dtype, $limits, limits.shape, $deltas, deltas.shape); + const rtNestedSplits = backend.makeTensorInfo([rtNestedSplitsData.length], 'int32', rtNestedSplitsData); + const rtDenseValues = backend.makeTensorInfo([rtDenseValuesData.length], starts.dtype, rtDenseValuesData); + return [rtNestedSplits, rtDenseValues]; + } + const raggedRangeConfig$1 = { + kernelName: RaggedRange, + backendName: 'cpu', + kernelFunc: raggedRange$1, + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function raggedTensorToTensor$1(args) { + const { inputs, backend, attrs } = args; + const { shape, values, defaultValue, rowPartitionTensors } = inputs; + const { rowPartitionTypes } = attrs; + const $shape = backend.data.get(shape.dataId).values; + const $values = backend.data.get(values.dataId).values; + const $defaultValue = backend.data.get(defaultValue.dataId).values; + const $rowPartitionValues = rowPartitionTensors.map(t => backend.data.get(t.dataId).values); + const rowPartitionValuesShapes = rowPartitionTensors.map(t => t.shape); + const [outputShape, output] = raggedTensorToTensorImpl($shape, shape.shape, $values, values.shape, values.dtype, $defaultValue, defaultValue.shape, $rowPartitionValues, rowPartitionValuesShapes, rowPartitionTypes); + return backend.makeTensorInfo(outputShape, values.dtype, output); + } + const raggedTensorToTensorConfig$1 = { + kernelName: RaggedTensorToTensor, + backendName: 'cpu', + kernelFunc: raggedTensorToTensor$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function range$1(args) { + const { backend, attrs } = args; + const { start, stop, dtype, step } = attrs; + const values = rangeImpl(start, stop, step, dtype); + return backend.makeTensorInfo([values.length], dtype, values); + } + const rangeConfig$1 = { + kernelName: Range, + backendName: 'cpu', + kernelFunc: range$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const reciprocal$1 = unaryKernelFunc$1(Reciprocal, (xi) => 1 / xi); + const reciprocalConfig$1 = { + kernelName: Reciprocal, + backendName: 'cpu', + kernelFunc: reciprocal$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function resizeBilinear$1(args) { + const { inputs, backend, attrs } = args; + const { images } = inputs; + const { alignCorners, halfPixelCenters, size } = attrs; + assertNotComplex$1(images, 'resizeBilinear'); + const imagesStrides = computeStrides(images.shape); + const [newHeight, newWidth] = size; + const [batch, oldHeight, oldWidth, numChannels] = images.shape; + const xValues = backend.data.get(images.dataId).values; + const result = new Float32Array(sizeFromShape([batch, newHeight, newWidth, numChannels])); + const effectiveInputSize = [ + (alignCorners && newHeight > 1) ? oldHeight - 1 : oldHeight, + (alignCorners && newWidth > 1) ? oldWidth - 1 : oldWidth + ]; + const effectiveOutputSize = [ + (alignCorners && newHeight > 1) ? newHeight - 1 : newHeight, + (alignCorners && newWidth > 1) ? newWidth - 1 : newWidth + ]; + let outputIdx = 0; + const effectiveRowSizeRatio = effectiveInputSize[0] / effectiveOutputSize[0]; + const effectiveColSizeRatio = effectiveInputSize[1] / effectiveOutputSize[1]; + for (let b = 0; b < batch; b++) { + for (let r = 0; r < newHeight; r++) { + let sourceFracRow; + if (halfPixelCenters) { + sourceFracRow = effectiveRowSizeRatio * (r + 0.5) - 0.5; + } + else { + sourceFracRow = effectiveRowSizeRatio * r; + } + const sourceRowFloor = Math.max(0, Math.floor(sourceFracRow)); + const rowFrac = sourceFracRow - sourceRowFloor; + const sourceRowCeil = Math.min(oldHeight - 1, Math.ceil(sourceFracRow)); + const topRowOffset = b * imagesStrides[0] + sourceRowFloor * imagesStrides[1]; + const botRowOffset = b * imagesStrides[0] + sourceRowCeil * imagesStrides[1]; + for (let c = 0; c < newWidth; c++) { + let sourceFracCol; + if (halfPixelCenters) { + sourceFracCol = effectiveColSizeRatio * (c + 0.5) - 0.5; + } + else { + sourceFracCol = effectiveColSizeRatio * c; + } + const sourceColFloor = Math.max(0, Math.floor(sourceFracCol)); + const colFrac = sourceFracCol - sourceColFloor; + const sourceColCeil = Math.min(oldWidth - 1, Math.ceil(sourceFracCol)); + const topLeftOffest = topRowOffset + sourceColFloor * imagesStrides[2]; + const botLeftOffset = botRowOffset + sourceColFloor * imagesStrides[2]; + const topRightOffset = topRowOffset + sourceColCeil * imagesStrides[2]; + const botRightOffest = botRowOffset + sourceColCeil * imagesStrides[2]; + for (let d = 0; d < numChannels; d++) { + // Begin shader. + // Compute the fractional index of the source. + const topLeft = xValues[topLeftOffest + d]; + const bottomLeft = xValues[botLeftOffset + d]; + const topRight = xValues[topRightOffset + d]; + const bottomRight = xValues[botRightOffest + d]; + const top = topLeft + (topRight - topLeft) * colFrac; + const bottom = bottomLeft + (bottomRight - bottomLeft) * colFrac; + const newValue = top + (bottom - top) * rowFrac; + result[outputIdx++] = newValue; + } + } + } + } + return backend.makeTensorInfo([batch, newHeight, newWidth, numChannels], 'float32', result); + } + const resizeBilinearConfig$1 = { + kernelName: ResizeBilinear, + backendName: 'cpu', + kernelFunc: resizeBilinear$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function resizeBilinearGrad$1(args) { + const { inputs, backend, attrs } = args; + const { images, dy } = inputs; + const { alignCorners } = attrs; + assertNotComplex$1([dy, images], 'resizeBilinearGrad'); + const imagesStrides = computeStrides(images.shape); + const [batch, xHeight, xWidth, depth] = images.shape; + const [, yHeight, yWidth] = dy.shape; + const output = new Float32Array(batch * xHeight * xWidth * depth); + // In the backwards pass, we want to find the pixels that were generated + // for each pixel in the input image the forward pass and add the + // corresponding coefficient from dy to the gradient (with some + // interpolation). + const effectiveXSize = [ + (alignCorners && yHeight > 1) ? xHeight - 1 : xHeight, + (alignCorners && yWidth > 1) ? xWidth - 1 : xWidth + ]; + const effectiveYSize = [ + (alignCorners && yHeight > 1) ? yHeight - 1 : yHeight, + (alignCorners && yWidth > 1) ? yWidth - 1 : yWidth + ]; + const heightScale = effectiveXSize[0] / effectiveYSize[0]; + const widthScale = effectiveXSize[1] / effectiveYSize[1]; + // Reference implementation + // tslint:disable-next-line:max-line-length + // https://github.com/tensorflow/tensorflow/blob/3039375c86a5bbc9610c7725dcaa95d635f87ba2/tensorflow/core/kernels/resize_bilinear_op.cc#L275 + const dyValues = backend.data.get(dy.dataId).values; + let offset = 0; + for (let b = 0; b < batch; b++) { + const bOffset = b * imagesStrides[0]; + for (let r = 0; r < yHeight; r++) { + const dxR = r * heightScale; + const topDxRIndex = Math.floor(dxR); + const bottomDxRIndex = Math.min(Math.ceil(dxR), xHeight - 1); + const topDxROffset = bOffset + topDxRIndex * imagesStrides[1]; + const bottomDxROffset = bOffset + bottomDxRIndex * imagesStrides[1]; + const dxRLerp = dxR - topDxRIndex; + const inverseDxRLerp = 1.0 - dxRLerp; + for (let c = 0; c < yWidth; c++) { + const dxC = c * widthScale; + const leftDxCIndex = Math.floor(dxC); + const rightDxCIndex = Math.min(Math.ceil(dxC), xWidth - 1); + const dxCLerp = dxC - leftDxCIndex; + const inverseDxCLerp = 1.0 - dxCLerp; + const topLeftRCOffset = topDxROffset + leftDxCIndex * imagesStrides[2]; + const topRightRCOffset = topDxROffset + rightDxCIndex * imagesStrides[2]; + const bottomLeftRCOffset = bottomDxROffset + leftDxCIndex * imagesStrides[2]; + const bottomRightRCOffset = bottomDxROffset + rightDxCIndex * imagesStrides[2]; + const inverseDxRLerpTimesInverseDxCLerp = inverseDxRLerp * inverseDxCLerp; + const inverseDxRLerpTimesDxCLerp = inverseDxRLerp * dxCLerp; + const dxRLerpTimesInverseDxCLerp = dxRLerp * inverseDxCLerp; + const dxRLerpTimesDxCLerp = dxRLerp * dxCLerp; + for (let d = 0; d < depth; d++) { + const dyVal = dyValues[offset++]; + output[topLeftRCOffset + d] += + dyVal * inverseDxRLerpTimesInverseDxCLerp; + output[topRightRCOffset + d] += dyVal * inverseDxRLerpTimesDxCLerp; + output[bottomLeftRCOffset + d] += dyVal * dxRLerpTimesInverseDxCLerp; + output[bottomRightRCOffset + d] += dyVal * dxRLerpTimesDxCLerp; + } + } + } + } + return backend.makeTensorInfo([batch, xWidth, xHeight, depth], 'float32', output); + } + const resizeBilinearGradConfig$1 = { + kernelName: ResizeBilinearGrad, + backendName: 'cpu', + kernelFunc: resizeBilinearGrad$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function resizeNearestNeighbor$1(args) { + const { inputs, backend, attrs } = args; + const { images } = inputs; + const { alignCorners, halfPixelCenters, size } = attrs; + assertNotComplex$1(images, 'resizeNearestNeighbor'); + const imagesStrides = computeStrides(images.shape); + const [newHeight, newWidth] = size; + const [batch, oldHeight, oldWidth, numChannels] = images.shape; + const xValues = backend.data.get(images.dataId).values; + const output = new Float32Array(batch * newHeight * newWidth * numChannels); + const effectiveInputSize = [ + (alignCorners && newHeight > 1) ? oldHeight - 1 : oldHeight, + (alignCorners && newWidth > 1) ? oldWidth - 1 : oldWidth + ]; + const effectiveOutputSize = [ + (alignCorners && newHeight > 1) ? newHeight - 1 : newHeight, + (alignCorners && newWidth > 1) ? newWidth - 1 : newWidth + ]; + const effectiveRowSizeRatio = effectiveInputSize[0] / effectiveOutputSize[0]; + const effectiveColSizeRatio = effectiveInputSize[1] / effectiveOutputSize[1]; + let outputOffset = 0; + for (let b = 0; b < batch; b++) { + const batchOffset = b * imagesStrides[0]; + for (let r = 0; r < newHeight; r++) { + const sourceFracRow = halfPixelCenters ? + effectiveRowSizeRatio * (r + 0.5) : + effectiveRowSizeRatio * r; + let sourceNearestRow = Math.min(oldHeight - 1, alignCorners ? Math.round(sourceFracRow) : Math.floor(sourceFracRow)); + if (halfPixelCenters) { + sourceNearestRow = Math.max(0, sourceNearestRow); + } + const rowOffset = batchOffset + sourceNearestRow * imagesStrides[1]; + for (let c = 0; c < newWidth; c++) { + const sourceFracCol = halfPixelCenters ? + effectiveColSizeRatio * (c + 0.5) : + effectiveColSizeRatio * c; + let sourceNearestCol = Math.min(oldWidth - 1, alignCorners ? Math.round(sourceFracCol) : + Math.floor(sourceFracCol)); + if (halfPixelCenters) { + sourceNearestCol = Math.max(0, sourceNearestCol); + } + const colOffset = rowOffset + sourceNearestCol * imagesStrides[2]; + for (let d = 0; d < numChannels; d++) { + // Begin shader. + // Compute the fractional index of the source. + const newVal = xValues[colOffset + d]; + output[outputOffset++] = newVal; + } + } + } + } + return backend.makeTensorInfo([batch, newHeight, newWidth, numChannels], images.dtype, output); + } + const resizeNearestNeighborConfig$1 = { + kernelName: ResizeNearestNeighbor, + backendName: 'cpu', + kernelFunc: resizeNearestNeighbor$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function resizeNearestNeighborGrad$1(args) { + const { inputs, backend, attrs } = args; + const { images, dy } = inputs; + const { alignCorners } = attrs; + assertNotComplex$1([dy, images], 'resizeNearestNeighborGrad'); + const imagesStrides = computeStrides(images.shape); + const dyStrides = computeStrides(dy.shape); + const [batch, xHeight, xWidth, depth] = images.shape; + const [, yHeight, yWidth] = dy.shape; + const output = new Float32Array(batch * xHeight * xWidth * depth); + const dyValues = backend.data.get(dy.dataId).values; + // In the backwards pass, we want to find the pixels that were generated + // for each pixel in the input image the forward pass + const effectiveXSize = [ + (alignCorners && yHeight > 1) ? xHeight - 1 : xHeight, + (alignCorners && yWidth > 1) ? xWidth - 1 : xWidth + ]; + const effectiveYSize = [ + (alignCorners && yHeight > 1) ? yHeight - 1 : yHeight, + (alignCorners && yWidth > 1) ? yWidth - 1 : yWidth + ]; + const heightScale = effectiveXSize[0] / effectiveYSize[0]; + const widthScale = effectiveXSize[1] / effectiveYSize[1]; + const invHeightScale = 1 / heightScale; + const invWidthScale = 1 / widthScale; + // This defines the size of the window of values around a particular + // index in dy that we want to search for contributions to dx. + const winHeight = (Math.ceil(invHeightScale) * 2) + 2; + const winWidth = (Math.ceil(invWidthScale) * 2) + 2; + // Loop over the output space. + for (let b = 0; b < batch; b++) { + const batchOffset = b * imagesStrides[0]; + for (let r = 0; r < xHeight; r++) { + const rowOffset = batchOffset + r * imagesStrides[1]; + // Compute bounds for where in dy we will look + const startRLerp = Math.floor(r * invHeightScale); + const startDyR = Math.floor(startRLerp - (winHeight / 2)); + for (let c = 0; c < xWidth; c++) { + const colOffset = rowOffset + c * imagesStrides[2]; + // Compute bounds for where in dy we will look + const startCLerp = Math.floor(c * invWidthScale); + const startDyC = Math.floor(startCLerp - (winWidth / 2)); + for (let d = 0; d < depth; d++) { + let accum = 0; + // loop over dy + for (let dyRIndex = 0; dyRIndex < winHeight; dyRIndex++) { + const dyR = dyRIndex + startDyR; + // Guard against the window exceeding the bounds of dy + if (dyR < 0 || dyR >= yHeight) { + continue; + } + const dyROffset = batchOffset + dyR * dyStrides[1]; + const sourceFracRow = dyR * heightScale; + const sourceNearestRow = Math.min(xHeight - 1, alignCorners ? Math.round(sourceFracRow) : + Math.floor(sourceFracRow)); + if (r !== sourceNearestRow) { + continue; + } + for (let dyCIndex = 0; dyCIndex < winWidth; dyCIndex++) { + const dyC = dyCIndex + startDyC; + // Guard against the window exceeding the bounds of dy + if (dyC < 0 || dyC >= yWidth) { + continue; + } + const dyCOffset = dyROffset + dyC * dyStrides[2]; + const sourceFracCol = dyC * widthScale; + const sourceNearestCol = Math.min(xWidth - 1, alignCorners ? Math.round(sourceFracCol) : + Math.floor(sourceFracCol)); + if (c === sourceNearestCol) { + accum += dyValues[dyCOffset + d]; + } + } + } + output[colOffset + d] = accum; + } + } + } + } + return backend.makeTensorInfo(images.shape, images.dtype, output); + } + const resizeNearestNeighborGradConfig$1 = { + kernelName: ResizeNearestNeighborGrad, + backendName: 'cpu', + kernelFunc: resizeNearestNeighborGrad$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function reverse$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { dims } = attrs; + assertNotComplex$1(x, 'reverse'); + const xRank = x.shape.length; + const $dims = parseAxisParam(dims, x.shape); + if (xRank === 0) { + return identity$1({ inputs: { x }, backend }); + } + const outBuf = new TensorBuffer(x.shape, x.dtype); + const xBuf = backend.bufferSync(x); + for (let i = 0; i < outBuf.size; i++) { + const outLoc = outBuf.indexToLoc(i); + const inLoc = outLoc.slice(); + $dims.forEach(d => inLoc[d] = x.shape[d] - 1 - inLoc[d]); + outBuf.set(xBuf.get(...inLoc), ...outLoc); + } + return backend.makeTensorInfo(outBuf.shape, outBuf.dtype, outBuf.values); + } + const reverseConfig$1 = { + kernelName: Reverse, + backendName: 'cpu', + kernelFunc: reverse$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const rotateWithOffsetConfig$1 = { + kernelName: RotateWithOffset, + backendName: 'cpu', + kernelFunc: ({ inputs, attrs, backend }) => { + const { image } = inputs; + const { radians, fillValue, center } = attrs; + const cpuBackend = backend; + const output = getTypedArrayFromDType(image.dtype, sizeFromShape(image.shape)); + const [batch, imageHeight, imageWidth, numChannels] = image.shape; + const [centerX, centerY] = getImageCenter(center, imageHeight, imageWidth); + const fullOpacityValue = 255; + const sinFactor = Math.sin(radians); + const cosFactor = Math.cos(radians); + const imageVals = cpuBackend.data.get(image.dataId).values; + for (let batchIdx = 0; batchIdx < batch; batchIdx++) { + const batchOffset = batchIdx * imageWidth * imageHeight * numChannels; + for (let row = 0; row < imageHeight; row++) { + const rowOffset = row * (imageWidth * numChannels); + for (let col = 0; col < imageWidth; col++) { + const colOffset = col * numChannels; + for (let channel = 0; channel < numChannels; channel++) { + const coords = [batch, row, col, channel]; + const x = coords[2]; + const y = coords[1]; + // coordX/coordY are the result of rotating and translating x/y. + let coordX = (x - centerX) * cosFactor - (y - centerY) * sinFactor; + let coordY = (x - centerX) * sinFactor + (y - centerY) * cosFactor; + coordX = Math.round(coordX + centerX); + coordY = Math.round(coordY + centerY); + let outputValue = fillValue; + if (typeof fillValue !== 'number') { + if (channel === 3) { + outputValue = fullOpacityValue; + } + else { + outputValue = fillValue[channel]; + } + } + // If the coordinate position falls within the image boundaries... + if (coordX >= 0 && coordX < imageWidth && coordY >= 0 && + coordY < imageHeight) { + // set the output to the image value at the coordinate position. + const rotatedRowOffset = coordY * (imageWidth * numChannels); + const rotatedColOffset = coordX * numChannels; + const imageIdx = batchOffset + rotatedRowOffset + rotatedColOffset + channel; + outputValue = imageVals[imageIdx]; + } + const outIdx = batchOffset + rowOffset + colOffset + channel; + output[outIdx] = outputValue; + } + } + } + } + const dataId = cpuBackend.write(output, image.shape, image.dtype); + return { dataId, shape: image.shape, dtype: image.dtype }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const round$1 = unaryKernelFunc$1(Round, (xi) => { + // The algorithm is based on banker's rounding. + const base = Math.floor(xi); + if (xi - base < 0.5) { + return Math.floor(xi); + } + else if (xi - base > 0.5) { + return Math.ceil(xi); + } + else { + if (base % 2.0 === 0.0) { + return base; + } + else { + return base + 1.0; + } + } + }); + const roundConfig$1 = { + kernelName: Round, + backendName: 'cpu', + kernelFunc: round$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function scatterNd$1(args) { + const { inputs, backend, attrs } = args; + const { indices, updates } = inputs; + const { shape } = attrs; + const { sliceRank, numUpdates, sliceSize, strides, outputSize } = calculateShapes(updates, indices, shape); + const sumDupeIndices = true; + const indicesBuf = backend.bufferSync(indices); + const updatesBuf = backend.bufferSync(updates); + const outBuf = scatterImpl(indicesBuf, updatesBuf, shape, outputSize, sliceSize, numUpdates, sliceRank, strides, 0 /* defaultValue */, sumDupeIndices); + return backend.makeTensorInfo(shape, outBuf.dtype, outBuf.values); + } + const scatterNdConfig$1 = { + kernelName: ScatterNd, + backendName: 'cpu', + kernelFunc: scatterNd$1 + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function lowerBound(array, value) { + let left = 0; + let right = array.length; + let mid = 0; + while (left < right) { + mid = Math.floor((left + right) / 2); + if (array[mid] < value) { + left = mid + 1; + } + else { + right = mid; + } + } + return right; + } + function upperBound(array, value) { + let left = 0; + let right = array.length; + let mid = 0; + while (left < right) { + mid = Math.floor((left + right) / 2); + if (array[mid] <= value) { + left = mid + 1; + } + else { + right = mid; + } + } + return right; + } + function searchSortedImpl(sortedInputs, values, batchSize, numInputs, numValues, side) { + const output = getArrayFromDType('int32', batchSize * numValues); + for (let b = 0; b < batchSize; ++b) { + const sortedInputsSlice = sortedInputs.slice(b * numInputs, (b + 1) * numInputs); + const outputOffset = b * numValues; + for (let i = 0; i < numValues; ++i) { + output[outputOffset + i] = side === 'left' ? + lowerBound(sortedInputsSlice, values[i + outputOffset]) : + upperBound(sortedInputsSlice, values[i + outputOffset]); + } + } + return output; + } + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function searchSorted$1(args) { + const { inputs, backend, attrs } = args; + const { sortedSequence, values } = inputs; + const { side } = attrs; + const $sortedSequence = backend.data.get(sortedSequence.dataId).values; + const $values = backend.data.get(values.dataId).values; + const output = searchSortedImpl($sortedSequence, $values, sortedSequence.shape[0], sortedSequence.shape[1], values.shape[1], side); + return backend.makeTensorInfo(values.shape, 'int32', output); + } + const searchSortedConfig$1 = { + kernelName: SearchSorted, + backendName: 'cpu', + kernelFunc: searchSorted$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function select$1(args) { + const { inputs, backend } = args; + const { condition, t, e } = inputs; + assertNotComplex$1([condition, t, e], 'select'); + const conditionRank = condition.shape.length; + const values = backend.data.get(condition.dataId).values; + const tValues = backend.data.get(t.dataId).values; + const eValues = backend.data.get(e.dataId).values; + const resultDtype = upcastType(t.dtype, e.dtype); + const newValues = makeZerosTypedArray(sizeFromShape(t.shape), resultDtype); + let index = 0; + const offset = conditionRank === 0 || conditionRank > 1 || t.shape.length === 1 ? + 1 : + sizeFromShape(t.shape.slice(1)); + for (let i = 0; i < values.length; i++) { + for (let j = 0; j < offset; j++) { + if (values[i] === 1) { + newValues[index++] = tValues[i]; + } + else { + newValues[index++] = eValues[i]; + } + } + } + return backend.makeTensorInfo(t.shape, resultDtype, newValues); + } + const selectConfig$1 = { + kernelName: Select, + backendName: 'cpu', + kernelFunc: select$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const scaleAlpha = SELU_SCALEALPHA; + const scale = SELU_SCALE; + const selu$1 = unaryKernelFunc$1(Selu$1, (xi) => { + if (xi >= 0) { + return scale * xi; + } + else { + return scaleAlpha * (Math.exp(xi) - 1); + } + }); + const seluConfig$1 = { + kernelName: Selu$1, + backendName: 'cpu', + kernelFunc: selu$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sign$1 = unaryKernelFunc$1(Sign, (xi) => { + if (xi < 0) { + return -1; + } + else if (xi > 0) { + return 1; + } + else { + return 0; + } + }); + const signConfig$1 = { + kernelName: Sign, + backendName: 'cpu', + kernelFunc: sign$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sin$1 = unaryKernelFunc$1(Sin, (xi) => Math.sin(xi)); + const sinConfig$1 = { + kernelName: Sin, + backendName: 'cpu', + kernelFunc: sin$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const sinh$1 = unaryKernelFunc$1(Sinh, (xi) => Math.sinh(xi)); + const sinhConfig$1 = { + kernelName: Sinh, + backendName: 'cpu', + kernelFunc: sinh$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // mirrors the implementation of tf.nn.softplus: https://goo.gl/vkcvwX + // epsilon is the difference between 1.0 and the next representable float. + // For a single precision 32 bit float this should be 2^-23, see: + // https://math.byu.edu/~schow/work/IEEEFloatingPoint.htm + const epsilon = 1.1920928955078125e-7; + const threshold = Math.log(epsilon) + 2.0; + const softplus$1 = unaryKernelFunc$1(Softplus$1, (xi) => { + // Value above which exp(x) may overflow, but softplus(x) == x + // is within machine epsilon. + const tooLarge = xi > -threshold; + // Value below which exp(x) may underflow, but softplus(x) == exp(x) + // is within machine epsilon. + const tooSmall = xi < threshold; + const expX = Math.exp(xi); + let result; + if (tooSmall) { + result = expX; + } + else if (tooLarge) { + result = xi; + } + else { + result = Math.log(1.0 + expX); + } + return result; + }); + const softplusConfig$1 = { + kernelName: Softplus$1, + backendName: 'cpu', + kernelFunc: softplus$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function spaceToBatchND$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { blockShape, paddings } = attrs; + assertNotComplex$1([x], 'spaceToBatchND'); + const prod = sizeFromShape(blockShape); + const completePaddings = [[0, 0]]; + completePaddings.push(...paddings); + for (let i = 1 + blockShape.length; i < x.shape.length; ++i) { + completePaddings.push([0, 0]); + } + const paddedX = padV2Config$1.kernelFunc({ + inputs: { x }, + backend, + attrs: { paddings: completePaddings, constantValue: 0 } + }); + const reshapedPaddedShape = getReshaped(paddedX.shape, blockShape, prod, false); + const permutedReshapedPaddedPermutation = getPermuted(reshapedPaddedShape.length, blockShape.length, false); + const flattenShape = getReshapedPermuted(paddedX.shape, blockShape, prod, false); + const reshapeInputs = { x: paddedX }; + const reshapeAttrs = { shape: reshapedPaddedShape }; + const paddedXReshaped = reshape$1({ inputs: reshapeInputs, backend, attrs: reshapeAttrs }); + const transposeInputs = { x: paddedXReshaped }; + const transposeAttrs = { perm: permutedReshapedPaddedPermutation }; + const paddedXT = transpose$1({ inputs: transposeInputs, backend, attrs: transposeAttrs }); + const resultReshapeInputs = { x: paddedXT }; + const resultReshapeAttrs = { shape: flattenShape }; + const result = reshape$1({ inputs: resultReshapeInputs, backend, attrs: resultReshapeAttrs }); + backend.disposeIntermediateTensorInfo(paddedX); + backend.disposeIntermediateTensorInfo(paddedXReshaped); + backend.disposeIntermediateTensorInfo(paddedXT); + return result; + } + const spaceToBatchNDConfig$1 = { + kernelName: SpaceToBatchND, + backendName: 'cpu', + kernelFunc: spaceToBatchND$1 + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseFillEmptyRows$1(args) { + const { inputs, backend } = args; + const { indices, values, denseShape, defaultValue } = inputs; + if (denseShape.shape.length !== 1) { + throw new Error(`Dense shape must be a vector, saw: + ${denseShape.shape}`); + } + if (indices.shape.length !== 2) { + throw new Error(`Indices must be a matrix, saw: + ${indices.shape}`); + } + if (values.shape.length !== 1) { + throw new Error(`Values must be a vector, saw: + ${values.shape}`); + } + if (defaultValue.shape.length !== 0) { + throw new Error(`Default value must be a scalar, saw: + ${defaultValue.shape}`); + } + const $indices = backend.data.get(indices.dataId).values; + const $values = backend.data.get(values.dataId).values; + const $denseShape = backend.data.get(denseShape.dataId).values; + const $defaultValue = backend.data.get(defaultValue.dataId).values[0]; + const [outputIndices, outputIndicesShape, outputValues, emptyRowIndicator, reverseIndexMap] = sparseFillEmptyRowsImpl($indices, indices.shape, indices.dtype, $values, values.dtype, $denseShape, $defaultValue); + return [ + backend.makeTensorInfo(outputIndicesShape, indices.dtype, outputIndices), + backend.makeTensorInfo([outputIndicesShape[0]], values.dtype, outputValues), + backend.makeTensorInfo([emptyRowIndicator.length], 'bool', new Uint8Array(emptyRowIndicator.map((value) => Number(value)))), + backend.makeTensorInfo([reverseIndexMap.length], indices.dtype, new Int32Array(reverseIndexMap)), + ]; + } + const sparseFillEmptyRowsConfig$1 = { + kernelName: SparseFillEmptyRows, + backendName: 'cpu', + kernelFunc: sparseFillEmptyRows$1, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseReshape$1(args) { + const { inputs, backend } = args; + const { inputIndices, inputShape, newShape } = inputs; + if (inputIndices.shape.length !== 2) { + throw new Error(`Input indices should be a matrix but received shape + ${inputIndices.shape}`); + } + if (inputShape.shape.length !== 1) { + throw new Error(`Input shape should be a vector but received shape + ${inputShape.shape}`); + } + if (newShape.shape.length !== 1) { + throw new Error(`Target shape should be a vector but received shape ${newShape.shape}`); + } + const $inputShape = Array.from(backend.data.get(inputShape.dataId).values); + const $inputIndices = backend.data.get(inputIndices.dataId).values; + const targetShape = Array.from(backend.data.get(newShape.dataId).values); + const [newIndices, indicesShape, outputShape] = sparseReshapeImpl($inputIndices, inputIndices.shape, inputIndices.dtype, $inputShape, targetShape); + return [ + backend.makeTensorInfo(indicesShape, inputIndices.dtype, newIndices), + backend.makeTensorInfo([outputShape.length], newShape.dtype, new Int32Array(outputShape)), + ]; + } + const sparseReshapeConfig$1 = { + kernelName: SparseReshape, + backendName: 'cpu', + kernelFunc: sparseReshape$1, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseSegmentMean$1(args) { + const { inputs, backend } = args; + const { data, indices, segmentIds } = inputs; + if (data.shape.length < 1) { + throw new Error(`Data should be at least 1 dimensional but received scalar`); + } + if (indices.shape.length !== 1) { + throw new Error(`Indices should be a vector but received shape + ${indices.shape}`); + } + if (segmentIds.shape.length !== 1) { + throw new Error(`Segment ids should be a vector but received shape + ${segmentIds.shape}`); + } + if (indices.shape[0] !== segmentIds.shape[0]) { + throw new Error(`segmentIds and indices should have same size.`); + } + const $data = backend.data.get(data.dataId).values; + const $indices = backend.data.get(indices.dataId).values; + const $segmentIds = backend.data.get(segmentIds.dataId).values; + const [outputData, outputDataShape] = sparseSegmentReductionImpl($data, data.shape, data.dtype, $indices, $segmentIds, true); + return backend.makeTensorInfo(outputDataShape, data.dtype, outputData); + } + const sparseSegmentMeanConfig$1 = { + kernelName: SparseSegmentMean, + backendName: 'cpu', + kernelFunc: sparseSegmentMean$1, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseSegmentSum$1(args) { + const { inputs, backend } = args; + const { data, indices, segmentIds } = inputs; + if (data.shape.length < 1) { + throw new Error(`Data should be at least 1 dimensional but received scalar`); + } + if (indices.shape.length !== 1) { + throw new Error(`Indices should be a vector but received shape + ${indices.shape}`); + } + if (segmentIds.shape.length !== 1) { + throw new Error(`Segment ids should be a vector but received shape + ${segmentIds.shape}`); + } + if (indices.shape[0] !== segmentIds.shape[0]) { + throw new Error(`segmentIds and indices should have same size.`); + } + const $data = backend.data.get(data.dataId).values; + const $indices = backend.data.get(indices.dataId).values; + const $segmentIds = backend.data.get(segmentIds.dataId).values; + const [outputData, outputDataShape] = sparseSegmentReductionImpl($data, data.shape, data.dtype, $indices, $segmentIds); + return backend.makeTensorInfo(outputDataShape, data.dtype, outputData); + } + const sparseSegmentSumConfig$1 = { + kernelName: SparseSegmentSum, + backendName: 'cpu', + kernelFunc: sparseSegmentSum$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseToDense$1(args) { + const { inputs, backend, attrs } = args; + const { sparseIndices, sparseValues, defaultValue } = inputs; + const { outputShape } = attrs; + const { sliceRank, numUpdates, sliceSize, strides, outputSize } = calculateShapes(sparseValues, sparseIndices, outputShape); + const sumDupeIndices = false; + const indicesBuf = backend.bufferSync(sparseIndices); + let outBuf; + switch (sparseValues.dtype) { + case 'bool': { + const updatesBuf = backend.bufferSync(sparseValues); + const $defaultValue = Boolean(backend.data.get(defaultValue.dataId).values[0]); + outBuf = scatterImpl(indicesBuf, updatesBuf, outputShape, outputSize, sliceSize, numUpdates, sliceRank, strides, $defaultValue, sumDupeIndices); + break; + } + case 'float32': { + const updatesBuf = backend.bufferSync(sparseValues); + const $defaultValue = backend.data.get(defaultValue.dataId).values[0]; + outBuf = scatterImpl(indicesBuf, updatesBuf, outputShape, outputSize, sliceSize, numUpdates, sliceRank, strides, $defaultValue, sumDupeIndices); + break; + } + case 'int32': { + const updatesBuf = backend.bufferSync(sparseValues); + const $defaultValue = backend.data.get(defaultValue.dataId).values[0]; + outBuf = scatterImpl(indicesBuf, updatesBuf, outputShape, outputSize, sliceSize, numUpdates, sliceRank, strides, $defaultValue, sumDupeIndices); + break; + } + case 'string': { + const updatesBuf = backend.bufferSync(sparseValues); + const $defaultValue = decodeString(backend.data.get(defaultValue.dataId).values[0]); + outBuf = scatterImpl(indicesBuf, updatesBuf, outputShape, outputSize, sliceSize, numUpdates, sliceRank, strides, $defaultValue, sumDupeIndices); + break; + } + default: + throw new Error(`Unsupported type ${sparseValues.dtype}`); + } + return backend.makeTensorInfo(outputShape, outBuf.dtype, outBuf.values); + } + const sparseToDenseConfig$1 = { + kernelName: SparseToDense, + backendName: 'cpu', + kernelFunc: sparseToDense$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function splitV$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { numOrSizeSplits, axis } = attrs; + const $axis = parseAxisParam(axis, x.shape)[0]; + const splitSizes = prepareSplitSize(x, numOrSizeSplits, $axis); + const begin = new Array(x.shape.length).fill(0); + const size = x.shape.slice(); + return splitSizes.map(s => { + const sliceSize = [...size]; + sliceSize[$axis] = s; + const sliceT = slice$1({ inputs: { x }, backend, attrs: { begin, size: sliceSize } }); + begin[$axis] += s; + return sliceT; + }); + } + const splitVConfig$1 = { + kernelName: SplitV, + backendName: 'cpu', + kernelFunc: splitV$1 + }; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const squareConfig$1 = { + kernelName: Square, + backendName: 'cpu', + kernelFunc: ({ inputs, backend }) => { + const { x } = inputs; + const cpuBackend = backend; + assertNotComplex$1(x, 'square'); + const values = cpuBackend.data.get(x.dataId).values; + const newValues = new Float32Array(values.length); + for (let i = 0; i < values.length; ++i) { + const value = values[i]; + newValues[i] = value * value; + } + const dataId = cpuBackend.write(newValues, x.shape, x.dtype); + return { dataId, shape: x.shape, dtype: x.dtype }; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const step$1 = unaryKernelFunc$1(Step, (xi, attrs) => { + const stepAttrs = attrs; + if (isNaN(xi)) { + return NaN; + } + else { + return xi > 0 ? 1 : stepAttrs.alpha; + } + }); + const stepConfig$1 = { + kernelName: Step, + backendName: 'cpu', + kernelFunc: step$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stridedSlice$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask } = attrs; + assertNotComplex$1(x, 'stridedSlice'); + const { finalShapeSparse, finalShape, isIdentity, sliceDim0, isSimpleSlice, begin: $begin, end: $end, strides: $strides } = sliceInfo(x.shape, begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask); + let result; + // ref: + // https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/strided_slice_op.cc + if (isIdentity) { + // Optimization #1, slice is a no-op plus reshape + result = reshape$1({ inputs: { x }, backend, attrs: { shape: finalShape } }); + } + else if (sliceDim0 || isSimpleSlice) { + // Optimization #2, slice is memory contiguous (only occurs in dim 0) + assert$1(x.shape.length >= 1, () => `Input must have rank at least 1, got: ${x.shape.length}`); + const size = computeOutShape$2($begin, $end, $strides); + // To tolerate begin[0] > end[0] (a 0-output slice), we min(begin, end). + const sliced = slice$1({ inputs: { x }, backend, attrs: { begin: $begin, size } }); + result = + reshape$1({ inputs: { x: sliced }, backend, attrs: { shape: finalShape } }); + backend.disposeIntermediateTensorInfo(sliced); + } + else { + const xBuf = backend.bufferSync(x); + const outBuf = stridedSliceImpl(finalShapeSparse, xBuf, $strides, $begin); + result = backend.makeTensorInfo(finalShape, outBuf.dtype, outBuf.values); + } + return result; + } + const stridedSliceConfig$1 = { + kernelName: StridedSlice, + backendName: 'cpu', + kernelFunc: stridedSlice$1 + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stringNGrams$1(args) { + const { inputs, backend, attrs } = args; + const { separator, nGramWidths, leftPad, rightPad, padWidth, preserveShortSequences } = attrs; + const { data, dataSplits } = inputs; + const $data = backend.data.get(data.dataId).values; + const $dataSplits = backend.data.get(dataSplits.dataId).values; + const [nGrams, nGramsSplits] = stringNGramsImpl($data, $dataSplits, separator, nGramWidths, leftPad, rightPad, padWidth, preserveShortSequences); + return [ + backend.makeTensorInfo([nGrams.length], 'string', nGrams), + backend.makeTensorInfo(dataSplits.shape, 'int32', nGramsSplits), + ]; + } + const stringNGramsConfig$1 = { + kernelName: StringNGrams, + backendName: 'cpu', + kernelFunc: stringNGrams$1, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stringSplit$1(args) { + const { inputs, backend, attrs } = args; + const { skipEmpty } = attrs; + const { input, delimiter } = inputs; + if (input.dtype !== 'string') { + throw new Error('Input must be of datatype string'); + } + if (input.shape.length !== 1) { + throw new Error(`Input must be a vector, got shape: ${input.shape}`); + } + if (delimiter.shape.length !== 0) { + throw new Error(`Delimiter must be a scalar, got shape: ${delimiter.shape}`); + } + const $input = backend.data.get(input.dataId).values; + const $delimiter = backend.data.get(delimiter.dataId).values[0]; + const [indices, values, shape] = stringSplitImpl($input, $delimiter, skipEmpty); + const outputSize = values.length; + return [ + backend.makeTensorInfo([outputSize, 2], 'int32', indices), + backend.makeTensorInfo([outputSize], 'string', values), + backend.makeTensorInfo([2], 'int32', new Int32Array(shape)) + ]; + } + const stringSplitConfig$1 = { + kernelName: StringSplit, + backendName: 'cpu', + kernelFunc: stringSplit$1, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stringToHashBucketFast$1(args) { + const { inputs, backend, attrs } = args; + const { numBuckets } = attrs; + const { input } = inputs; + if (input.dtype !== 'string') { + throw new Error('Input must be of datatype string'); + } + if (numBuckets <= 0) { + throw new Error(`Number of buckets must be at least 1`); + } + const $input = backend.data.get(input.dataId).values; + const output = stringToHashBucketFastImpl($input, numBuckets); + return backend.makeTensorInfo(input.shape, 'int32', output); + } + const stringToHashBucketFastConfig$1 = { + kernelName: StringToHashBucketFast, + backendName: 'cpu', + kernelFunc: stringToHashBucketFast$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const tan$1 = unaryKernelFunc$1(Tan, (xi) => Math.tan(xi)); + const tanConfig$1 = { + kernelName: Tan, + backendName: 'cpu', + kernelFunc: tan$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const tanh$1 = unaryKernelFunc$1(Tanh$1, (xi) => Math.tanh(xi)); + const tanhConfig$1 = { + kernelName: Tanh$1, + backendName: 'cpu', + kernelFunc: tanh$1, + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function tensorScatterUpdate$1(args) { + const { inputs, backend } = args; + const { tensor, indices, updates } = inputs; + const { sliceRank, numUpdates, sliceSize, strides, outputSize } = calculateShapes(updates, indices, tensor.shape); + const sumDupeIndices = false; + const indicesBuf = backend.bufferSync(indices); + const updatesBuf = backend.bufferSync(updates); + const tensorBuf = backend.bufferSync(tensor); + const outBuf = scatterImpl(indicesBuf, updatesBuf, tensor.shape, outputSize, sliceSize, numUpdates, sliceRank, strides, tensorBuf, sumDupeIndices); + return backend.makeTensorInfo(tensor.shape, outBuf.dtype, outBuf.values); + } + const tensorScatterUpdateConfig$1 = { + kernelName: TensorScatterUpdate, + backendName: 'cpu', + kernelFunc: tensorScatterUpdate$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function tile$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { reps } = attrs; + assertNotComplex$1(x, 'tile'); + const outBuf = tileImpl(backend.bufferSync(x), reps); + return backend.makeTensorInfo(outBuf.shape, outBuf.dtype, outBuf.values); + } + const tileConfig$1 = { + kernelName: Tile, + backendName: 'cpu', + kernelFunc: tile$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function topK$1(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { k, sorted } = attrs; + assertNotComplex$1(x, 'topk'); + const xVals = backend.data.get(x.dataId).values; + const [allTopKVals, allTopKIndices] = topKImpl(xVals, x.shape, x.dtype, k, sorted); + return [ + backend.makeTensorInfo(allTopKVals.shape, allTopKVals.dtype, allTopKVals.values), + backend.makeTensorInfo(allTopKIndices.shape, allTopKIndices.dtype, allTopKIndices.values) + ]; + } + const topKConfig$1 = { + kernelName: TopK, + backendName: 'cpu', + kernelFunc: topK$1 + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function transform$1(args) { + const { inputs, attrs, backend } = args; + const { image, transforms } = inputs; + const { interpolation, fillMode, fillValue, outputShape } = attrs; + const [batch, imageHeight, imageWidth, numChannels] = image.shape; + const [outHeight, outWidth] = outputShape != null ? outputShape : [imageHeight, imageWidth]; + const outShape = [batch, outHeight, outWidth, numChannels]; + const inStrides = computeStrides(image.shape); + const batchInStride = inStrides[0]; + const rowInStride = inStrides[1]; + const colInStride = inStrides[2]; + const outStrides = computeStrides(outShape); + const batchOutStride = outStrides[0]; + const rowOutStride = outStrides[1]; + const colOutStride = outStrides[2]; + const outVals = getTypedArrayFromDType(image.dtype, sizeFromShape(outShape)); + outVals.fill(fillValue); + const imageVals = backend.data.get(image.dataId).values; + const transformVals = backend.data.get(transforms.dataId).values; + // Ref TF implementation: + // https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/image/image_ops.h + for (let b = 0; b < batch; ++b) { + const transform = transforms.shape[0] === 1 ? + transformVals : + transformVals.subarray(b * 8, b * 8 + 8); + for (let outY = 0; outY < outHeight; ++outY) { + for (let outX = 0; outX < outWidth; ++outX) { + for (let channel = 0; channel < numChannels; ++channel) { + let val; + const projection = transform[6] * outX + transform[7] * outY + 1; + if (projection === 0) { + // Return the fill value for infinite coordinates, + // which are outside the input image + continue; + } + const inX = (transform[0] * outX + transform[1] * outY + transform[2]) / + projection; + const inY = (transform[3] * outX + transform[4] * outY + transform[5]) / + projection; + const x = mapCoord(inX, imageWidth, fillMode); + const y = mapCoord(inY, imageHeight, fillMode); + switch (interpolation) { + case 'nearest': + val = nearestInterpolation(imageVals, imageHeight, imageWidth, batchInStride, rowInStride, colInStride, b, y, x, channel, fillValue); + break; + case 'bilinear': + val = bilinearInterpolation(imageVals, imageHeight, imageWidth, batchInStride, rowInStride, colInStride, b, y, x, channel, fillValue); + break; + default: + throw new Error(`Error in Transform: Expect 'nearest' or ` + + `'bilinear', but got ${interpolation}`); + } + const ind = b * batchOutStride + outY * rowOutStride + + outX * colOutStride + channel; + outVals[ind] = val; + } + } + } + return backend.makeTensorInfo(outShape, image.dtype, outVals); + } + const dataId = backend.write(outVals, outShape, image.dtype); + return { dataId, shape: image.shape, dtype: image.dtype }; + } + const transformConfig$1 = { + kernelName: Transform, + backendName: 'cpu', + kernelFunc: transform$1 + }; + function mapCoord(outCoord, len, mode) { + switch (mode) { + case 'reflect': + return mapCoordReflect(outCoord, len); + case 'wrap': + return mapCoordWrap(outCoord, len); + case 'nearest': + return mapCoordNearest(outCoord, len); + case 'constant': + default: + return mapCoordConstant(outCoord, len); + } + } + function mapCoordReflect(outCoord, len) { + // Reflect [abcd] to [dcba|abcd|dcba]. + let inCoord = outCoord; + if (inCoord < 0) { + if (len <= 1) { + inCoord = 0; + } + else { + const sz2 = 2 * len; + if (inCoord < sz2) { + inCoord = sz2 * Math.trunc(-inCoord / sz2) + inCoord; + } + inCoord = inCoord < -len ? inCoord + sz2 : -inCoord - 1; + } + } + else if (inCoord > len - 1) { + if (len <= 1) { + inCoord = 0; + } + else { + const sz2 = 2 * len; + inCoord -= sz2 * Math.trunc(inCoord / sz2); + if (inCoord >= len) { + inCoord = sz2 - inCoord - 1; + } + } + } + // clamp is necessary because when outCoord = 3.5 and len = 4, + // inCoord = 3.5 and will be rounded to 4 in nearest interpolation. + return clamp(0, inCoord, len - 1); + } + function mapCoordWrap(outCoord, len) { + // Wrap [abcd] to [abcd|abcd|abcd]. + let inCoord = outCoord; + if (inCoord < 0) { + if (len <= 1) { + inCoord = 0; + } + else { + const sz = len - 1; + inCoord += len * (Math.trunc(-inCoord / sz) + 1); + } + } + else if (inCoord > len - 1) { + if (len <= 1) { + inCoord = 0; + } + else { + const sz = len - 1; + inCoord -= len * Math.trunc(inCoord / sz); + } + } + // clamp is necessary because when outCoord = -0.5 and len = 4, + // inCoord = 3.5 and will be rounded to 4 in nearest interpolation. + return clamp(0, inCoord, len - 1); + } + function mapCoordConstant(outCoord, len) { + return outCoord; + } + function mapCoordNearest(outCoord, len) { + return clamp(0, outCoord, len - 1); + } + function readWithFillValue(imageVals, imageHeight, imageWidth, batchStride, rowStride, colStride, batch, y, x, channel, fillValue) { + const ind = batch * batchStride + y * rowStride + x * colStride + channel; + if (0 <= y && y < imageHeight && 0 <= x && x < imageWidth) { + return imageVals[ind]; + } + else { + return fillValue; + } + } + function nearestInterpolation(imageVals, imageHeight, imageWidth, batchStride, rowStride, colStride, batch, y, x, channel, fillValue) { + const $y = Math.round(y); + const $x = Math.round(x); + return readWithFillValue(imageVals, imageHeight, imageWidth, batchStride, rowStride, colStride, batch, $y, $x, channel, fillValue); + } + function bilinearInterpolation(imageVals, imageHeight, imageWidth, batchStride, rowStride, colStride, batch, y, x, channel, fillValue) { + const yFloor = Math.floor(y); + const xFloor = Math.floor(x); + const yCeil = yFloor + 1; + const xCeil = xFloor + 1; + // f(x, yFloor) = (xCeil - x) / (xCeil - xFloor) * f(xFloor, yFloor) + // + (x - xFloor) / (xCeil - xFloor) * f(xCeil, yFloor) + const valueYFloor = (xCeil - x) * + readWithFillValue(imageVals, imageHeight, imageWidth, batchStride, rowStride, colStride, batch, yFloor, xFloor, channel, fillValue) + + (x - xFloor) * + readWithFillValue(imageVals, imageHeight, imageWidth, batchStride, rowStride, colStride, batch, yFloor, xCeil, channel, fillValue); + // f(x, yCeil) = (xCeil - x) / (xCeil - xFloor) * f(xFloor, yCeil) + // + (x - xFloor) / (xCeil - xFloor) * f(xCeil, yCeil) + const valueYCeil = (xCeil - x) * + readWithFillValue(imageVals, imageHeight, imageWidth, batchStride, rowStride, colStride, batch, yCeil, xFloor, channel, fillValue) + + (x - xFloor) * + readWithFillValue(imageVals, imageHeight, imageWidth, batchStride, rowStride, colStride, batch, yCeil, xCeil, channel, fillValue); + // f(x, y) = (yCeil - y) / (yCeil - yFloor) * f(x, yFloor) + // + (y - yFloor) / (yCeil - yFloor) * f(x, yCeil) + return (yCeil - y) * valueYFloor + (y - yFloor) * valueYCeil; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function unique$1(args) { + const { inputs, attrs, backend } = args; + const { axis } = attrs; + const { x } = inputs; + assertNotComplex$1(x, 'unique'); + const values = backend.data.get(x.dataId).values; + const { outputValues, outputShape, indices } = uniqueImpl(values, axis, x.shape, x.dtype); + return [ + backend.makeTensorInfo(outputShape, x.dtype, outputValues), + backend.makeTensorInfo([indices.length], 'int32', indices), + ]; + } + const uniqueConfig$1 = { + kernelName: Unique, + backendName: 'cpu', + kernelFunc: unique$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function unpack$1(args) { + const { inputs, backend, attrs } = args; + const { value } = inputs; + let { axis } = attrs; + if (axis < 0) { + axis += value.shape.length; + } + const valueRank = value.shape.length; + const num = value.shape[axis]; + const outShape = new Array(valueRank - 1); + let outIndex = 0; + for (let i = 0; i < valueRank; i++) { + if (i !== axis) { + outShape[outIndex++] = value.shape[i]; + } + } + const begin = new Array(valueRank).fill(0); + const size = value.shape.slice(); + size[axis] = 1; + const res = new Array(num); + for (let i = 0; i < res.length; i++) { + begin[axis] = i; + const tempRes = slice$1({ inputs: { x: value }, backend, attrs: { begin, size } }); + res[i] = reshape$1({ inputs: { x: tempRes }, backend, attrs: { shape: outShape } }); + backend.disposeIntermediateTensorInfo(tempRes); + } + return res; + } + const unpackConfig$1 = { + kernelName: Unpack, + backendName: 'cpu', + kernelFunc: unpack$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function unsortedSegmentSum$1(args) { + const { inputs, backend, attrs } = args; + const { x, segmentIds } = inputs; + const { numSegments } = attrs; + assertNotComplex$1(x, 'unsortedSegmentSum'); + const xRank = x.shape.length; + const segmentIdsRank = segmentIds.shape.length; + const res = []; + const intermediates = []; + // Reshape the segment id's so that they can be broadcast with + // x. The new shape should be [segmentIds.shape, 1, ..., 1] + const numIters = xRank - segmentIdsRank; + let $segmentIds = segmentIds; + for (let i = 0; i < numIters; ++i) { + const expanded = expandDims$1({ inputs: { input: $segmentIds }, backend, attrs: { dim: i + 1 } }); + $segmentIds = expanded; + intermediates.push(expanded); + } + for (let i = 0; i < numSegments; ++i) { + const scalarValue = createScalarValue(i, 'int32'); + const segmentId = backend.makeTensorInfo([], 'int32', scalarValue); + const mask = equal$1({ inputs: { a: segmentId, b: $segmentIds }, backend }); + const maskCasted = cast$1({ inputs: { x: mask }, backend, attrs: { dtype: 'float32' } }); + const mul = multiply$1({ inputs: { a: maskCasted, b: x }, backend }); + const sumTensorInfo = sum$1({ inputs: { x: mul }, backend, attrs: { axis: 0, keepDims: false } }); + res.push(sumTensorInfo); + intermediates.push(segmentId); + intermediates.push(mask); + intermediates.push(maskCasted); + intermediates.push(mul); + intermediates.push(sumTensorInfo); + } + const result = pack$1({ inputs: res, backend, attrs: { axis: 0 } }); + intermediates.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return result; + } + const unsortedSegmentSumConfig$1 = { + kernelName: UnsortedSegmentSum, + backendName: 'cpu', + kernelFunc: unsortedSegmentSum$1 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // List all kernel configs here + const kernelConfigs$1 = [ + _fusedMatMulConfig$1, + absConfig$1, + acosConfig$1, + acoshConfig$1, + addConfig$1, + addNConfig$1, + allConfig$1, + anyConfig$1, + argMaxConfig$1, + argMinConfig$1, + asinConfig$1, + asinhConfig$1, + atanConfig$1, + atan2Config$1, + atanhConfig$1, + avgPoolConfig$1, + avgPool3DConfig$1, + avgPool3DGradConfig$1, + avgPoolGradConfig$1, + batchMatMulConfig$1, + batchNormConfig$1, + batchToSpaceNDConfig$1, + bincountConfig$1, + bitwiseAndConfig$1, + broadcastArgsConfig$1, + castConfig$1, + ceilConfig$1, + clipByValueConfig$1, + complexConfig$1, + complexAbsConfig$1, + concatConfig$1, + conv2DConfig$1, + conv2DBackpropFilterConfig$1, + conv2DBackpropInputConfig$1, + conv3DConfig$1, + conv3DBackpropFilterV2Config$1, + conv3DBackpropInputV2Config, + cosConfig$1, + coshConfig$1, + cropAndResizeConfig$1, + cumprodConfig$1, + cumsumConfig$1, + denseBincountConfig$1, + depthToSpaceConfig$1, + depthwiseConv2dNativeConfig$1, + depthwiseConv2dNativeBackpropFilterConfig$1, + depthwiseConv2dNativeBackpropInputConfig$1, + diagConfig$1, + dilation2DConfig$1, + dilation2DBackpropFilterConfig, + dilation2DBackpropInputConfig, + drawConfig, + einsumConfig$1, + eluConfig$1, + eluGradConfig$1, + equalConfig$1, + erfConfig$1, + expConfig$1, + expandDimsConfig$1, + expm1Config$1, + fftConfig$1, + fillConfig$1, + flipLeftRightConfig$1, + floorConfig$1, + floorDivConfig$1, + fusedConv2DConfig$1, + fusedDepthwiseConv2DConfig$1, + gatherNdConfig$1, + gatherV2Config$1, + greaterConfig$1, + greaterEqualConfig$1, + identityConfig$1, + ifftConfig$1, + imagConfig$1, + isFiniteConfig$1, + isInfConfig$1, + isNaNConfig$1, + leakyReluConfig$1, + lessConfig$1, + lessEqualConfig$1, + linSpaceConfig$1, + logConfig$1, + log1pConfig$1, + logicalAndConfig$1, + logicalNotConfig$1, + logicalOrConfig$1, + LRNConfig$1, + LRNGradConfig$1, + maxConfig$1, + maximumConfig$1, + maxPoolConfig$1, + maxPool3DConfig$1, + maxPool3DGradConfig$1, + maxPoolGradConfig$1, + maxPoolWithArgmaxConfig$1, + meanConfig$1, + minConfig$1, + minimumConfig$1, + mirrorPadConfig$1, + modConfig$1, + multinomialConfig$1, + multiplyConfig$1, + negConfig$1, + nonMaxSuppressionV3Config$1, + nonMaxSuppressionV4Config$1, + nonMaxSuppressionV5Config$1, + notEqualConfig$1, + oneHotConfig$1, + onesLikeConfig$1, + packConfig$1, + padV2Config$1, + powConfig$1, + preluConfig$1, + prodConfig$1, + raggedGatherConfig$1, + raggedRangeConfig$1, + raggedTensorToTensorConfig$1, + rangeConfig$1, + realConfig$1, + realDivConfig$1, + reciprocalConfig$1, + reluConfig$1, + relu6Config$1, + reshapeConfig$1, + resizeBilinearConfig$1, + resizeBilinearGradConfig$1, + resizeNearestNeighborConfig$1, + resizeNearestNeighborGradConfig$1, + reverseConfig$1, + rotateWithOffsetConfig$1, + roundConfig$1, + rsqrtConfig$1, + scatterNdConfig$1, + searchSortedConfig$1, + selectConfig$1, + seluConfig$1, + sigmoidConfig$1, + signConfig$1, + sinConfig$1, + sinhConfig$1, + sliceConfig$1, + softmaxConfig$1, + softplusConfig$1, + spaceToBatchNDConfig$1, + sparseFillEmptyRowsConfig$1, + sparseReshapeConfig$1, + sparseSegmentMeanConfig$1, + sparseSegmentSumConfig$1, + sparseToDenseConfig$1, + splitVConfig$1, + sqrtConfig$1, + squareConfig$1, + squaredDifferenceConfig$1, + staticRegexReplaceConfig$1, + stepConfig$1, + stridedSliceConfig$1, + stringNGramsConfig$1, + stringSplitConfig$1, + stringToHashBucketFastConfig$1, + subConfig$1, + sumConfig$1, + tanConfig$1, + tanhConfig$1, + tensorScatterUpdateConfig$1, + tileConfig$1, + topKConfig$1, + transformConfig$1, + transposeConfig$1, + uniqueConfig$1, + unpackConfig$1, + unsortedSegmentSumConfig$1, + zerosLikeConfig$1 + ]; + for (const kernelConfig of kernelConfigs$1) { + registerKernel(kernelConfig); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const contexts = {}; + const WEBGL_ATTRIBUTES = { + alpha: false, + antialias: false, + premultipliedAlpha: false, + preserveDrawingBuffer: false, + depth: false, + stencil: false, + failIfMajorPerformanceCaveat: true + }; + function clearWebGLContext(webGLVersion) { + delete contexts[webGLVersion]; + } + function setWebGLContext(webGLVersion, gl) { + contexts[webGLVersion] = gl; + } + function getWebGLContext(webGLVersion, customCanvas) { + if (!(webGLVersion in contexts) || customCanvas != null) { + const newCtx = getWebGLRenderingContext(webGLVersion, customCanvas); + if (newCtx !== null) { + contexts[webGLVersion] = newCtx; + } + else { + console.log('Could not get context for WebGL version', webGLVersion); + return null; + } + } + const gl = contexts[webGLVersion]; + if (gl == null || gl.isContextLost()) { + delete contexts[webGLVersion]; + return getWebGLContext(webGLVersion); + } + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.STENCIL_TEST); + gl.disable(gl.BLEND); + gl.disable(gl.DITHER); + gl.disable(gl.POLYGON_OFFSET_FILL); + gl.disable(gl.SAMPLE_COVERAGE); + gl.enable(gl.SCISSOR_TEST); + gl.enable(gl.CULL_FACE); + gl.cullFace(gl.BACK); + return contexts[webGLVersion]; + } + function createCanvas(webGLVersion) { + // Use canvas element for Safari, since its offscreen canvas does not support + // fencing. + if (!env().getBool('IS_SAFARI') && typeof OffscreenCanvas !== 'undefined' && + webGLVersion === 2) { + return new OffscreenCanvas(300, 150); + } + else if (typeof document !== 'undefined') { + return document.createElement('canvas'); + } + else { + throw new Error('Cannot create a canvas in this context'); + } + } + function getWebGLRenderingContext(webGLVersion, customCanvas) { + if (webGLVersion !== 1 && webGLVersion !== 2) { + throw new Error('Cannot get WebGL rendering context, WebGL is disabled.'); + } + const canvas = customCanvas == null ? createCanvas(webGLVersion) : customCanvas; + canvas.addEventListener('webglcontextlost', (ev) => { + ev.preventDefault(); + delete contexts[webGLVersion]; + }, false); + if (env().getBool('SOFTWARE_WEBGL_ENABLED')) { + WEBGL_ATTRIBUTES.failIfMajorPerformanceCaveat = false; + } + if (webGLVersion === 1) { + return ( + // tslint:disable-next-line + canvas.getContext('webgl', WEBGL_ATTRIBUTES) || + canvas + .getContext('experimental-webgl', WEBGL_ATTRIBUTES)); + } + return canvas.getContext('webgl2', WEBGL_ATTRIBUTES); + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + var PackingScheme; + (function (PackingScheme) { + /** + * All values in a single texel are densely packed without any constraints. + * + * This is how the shader encodes a tensor with shape = [2, 3, 4] + * (indices are [batch, row, col]). + * + * 000|001 010|011 020|021 + * ------- ------- ------- + * 002|003 012|013 022|023 + * + * 100|101 110|111 120|121 + * ------- ------- ------- + * 102|103 112|113 122|123 + * + */ + PackingScheme[PackingScheme["DENSE"] = 0] = "DENSE"; + /** + * Single texels contain only values from the same batch, and from adjacent + * rows and columns. + * + * This is how the shader encodes a tensor with shape = [2, 3, 5] + * (indices are [batch, row, col]). + * + * 000|001 002|003 004|xxx 020|021 022|023 024|xxx + * ------- ------- ------- ------- ------- ------- + * 010|011 012|013 014|xxx xxx|xxx xxx|xxx xxx|xxx + * + * 100|101 102|103 104|xxx 120|121 122|123 124|xxx + * ------- ------- ------- ------- ------- ------- + * 110|111 112|113 114|xxx xxx|xxx xxx|xxx xxx|xxx + * + */ + PackingScheme[PackingScheme["SHARED_BATCH"] = 1] = "SHARED_BATCH"; + })(PackingScheme || (PackingScheme = {})); + var TextureUsage; + (function (TextureUsage) { + TextureUsage[TextureUsage["RENDER"] = 0] = "RENDER"; + TextureUsage[TextureUsage["UPLOAD"] = 1] = "UPLOAD"; + TextureUsage[TextureUsage["PIXELS"] = 2] = "PIXELS"; + TextureUsage[TextureUsage["DOWNLOAD"] = 3] = "DOWNLOAD"; + })(TextureUsage || (TextureUsage = {})); + var PhysicalTextureType; + (function (PhysicalTextureType) { + PhysicalTextureType[PhysicalTextureType["UNPACKED_FLOAT16"] = 0] = "UNPACKED_FLOAT16"; + PhysicalTextureType[PhysicalTextureType["UNPACKED_FLOAT32"] = 1] = "UNPACKED_FLOAT32"; + PhysicalTextureType[PhysicalTextureType["PACKED_4X1_UNSIGNED_BYTE"] = 2] = "PACKED_4X1_UNSIGNED_BYTE"; + PhysicalTextureType[PhysicalTextureType["PACKED_2X2_FLOAT32"] = 3] = "PACKED_2X2_FLOAT32"; + PhysicalTextureType[PhysicalTextureType["PACKED_2X2_FLOAT16"] = 4] = "PACKED_2X2_FLOAT16"; + })(PhysicalTextureType || (PhysicalTextureType = {})); + function getUnpackedMatrixTextureShapeWidthHeight(rows, columns) { + return [columns, rows]; + } + function getUnpackedArraySizeFromMatrixSize(matrixSize, channelsPerTexture) { + return matrixSize * channelsPerTexture; + } + function getColorMatrixTextureShapeWidthHeight(rows, columns) { + return [columns * 4, rows]; + } + /** + * Get shape for densely packed RGBA texture. + */ + function getDenseTexShape(shape) { + const size = sizeFromShape(shape); + const texelsNeeded = Math.ceil(size / 4); + return sizeToSquarishShape(texelsNeeded); + } + function getMatrixSizeFromUnpackedArraySize(unpackedSize, channelsPerTexture) { + if (unpackedSize % channelsPerTexture !== 0) { + throw new Error(`unpackedSize (${unpackedSize}) must be a multiple of ` + + `${channelsPerTexture}`); + } + return unpackedSize / channelsPerTexture; + } + function decodeMatrixFromUnpackedColorRGBAArray(unpackedArray, matrix, channels) { + const requiredSize = unpackedArray.length * channels / 4; + if (matrix.length < requiredSize) { + throw new Error(`matrix length (${matrix.length}) must be >= ${requiredSize}`); + } + let dst = 0; + for (let src = 0; src < unpackedArray.length; src += 4) { + for (let c = 0; c < channels; c++) { + matrix[dst++] = unpackedArray[src + c]; + } + } + } + function getPackedMatrixTextureShapeWidthHeight(rows, columns) { + return [ + Math.max(1, Math.ceil(columns / 2)), Math.max(1, Math.ceil(rows / 2)) + ]; + } + function getPackedRGBAArraySizeFromMatrixShape(rows, columns) { + const [w, h] = getPackedMatrixTextureShapeWidthHeight(rows, columns); + return w * h * 4; + } + function getTextureConfig( + // tslint:disable-next-line:no-any + gl, textureHalfFloatExtension) { + // tslint:disable-next-line:no-any + const glany = gl; + let internalFormatFloat; + let internalFormatHalfFloat; + let internalFormatPackedHalfFloat; + let internalFormatPackedFloat; + let textureFormatFloat; + let downloadTextureFormat; + let downloadUnpackNumChannels; + let defaultNumChannels; + let textureTypeHalfFloat; + let textureTypeFloat; + if (env().getNumber('WEBGL_VERSION') === 2) { + internalFormatFloat = glany.R32F; + internalFormatHalfFloat = glany.R16F; + internalFormatPackedHalfFloat = glany.RGBA16F; + internalFormatPackedFloat = glany.RGBA32F; + textureFormatFloat = glany.RED; + downloadUnpackNumChannels = 4; + defaultNumChannels = 1; + textureTypeHalfFloat = glany.HALF_FLOAT; + textureTypeFloat = glany.FLOAT; + downloadTextureFormat = glany.RGBA8; + } + else { + internalFormatFloat = gl.RGBA; + internalFormatHalfFloat = gl.RGBA; + internalFormatPackedHalfFloat = gl.RGBA; + internalFormatPackedFloat = glany.RGBA; + textureFormatFloat = gl.RGBA; + downloadUnpackNumChannels = 4; + defaultNumChannels = 4; + textureTypeHalfFloat = textureHalfFloatExtension != null ? + textureHalfFloatExtension.HALF_FLOAT_OES : + null; + textureTypeFloat = gl.FLOAT; + downloadTextureFormat = gl.RGBA; + } + return { + internalFormatFloat, + internalFormatHalfFloat, + internalFormatPackedHalfFloat, + internalFormatPackedFloat, + textureFormatFloat, + downloadTextureFormat, + downloadUnpackNumChannels, + defaultNumChannels, + textureTypeHalfFloat, + textureTypeFloat + }; + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function callAndCheck(gl, func) { + const returnValue = func(); + if (env().getBool('DEBUG')) { + checkWebGLError(gl); + } + return returnValue; + } + function checkWebGLError(gl) { + const error = gl.getError(); + if (error !== gl.NO_ERROR) { + throw new Error('WebGL Error: ' + getWebGLErrorMessage(gl, error)); + } + } + // https://en.wikipedia.org/wiki/Half-precision_floating-point_format + const MIN_FLOAT16 = 5.96e-8; + const MAX_FLOAT16 = 65504; + function canBeRepresented(num) { + if (env().getBool('WEBGL_RENDER_FLOAT32_ENABLED') || num === 0 || + (MIN_FLOAT16 < Math.abs(num) && Math.abs(num) < MAX_FLOAT16)) { + return true; + } + return false; + } + function getWebGLErrorMessage(gl, status) { + switch (status) { + case gl.NO_ERROR: + return 'NO_ERROR'; + case gl.INVALID_ENUM: + return 'INVALID_ENUM'; + case gl.INVALID_VALUE: + return 'INVALID_VALUE'; + case gl.INVALID_OPERATION: + return 'INVALID_OPERATION'; + case gl.INVALID_FRAMEBUFFER_OPERATION: + return 'INVALID_FRAMEBUFFER_OPERATION'; + case gl.OUT_OF_MEMORY: + return 'OUT_OF_MEMORY'; + case gl.CONTEXT_LOST_WEBGL: + return 'CONTEXT_LOST_WEBGL'; + default: + return `Unknown error code ${status}`; + } + } + function getExtensionOrThrow(gl, extensionName) { + return throwIfNull(gl, () => gl.getExtension(extensionName), 'Extension "' + extensionName + '" not supported on this browser.'); + } + function createVertexShader$1(gl, vertexShaderSource) { + const vertexShader = throwIfNull(gl, () => gl.createShader(gl.VERTEX_SHADER), 'Unable to create vertex WebGLShader.'); + callAndCheck(gl, () => gl.shaderSource(vertexShader, vertexShaderSource)); + callAndCheck(gl, () => gl.compileShader(vertexShader)); + if (gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS) === false) { + console.log(gl.getShaderInfoLog(vertexShader)); + throw new Error('Failed to compile vertex shader.'); + } + return vertexShader; + } + function createFragmentShader(gl, fragmentShaderSource) { + const fragmentShader = throwIfNull(gl, () => gl.createShader(gl.FRAGMENT_SHADER), 'Unable to create fragment WebGLShader.'); + callAndCheck(gl, () => gl.shaderSource(fragmentShader, fragmentShaderSource)); + callAndCheck(gl, () => gl.compileShader(fragmentShader)); + if (env().get('ENGINE_COMPILE_ONLY')) { + return fragmentShader; + } + if (gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) === false) { + logShaderSourceAndInfoLog(fragmentShaderSource, gl.getShaderInfoLog(fragmentShader)); + throw new Error('Failed to compile fragment shader.'); + } + return fragmentShader; + } + const lineNumberRegex = /ERROR: [0-9]+:([0-9]+):/g; + function logShaderSourceAndInfoLog(shaderSource, shaderInfoLog) { + const lineNumberRegexResult = lineNumberRegex.exec(shaderInfoLog); + if (lineNumberRegexResult == null) { + console.log(`Couldn't parse line number in error: ${shaderInfoLog}`); + console.log(shaderSource); + return; + } + const lineNumber = +lineNumberRegexResult[1]; + const shaderLines = shaderSource.split('\n'); + const pad = shaderLines.length.toString().length + 2; + const linesWithLineNumbers = shaderLines.map((line, lineNumber) => rightPad((lineNumber + 1).toString(), pad) + line); + let maxLineLength = 0; + for (let i = 0; i < linesWithLineNumbers.length; i++) { + maxLineLength = Math.max(linesWithLineNumbers[i].length, maxLineLength); + } + const beforeErrorLines = linesWithLineNumbers.slice(0, lineNumber - 1); + const errorLine = linesWithLineNumbers.slice(lineNumber - 1, lineNumber); + const afterErrorLines = linesWithLineNumbers.slice(lineNumber); + console.log(beforeErrorLines.join('\n')); + console.log(shaderInfoLog.split('\n')[0]); + console.log(`%c ${rightPad(errorLine[0], maxLineLength)}`, 'border:1px solid red; background-color:#e3d2d2; color:#a61717'); + console.log(afterErrorLines.join('\n')); + } + function createProgram(gl) { + return throwIfNull(gl, () => gl.createProgram(), 'Unable to create WebGLProgram.'); + } + function linkProgram(gl, program) { + callAndCheck(gl, () => gl.linkProgram(program)); + if (env().get('ENGINE_COMPILE_ONLY')) { + return; + } + if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) { + console.log(gl.getProgramInfoLog(program)); + throw new Error('Failed to link vertex and fragment shaders.'); + } + } + /// validateProgram is effectively "If we `useProgram(program); drawArrays();`, + /// give feedback in log about perf/correctness warnings or errors that would + /// occur." + /// So make sure we set up all vertex/texture/sampler/uniform data before + /// calling validateProgram! + function validateProgram(gl, program) { + callAndCheck(gl, () => gl.validateProgram(program)); + if (gl.getProgramParameter(program, gl.VALIDATE_STATUS) === false) { + console.log(gl.getProgramInfoLog(program)); + throw new Error('Shader program validation failed.'); + } + } + function createStaticVertexBuffer(gl, data) { + const buffer = throwIfNull(gl, () => gl.createBuffer(), 'Unable to create WebGLBuffer'); + callAndCheck(gl, () => gl.bindBuffer(gl.ARRAY_BUFFER, buffer)); + callAndCheck(gl, () => gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW)); + return buffer; + } + function createStaticIndexBuffer(gl, data) { + const buffer = throwIfNull(gl, () => gl.createBuffer(), 'Unable to create WebGLBuffer'); + callAndCheck(gl, () => gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer)); + callAndCheck(gl, () => gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, gl.STATIC_DRAW)); + return buffer; + } + function getNumChannels() { + if (env().getNumber('WEBGL_VERSION') === 2) { + return 1; + } + return 4; + } + function createTexture(gl) { + return throwIfNull(gl, () => gl.createTexture(), 'Unable to create WebGLTexture.'); + } + function validateTextureSize(width, height) { + const maxTextureSize = env().getNumber('WEBGL_MAX_TEXTURE_SIZE'); + if ((width <= 0) || (height <= 0)) { + const requested = `[${width}x${height}]`; + throw new Error('Requested texture size ' + requested + ' is invalid.'); + } + if ((width > maxTextureSize) || (height > maxTextureSize)) { + const requested = `[${width}x${height}]`; + const max = `[${maxTextureSize}x${maxTextureSize}]`; + throw new Error('Requested texture size ' + requested + + ' greater than WebGL maximum on this browser / GPU ' + max + '.'); + } + } + function createFramebuffer(gl) { + return throwIfNull(gl, () => gl.createFramebuffer(), 'Unable to create WebGLFramebuffer.'); + } + function bindVertexBufferToProgramAttribute(gl, program, attribute, buffer, arrayEntriesPerItem, itemStrideInBytes, itemOffsetInBytes) { + const loc = gl.getAttribLocation(program, attribute); + if (loc === -1) { + // The GPU compiler decided to strip out this attribute because it's unused, + // thus no need to bind. + return false; + } + callAndCheck(gl, () => gl.bindBuffer(gl.ARRAY_BUFFER, buffer)); + callAndCheck(gl, () => gl.vertexAttribPointer(loc, arrayEntriesPerItem, gl.FLOAT, false, itemStrideInBytes, itemOffsetInBytes)); + callAndCheck(gl, () => gl.enableVertexAttribArray(loc)); + return true; + } + function bindTextureUnit(gl, texture, textureUnit) { + validateTextureUnit(gl, textureUnit); + callAndCheck(gl, () => gl.activeTexture(gl.TEXTURE0 + textureUnit)); + callAndCheck(gl, () => gl.bindTexture(gl.TEXTURE_2D, texture)); + } + function unbindTextureUnit(gl, textureUnit) { + validateTextureUnit(gl, textureUnit); + callAndCheck(gl, () => gl.activeTexture(gl.TEXTURE0 + textureUnit)); + callAndCheck(gl, () => gl.bindTexture(gl.TEXTURE_2D, null)); + } + function getProgramUniformLocationOrThrow(gl, program, uniformName) { + return throwIfNull(gl, () => gl.getUniformLocation(program, uniformName), 'uniform "' + uniformName + '" not present in program.'); + } + function getProgramUniformLocation(gl, program, uniformName) { + return gl.getUniformLocation(program, uniformName); + } + function bindTextureToProgramUniformSampler(gl, texture, uniformSamplerLocation, textureUnit) { + callAndCheck(gl, () => bindTextureUnit(gl, texture, textureUnit)); + callAndCheck(gl, () => gl.uniform1i(uniformSamplerLocation, textureUnit)); + } + function bindCanvasToFramebuffer(gl) { + callAndCheck(gl, () => gl.bindFramebuffer(gl.FRAMEBUFFER, null)); + callAndCheck(gl, () => gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)); + callAndCheck(gl, () => gl.scissor(0, 0, gl.canvas.width, gl.canvas.height)); + } + function bindColorTextureToFramebuffer(gl, texture, framebuffer) { + callAndCheck(gl, () => gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)); + callAndCheck(gl, () => gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0)); + } + function unbindColorTextureFromFramebuffer(gl, framebuffer) { + callAndCheck(gl, () => gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)); + callAndCheck(gl, () => gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0)); + } + function validateFramebuffer(gl) { + const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); + if (status !== gl.FRAMEBUFFER_COMPLETE) { + throw new Error('Error binding framebuffer: ' + getFramebufferErrorMessage(gl, status)); + } + } + function getFramebufferErrorMessage(gl, status) { + switch (status) { + case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + return 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT'; + case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + return 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'; + case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + return 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS'; + case gl.FRAMEBUFFER_UNSUPPORTED: + return 'FRAMEBUFFER_UNSUPPORTED'; + default: + return `unknown error ${status}`; + } + } + function throwIfNull(gl, returnTOrNull, failureMessage) { + const tOrNull = callAndCheck(gl, () => returnTOrNull()); + if (tOrNull == null) { + throw new Error(failureMessage); + } + return tOrNull; + } + function validateTextureUnit(gl, textureUnit) { + const maxTextureUnit = gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1; + const glTextureUnit = textureUnit + gl.TEXTURE0; + if (glTextureUnit < gl.TEXTURE0 || glTextureUnit > maxTextureUnit) { + const textureUnitRange = `[gl.TEXTURE0, gl.TEXTURE${maxTextureUnit}]`; + throw new Error(`textureUnit must be in ${textureUnitRange}.`); + } + } + function getBatchDim(shape, dimsToSkip = 2) { + return sizeFromShape(shape.slice(0, shape.length - dimsToSkip)); + } + function getRowsCols(shape) { + if (shape.length === 0) { + throw Error('Cannot get rows and columns of an empty shape array.'); + } + return [ + shape.length > 1 ? shape[shape.length - 2] : 1, shape[shape.length - 1] + ]; + } + function getShapeAs3D(shape) { + let shapeAs3D = [1, 1, 1]; + const isScalar = shape.length === 0 || (shape.length === 1 && shape[0] === 1); + if (!isScalar) { + shapeAs3D = + [getBatchDim(shape), ...getRowsCols(shape)]; + } + return shapeAs3D; + } + function getTextureShapeFromLogicalShape(logShape, isPacked = false) { + let maxTexSize = env().getNumber('WEBGL_MAX_TEXTURE_SIZE'); + let maxSizeForNarrowTex = env().getNumber('WEBGL_MAX_SIZE_FOR_NARROW_TEXTURE'); + if (maxSizeForNarrowTex === Infinity && + env().getBool('WEBGL_AUTO_SQUARIFY_NARROW_TEXTURE_SHAPE')) { + maxSizeForNarrowTex = maxTexSize / 2; + } + if (isPacked) { + maxTexSize = maxTexSize * 2; + maxSizeForNarrowTex = maxSizeForNarrowTex * 2; + // This logic ensures we accurately count the number of packed texels needed + // to accommodate the tensor. We can only pack values in the same texel if + // they are from adjacent pairs of rows/cols within the same batch. So if a + // tensor has 3 rows, we pretend it has 4 rows in order to account for the + // fact that the texels containing the third row are half empty. + logShape = logShape.map((d, i) => i >= logShape.length - 2 ? + nearestLargerEven(logShape[i]) : + logShape[i]); + // Packed texture height is at least 2 (the channel height of a single + // texel). + if (logShape.length === 1) { + logShape = [2, logShape[0]]; + } + } + // If logical shape is 2, we don't squeeze, since we want to match physical. + if (logShape.length !== 2) { + const squeezeResult = squeezeShape(logShape); + logShape = squeezeResult.newShape; + } + let size = sizeFromShape(logShape); + let textureShape = null; + if (logShape.length <= 1 && size <= maxTexSize) { + textureShape = [1, size]; + } + else if (logShape.length === 2 && logShape[0] <= maxTexSize && + logShape[1] <= maxTexSize) { + textureShape = logShape; + } + else if (logShape.length === 3 && logShape[0] * logShape[1] <= maxTexSize && + logShape[2] <= maxTexSize) { + textureShape = [logShape[0] * logShape[1], logShape[2]]; + } + else if (logShape.length === 3 && logShape[0] <= maxTexSize && + logShape[1] * logShape[2] <= maxTexSize) { + textureShape = [logShape[0], logShape[1] * logShape[2]]; + } + else if (logShape.length === 4 && + logShape[0] * logShape[1] * logShape[2] <= maxTexSize && + logShape[3] <= maxTexSize) { + textureShape = [logShape[0] * logShape[1] * logShape[2], logShape[3]]; + } + else if (logShape.length === 4 && logShape[0] <= maxTexSize && + logShape[1] * logShape[2] * logShape[3] <= maxTexSize) { + textureShape = [logShape[0], logShape[1] * logShape[2] * logShape[3]]; + } + // true if one edge length is 1 (1 or 2, if packed), while another edge + // length exceeds maxSizeForNarrowTex. + const isLongNarrowTex = textureShape != null && + Math.max(...textureShape) > maxSizeForNarrowTex && + Math.min(...textureShape) <= (isPacked ? 2 : 1) && + Math.min(...textureShape) > 0; + if (textureShape == null || isLongNarrowTex) { + if (isPacked) { + // For packed textures size equals the number of channels required to + // accommodate the texture data. However in order to squarify such that + // inner dimensions stay even, we rewrite size to equal the number of + // texels. Then in the return statement we rehydrate the squarified + // dimensions to channel units. + const batchDim = getBatchDim(logShape); + let rows = 2, cols = 2; + if (logShape.length) { + [rows, cols] = getRowsCols(logShape); + } + size = batchDim * (rows / 2) * (cols / 2); + textureShape = + sizeToSquarishShape(size).map(d => d * 2); + } + else { + textureShape = sizeToSquarishShape(size); + } + } + return textureShape; + } + function isEven(n) { + return n % 2 === 0; + } + /** + * This determines whether reshaping a packed texture requires rearranging + * the data within the texture, assuming 2x2 packing. + */ + function isReshapeFree(shape1, shape2) { + shape1 = shape1.slice(-2); + shape2 = shape2.slice(-2); + if (arraysEqual(shape1, shape2)) { + return true; + } + if (!shape1.length || !shape2.length) { // One of the shapes is a scalar. + return true; + } + if (shape1[0] === 0 || shape1[1] === 0 || shape2[0] === 0 || + shape2[1] === 0) { + return true; + } + if (shape1.length !== shape2.length) { // One of the shapes is a vector. + const shape1Cols = shape1[shape1.length - 1]; + const shape2Cols = shape2[shape2.length - 1]; + if (shape1Cols === shape2Cols) { + return true; + } + if (isEven(shape1Cols) && isEven(shape2Cols) && + (shape1[0] === 1 || shape2[0] === 1)) { + return true; + } + } + return shape1[1] === shape2[1] && isEven(shape1[0]) && isEven(shape2[0]); + } + // We cache webgl params because the environment gets reset between + // unit tests and we don't want to constantly query the WebGLContext for + // MAX_TEXTURE_SIZE. + let MAX_TEXTURE_SIZE; + let MAX_TEXTURES_IN_SHADER; + function getWebGLMaxTextureSize(webGLVersion) { + if (MAX_TEXTURE_SIZE == null) { + const gl = getWebGLContext(webGLVersion); + MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE); + } + return MAX_TEXTURE_SIZE; + } + function resetMaxTextureSize() { + MAX_TEXTURE_SIZE = null; + } + function resetMaxTexturesInShader() { + MAX_TEXTURES_IN_SHADER = null; + } + function getMaxTexturesInShader(webGLVersion) { + if (MAX_TEXTURES_IN_SHADER == null) { + const gl = getWebGLContext(webGLVersion); + MAX_TEXTURES_IN_SHADER = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + } + // We cap at 16 to avoid spurious runtime "memory exhausted" error. + return Math.min(16, MAX_TEXTURES_IN_SHADER); + } + function getWebGLDisjointQueryTimerVersion(webGLVersion) { + if (webGLVersion === 0) { + return 0; + } + let queryTimerVersion; + const gl = getWebGLContext(webGLVersion); + if (hasExtension(gl, 'EXT_disjoint_timer_query_webgl2') && + webGLVersion === 2) { + queryTimerVersion = 2; + } + else if (hasExtension(gl, 'EXT_disjoint_timer_query')) { + queryTimerVersion = 1; + } + else { + queryTimerVersion = 0; + } + return queryTimerVersion; + } + function hasExtension(gl, extensionName) { + const ext = gl.getExtension(extensionName); + return ext != null; + } + function isWebGLVersionEnabled(webGLVersion) { + try { + const gl = getWebGLContext(webGLVersion); + if (gl != null) { + return true; + } + } + catch (e) { + console.log('Error when getting WebGL context: ', e); + return false; + } + return false; + } + function isCapableOfRenderingToFloatTexture(webGLVersion) { + if (webGLVersion === 0) { + return false; + } + const gl = getWebGLContext(webGLVersion); + if (webGLVersion === 1) { + if (!hasExtension(gl, 'OES_texture_float')) { + return false; + } + } + else { + if (!hasExtension(gl, 'EXT_color_buffer_float')) { + return false; + } + } + const isFrameBufferComplete = createFloatTextureAndBindToFramebuffer(gl); + return isFrameBufferComplete; + } + /** + * Check if we can download values from a float/half-float texture. + * + * Note that for performance reasons we use binding a texture to a framebuffer + * as a proxy for ability to download float values later using readPixels. The + * texture params of this texture will not match those in readPixels exactly + * but if we are unable to bind some kind of float texture to the frameBuffer + * then we definitely will not be able to read float values from it. + */ + function isDownloadFloatTextureEnabled(webGLVersion) { + if (webGLVersion === 0) { + return false; + } + const gl = getWebGLContext(webGLVersion); + if (webGLVersion === 1) { + if (!hasExtension(gl, 'OES_texture_float')) { + return false; + } + if (!hasExtension(gl, 'WEBGL_color_buffer_float')) { + return false; + } + } + else { + if (hasExtension(gl, 'EXT_color_buffer_float')) { + return createFloatTextureAndBindToFramebuffer(gl); + } + const COLOR_BUFFER_HALF_FLOAT = 'EXT_color_buffer_half_float'; + if (hasExtension(gl, COLOR_BUFFER_HALF_FLOAT)) { + const textureHalfFloatExtension = gl.getExtension(COLOR_BUFFER_HALF_FLOAT); + return createHalfFloatTextureAndBindToFramebuffer(gl, textureHalfFloatExtension); + } + return false; + } + const isFrameBufferComplete = createFloatTextureAndBindToFramebuffer(gl); + return isFrameBufferComplete; + } + function createFloatTextureAndBindToFramebuffer(gl) { + const texConfig = getTextureConfig(gl); + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + const width = 1; + const height = 1; + gl.texImage2D(gl.TEXTURE_2D, 0, texConfig.internalFormatFloat, width, height, 0, texConfig.textureFormatFloat, texConfig.textureTypeFloat, null); + const frameBuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + const isFrameBufferComplete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE; + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteTexture(texture); + gl.deleteFramebuffer(frameBuffer); + return isFrameBufferComplete; + } + function createHalfFloatTextureAndBindToFramebuffer( + // tslint:disable-next-line:no-any + gl, textureHalfFloatExtension) { + const texConfig = getTextureConfig(gl, textureHalfFloatExtension); + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + const width = 1; + const height = 1; + gl.texImage2D(gl.TEXTURE_2D, 0, texConfig.internalFormatHalfFloat, width, height, 0, texConfig.textureFormatFloat, texConfig.textureTypeHalfFloat, null); + const frameBuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + const isFrameBufferComplete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE; + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteTexture(texture); + gl.deleteFramebuffer(frameBuffer); + return isFrameBufferComplete; + } + function isWebGLFenceEnabled(webGLVersion) { + if (webGLVersion !== 2) { + return false; + } + const gl = getWebGLContext(webGLVersion); + // tslint:disable-next-line:no-any + const isEnabled = gl.fenceSync != null; + return isEnabled; + } + function assertNotComplex(tensor, opName) { + if (!Array.isArray(tensor)) { + tensor = [tensor]; + } + tensor.forEach(t => { + if (t != null) { + assert$1(t.dtype !== 'complex64', () => `${opName} does not support complex64 tensors ` + + 'in the WebGL backend.'); + } + }); + } + + var webgl_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + assertNotComplex: assertNotComplex, + bindCanvasToFramebuffer: bindCanvasToFramebuffer, + bindColorTextureToFramebuffer: bindColorTextureToFramebuffer, + bindTextureToProgramUniformSampler: bindTextureToProgramUniformSampler, + bindTextureUnit: bindTextureUnit, + bindVertexBufferToProgramAttribute: bindVertexBufferToProgramAttribute, + callAndCheck: callAndCheck, + canBeRepresented: canBeRepresented, + createFragmentShader: createFragmentShader, + createFramebuffer: createFramebuffer, + createProgram: createProgram, + createStaticIndexBuffer: createStaticIndexBuffer, + createStaticVertexBuffer: createStaticVertexBuffer, + createTexture: createTexture, + createVertexShader: createVertexShader$1, + getBatchDim: getBatchDim, + getExtensionOrThrow: getExtensionOrThrow, + getFramebufferErrorMessage: getFramebufferErrorMessage, + getMaxTexturesInShader: getMaxTexturesInShader, + getNumChannels: getNumChannels, + getProgramUniformLocation: getProgramUniformLocation, + getProgramUniformLocationOrThrow: getProgramUniformLocationOrThrow, + getRowsCols: getRowsCols, + getShapeAs3D: getShapeAs3D, + getTextureShapeFromLogicalShape: getTextureShapeFromLogicalShape, + getWebGLDisjointQueryTimerVersion: getWebGLDisjointQueryTimerVersion, + getWebGLErrorMessage: getWebGLErrorMessage, + getWebGLMaxTextureSize: getWebGLMaxTextureSize, + hasExtension: hasExtension, + isCapableOfRenderingToFloatTexture: isCapableOfRenderingToFloatTexture, + isDownloadFloatTextureEnabled: isDownloadFloatTextureEnabled, + isReshapeFree: isReshapeFree, + isWebGLFenceEnabled: isWebGLFenceEnabled, + isWebGLVersionEnabled: isWebGLVersionEnabled, + linkProgram: linkProgram, + logShaderSourceAndInfoLog: logShaderSourceAndInfoLog, + resetMaxTextureSize: resetMaxTextureSize, + resetMaxTexturesInShader: resetMaxTexturesInShader, + unbindColorTextureFromFramebuffer: unbindColorTextureFromFramebuffer, + unbindTextureUnit: unbindTextureUnit, + validateFramebuffer: validateFramebuffer, + validateProgram: validateProgram, + validateTextureSize: validateTextureSize + }); + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ENV = env(); + /** + * This file contains WebGL-specific flag registrations. + */ + /** + * True if WebGL is supported. + */ + ENV.registerFlag('HAS_WEBGL', () => ENV.getNumber('WEBGL_VERSION') > 0); + /** 0: No WebGL, 1: WebGL 1.0, 2: WebGL 2.0. */ + ENV.registerFlag('WEBGL_VERSION', () => { + if (isWebGLVersionEnabled(2)) { + return 2; + } + else if (isWebGLVersionEnabled(1)) { + return 1; + } + return 0; + }); + /** Whether to check for numerical representation problems. */ + ENV.registerFlag('WEBGL_CHECK_NUMERICAL_PROBLEMS', () => false); + ENV.registerFlag('WEBGL_BUFFER_SUPPORTED', () => ENV.get('WEBGL_VERSION') === 2); + /** Whether the WebGL backend will sometimes forward ops to the CPU. */ + ENV.registerFlag('WEBGL_CPU_FORWARD', () => true); + /** Whether the WebGL backend will always use f16 textures for rendering. */ + ENV.registerFlag('WEBGL_FORCE_F16_TEXTURES', () => false); + /** Whether to turn all packing related flags on. */ + ENV.registerFlag('WEBGL_PACK', () => ENV.getBool('HAS_WEBGL')); + /** Whether we will pack the batchnormalization op. */ + ENV.registerFlag('WEBGL_PACK_NORMALIZATION', () => ENV.getBool('WEBGL_PACK')); + /** Whether we will pack the clip op. */ + ENV.registerFlag('WEBGL_PACK_CLIP', () => ENV.getBool('WEBGL_PACK')); + /** Whether we will pack the depthwise conv op. */ + ENV.registerFlag('WEBGL_PACK_DEPTHWISECONV', () => ENV.getBool('WEBGL_PACK')); + /** Whether we will pack binary ops. */ + ENV.registerFlag('WEBGL_PACK_BINARY_OPERATIONS', () => ENV.getBool('WEBGL_PACK')); + /** Whether we will pack unary ops. */ + ENV.registerFlag('WEBGL_PACK_UNARY_OPERATIONS', () => ENV.getBool('WEBGL_PACK')); + /** Whether we will pack array ops. */ + ENV.registerFlag('WEBGL_PACK_ARRAY_OPERATIONS', () => ENV.getBool('WEBGL_PACK')); + /** Whether we will pack image ops. */ + ENV.registerFlag('WEBGL_PACK_IMAGE_OPERATIONS', () => ENV.getBool('WEBGL_PACK')); + /** Whether we will pack reduce ops. */ + ENV.registerFlag('WEBGL_PACK_REDUCE', () => ENV.getBool('WEBGL_PACK')); + /** Whether packed WebGL kernels lazily unpack their outputs. */ + ENV.registerFlag('WEBGL_LAZILY_UNPACK', () => ENV.getBool('WEBGL_PACK')); + /** Whether we will use the im2col algorithm to speed up convolutions. */ + ENV.registerFlag('WEBGL_CONV_IM2COL', () => ENV.getBool('WEBGL_PACK')); + /** Whether we will pack conv2dTranspose op. */ + ENV.registerFlag('WEBGL_PACK_CONV2DTRANSPOSE', () => ENV.getBool('WEBGL_PACK')); + /** The maximum texture dimension. */ + ENV.registerFlag('WEBGL_MAX_TEXTURE_SIZE', () => getWebGLMaxTextureSize(ENV.getNumber('WEBGL_VERSION'))); + /** The maximum texture dimension. */ + ENV.registerFlag('WEBGL_MAX_TEXTURES_IN_SHADER', () => getMaxTexturesInShader(ENV.getNumber('WEBGL_VERSION'))); + /** + * The disjoint_query_timer extension version. + * 0: disabled, 1: EXT_disjoint_timer_query, 2: + * EXT_disjoint_timer_query_webgl2. + * In Firefox with WebGL 2.0, + * EXT_disjoint_timer_query_webgl2 is not available, so we must use the + * WebGL 1.0 extension. + */ + ENV.registerFlag('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION', () => { + const webGLVersion = ENV.getNumber('WEBGL_VERSION'); + if (webGLVersion === 0) { + return 0; + } + return getWebGLDisjointQueryTimerVersion(webGLVersion); + }); + /** + * Whether the timer object from the disjoint_query_timer extension gives + * timing information that is reliable. + */ + ENV.registerFlag('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE', () => ENV.getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION') > 0 && + !isMobile()); + /** + * Whether the device is physically capable of rendering to float32 textures. + */ + ENV.registerFlag('WEBGL_RENDER_FLOAT32_CAPABLE', () => isCapableOfRenderingToFloatTexture(ENV.getNumber('WEBGL_VERSION'))); + /** + * Whether rendering to float32 textures is enabled. If disabled, renders to + * float16 textures. + */ + ENV.registerFlag('WEBGL_RENDER_FLOAT32_ENABLED', () => { + return ENV.getBool('WEBGL_FORCE_F16_TEXTURES') ? + false : + ENV.getBool('WEBGL_RENDER_FLOAT32_CAPABLE'); + }); + /** + * Whether downloading float textures is enabled (16 or 32 bit). If disabled, + * uses IEEE 754 encoding of the float32 values to 4 uint8 when downloading. + */ + ENV.registerFlag('WEBGL_DOWNLOAD_FLOAT_ENABLED', () => isDownloadFloatTextureEnabled(ENV.getNumber('WEBGL_VERSION'))); + /** Whether the fence API is available. */ + ENV.registerFlag('WEBGL_FENCE_API_ENABLED', () => isWebGLFenceEnabled(ENV.getNumber('WEBGL_VERSION'))); + /** + * Tensors with size <= than this will be uploaded as uniforms, not textures. + */ + ENV.registerFlag('WEBGL_SIZE_UPLOAD_UNIFORM', () => { + // Use uniform uploads only when 32bit floats are supported. In + // 16bit + // environments there are problems with comparing a 16bit texture value + // with a 32bit uniform value. + const useUniforms = ENV.getBool('WEBGL_RENDER_FLOAT32_ENABLED'); + return useUniforms ? 4 : 0; + }); + /** + * If the total number of bytes allocated on the GPU is greater than this + * number, we will aggressively delete textures upon disposal with + * gl.deleteMatrixTexture, rather than making them available for reuse. + * + * Default value -1 indicates that we will never aggressively delete textures. + */ + ENV.registerFlag('WEBGL_DELETE_TEXTURE_THRESHOLD', () => { + return -1; + }, threshold => { + if (!(typeof threshold === 'number')) { + throw new Error('WEBGL_DELETE_TEXTURE_THRESHOLD must be a number but ' + + `got ${threshold}.`); + } + if (threshold < 0 && threshold !== -1) { + throw new Error(`WEBGL_DELETE_TEXTURE_THRESHOLD must be -1 (indicating never ` + + `delete) or at least 0, but got ${threshold}.`); + } + }); + /** + * Trigger a manual GL command flush if the threshold of time has passed since + * previous Kernel execution. This can be useful for Andorid device where GL + * command flush are delayed un til the end of javascript task. This value is + * measured in millisecond. Typically you want to set this value to close to 1. + * + * Default value 1 for mobile chrome, and -1 for rest cases. -1 indicates that + * we will not enforce manual flush and depend on system default flush schedule. + */ + ENV.registerFlag('WEBGL_FLUSH_THRESHOLD', () => { + return isMobile() ? 1 : -1; + }, threshold => { + if (!(typeof threshold === 'number')) { + throw new Error('WEBGL_FLUSH_THRESHOLD must be a number but got ' + + `${threshold}.`); + } + if (threshold < 0 && threshold !== -1) { + throw new Error(`WEBGL_FLUSH_THRESHOLD must be -1 (indicating never ` + + `manual flush) or at least 0, but got ${threshold}.`); + } + }); + /** + * Threshold for input tensor size that determines whether WebGL backend will + * delegate computation to CPU. + * + * Default value is 128. + */ + ENV.registerFlag('CPU_HANDOFF_SIZE_THRESHOLD', () => 128); + /** Whether we will use shapes uniforms. */ + ENV.registerFlag('WEBGL_USE_SHAPES_UNIFORMS', () => false); + /** + * Threshold for last dimension of input tensor that determines whether + * WebGL backend for the Top K op will delegate computation to CPU. If input + * is smaller than threshold then CPU will be used + * + * Default value is 100000. + */ + ENV.registerFlag('TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD', () => 100000); + /** + * Threshold for K that determines whether + * WebGL backend for the Top K op will delegate computation to CPU. If k + * is larger than threshold then CPU will be used + * + * Default value is 128. + */ + ENV.registerFlag('TOPK_K_CPU_HANDOFF_THRESHOLD', () => 128); + /** Whether we will use the experimental conv op. */ + ENV.registerFlag('WEBGL_EXP_CONV', () => false); + /** + * If the device performance is low or if no hardware GPU is available, whether + * software WebGL will be used. + */ + ENV.registerFlag('SOFTWARE_WEBGL_ENABLED', () => ENV.getBool('IS_TEST')); + /** + * For narrow texture (physical height or physical width is 1), if the length of + * any texture edges exceed the threshold, the texture will be reshaped to be + * more squarish. + * + * This flag is used to help some GPUs that could not provide correct + * interpolations for long skinny triangles. We found Mali GPU probably has this + * problem: https://github.com/tensorflow/tfjs/issues/6775. + */ + ENV.registerFlag('WEBGL_MAX_SIZE_FOR_NARROW_TEXTURE', () => Infinity); + /** + * If the flag is set to true, the max size of the narrow texture will be auto + * computed and it will be considerred as a threshold to reshape the narrow + * texture to be more squarish. + * + * This flag is used to help some GPUs that could not provide correct + * interpolations for long skinny triangles. We found Mali GPU probably has this + * problem: https://github.com/tensorflow/tfjs/issues/6775. + */ + ENV.registerFlag('WEBGL_AUTO_SQUARIFY_NARROW_TEXTURE_SHAPE', () => false); + /** + * Whether to use the customized isnan. It's only useful for webgl2 since webgl1 + * doesn't have the builtin isnan. + */ + ENV.registerFlag('WEBGL2_ISNAN_CUSTOM', () => false); + /** Experimental flag, whether enter compile only phase. */ + ENV.registerFlag('ENGINE_COMPILE_ONLY', () => false); + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function getGlslDifferences() { + let version; + let attribute; + let varyingVs; + let varyingFs; + let texture2D; + let output; + let defineOutput; + let defineSpecialNaN; + let defineSpecialInf; + let defineRound; + if (env().getNumber('WEBGL_VERSION') === 2) { + version = '#version 300 es'; + attribute = 'in'; + varyingVs = 'out'; + varyingFs = 'in'; + texture2D = 'texture'; + output = 'outputColor'; + defineOutput = 'out vec4 outputColor;'; + // Use custom isnan definition to work across differences between + // implementations on various platforms. While this should happen in ANGLE + // we still see differences between android and windows (on chrome) when + // using isnan directly. Since WebGL2 supports uint type and + // floatBitsToUinT built-in function, we could implment isnan following + // IEEE 754 rules. + // NaN defination in IEEE 754-1985 is : + // - sign = either 0 or 1. + // - biased exponent = all 1 bits. + // - fraction = anything except all 0 bits (since all 0 bits represents + // infinity). + // https://en.wikipedia.org/wiki/IEEE_754-1985#Representation_of_non-numbers + defineSpecialNaN = env().getBool('WEBGL2_ISNAN_CUSTOM') ? ` + bool isnan_custom(float val) { + uint floatToUint = floatBitsToUint(val); + return (floatToUint & 0x7fffffffu) > 0x7f800000u; + } + + bvec4 isnan_custom(vec4 val) { + return bvec4(isnan_custom(val.x), + isnan_custom(val.y), isnan_custom(val.z), isnan_custom(val.w)); + } + + #define isnan(value) isnan_custom(value) + ` : + ''; + // In webgl 2 we do not need to specify a custom isinf so there is no + // need for a special INFINITY constant. + defineSpecialInf = ``; + defineRound = ` + #define round(value) newRound(value) + int newRound(float value) { + return int(floor(value + 0.5)); + } + + ivec4 newRound(vec4 value) { + return ivec4(floor(value + vec4(0.5))); + } + `; + } + else { + version = ''; + attribute = 'attribute'; + varyingVs = 'varying'; + varyingFs = 'varying'; + texture2D = 'texture2D'; + output = 'gl_FragColor'; + defineOutput = ''; + // WebGL1 has no built in isnan so we define one here. + defineSpecialNaN = ` + #define isnan(value) isnan_custom(value) + bool isnan_custom(float val) { + return (val > 0. || val < 1. || val == 0.) ? false : true; + } + bvec4 isnan_custom(vec4 val) { + return bvec4(isnan(val.x), isnan(val.y), isnan(val.z), isnan(val.w)); + } + `; + defineSpecialInf = ` + uniform float INFINITY; + + bool isinf(float val) { + return abs(val) == INFINITY; + } + bvec4 isinf(vec4 val) { + return equal(abs(val), vec4(INFINITY)); + } + `; + defineRound = ` + int round(float value) { + return int(floor(value + 0.5)); + } + + ivec4 round(vec4 value) { + return ivec4(floor(value + vec4(0.5))); + } + `; + } + return { + version, + attribute, + varyingVs, + varyingFs, + texture2D, + output, + defineOutput, + defineSpecialNaN, + defineSpecialInf, + defineRound + }; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Produces GLSL code that derives logical coordinates from a flat + * index. The code performs integer division with each stride and decrements + * the index until the index equals the final dimension coordinate. + */ + function getLogicalCoordinatesFromFlatIndex(coords, shape, index = 'index') { + const strides = computeStrides(shape); + return strides + .map((stride, i) => { + const line1 = `int ${coords[i]} = ${index} / ${stride}`; + const line2 = i === strides.length - 1 ? + `int ${coords[i + 1]} = ${index} - ${coords[i]} * ${stride}` : + `index -= ${coords[i]} * ${stride}`; + return `${line1}; ${line2};`; + }) + .join(''); + } + function getOutputLogicalCoordinatesFromFlatIndexByUniform(coords, shape, index = 'index') { + const strides = computeStrides(shape); + return strides + .map((_, i) => { + const line1 = `int ${coords[i]} = ${index} / outShapeStrides[${i}]`; + const line2 = i === strides.length - 1 ? + `int ${coords[i + 1]} = ${index} - ${coords[i]} * outShapeStrides[${i}]` : + `index -= ${coords[i]} * outShapeStrides[${i}]`; + return `${line1}; ${line2};`; + }) + .join(''); + } + // Produces GLSL code that computes strides. + function symbolicallyComputeStrides(indicesArr, variableName) { + const numCoords = indicesArr.length; + const shape = indicesArr.map(d => `${variableName}[${d}]`); + const strides = new Array(numCoords - 1); + strides[numCoords - 2] = shape[numCoords - 1]; + for (let i = numCoords - 3; i >= 0; --i) { + strides[i] = `(${strides[i + 1]} * ${shape[i + 1]})`; + } + return strides; + } + function getLogicalCoordinatesFromFlatIndexByUniform(coords, variableName, index = 'index') { + const indicesArray = coords.map((_, i) => i); + const strides = symbolicallyComputeStrides(indicesArray, variableName); + return strides + .map((_, i) => { + const line1 = `int ${coords[i]} = ${index} / ${strides[i]}`; + const line2 = i === strides.length - 1 ? + `int ${coords[i + 1]} = ${index} - ${coords[i]} * ${strides[i]}` : + `index -= ${coords[i]} * ${strides[i]}`; + return `${line1}; ${line2};`; + }) + .join(''); + } + function buildVec(x) { + if (x.length === 1) { + return `${x[0]}`; + } + return `vec${x.length}(${x.join(',')})`; + } + /** + * Produces GLSL code that computes the dot product of the input x and y + * vectors. Handles splitting inputs into increments of vec4s when necessary. + */ + function dotify(x, y) { + if (x.length !== y.length) { + throw new Error(`Vectors to be dotted must be of the same length -` + + `got ${x.length} and ${y.length}`); + } + const slices = []; + const nearestVec4 = Math.floor(x.length / 4); + const nearestVec4Remainder = x.length % 4; + for (let i = 0; i < nearestVec4; i++) { + const xSlice = x.slice(i * 4, i * 4 + 4); + const ySlice = y.slice(i * 4, i * 4 + 4); + slices.push(`${buildVec(xSlice)}, ${buildVec(ySlice)}`); + } + if (nearestVec4Remainder !== 0) { + let xSlice = x.slice(nearestVec4 * 4); + let ySlice = y.slice(nearestVec4 * 4); + if (xSlice.length === 1) { + xSlice = xSlice.map(d => `float(${d})`); + ySlice = ySlice.map(d => `float(${d})`); + } + slices.push(`${buildVec(xSlice)}, ${buildVec(ySlice)}`); + } + return slices.map((d, i) => `dot(${d})`).join('+'); + } + /** + * Produces GLSL that computes the flat index from 3D coordinates. + */ + function getFlatIndexFrom3D(shape) { + const strides = computeStrides(shape).map(d => d.toString()); + return ` + int getFlatIndex(ivec3 coords) { + return coords.x * ${strides[0]} + coords.y * ${strides[1]} + coords.z; + } +`; + } + function getFlatIndexFrom3DOutput() { + return ` + int getFlatIndex(ivec3 coords) { + return coords.x * outShapeStrides[0] + coords.y * outShapeStrides[1] + coords.z; + } +`; + } + const ENCODE_FLOAT_SNIPPET = ` + const float FLOAT_MAX = 1.70141184e38; + const float FLOAT_MIN = 1.17549435e-38; + + lowp vec4 encode_float(highp float v) { + if (isnan(v)) { + return vec4(255, 255, 255, 255); + } + + highp float av = abs(v); + + if(av < FLOAT_MIN) { + return vec4(0.0, 0.0, 0.0, 0.0); + } else if(v > FLOAT_MAX) { + return vec4(0.0, 0.0, 128.0, 127.0) / 255.0; + } else if(v < -FLOAT_MAX) { + return vec4(0.0, 0.0, 128.0, 255.0) / 255.0; + } + + highp vec4 c = vec4(0,0,0,0); + + highp float e = floor(log2(av)); + highp float m = exp2(fract(log2(av))) - 1.0; + + c[2] = floor(128.0 * m); + m -= c[2] / 128.0; + c[1] = floor(32768.0 * m); + m -= c[1] / 32768.0; + c[0] = floor(8388608.0 * m); + + highp float ebias = e + 127.0; + c[3] = floor(ebias / 2.0); + ebias -= c[3] * 2.0; + c[2] += floor(ebias) * 128.0; + + c[3] += 128.0 * step(0.0, -v); + + return c / 255.0; + } +`; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const { getBroadcastDims } = backend_util; + function makeShader(inputsInfo, outputShape, program) { + const prefixSnippets = []; + inputsInfo.forEach(x => { + const size = sizeFromShape(x.shapeInfo.logicalShape); + // Snippet when we decided to upload the values as uniform. + if (x.shapeInfo.isUniform) { + prefixSnippets.push(`uniform float ${x.name}${size > 1 ? `[${size}]` : ''};`); + } + else { + prefixSnippets.push(`uniform sampler2D ${x.name};`); + prefixSnippets.push(`uniform int offset${x.name};`); + } + if (program.enableShapeUniforms) { + const { uniformShape } = getUniformInfoFromShape(program.packedInputs, x.shapeInfo.logicalShape, x.shapeInfo.texShape); + switch (uniformShape.length) { + case 1: + prefixSnippets.push(`uniform int ${x.name}Shape;`); + break; + case 2: + prefixSnippets.push(`uniform ivec2 ${x.name}Shape;`); + break; + case 3: + prefixSnippets.push(`uniform ivec3 ${x.name}Shape;`); + break; + case 4: + prefixSnippets.push(`uniform ivec4 ${x.name}Shape;`); + break; + default: + break; + } + prefixSnippets.push(`uniform ivec2 ${x.name}TexShape;`); + } + }); + if (program.enableShapeUniforms) { + switch (outputShape.logicalShape.length) { + case 1: + prefixSnippets.push(`uniform int outShape;`); + break; + case 2: + prefixSnippets.push(`uniform ivec2 outShape;`); + prefixSnippets.push(`uniform int outShapeStrides;`); + break; + case 3: + prefixSnippets.push(`uniform ivec3 outShape;`); + prefixSnippets.push(`uniform ivec2 outShapeStrides;`); + break; + case 4: + prefixSnippets.push(`uniform ivec4 outShape;`); + prefixSnippets.push(`uniform ivec3 outShapeStrides;`); + break; + default: + break; + } + prefixSnippets.push(`uniform ivec2 outTexShape;`); + } + if (program.customUniforms) { + program.customUniforms.forEach((d) => { + prefixSnippets.push(`uniform ${d.type} ${d.name}${d.arrayIndex ? `[${d.arrayIndex}]` : ''};`); + }); + } + const inputPrefixSnippet = prefixSnippets.join('\n'); + const inputSamplingSnippet = inputsInfo + .map(x => getInputSamplingSnippet(x, outputShape, program.packedInputs, program.enableShapeUniforms)) + .join('\n'); + const outTexShape = outputShape.texShape; + const glsl = getGlslDifferences(); + const floatTextureSampleSnippet = getFloatTextureSampleSnippet(glsl); + let outputSamplingSnippet; + let floatTextureSetOutputSnippet; + let shaderPrefix = getShaderPrefix(glsl); + if (outputShape.isPacked) { + outputSamplingSnippet = getPackedOutputSamplingSnippet(outputShape.logicalShape, outTexShape, program.enableShapeUniforms); + floatTextureSetOutputSnippet = getFloatTextureSetRGBASnippet(glsl); + } + else { + outputSamplingSnippet = getOutputSamplingSnippet(outputShape.logicalShape, outTexShape, program.enableShapeUniforms); + floatTextureSetOutputSnippet = getFloatTextureSetRSnippet(glsl); + } + if (program.packedInputs) { + shaderPrefix += SHADER_PACKED_PREFIX; + } + const source = [ + shaderPrefix, floatTextureSampleSnippet, floatTextureSetOutputSnippet, + inputPrefixSnippet, outputSamplingSnippet, inputSamplingSnippet, + program.userCode + ].join('\n'); + return source; + } + function getSamplerFromInInfo(inInfo, enableShapeUniforms = false) { + const shape = inInfo.shapeInfo.logicalShape; + switch (shape.length) { + case 0: + return getSamplerScalar(inInfo, enableShapeUniforms); + case 1: + return getSampler1D(inInfo, enableShapeUniforms); + case 2: + return getSampler2D(inInfo, enableShapeUniforms); + case 3: + return getSampler3D(inInfo, enableShapeUniforms); + case 4: + return getSampler4D(inInfo, enableShapeUniforms); + case 5: + return getSampler5D(inInfo); + case 6: + return getSampler6D(inInfo); + default: + throw new Error(`${shape.length}-D input sampling` + + ` is not yet supported`); + } + } + function getPackedSamplerFromInInfo(inInfo, enableShapeUniforms) { + const shape = inInfo.shapeInfo.logicalShape; + switch (shape.length) { + case 0: + return getPackedSamplerScalar(inInfo); + case 1: + return getPackedSampler1D(inInfo, enableShapeUniforms); + case 2: + return getPackedSampler2D(inInfo, enableShapeUniforms); + case 3: + return getPackedSampler3D(inInfo, enableShapeUniforms); + default: + return getPackedSamplerND(inInfo, enableShapeUniforms); + } + } + function getInputSamplingSnippet(inInfo, outShapeInfo, usesPackedTextures = false, enableShapeUniforms) { + let res = ''; + if (usesPackedTextures) { + res += getPackedSamplerFromInInfo(inInfo, enableShapeUniforms); + } + else { + res += getSamplerFromInInfo(inInfo, enableShapeUniforms); + } + const inShape = inInfo.shapeInfo.logicalShape; + const outShape = outShapeInfo.logicalShape; + if (inShape.length <= outShape.length) { + if (usesPackedTextures) { + res += getPackedSamplerAtOutputCoords(inInfo, outShapeInfo); + } + else { + res += getSamplerAtOutputCoords(inInfo, outShapeInfo); + } + } + return res; + } + function getPackedOutputSamplingSnippet(outShape, outTexShape, enableShapeUniforms) { + switch (outShape.length) { + case 0: + return getOutputScalarCoords(); + case 1: + return getOutputPacked1DCoords(outShape, outTexShape, enableShapeUniforms); + case 2: + return getOutputPacked2DCoords(outShape, outTexShape, enableShapeUniforms); + case 3: + return getOutputPacked3DCoords(outShape, outTexShape, enableShapeUniforms); + default: + return getOutputPackedNDCoords(outShape, outTexShape, enableShapeUniforms); + } + } + function getOutputSamplingSnippet(outShape, outTexShape, enableShapeUniforms) { + switch (outShape.length) { + case 0: + return getOutputScalarCoords(); + case 1: + return getOutput1DCoords(outShape, outTexShape, enableShapeUniforms); + case 2: + return getOutput2DCoords(outShape, outTexShape, enableShapeUniforms); + case 3: + return getOutput3DCoords(outShape, outTexShape, enableShapeUniforms); + case 4: + return getOutput4DCoords(outShape, outTexShape, enableShapeUniforms); + case 5: + return getOutput5DCoords(outShape, outTexShape); + case 6: + return getOutput6DCoords(outShape, outTexShape); + default: + throw new Error(`${outShape.length}-D output sampling is not yet supported`); + } + } + function getFloatTextureSampleSnippet(glsl) { + return ` + float sampleTexture(sampler2D textureSampler, vec2 uv) { + return ${glsl.texture2D}(textureSampler, uv).r; + } + `; + } + function getFloatTextureSetRSnippet(glsl) { + return ` + void setOutput(float val) { + ${glsl.output} = vec4(val, 0, 0, 0); + } + `; + } + function getFloatTextureSetRGBASnippet(glsl) { + return ` + void setOutput(vec4 val) { + ${glsl.output} = val; + } + `; + } + function getShaderPrefix(glsl) { + const SHADER_PREFIX = `${glsl.version} + precision highp float; + precision highp int; + precision highp sampler2D; + ${glsl.varyingFs} vec2 resultUV; + ${glsl.defineOutput} + const vec2 halfCR = vec2(0.5, 0.5); + + struct ivec5 + { + int x; + int y; + int z; + int w; + int u; + }; + + struct ivec6 + { + int x; + int y; + int z; + int w; + int u; + int v; + }; + + uniform float NAN; + ${glsl.defineSpecialNaN} + ${glsl.defineSpecialInf} + ${glsl.defineRound} + + int imod(int x, int y) { + return x - y * (x / y); + } + + int idiv(int a, int b, float sign) { + int res = a / b; + int mod = imod(a, b); + if (sign < 0. && mod != 0) { + res -= 1; + } + return res; + } + + //Based on the work of Dave Hoskins + //https://www.shadertoy.com/view/4djSRW + #define HASHSCALE1 443.8975 + float random(float seed){ + vec2 p = resultUV * seed; + vec3 p3 = fract(vec3(p.xyx) * HASHSCALE1); + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.x + p3.y) * p3.z); + } + + ${SAMPLE_1D_SNIPPET} + ${SAMPLE_2D_SNIPPET} + ${SAMPLE_3D_SNIPPET} + `; + return SHADER_PREFIX; + } + const SAMPLE_1D_SNIPPET = ` +vec2 uvFromFlat(int texNumR, int texNumC, int index) { + int texR = index / texNumC; + int texC = index - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); +} +vec2 packedUVfrom1D(int texNumR, int texNumC, int index) { + int texelIndex = index / 2; + int texR = texelIndex / texNumC; + int texC = texelIndex - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); +} +`; + const SAMPLE_2D_SNIPPET = ` +vec2 packedUVfrom2D(int texelsInLogicalRow, int texNumR, + int texNumC, int row, int col) { + int texelIndex = (row / 2) * texelsInLogicalRow + (col / 2); + int texR = texelIndex / texNumC; + int texC = texelIndex - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); +} +`; + const SAMPLE_3D_SNIPPET = ` +vec2 packedUVfrom3D(int texNumR, int texNumC, + int texelsInBatch, int texelsInLogicalRow, int b, + int row, int col) { + int index = b * texelsInBatch + (row / 2) * texelsInLogicalRow + (col / 2); + int texR = index / texNumC; + int texC = index - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); +} +`; + const SHADER_PACKED_PREFIX = ` + float getChannel(vec4 frag, vec2 innerDims) { + vec2 modCoord = mod(innerDims, 2.); + return modCoord.x == 0. ? + (modCoord.y == 0. ? frag.r : frag.g) : + (modCoord.y == 0. ? frag.b : frag.a); + } + float getChannel(vec4 frag, int dim) { + float modCoord = mod(float(dim), 2.); + return modCoord == 0. ? frag.r : frag.g; + } +`; + function getOutputScalarCoords() { + return ` + int getOutputCoords() { + return 0; + } + `; + } + function getOutputPacked1DCoords(shape, texShape, enableShapeUniforms) { + const packedTexShape = [Math.ceil(texShape[0] / 2), Math.ceil(texShape[1] / 2)]; + if (packedTexShape[0] === 1) { + if (enableShapeUniforms) { + return ` + int getOutputCoords() { + return 2 * int(resultUV.x * ceil(float(outTexShape[1]) / 2.0)); + } + `; + } + return ` + int getOutputCoords() { + return 2 * int(resultUV.x * ${packedTexShape[1]}.0); + } + `; + } + if (packedTexShape[1] === 1) { + if (enableShapeUniforms) { + return ` + int getOutputCoords() { + return 2 * int(resultUV.y * ceil(float(outTexShape[0]) / 2.0)); + } + `; + } + return ` + int getOutputCoords() { + return 2 * int(resultUV.y * ${packedTexShape[0]}.0); + } + `; + } + if (enableShapeUniforms) { + return ` + int getOutputCoords() { + ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0)); + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(packedTexShape[0], packedTexShape[1])); + return 2 * (resTexRC.x * packedTexShape[1] + resTexRC.y); + } + `; + } + return ` + int getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + return 2 * (resTexRC.x * ${packedTexShape[1]} + resTexRC.y); + } + `; + } + function getOutput1DCoords(shape, texShape, enableShapeUniforms) { + if (texShape[0] === 1) { + if (enableShapeUniforms) { + return ` + int getOutputCoords() { + return int(resultUV.x * float(outTexShape[1])); + } + `; + } + return ` + int getOutputCoords() { + return int(resultUV.x * ${texShape[1]}.0); + } + `; + } + if (texShape[1] === 1) { + if (enableShapeUniforms) { + return ` + int getOutputCoords() { + return int(resultUV.y * float(outTexShape[0])); + } + `; + } + return ` + int getOutputCoords() { + return int(resultUV.y * ${texShape[0]}.0); + } + `; + } + if (enableShapeUniforms) { + return ` + int getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(outTexShape[0], outTexShape[1])); + return resTexRC.x * outTexShape[1] + resTexRC.y; + } + `; + } + return ` + int getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${texShape[0]}, ${texShape[1]})); + return resTexRC.x * ${texShape[1]} + resTexRC.y; + } + `; + } + function getOutputPacked3DCoords(shape, texShape, enableShapeUniforms) { + if (enableShapeUniforms) { + return ` + ivec3 getOutputCoords() { + ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0)); + int texelsInLogicalRow = int(ceil(float(outShape[2]) / 2.0)); + int texelsInBatch = texelsInLogicalRow * int(ceil(float(outShape[1]) / 2.0)); + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(packedTexShape[0], packedTexShape[1])); + int index = resTexRC.x * packedTexShape[1] + resTexRC.y; + + int b = index / texelsInBatch; + index -= b * texelsInBatch; + + int r = 2 * (index / texelsInLogicalRow); + int c = imod(index, texelsInLogicalRow) * 2; + + return ivec3(b, r, c); + } + `; + } + const packedTexShape = [Math.ceil(texShape[0] / 2), Math.ceil(texShape[1] / 2)]; + const texelsInLogicalRow = Math.ceil(shape[2] / 2); + const texelsInBatch = texelsInLogicalRow * Math.ceil(shape[1] / 2); + return ` + ivec3 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + int index = resTexRC.x * ${packedTexShape[1]} + resTexRC.y; + + int b = index / ${texelsInBatch}; + index -= b * ${texelsInBatch}; + + int r = 2 * (index / ${texelsInLogicalRow}); + int c = imod(index, ${texelsInLogicalRow}) * 2; + + return ivec3(b, r, c); + } + `; + } + function getOutput3DCoords(shape, texShape, enableShapeUniforms) { + if (enableShapeUniforms) { + const coordsFromIndexSnippet = getOutputLogicalCoordinatesFromFlatIndexByUniform(['r', 'c', 'd'], shape); + return ` + ivec3 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(outTexShape[0], outTexShape[1])); + int index = resTexRC.x * outTexShape[1] + resTexRC.y; + ${coordsFromIndexSnippet} + return ivec3(r, c, d); + } +`; + } + const coordsFromIndexSnippet = getLogicalCoordinatesFromFlatIndex(['r', 'c', 'd'], shape); + return ` + ivec3 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.x * ${texShape[1]} + resTexRC.y; + ${coordsFromIndexSnippet} + return ivec3(r, c, d); + } + `; + } + function getOutputPackedNDCoords(shape, texShape, enableShapeUniforms) { + if (enableShapeUniforms) { + // TODO: support 5d and 6d + return ` + ivec4 getOutputCoords() { + ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0)); + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(packedTexShape[0], packedTexShape[1])); + int index = resTexRC.x * packedTexShape[1] + resTexRC.y; + + int texelsInLogicalRow = int(ceil(float(outShape[3]) / 2.0)); + int texelsInBatch = texelsInLogicalRow * int(ceil(float(outShape[2]) / 2.0)); + int texelsInBatchN = texelsInBatch * outShape[1]; + + int b2 = index / texelsInBatchN; + index -= b2 * texelsInBatchN; + + int b = index / texelsInBatch; + index -= b * texelsInBatch; + + int r = 2 * (index / texelsInLogicalRow); + int c = imod(index, texelsInLogicalRow) * 2; + + return ivec4(b2, b, r, c); + } + `; + } + const packedTexShape = [Math.ceil(texShape[0] / 2), Math.ceil(texShape[1] / 2)]; + const texelsInLogicalRow = Math.ceil(shape[shape.length - 1] / 2); + const texelsInBatch = texelsInLogicalRow * Math.ceil(shape[shape.length - 2] / 2); + let texelsInBatchN = texelsInBatch; + let batches = ``; + let coords = 'b, r, c'; + for (let b = 2; b < shape.length - 1; b++) { + texelsInBatchN *= shape[shape.length - b - 1]; + batches = ` + int b${b} = index / ${texelsInBatchN}; + index -= b${b} * ${texelsInBatchN}; + ` + batches; + coords = `b${b}, ` + coords; + } + return ` + ivec${shape.length} getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + int index = resTexRC.x * ${packedTexShape[1]} + resTexRC.y; + + ${batches} + + int b = index / ${texelsInBatch}; + index -= b * ${texelsInBatch}; + + int r = 2 * (index / ${texelsInLogicalRow}); + int c = imod(index, ${texelsInLogicalRow}) * 2; + + return ivec${shape.length}(${coords}); + } + `; + } + function getOutput4DCoords(shape, texShape, enableShapeUniforms) { + if (enableShapeUniforms) { + const coordsFromIndexSnippet = getOutputLogicalCoordinatesFromFlatIndexByUniform(['r', 'c', 'd', 'd2'], shape); + return ` + ivec4 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(outTexShape[0], outTexShape[1])); + int index = resTexRC.x * outTexShape[1] + resTexRC.y; + ${coordsFromIndexSnippet} + return ivec4(r, c, d, d2); + } + `; + } + const coordsFromIndexSnippet = getLogicalCoordinatesFromFlatIndex(['r', 'c', 'd', 'd2'], shape); + return ` + ivec4 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.x * ${texShape[1]} + resTexRC.y; + ${coordsFromIndexSnippet} + return ivec4(r, c, d, d2); + } + `; + } + function getOutput5DCoords(shape, texShape) { + const coordsFromIndexSnippet = getLogicalCoordinatesFromFlatIndex(['r', 'c', 'd', 'd2', 'd3'], shape); + return ` + ivec5 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * vec2(${texShape[0]}, + ${texShape[1]})); + + int index = resTexRC.x * ${texShape[1]} + resTexRC.y; + + ${coordsFromIndexSnippet} + + ivec5 outShape = ivec5(r, c, d, d2, d3); + return outShape; + } + `; + } + function getOutput6DCoords(shape, texShape) { + const coordsFromIndexSnippet = getLogicalCoordinatesFromFlatIndex(['r', 'c', 'd', 'd2', 'd3', 'd4'], shape); + return ` + ivec6 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.x * ${texShape[1]} + resTexRC.y; + + ${coordsFromIndexSnippet} + + ivec6 result = ivec6(r, c, d, d2, d3, d4); + return result; + } + `; + } + function getOutputPacked2DCoords(shape, texShape, enableShapeUniforms) { + const packedTexShape = [Math.ceil(texShape[0] / 2), Math.ceil(texShape[1] / 2)]; + if (arraysEqual(shape, texShape)) { + if (enableShapeUniforms) { + return ` + ivec2 getOutputCoords() { + ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0)); + return 2 * ivec2(resultUV.yx * vec2(packedTexShape[0], packedTexShape[1])); + } + `; + } + return ` + ivec2 getOutputCoords() { + return 2 * ivec2(resultUV.yx * vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + } + `; + } + // texels needed to accommodate a logical row + const texelsInLogicalRow = Math.ceil(shape[1] / 2); + /** + * getOutputCoords + * + * resTexRC: The rows and columns of the texels. If you move over one + * texel to the right in the packed texture, you are moving over one column + * (not two). + * + * index: The texel index + */ + if (enableShapeUniforms) { + return ` + ivec2 getOutputCoords() { + ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0)); + int texelsInLogicalRow = int(ceil(float(outShape[1]) / 2.0)); + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(packedTexShape[0], packedTexShape[1])); + + int index = resTexRC.x * packedTexShape[1] + resTexRC.y; + int r = 2 * (index / texelsInLogicalRow); + int c = imod(index, texelsInLogicalRow) * 2; + + return ivec2(r, c); + } + `; + } + return ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + + int index = resTexRC.x * ${packedTexShape[1]} + resTexRC.y; + int r = 2 * (index / ${texelsInLogicalRow}); + int c = imod(index, ${texelsInLogicalRow}) * 2; + + return ivec2(r, c); + } + `; + } + function getOutput2DCoords(shape, texShape, enableShapeUniforms) { + if (arraysEqual(shape, texShape)) { + if (enableShapeUniforms) { + return ` + ivec2 getOutputCoords() { + return ivec2(resultUV.yx * vec2(outTexShape[0], outTexShape[1])); + } + `; + } + return ` + ivec2 getOutputCoords() { + return ivec2(resultUV.yx * vec2(${texShape[0]}, ${texShape[1]})); + } + `; + } + if (shape[1] === 1) { + if (enableShapeUniforms) { + return ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(outTexShape[0], outTexShape[1])); + int index = resTexRC.x * outTexShape[1] + resTexRC.y; + return ivec2(index, 0); + } + `; + } + return ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.x * ${texShape[1]} + resTexRC.y; + return ivec2(index, 0); + } + `; + } + if (shape[0] === 1) { + if (enableShapeUniforms) { + return ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(outTexShape[0], outTexShape[1])); + int index = resTexRC.x * outTexShape[1] + resTexRC.y; + return ivec2(0, index); + } + `; + } + return ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.x * ${texShape[1]} + resTexRC.y; + return ivec2(0, index); + } + `; + } + if (enableShapeUniforms) { + return ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(outTexShape[0], outTexShape[1])); + int index = resTexRC.x * outTexShape[1] + resTexRC.y; + int r = index / outShape[1]; + int c = index - r * outShape[1]; + return ivec2(r, c); + } + `; + } + return ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(resultUV.yx * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.x * ${texShape[1]} + resTexRC.y; + int r = index / ${shape[1]}; + int c = index - r * ${shape[1]}; + return ivec2(r, c); + } + `; + } + function getFlatOffsetUniformName(texName) { + return `offset${texName}`; + } + function getPackedSamplerScalar(inputInfo) { + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const glsl = getGlslDifferences(); + return ` + vec4 ${funcName}() { + return ${glsl.texture2D}(${texName}, halfCR); + } + `; + } + function getSamplerScalar(inputInfo, enableShapeUniforms) { + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + if (inputInfo.shapeInfo.isUniform) { + return `float ${funcName}() {return ${texName};}`; + } + const [texNumR, texNumC] = inputInfo.shapeInfo.texShape; + if (texNumR === 1 && texNumC === 1) { + return ` + float ${funcName}() { + return sampleTexture(${texName}, halfCR); + } + `; + } + const offset = getFlatOffsetUniformName(texName); + if (enableShapeUniforms) { + return ` + float ${funcName}() { + vec2 uv = uvFromFlat(${texName}TexShape[0], ${texName}TexShape[1], ${offset}); + return sampleTexture(${texName}, uv); + } + `; + } + const [tNumR, tNumC] = inputInfo.shapeInfo.texShape; + return ` + float ${funcName}() { + vec2 uv = uvFromFlat(${tNumR}, ${tNumC}, ${offset}); + return sampleTexture(${texName}, uv); + } + `; + } + function getPackedSampler1D(inputInfo, enableShapeUniforms) { + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const texShape = inputInfo.shapeInfo.texShape; + const glsl = getGlslDifferences(); + if (enableShapeUniforms) { + return ` + vec4 ${funcName}(int index) { + ivec2 packedTexShape = ivec2(ceil(float(${texName}TexShape[0]) / 2.0), ceil(float(${texName}TexShape[1]) / 2.0)); + vec2 uv = packedUVfrom1D( + packedTexShape[0], packedTexShape[1], index); + return ${glsl.texture2D}(${texName}, uv); + } + `; + } + const packedTexShape = [Math.ceil(texShape[0] / 2), Math.ceil(texShape[1] / 2)]; + return ` + vec4 ${funcName}(int index) { + vec2 uv = packedUVfrom1D( + ${packedTexShape[0]}, ${packedTexShape[1]}, index); + return ${glsl.texture2D}(${texName}, uv); + } + `; + } + function getSampler1D(inputInfo, enableShapeUniforms) { + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + if (inputInfo.shapeInfo.isUniform) { + // Uniform arrays will be less than 65505 (no risk of float16 overflow). + return ` + float ${funcName}(int index) { + ${getUniformSampler(inputInfo)} + } + `; + } + const texShape = inputInfo.shapeInfo.texShape; + const tNumR = texShape[0]; + const tNumC = texShape[1]; + if (tNumC === 1 && tNumR === 1) { + return ` + float ${funcName}(int index) { + return sampleTexture(${texName}, halfCR); + } + `; + } + const offset = getFlatOffsetUniformName(texName); + if (tNumC === 1) { + if (enableShapeUniforms) { + return ` + float ${funcName}(int index) { + vec2 uv = vec2(0.5, (float(index + ${offset}) + 0.5) / float(${texName}TexShape[0])); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int index) { + vec2 uv = vec2(0.5, (float(index + ${offset}) + 0.5) / ${tNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + if (tNumR === 1) { + if (enableShapeUniforms) { + return ` + float ${funcName}(int index) { + vec2 uv = vec2((float(index + ${offset}) + 0.5) / float(${texName}TexShape[1]), 0.5); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int index) { + vec2 uv = vec2((float(index + ${offset}) + 0.5) / ${tNumC}.0, 0.5); + return sampleTexture(${texName}, uv); + } + `; + } + if (enableShapeUniforms) { + return ` + float ${funcName}(int index) { + vec2 uv = uvFromFlat(${texName}TexShape[0], ${texName}TexShape[1], index + ${offset}); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int index) { + vec2 uv = uvFromFlat(${tNumR}, ${tNumC}, index + ${offset}); + return sampleTexture(${texName}, uv); + } + `; + } + function getPackedSampler2D(inputInfo, enableShapeUniforms) { + const shape = inputInfo.shapeInfo.logicalShape; + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const texShape = inputInfo.shapeInfo.texShape; + const texNumR = texShape[0]; + const texNumC = texShape[1]; + const glsl = getGlslDifferences(); + if (texShape != null && arraysEqual(shape, texShape)) { + if (enableShapeUniforms) { + return ` + vec4 ${funcName}(int row, int col) { + vec2 uv = (vec2(col, row) + halfCR) / vec2(${texName}TexShape[1], ${texName}TexShape[0]); + + return ${glsl.texture2D}(${texName}, uv); + } + `; + } + return ` + vec4 ${funcName}(int row, int col) { + vec2 uv = (vec2(col, row) + halfCR) / vec2(${texNumC}.0, ${texNumR}.0); + + return ${glsl.texture2D}(${texName}, uv); + } + `; + } + if (enableShapeUniforms) { + return ` + vec4 ${funcName}(int row, int col) { + ivec2 packedTexShape = ivec2(ceil(float(${texName}TexShape[0]) / 2.0), ceil(float(${texName}TexShape[1]) / 2.0)); + int valuesPerRow = int(ceil(float(${texName}Shape[1]) / 2.0)); + vec2 uv = packedUVfrom2D(valuesPerRow, packedTexShape[0], packedTexShape[1], row, col); + return ${glsl.texture2D}(${texName}, uv); + } + `; + } + const packedTexShape = [Math.ceil(texShape[0] / 2), Math.ceil(texShape[1] / 2)]; + const valuesPerRow = Math.ceil(shape[1] / 2); + return ` + vec4 ${funcName}(int row, int col) { + vec2 uv = packedUVfrom2D(${valuesPerRow}, ${packedTexShape[0]}, ${packedTexShape[1]}, row, col); + return ${glsl.texture2D}(${texName}, uv); + } + `; + } + function getSampler2D(inputInfo, enableShapeUniforms) { + const shape = inputInfo.shapeInfo.logicalShape; + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const texShape = inputInfo.shapeInfo.texShape; + if (texShape != null && arraysEqual(shape, texShape)) { + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col) { + vec2 uv = (vec2(col, row) + halfCR) / vec2(${texName}TexShape[1], ${texName}TexShape[0]); + return sampleTexture(${texName}, uv); + } + `; + } + const texNumR = texShape[0]; + const texNumC = texShape[1]; + return ` + float ${funcName}(int row, int col) { + vec2 uv = (vec2(col, row) + halfCR) / vec2(${texNumC}.0, ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + const { newShape, keptDims } = squeezeShape(shape); + const squeezedShape = newShape; + if (squeezedShape.length < shape.length) { + const newInputInfo = squeezeInputInfo(inputInfo, squeezedShape); + const params = ['row', 'col']; + return ` + ${getSamplerFromInInfo(newInputInfo, enableShapeUniforms)} + float ${funcName}(int row, int col) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + } + if (inputInfo.shapeInfo.isUniform) { + // Uniform arrays will be less than 65505 (no risk of float16 overflow). + return ` + float ${funcName}(int row, int col) { + int index = round(dot(vec2(row, col), vec2(${shape[1]}, 1))); + ${getUniformSampler(inputInfo)} + } + `; + } + const texNumR = texShape[0]; + const texNumC = texShape[1]; + const offset = getFlatOffsetUniformName(texName); + if (texNumC === 1) { + // index is used directly as physical (no risk of float16 overflow). + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col) { + float index = dot(vec3(row, col, ${offset}), vec3(${texName}Shape[1], 1, 1)); + vec2 uv = vec2(0.5, (index + 0.5) / float(${texName}TexShape[0])); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int row, int col) { + float index = dot(vec3(row, col, ${offset}), vec3(${shape[1]}, 1, 1)); + vec2 uv = vec2(0.5, (index + 0.5) / ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + if (texNumR === 1) { + // index is used directly as physical (no risk of float16 overflow). + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col) { + float index = dot(vec3(row, col, ${offset}), vec3(${texName}Shape[1], 1, 1)); + vec2 uv = vec2((index + 0.5) / float(${texName}TexShape[1]), 0.5); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int row, int col) { + float index = dot(vec3(row, col, ${offset}), vec3(${shape[1]}, 1, 1)); + vec2 uv = vec2((index + 0.5) / ${texNumC}.0, 0.5); + return sampleTexture(${texName}, uv); + } + `; + } + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col) { + // Explicitly use integer operations as dot() only works on floats. + int index = row * ${texName}Shape[1] + col + ${offset}; + vec2 uv = uvFromFlat(${texName}TexShape[0], ${texName}TexShape[1], index); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int row, int col) { + // Explicitly use integer operations as dot() only works on floats. + int index = row * ${shape[1]} + col + ${offset}; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${texName}, uv); + } +`; + } + function getPackedSampler3D(inputInfo, enableShapeUniforms) { + const shape = inputInfo.shapeInfo.logicalShape; + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const texShape = inputInfo.shapeInfo.texShape; + const packedTexShape = [Math.ceil(texShape[0] / 2), Math.ceil(texShape[1] / 2)]; + if (shape[0] === 1) { + const squeezedShape = shape.slice(1); + const keptDims = [1, 2]; + const newInputInfo = squeezeInputInfo(inputInfo, squeezedShape); + const params = ['b', 'row', 'col']; + return ` + ${getPackedSamplerFromInInfo(newInputInfo, enableShapeUniforms)} + vec4 ${funcName}(int b, int row, int col) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + } + const glsl = getGlslDifferences(); + if (enableShapeUniforms) { + return ` + vec4 ${funcName}(int b, int row, int col) { + ivec2 packedTexShape = ivec2(ceil(float(${texName}TexShape[0]) / 2.0), ceil(float(${texName}TexShape[1]) / 2.0)); + int valuesPerRow = int(ceil(float(${texName}Shape[2]) / 2.0)); + int texelsInBatch = valuesPerRow * int(ceil(float(${texName}Shape[1]) / 2.0)); + vec2 uv = packedUVfrom3D( + packedTexShape[0], packedTexShape[1], texelsInBatch, valuesPerRow, b, row, col); + return ${glsl.texture2D}(${texName}, uv); + } + `; + } + const texNumR = packedTexShape[0]; + const texNumC = packedTexShape[1]; + const valuesPerRow = Math.ceil(shape[2] / 2); + const texelsInBatch = valuesPerRow * Math.ceil(shape[1] / 2); + return ` + vec4 ${funcName}(int b, int row, int col) { + vec2 uv = packedUVfrom3D( + ${texNumR}, ${texNumC}, ${texelsInBatch}, ${valuesPerRow}, b, row, col); + return ${glsl.texture2D}(${texName}, uv); + } + `; + } + function getSampler3D(inputInfo, enableShapeUniforms) { + const shape = inputInfo.shapeInfo.logicalShape; + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const stride0 = shape[1] * shape[2]; + const stride1 = shape[2]; + const { newShape, keptDims } = squeezeShape(shape); + const squeezedShape = newShape; + if (squeezedShape.length < shape.length) { + const newInputInfo = squeezeInputInfo(inputInfo, squeezedShape); + const params = ['row', 'col', 'depth']; + return ` + ${getSamplerFromInInfo(newInputInfo, enableShapeUniforms)} + float ${funcName}(int row, int col, int depth) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + } + if (inputInfo.shapeInfo.isUniform) { + // Uniform arrays will be less than 65505 (no risk of float16 overflow). + return ` + float ${funcName}(int row, int col, int depth) { + int index = round(dot(vec3(row, col, depth), + vec3(${stride0}, ${stride1}, 1))); + ${getUniformSampler(inputInfo)} + } + `; + } + const texShape = inputInfo.shapeInfo.texShape; + const texNumR = texShape[0]; + const texNumC = texShape[1]; + const flatOffset = inputInfo.shapeInfo.flatOffset; + if (texNumC === stride0 && flatOffset == null) { + // texC is used directly as physical (no risk of float16 overflow). + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col, int depth) { + int stride1 = ${texName}Shape[2]; + float texR = float(row); + float texC = dot(vec2(col, depth), vec2(stride1, 1)); + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texName}TexShape[1], ${texName}TexShape[0]); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int row, int col, int depth) { + float texR = float(row); + float texC = dot(vec2(col, depth), vec2(${stride1}, 1)); + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texNumC}.0, ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + if (texNumC === stride1 && flatOffset == null) { + // texR is used directly as physical (no risk of float16 overflow). + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col, int depth) { + float texR = dot(vec2(row, col), vec2(${texName}Shape[1], 1)); + float texC = float(depth); + vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${texName}TexShape[1], ${texName}TexShape[0]); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int row, int col, int depth) { + float texR = dot(vec2(row, col), vec2(${shape[1]}, 1)); + float texC = float(depth); + vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${texNumC}.0, ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + const offset = getFlatOffsetUniformName(texName); + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col, int depth) { + // Explicitly use integer operations as dot() only works on floats. + int stride0 = ${texName}Shape[1] * ${texName}Shape[2]; + int stride1 = ${texName}Shape[2]; + int index = row * stride0 + col * stride1 + depth + ${offset}; + vec2 uv = uvFromFlat(${texName}TexShape[0], ${texName}TexShape[1], index); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int row, int col, int depth) { + // Explicitly use integer operations as dot() only works on floats. + int index = row * ${stride0} + col * ${stride1} + depth + ${offset}; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${texName}, uv); + } + `; + } + function getPackedSamplerND(inputInfo, enableShapeUniforms) { + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const glsl = getGlslDifferences(); + if (enableShapeUniforms) { + // TODO: support 5d and 6d + return ` + vec4 ${funcName}(int b2, int b, int row, int col) { + int valuesPerRow = int(ceil(float(${texName}Shape[3]) / 2.0)); + int texelsInBatch = valuesPerRow * int(ceil(float(${texName}Shape[2]) / 2.0)); + int index = b * texelsInBatch + (row / 2) * valuesPerRow + (col / 2); + texelsInBatch *= ${texName}Shape[1]; + index = b2 * texelsInBatch + index; + ivec2 packedTexShape = ivec2(ceil(float(${texName}TexShape[0]) / 2.0), ceil(float(${texName}TexShape[1]) / 2.0)); + int texR = index / packedTexShape[1]; + int texC = index - texR * packedTexShape[1]; + vec2 uv = (vec2(texC, texR) + halfCR) / vec2(packedTexShape[1], packedTexShape[0]); return ${glsl.texture2D}(${texName}, uv); + } + `; + } + const shape = inputInfo.shapeInfo.logicalShape; + const rank = shape.length; + const texShape = inputInfo.shapeInfo.texShape; + const packedTexShape = [Math.ceil(texShape[0] / 2), Math.ceil(texShape[1] / 2)]; + const texNumR = packedTexShape[0]; + const texNumC = packedTexShape[1]; + const valuesPerRow = Math.ceil(shape[rank - 1] / 2); + let texelsInBatch = valuesPerRow * Math.ceil(shape[rank - 2] / 2); + let params = `int b, int row, int col`; + let index = `b * ${texelsInBatch} + (row / 2) * ${valuesPerRow} + (col / 2)`; + for (let b = 2; b < rank - 1; b++) { + params = `int b${b}, ` + params; + texelsInBatch *= shape[rank - b - 1]; + index = `b${b} * ${texelsInBatch} + ` + index; + } + return ` + vec4 ${funcName}(${params}) { + int index = ${index}; + int texR = index / ${texNumC}; + int texC = index - texR * ${texNumC}; + vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${texNumC}, ${texNumR}); + return ${glsl.texture2D}(${texName}, uv); + } + `; + } + function getSampler4D(inputInfo, enableShapeUniforms) { + const shape = inputInfo.shapeInfo.logicalShape; + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const stride2 = shape[3]; + const stride1 = shape[2] * stride2; + const stride0 = shape[1] * stride1; + const { newShape, keptDims } = squeezeShape(shape); + if (newShape.length < shape.length) { + const newInputInfo = squeezeInputInfo(inputInfo, newShape); + const params = ['row', 'col', 'depth', 'depth2']; + return ` + ${getSamplerFromInInfo(newInputInfo, enableShapeUniforms)} + float ${funcName}(int row, int col, int depth, int depth2) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + } + if (inputInfo.shapeInfo.isUniform) { + // Uniform arrays will be less than 65505 (no risk of float16 overflow). + return ` + float ${funcName}(int row, int col, int depth, int depth2) { + int index = round(dot(vec4(row, col, depth, depth2), + vec4(${stride0}, ${stride1}, ${stride2}, 1))); + ${getUniformSampler(inputInfo)} + } + `; + } + const flatOffset = inputInfo.shapeInfo.flatOffset; + const texShape = inputInfo.shapeInfo.texShape; + const texNumR = texShape[0]; + const texNumC = texShape[1]; + const stride2Str = `int stride2 = ${texName}Shape[3];`; + const stride1Str = `int stride1 = ${texName}Shape[2] * stride2;`; + const stride0Str = `int stride0 = ${texName}Shape[1] * stride1;`; + if (texNumC === stride0 && flatOffset == null) { + // texC is used directly as physical (no risk of float16 overflow). + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col, int depth, int depth2) { + ${stride2Str} + ${stride1Str} + float texR = float(row); + float texC = + dot(vec3(col, depth, depth2), + vec3(stride1, stride2, 1)); + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texName}TexShape[1], ${texName}TexShape[0]); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int row, int col, int depth, int depth2) { + float texR = float(row); + float texC = + dot(vec3(col, depth, depth2), + vec3(${stride1}, ${stride2}, 1)); + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texNumC}.0, ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + if (texNumC === stride2 && flatOffset == null) { + // texR is used directly as physical (no risk of float16 overflow). + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col, int depth, int depth2) { + float texR = dot(vec3(row, col, depth), + vec3(${texName}Shape[1] * ${texName}Shape[2], ${texName}Shape[2], 1)); + float texC = float(depth2); + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texName}TexShape[1], ${texName}TexShape[0]); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int row, int col, int depth, int depth2) { + float texR = dot(vec3(row, col, depth), + vec3(${shape[1] * shape[2]}, ${shape[2]}, 1)); + float texC = float(depth2); + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texNumC}.0, ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + const offset = getFlatOffsetUniformName(texName); + if (enableShapeUniforms) { + return ` + float ${funcName}(int row, int col, int depth, int depth2) { + // Explicitly use integer operations as dot() only works on floats. + ${stride2Str} + ${stride1Str} + ${stride0Str} + int index = row * stride0 + col * stride1 + + depth * stride2 + depth2; + vec2 uv = uvFromFlat(${texName}TexShape[0], ${texName}TexShape[1], index + ${offset}); + return sampleTexture(${texName}, uv); + } + `; + } + return ` + float ${funcName}(int row, int col, int depth, int depth2) { + // Explicitly use integer operations as dot() only works on floats. + int index = row * ${stride0} + col * ${stride1} + + depth * ${stride2} + depth2; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index + ${offset}); + return sampleTexture(${texName}, uv); + } + `; + } + function getSampler5D(inputInfo) { + const shape = inputInfo.shapeInfo.logicalShape; + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const stride3 = shape[4]; + const stride2 = shape[3] * stride3; + const stride1 = shape[2] * stride2; + const stride0 = shape[1] * stride1; + const { newShape, keptDims } = squeezeShape(shape); + if (newShape.length < shape.length) { + const newInputInfo = squeezeInputInfo(inputInfo, newShape); + const params = ['row', 'col', 'depth', 'depth2', 'depth3']; + return ` + ${getSamplerFromInInfo(newInputInfo)} + float ${funcName}(int row, int col, int depth, int depth2, int depth3) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + } + if (inputInfo.shapeInfo.isUniform) { + // Uniform arrays will be less than 65505 (no risk of float16 overflow). + return ` + float ${funcName}(int row, int col, int depth, int depth2, int depth3) { + float index = dot( + vec4(row, col, depth, depth2), + vec4(${stride0}, ${stride1}, ${stride2}, ${stride3})) + + depth3; + ${getUniformSampler(inputInfo)} + } + `; + } + const flatOffset = inputInfo.shapeInfo.flatOffset; + const texShape = inputInfo.shapeInfo.texShape; + const texNumR = texShape[0]; + const texNumC = texShape[1]; + if (texNumC === stride0 && flatOffset == null) { + // texC is used directly as physical (no risk of float16 overflow). + return ` + float ${funcName}(int row, int col, int depth, int depth2, int depth3) { + int texR = row; + float texC = dot(vec4(col, depth, depth2, depth3), + vec4(${stride1}, ${stride2}, ${stride3}, 1)); + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texNumC}.0, ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + if (texNumC === stride3 && flatOffset == null) { + // texR is used directly as physical (no risk of float16 overflow). + return ` + float ${funcName}(int row, int col, int depth, int depth2, int depth3) { + float texR = dot( + vec4(row, col, depth, depth2), + vec4(${shape[1] * shape[2] * shape[3]}, + ${shape[2] * shape[3]}, ${shape[3]}, 1)); + int texC = depth3; + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texNumC}.0, ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + const offset = getFlatOffsetUniformName(texName); + return ` + float ${funcName}(int row, int col, int depth, int depth2, int depth3) { + // Explicitly use integer operations as dot() only works on floats. + int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} + + depth2 * ${stride3} + depth3 + ${offset}; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${texName}, uv); + } + `; + } + function getSampler6D(inputInfo) { + const shape = inputInfo.shapeInfo.logicalShape; + const texName = inputInfo.name; + const funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1); + const { newShape, keptDims } = squeezeShape(shape); + if (newShape.length < shape.length) { + const newInputInfo = squeezeInputInfo(inputInfo, newShape); + const params = ['row', 'col', 'depth', 'depth2', 'depth3', 'depth4']; + return ` + ${getSamplerFromInInfo(newInputInfo)} + float ${funcName}(int row, int col, int depth, + int depth2, int depth3, int depth4) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + } + const stride4 = shape[5]; + const stride3 = shape[4] * stride4; + const stride2 = shape[3] * stride3; + const stride1 = shape[2] * stride2; + const stride0 = shape[1] * stride1; + if (inputInfo.shapeInfo.isUniform) { + // Uniform arrays will be less than 65505 (no risk of float16 overflow). + return ` + float ${funcName}(int row, int col, int depth, + int depth2, int depth3, int depth4) { + int index = round(dot( + vec4(row, col, depth, depth2), + vec4(${stride0}, ${stride1}, ${stride2}, ${stride3})) + + dot( + vec2(depth3, depth4), + vec2(${stride4}, 1))); + ${getUniformSampler(inputInfo)} + } + `; + } + const flatOffset = inputInfo.shapeInfo.flatOffset; + const texShape = inputInfo.shapeInfo.texShape; + const texNumR = texShape[0]; + const texNumC = texShape[1]; + if (texNumC === stride0 && flatOffset == null) { + // texC is used directly as physical (no risk of float16 overflow). + return ` + float ${funcName}(int row, int col, int depth, + int depth2, int depth3, int depth4) { + int texR = row; + float texC = dot(vec4(col, depth, depth2, depth3), + vec4(${stride1}, ${stride2}, ${stride3}, ${stride4})) + + float(depth4); + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texNumC}.0, ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + if (texNumC === stride4 && flatOffset == null) { + // texR is used directly as physical (no risk of float16 overflow). + return ` + float ${funcName}(int row, int col, int depth, + int depth2, int depth3, int depth4) { + float texR = dot(vec4(row, col, depth, depth2), + vec4(${shape[1] * shape[2] * shape[3] * shape[4]}, + ${shape[2] * shape[3] * shape[4]}, + ${shape[3] * shape[4]}, + ${shape[4]})) + float(depth3); + int texC = depth4; + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${texNumC}.0, ${texNumR}.0); + return sampleTexture(${texName}, uv); + } + `; + } + const offset = getFlatOffsetUniformName(texName); + return ` + float ${funcName}(int row, int col, int depth, + int depth2, int depth3, int depth4) { + // Explicitly use integer operations as dot() only works on floats. + int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} + + depth2 * ${stride3} + depth3 * ${stride4} + depth4 + ${offset}; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${texName}, uv); + } + `; + } + function getUniformSampler(inputInfo) { + const texName = inputInfo.name; + const inSize = sizeFromShape(inputInfo.shapeInfo.logicalShape); + if (inSize < 2) { + return `return ${texName};`; + } + return ` + for (int i = 0; i < ${inSize}; i++) { + if (i == index) { + return ${texName}[i]; + } + } + `; + } + function getPackedSamplerAtOutputCoords(inputInfo, outShapeInfo) { + const texName = inputInfo.name; + const texFuncSnippet = texName.charAt(0).toUpperCase() + texName.slice(1); + const funcName = 'get' + texFuncSnippet + 'AtOutCoords'; + const inRank = inputInfo.shapeInfo.logicalShape.length; + const outRank = outShapeInfo.logicalShape.length; + const broadcastDims = getBroadcastDims(inputInfo.shapeInfo.logicalShape, outShapeInfo.logicalShape); + const type = getCoordsDataType(outRank); + const rankDiff = outRank - inRank; + let coordsSnippet; + const fields = ['x', 'y', 'z', 'w', 'u', 'v']; + if (inRank === 0) { + coordsSnippet = ''; + } + else if (outRank < 2 && broadcastDims.length >= 1) { + coordsSnippet = 'coords = 0;'; + } + else { + coordsSnippet = + broadcastDims.map(d => `coords.${fields[d + rankDiff]} = 0;`) + .join('\n'); + } + let unpackedCoordsSnippet = ''; + if (outRank < 2 && inRank > 0) { + unpackedCoordsSnippet = 'coords'; + } + else { + unpackedCoordsSnippet = inputInfo.shapeInfo.logicalShape + .map((s, i) => `coords.${fields[i + rankDiff]}`) + .join(', '); + } + let output = `return outputValue;`; + const inSize = sizeFromShape(inputInfo.shapeInfo.logicalShape); + const isInputScalar = inSize === 1; + const outSize = sizeFromShape(outShapeInfo.logicalShape); + const isOutputScalar = outSize === 1; + if (inRank === 1 && !isInputScalar && !isOutputScalar) { + output = ` + return vec4(outputValue.xy, outputValue.xy); + `; + } + else if (isInputScalar && !isOutputScalar) { + if (outRank === 1) { + output = ` + return vec4(outputValue.x, outputValue.x, 0., 0.); + `; + } + else { + output = ` + return vec4(outputValue.x); + `; + } + } + else if (broadcastDims.length) { + const rows = inRank - 2; + const cols = inRank - 1; + if (broadcastDims.indexOf(rows) > -1 && broadcastDims.indexOf(cols) > -1) { + output = `return vec4(outputValue.x);`; + } + else if (broadcastDims.indexOf(rows) > -1) { + output = `return vec4(outputValue.x, outputValue.y, ` + + `outputValue.x, outputValue.y);`; + } + else if (broadcastDims.indexOf(cols) > -1) { + output = `return vec4(outputValue.xx, outputValue.zz);`; + } + } + return ` + vec4 ${funcName}() { + ${type} coords = getOutputCoords(); + ${coordsSnippet} + vec4 outputValue = get${texFuncSnippet}(${unpackedCoordsSnippet}); + ${output} + } + `; + } + function getSamplerAtOutputCoords(inputInfo, outShapeInfo) { + const texName = inputInfo.name; + const texFuncSnippet = texName.charAt(0).toUpperCase() + texName.slice(1); + const funcName = 'get' + texFuncSnippet + 'AtOutCoords'; + const outTexShape = outShapeInfo.texShape; + const inTexShape = inputInfo.shapeInfo.texShape; + const inRank = inputInfo.shapeInfo.logicalShape.length; + const outRank = outShapeInfo.logicalShape.length; + if (!inputInfo.shapeInfo.isUniform && inRank === outRank && + inputInfo.shapeInfo.flatOffset == null && + arraysEqual(inTexShape, outTexShape)) { + return ` + float ${funcName}() { + return sampleTexture(${texName}, resultUV); + } + `; + } + const type = getCoordsDataType(outRank); + const broadcastDims = getBroadcastDims(inputInfo.shapeInfo.logicalShape, outShapeInfo.logicalShape); + const rankDiff = outRank - inRank; + let coordsSnippet; + const fields = ['x', 'y', 'z', 'w', 'u', 'v']; + if (inRank === 0) { + coordsSnippet = ''; + } + else if (outRank < 2 && broadcastDims.length >= 1) { + coordsSnippet = 'coords = 0;'; + } + else { + coordsSnippet = + broadcastDims.map(d => `coords.${fields[d + rankDiff]} = 0;`) + .join('\n'); + } + let unpackedCoordsSnippet = ''; + if (outRank < 2 && inRank > 0) { + unpackedCoordsSnippet = 'coords'; + } + else { + unpackedCoordsSnippet = inputInfo.shapeInfo.logicalShape + .map((s, i) => `coords.${fields[i + rankDiff]}`) + .join(', '); + } + return ` + float ${funcName}() { + ${type} coords = getOutputCoords(); + ${coordsSnippet} + return get${texFuncSnippet}(${unpackedCoordsSnippet}); + } + `; + } + function getCoordsDataType(rank) { + if (rank <= 1) { + return 'int'; + } + else if (rank === 2) { + return 'ivec2'; + } + else if (rank === 3) { + return 'ivec3'; + } + else if (rank === 4) { + return 'ivec4'; + } + else if (rank === 5) { + return 'ivec5'; + } + else if (rank === 6) { + return 'ivec6'; + } + else { + throw Error(`GPU for rank ${rank} is not yet supported`); + } + } + function getUniformInfoFromShape(isPacked, shape, texShape) { + const { newShape, keptDims } = squeezeShape(shape); + const rank = shape.length; + const useSqueezePackedShape = isPacked && rank === 3 && shape[0] === 1; + const squeezeShape$1 = useSqueezePackedShape ? shape.slice(1) : newShape; + const useSqueezeShape = (!isPacked && rank > 1 && !arraysEqual(shape, texShape) && + newShape.length < rank) || + useSqueezePackedShape; + const uniformShape = useSqueezeShape ? squeezeShape$1 : shape; + return { useSqueezeShape, uniformShape, keptDims }; + } + /** Returns a new input info (a copy) that has a squeezed logical shape. */ + function squeezeInputInfo(inInfo, squeezedShape) { + // Deep copy. + const newInputInfo = JSON.parse(JSON.stringify(inInfo)); + newInputInfo.shapeInfo.logicalShape = squeezedShape; + return newInputInfo; + } + function getSqueezedParams(params, keptDims) { + return keptDims.map(d => params[d]).join(', '); + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function compileProgram(gpgpu, program, inputs, output) { + const inputInfos = inputs.map((input, i) => { + const shapeInfo = { + logicalShape: input.shape, + texShape: input.isUniform ? null : input.texData.texShape, + isUniform: input.isUniform, + isPacked: input.isUniform ? false : input.texData.isPacked, + flatOffset: null + }; + if (input.texData != null && input.texData.slice != null && + input.texData.slice.flatOffset > 0) { + shapeInfo.flatOffset = input.texData.slice.flatOffset; + } + return { name: program.variableNames[i], shapeInfo }; + }); + const inShapeInfos = inputInfos.map(x => x.shapeInfo); + const outShapeInfo = { + logicalShape: output.shape, + texShape: output.texData.texShape, + isUniform: false, + isPacked: output.texData.isPacked, + flatOffset: null + }; + const source = makeShader(inputInfos, outShapeInfo, program); + const fragmentShader = createFragmentShader(gpgpu.gl, source); + const webGLProgram = gpgpu.createProgram(fragmentShader); + if (!env().get('ENGINE_COMPILE_ONLY')) { + gpgpu.buildVao(webGLProgram); + return Object.assign({ program, + fragmentShader, + source, + webGLProgram, + inShapeInfos, + outShapeInfo }, getUniformLocations(gpgpu, program, webGLProgram)); + } + else { + return { + program, + fragmentShader, + source, + webGLProgram, + inShapeInfos, + outShapeInfo, + variablesLocations: null, + customUniformLocations: null, + infLoc: null, + nanLoc: null, + outShapeLocation: null, + outShapeStridesLocation: null, + outTexShapeLocation: null + }; + } + } + function getUniformLocations(gpgpu, program, webGLProgram) { + const variablesLocations = []; + const customUniformLocations = []; + let outShapeLocation; + let outTexShapeLocation; + let outShapeStridesLocation; + let infLoc = null; + let nanLoc = null; + // Add special uniforms (NAN, INFINITY) + nanLoc = gpgpu.getUniformLocation(webGLProgram, 'NAN', false); + if (env().getNumber('WEBGL_VERSION') === 1) { + infLoc = gpgpu.getUniformLocation(webGLProgram, 'INFINITY', false); + } + // Add user-defined uniforms + const shouldThrow = false; + for (const varName of program.variableNames) { + const varLocs = { + name: varName, + uniform: gpgpu.getUniformLocation(webGLProgram, varName, shouldThrow), + offset: gpgpu.getUniformLocation(webGLProgram, `offset${varName}`, shouldThrow), + }; + if (program.enableShapeUniforms) { + varLocs.shape = gpgpu.getUniformLocation(webGLProgram, `${varName}Shape`, shouldThrow); + varLocs.texShape = gpgpu.getUniformLocation(webGLProgram, `${varName}TexShape`, shouldThrow); + } + variablesLocations.push(varLocs); + } + if (program.enableShapeUniforms) { + outShapeLocation = + gpgpu.getUniformLocation(webGLProgram, 'outShape', shouldThrow); + outShapeStridesLocation = + gpgpu.getUniformLocation(webGLProgram, 'outShapeStrides', shouldThrow); + outTexShapeLocation = + gpgpu.getUniformLocation(webGLProgram, 'outTexShape', shouldThrow); + } + if (program.customUniforms) { + for (const d of program.customUniforms) { + customUniformLocations.push(gpgpu.getUniformLocation(webGLProgram, d.name, shouldThrow)); + } + } + return { + variablesLocations, + customUniformLocations, + infLoc, + nanLoc, + outShapeLocation, + outShapeStridesLocation, + outTexShapeLocation + }; + } + function validateBinaryAndProgram(shapeInfos, inputs) { + if (shapeInfos.length !== inputs.length) { + throw Error(`Binary was compiled with ${shapeInfos.length} inputs, but ` + + `was executed with ${inputs.length} inputs`); + } + shapeInfos.forEach((s, i) => { + const shapeA = s.logicalShape; + const input = inputs[i]; + const shapeB = input.shape; + if (!arraysEqual(shapeA, shapeB)) { + throw Error(`Binary was compiled with different shapes than ` + + `the current args. Shapes ${shapeA} and ${shapeB} must match`); + } + // The input is uploaded as uniform. + if (s.isUniform && input.isUniform) { + return; + } + const texShapeA = s.texShape; + const texShapeB = input.isUniform ? null : input.texData.texShape; + if (!arraysEqual(texShapeA, texShapeB)) { + throw Error(`Binary was compiled with different texture shapes than the` + + ` current args. Shape ${texShapeA} and ${texShapeB} must match`); + } + }); + } + function runProgram(gpgpu, binary, inputs, output, customUniformValues) { + if (!binary.program.enableShapeUniforms) { + validateBinaryAndProgram(binary.inShapeInfos, inputs); + validateBinaryAndProgram([binary.outShapeInfo], [output]); + } + const outTex = output.texData.texture; + const outTexShape = output.texData.texShape; + if (output.texData.isPacked) { + gpgpu.setOutputPackedMatrixTexture(outTex.texture, outTexShape[0], outTexShape[1]); + } + else { + gpgpu.setOutputMatrixTexture(outTex.texture, outTexShape[0], outTexShape[1]); + } + gpgpu.setProgram(binary.webGLProgram); + gpgpu.bindVertexArray(binary.webGLProgram.vao); + // Set special uniforms (NAN, INFINITY) + if (env().getNumber('WEBGL_VERSION') === 1) { + if (binary.infLoc !== null) { + gpgpu.gl.uniform1f(binary.infLoc, Infinity); + } + } + if (binary.nanLoc !== null) { + gpgpu.gl.uniform1f(binary.nanLoc, NaN); + } + // Set user-defined inputs + for (let i = 0; i < inputs.length; ++i) { + const input = inputs[i]; + const { uniform: varLoc, offset: varOffsetLoc, shape: varShapeLoc, texShape: varTexShapeLoc, } = binary.variablesLocations[i]; + if (varShapeLoc) { + const { uniformShape } = getUniformInfoFromShape(binary.program.packedInputs, input.shape, input.texData.texShape); + switch (uniformShape.length) { + case 1: + gpgpu.gl.uniform1iv(varShapeLoc, new Int32Array(uniformShape)); + break; + case 2: + gpgpu.gl.uniform2iv(varShapeLoc, new Int32Array(uniformShape)); + break; + case 3: + gpgpu.gl.uniform3iv(varShapeLoc, new Int32Array(uniformShape)); + break; + case 4: + gpgpu.gl.uniform4iv(varShapeLoc, new Int32Array(uniformShape)); + break; + default: + break; + } + } + if (varTexShapeLoc) { + gpgpu.gl.uniform2i(varTexShapeLoc, input.texData.texShape[0], input.texData.texShape[1]); + } + if (varLoc == null) { + // The compiler inferred that this variable is not used in this shader. + continue; + } + if (input.isUniform) { + // Upload the values of the tensor as uniform. + if (sizeFromShape(input.shape) < 2) { + gpgpu.gl.uniform1f(varLoc, input.uniformValues[0]); + } + else { + let vals = input.uniformValues; + if (!(vals instanceof Float32Array)) { + vals = new Float32Array(vals); + } + gpgpu.gl.uniform1fv(varLoc, vals); + } + continue; + } + // If the input was sliced, upload the flat offset index. + if (input.texData.slice != null && varOffsetLoc != null) { + gpgpu.gl.uniform1i(varOffsetLoc, input.texData.slice.flatOffset); + } + gpgpu.setInputMatrixTexture(input.texData.texture.texture, varLoc, i); + } + const outShapeLoc = binary.outShapeLocation; + if (outShapeLoc) { + switch (output.shape.length) { + case 1: + gpgpu.gl.uniform1iv(outShapeLoc, new Int32Array(output.shape)); + break; + case 2: + gpgpu.gl.uniform2iv(outShapeLoc, new Int32Array(output.shape)); + break; + case 3: + gpgpu.gl.uniform3iv(outShapeLoc, new Int32Array(output.shape)); + break; + case 4: + gpgpu.gl.uniform4iv(outShapeLoc, new Int32Array(output.shape)); + break; + default: + break; + } + } + if (binary.outShapeStridesLocation) { + const strides = computeStrides(output.shape); + switch (output.shape.length) { + case 2: + gpgpu.gl.uniform1iv(binary.outShapeStridesLocation, new Int32Array(strides)); + break; + case 3: + gpgpu.gl.uniform2iv(binary.outShapeStridesLocation, new Int32Array(strides)); + break; + case 4: + gpgpu.gl.uniform3iv(binary.outShapeStridesLocation, new Int32Array(strides)); + break; + default: + break; + } + } + if (binary.outTexShapeLocation) { + gpgpu.gl.uniform2i(binary.outTexShapeLocation, output.texData.texShape[0], output.texData.texShape[1]); + } + if (binary.program.customUniforms && customUniformValues) { + for (let i = 0; i < binary.program.customUniforms.length; ++i) { + const d = binary.program.customUniforms[i]; + const customLoc = binary.customUniformLocations[i]; + const customValue = customUniformValues[i]; + if (d.type === 'float') { + gpgpu.gl.uniform1fv(customLoc, customValue); + } + else if (d.type === 'vec2') { + gpgpu.gl.uniform2fv(customLoc, customValue); + } + else if (d.type === 'vec3') { + gpgpu.gl.uniform3fv(customLoc, customValue); + } + else if (d.type === 'vec4') { + gpgpu.gl.uniform4fv(customLoc, customValue); + } + else if (d.type === 'int') { + gpgpu.gl.uniform1iv(customLoc, customValue); + } + else if (d.type === 'ivec2') { + gpgpu.gl.uniform2iv(customLoc, customValue); + } + else if (d.type === 'ivec3') { + gpgpu.gl.uniform3iv(customLoc, customValue); + } + else if (d.type === 'ivec4') { + gpgpu.gl.uniform4iv(customLoc, customValue); + } + else { + throw Error(`uniform type ${d.type} is not supported yet.`); + } + } + } + gpgpu.executeProgram(); + } + function makeShaderKey(program, inputs, output) { + let keyInputs = ''; + inputs.concat(output).forEach(x => { + const hasOffset = x.texData != null && x.texData.slice != null && + x.texData.slice.flatOffset > 0; + // TODO: Remove the condition of !x.isUniform. + if (program.enableShapeUniforms && !x.isUniform) { + const xTexShape = x.texData.texShape; + const { useSqueezeShape, uniformShape, keptDims } = getUniformInfoFromShape(program.packedInputs, x.shape, xTexShape); + let rank1 = '', rank2 = '', rank34 = ''; + if (uniformShape.length === 1 && program.packedInputs) { + const packedTexShape = [Math.ceil(xTexShape[0] / 2), Math.ceil(xTexShape[1] / 2)]; + rank1 = `${packedTexShape[0] > 1}_${packedTexShape[1] > 1}`; + } + else if (uniformShape.length === 2 && !program.packedInputs) { + rank2 = `${uniformShape[0] > 1}_${uniformShape[1] > 1}`; + } + else if (uniformShape.length > 2 && !program.packedInputs) { + const strides = computeStrides(uniformShape); + rank34 = `${strides[0] === xTexShape[1]}_${strides[strides.length - 1] === xTexShape[1]}`; + } + const xRank = x.shape.length; + const isLogicalShapTexShapeEqual = uniformShape.length === 2 && arraysEqual(x.shape, xTexShape); + const isScalar = sizeFromShape(x.shape) === 1; + const broadcastDims = getBroadcastDims$1(x.shape, output.shape); + const isInOutTexShapeEqual = !program.packedInputs && + xRank === output.shape.length && + arraysEqual(xTexShape, output.texData.texShape); + const isTexShapeGreaterThanOne = program.packedInputs || uniformShape.length > 2 ? + '' : + `${xTexShape[0] > 1}_${xTexShape[1] > 1}`; + // These key components are needed due to shader_compiler is embedding + // them in the shader. + // |xRank| is used to determine the coords length. See + // get[Packed]SamplerAtOutputCoords. + // |isInOutTexShapeEqual| is used to determine whether going to an + // optimization path in getSamplerAtOutputCoords. + // |useSqueezeShape| is extracted from squeezeInputInfo of + // getSampler[2|3|4]D/getPackedSampler3D. + // |isScalar| is extracted from isInputScalar/isOutputScalar in + // getPackedSamplerAtOutputCoords. + // |broadcastDims| is extracted from get[Packed]SamplerAtOutputCoords. + // |isLogicalShapTexShapeEqual| is used in + // getOutput[Packed]2DCoords/get[Packed]Sampler2D. + // |rank1| is used in getOutputPacked1DCoords. + // |rank2| is used in getOutput2DCoords. + // |rank34| is used in getSampler3D/getSampler4D. + // |isTexShapeGreaterThanOne| are used in + // getSampler[Scalar|1D|2D]/getOutput1DCoords. + keyInputs += `${xRank}_${isInOutTexShapeEqual}_${useSqueezeShape ? keptDims : ''}_${uniformShape.length}_${isScalar}_${broadcastDims}_${isLogicalShapTexShapeEqual}_${rank1}_${rank2}_${rank34}_${isTexShapeGreaterThanOne}_${hasOffset}`; + } + else { + const texShape = x.isUniform ? 'uniform' : x.texData.texShape; + keyInputs += `${x.shape}_${texShape}_${hasOffset}`; + } + }); + const keyUserCode = program.userCode; + let key = program.constructor.name; + // Fast string concat. See https://jsperf.com/string-concatenation/14. + key += '_' + keyInputs + '_' + keyUserCode + + `${env().getNumber('WEBGL_VERSION')}`; + return key; + } + function useShapeUniforms(rank) { + // TODO: Remove the limitaion of rank <= 4. + return env().getBool('WEBGL_USE_SHAPES_UNIFORMS') && rank <= 4; + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class DecodeMatrixProgram { + constructor(outputShape) { + this.variableNames = ['A']; + this.packedInputs = false; + this.packedOutput = true; + this.outPackingScheme = PackingScheme.DENSE; + this.customUniforms = [{ name: 'texShape', type: 'ivec2' }]; + const glsl = getGlslDifferences(); + this.outputShape = outputShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + this.userCode = ` + ivec3 outCoordsFromFlatIndex(int index) { + ${this.enableShapeUniforms ? + getOutputLogicalCoordinatesFromFlatIndexByUniform(['r', 'c', 'd'], outputShape) : + getLogicalCoordinatesFromFlatIndex(['r', 'c', 'd'], outputShape)} + return ivec3(r, c, d); + } + + void main() { + ivec2 resTexRC = ivec2(resultUV.yx * vec2(texShape[0], texShape[1])); + int index = 4 * (resTexRC.x * texShape[1] + resTexRC.y); + + vec4 result = vec4(0.); + + for (int i=0; i<4; i++) { + int flatIndex = index + i; + ivec3 rc = outCoordsFromFlatIndex(flatIndex); + result[i] = getA(rc.x, rc.y, rc.z); + } + + ${glsl.output} = result; + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class DecodeMatrixPackedProgram { + constructor(outputShape) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = true; + this.outPackingScheme = PackingScheme.DENSE; + this.customUniforms = [{ name: 'texShape', type: 'ivec2' }]; + const glsl = getGlslDifferences(); + this.outputShape = outputShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + this.userCode = ` + ivec3 outCoordsFromFlatIndex(int index) { + ${this.enableShapeUniforms ? + getOutputLogicalCoordinatesFromFlatIndexByUniform(['r', 'c', 'd'], outputShape) : + getLogicalCoordinatesFromFlatIndex(['r', 'c', 'd'], outputShape)} + return ivec3(r, c, d); + } + + void main() { + ivec2 resTexRC = ivec2(resultUV.yx * vec2(texShape[0], texShape[1])); + int index = 4 * (resTexRC.x * texShape[1] + resTexRC.y); + + vec4 result = vec4(0.); + + for (int i=0; i<4; i++) { + int flatIndex = index + i; + ivec3 rc = outCoordsFromFlatIndex(flatIndex); + result[i] = getChannel(getA(rc.x, rc.y, rc.z), vec2(rc.y, rc.z)); + } + + ${glsl.output} = result; + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class EncodeFloatProgram { + constructor(outputShape) { + this.variableNames = ['A']; + this.outTexUsage = TextureUsage.DOWNLOAD; + const glsl = getGlslDifferences(); + this.outputShape = outputShape; + this.userCode = ` + ${ENCODE_FLOAT_SNIPPET} + + void main() { + float x = getAAtOutCoords(); + ${glsl.output} = encode_float(x); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class EncodeFloatPackedProgram { + constructor(outputShape) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = false; + this.outTexUsage = TextureUsage.DOWNLOAD; + const glsl = getGlslDifferences(); + this.outputShape = outputShape; + this.userCode = ` + ${ENCODE_FLOAT_SNIPPET} + + void main() { + ivec3 coords = getOutputCoords(); + float x = getChannel(getAAtOutCoords(), vec2(coords.y, coords.z)); + ${glsl.output} = encode_float(x); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const CHANNEL_CHAR_TO_INDEX_MAP = { + 'R': 0, + 'G': 1, + 'B': 2, + 'A': 3 + }; + class EncodeMatrixProgram { + constructor(outputShape, inputIsUnsignedByte = false, usedChannels = 'RGBA') { + this.variableNames = ['A']; + this.customUniforms = [{ name: 'texShape', type: 'ivec2' }]; + const glsl = getGlslDifferences(); + this.outputShape = outputShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + let output = `result`; + if (inputIsUnsignedByte) { + output = `floor(result * 255. + 0.5)`; + } + let mainLoop = ''; + for (let usedChannelIndex = 0; usedChannelIndex < usedChannels.length; usedChannelIndex++) { + const curChannel = usedChannels[usedChannelIndex]; + mainLoop += ` + if(offset == ${usedChannelIndex}) { + result = values[${CHANNEL_CHAR_TO_INDEX_MAP[curChannel]}]; + }`; + } + this.userCode = ` + ${this.enableShapeUniforms ? getFlatIndexFrom3DOutput() : + getFlatIndexFrom3D(outputShape)} + + void main() { + ivec3 coords = getOutputCoords(); + int flatIndex = getFlatIndex(coords); + float result = 0.; + int offset = imod(flatIndex, ${usedChannels.length}); + + flatIndex = idiv(flatIndex, ${usedChannels.length}, 1.); + + int r = flatIndex / texShape[1]; + if (r < texShape[0]) { + int c = imod(flatIndex, texShape[1]); + vec2 uv = (vec2(c, r) + halfCR) / vec2(texShape[1], texShape[0]); + vec4 values = ${glsl.texture2D}(A, uv); + ${mainLoop} + } + ${glsl.output} = vec4(${output}, 0., 0., 0.); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /* + This is how the shader encodes a tensor with shape = [2, 3, 5] + (indices are [batch, row, col]). + + 000|001 002|003 004|xxx 020|021 022|023 024|xxx + ------- ------- ------- ------- ------- ------- + 010|011 012|013 014|xxx xxx|xxx xxx|xxx xxx|xxx + + 100|101 102|103 104|xxx 120|121 122|123 124|xxx + ------- ------- ------- ------- ------- ------- + 110|111 112|113 114|xxx xxx|xxx xxx|xxx xxx|xxx + + Single texels contain only values from the same batch, and from adjacent rows + and columns. + */ + class EncodeMatrixPackedProgram { + constructor(outputShape, inputIsUnsignedByte = false) { + this.variableNames = ['A']; + this.packedInputs = false; + this.packedOutput = true; + this.customUniforms = [{ name: 'texShape', type: 'ivec2' }]; + const glsl = getGlslDifferences(); + this.outputShape = outputShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + let mainLoop = ''; + let output = 'result'; + if (inputIsUnsignedByte) { + output = 'floor(result * 255. + 0.5)'; + } + for (let row = 0; row <= 1; row++) { + for (let col = 0; col <= 1; col++) { + const channel = row * 2 + col; + mainLoop += ` + localCoords = coords; + if(localCoords[2] + ${col} < ${this.enableShapeUniforms ? 'outShape[2]' : `${outputShape[2]}`}) { + localCoords[2] += ${col}; + if (localCoords[1] + ${row} < ${this.enableShapeUniforms ? 'outShape[1]' : `${outputShape[1]}`}) { + localCoords[1] += ${row}; + + flatIndex = getFlatIndex(localCoords); + offset = imod(flatIndex, 4); + + flatIndex = idiv(flatIndex, 4, 1.); + + int r = flatIndex / texShape[1]; + int c = imod(flatIndex, texShape[1]); + vec2 uv = (vec2(c, r) + halfCR) / vec2(texShape[1], texShape[0]); + values = ${glsl.texture2D}(A, uv); + + if (offset == 0) { + result[${channel}] = values[0]; + } else if (offset == 1) { + result[${channel}] = values[1]; + } else if (offset == 2) { + result[${channel}] = values[2]; + } else { + result[${channel}] = values[3]; + } + } + } + `; + } + } + this.userCode = ` + ${this.enableShapeUniforms ? getFlatIndexFrom3DOutput() : + getFlatIndexFrom3D(outputShape)} + + void main() { + ivec3 coords = getOutputCoords(); + + vec4 result = vec4(0.); + int flatIndex, r, c, offset; + ivec3 localCoords; + vec2 uv; + vec4 values; + + ${mainLoop} + + ${glsl.output} = ${output}; + } + `; + } + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function createVertexShader(gl) { + const glsl = getGlslDifferences(); + const vertexShaderSource = `${glsl.version} + precision highp float; + ${glsl.attribute} vec3 clipSpacePos; + ${glsl.attribute} vec2 uv; + ${glsl.varyingVs} vec2 resultUV; + + void main() { + gl_Position = vec4(clipSpacePos, 1); + resultUV = uv; + }`; + return createVertexShader$1(gl, vertexShaderSource); + } + function createVertexBuffer(gl) { + // [x y z u v] * [upper-left, lower-left, upper-right, lower-right] + const vertexArray = new Float32Array([-1, 1, 0, 0, 1, -1, -1, 0, 0, 0, 1, 1, 0, 1, 1, 1, -1, 0, 1, 0]); + return createStaticVertexBuffer(gl, vertexArray); + } + function createIndexBuffer(gl) { + // OpenGL (and WebGL) have "CCW == front" winding + const triangleVertexIndices = new Uint16Array([0, 1, 2, 2, 1, 3]); + return createStaticIndexBuffer(gl, triangleVertexIndices); + } + function createAndConfigureTexture(gl, width, height, internalFormat, textureFormat, textureType) { + validateTextureSize(width, height); + const texture = createTexture(gl); + const tex2d = gl.TEXTURE_2D; + callAndCheck(gl, () => gl.bindTexture(tex2d, texture)); + callAndCheck(gl, () => gl.texParameteri(tex2d, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)); + callAndCheck(gl, () => gl.texParameteri(tex2d, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)); + callAndCheck(gl, () => gl.texParameteri(tex2d, gl.TEXTURE_MIN_FILTER, gl.NEAREST)); + callAndCheck(gl, () => gl.texParameteri(tex2d, gl.TEXTURE_MAG_FILTER, gl.NEAREST)); + if (env().getNumber('WEBGL_VERSION') === 1) { + callAndCheck(gl, () => gl.texImage2D(tex2d, 0, internalFormat, width, height, 0, textureFormat, textureType, null)); + } + else { + callAndCheck(gl, () => gl + .texStorage2D(tex2d, 1, internalFormat, width, height)); + } + callAndCheck(gl, () => gl.bindTexture(gl.TEXTURE_2D, null)); + return { texture, texShape: [height, width] }; + } + function getInternalFormatForFloat32MatrixTexture(textureConfig) { + return textureConfig.internalFormatFloat; + } + function createFloat32MatrixTexture(gl, rows, columns, textureConfig) { + const [width, height] = getUnpackedMatrixTextureShapeWidthHeight(rows, columns); + return createAndConfigureTexture(gl, width, height, getInternalFormatForFloat32MatrixTexture(textureConfig), textureConfig.textureFormatFloat, gl.FLOAT); + } + function getInternalFormatForFloat16MatrixTexture(textureConfig) { + return textureConfig.internalFormatHalfFloat; + } + function createFloat16MatrixTexture(gl, rows, columns, textureConfig) { + const [width, height] = getUnpackedMatrixTextureShapeWidthHeight(rows, columns); + return createAndConfigureTexture(gl, width, height, getInternalFormatForFloat16MatrixTexture(textureConfig), textureConfig.textureFormatFloat, textureConfig.textureTypeHalfFloat); + } + function getInternalFormatForUnsignedBytesMatrixTexture(textureConfig) { + return textureConfig.downloadTextureFormat; + } + function createUnsignedBytesMatrixTexture(gl, rows, columns, textureConfig) { + const [width, height] = getUnpackedMatrixTextureShapeWidthHeight(rows, columns); + return createAndConfigureTexture(gl, width, height, getInternalFormatForUnsignedBytesMatrixTexture(textureConfig), gl.RGBA, gl.UNSIGNED_BYTE); + } + function getInternalFormatForPackedMatrixTexture(textureConfig) { + return textureConfig.internalFormatPackedFloat; + } + function createPackedMatrixTexture(gl, rows, columns, textureConfig) { + const [width, height] = getPackedMatrixTextureShapeWidthHeight(rows, columns); + return createAndConfigureTexture(gl, width, height, getInternalFormatForPackedMatrixTexture(textureConfig), gl.RGBA, gl.FLOAT); + } + function getInternalFormatForFloat16PackedMatrixTexture(textureConfig) { + return textureConfig.internalFormatPackedHalfFloat; + } + function createFloat16PackedMatrixTexture(gl, rows, columns, textureConfig) { + const [width, height] = getPackedMatrixTextureShapeWidthHeight(rows, columns); + return createAndConfigureTexture(gl, width, height, getInternalFormatForFloat16PackedMatrixTexture(textureConfig), gl.RGBA, textureConfig.textureTypeHalfFloat); + } + function bindVertexProgramAttributeStreams(gl, program, vertexBuffer) { + const posOffset = 0; // x is the first buffer element + const uvOffset = 3 * 4; // uv comes after [x y z] + const stride = (3 * 4) + (2 * 4); // xyz + uv, each entry is 4-byte float. + callAndCheck(gl, () => gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)); + const success = bindVertexBufferToProgramAttribute(gl, program, 'clipSpacePos', vertexBuffer, 3, stride, posOffset); + return success && + bindVertexBufferToProgramAttribute(gl, program, 'uv', vertexBuffer, 2, stride, uvOffset); + } + function uploadDenseMatrixToTexture(gl, texture, width, height, data, textureConfig) { + callAndCheck(gl, () => gl.bindTexture(gl.TEXTURE_2D, texture)); + let dataForUpload, texelDataType, internalFormat; + if (data instanceof Uint8Array) { + dataForUpload = new Uint8Array(width * height * 4); + texelDataType = gl.UNSIGNED_BYTE; + internalFormat = gl.RGBA; + } + else { + dataForUpload = new Float32Array(width * height * 4); + texelDataType = gl.FLOAT; + internalFormat = textureConfig.internalFormatPackedFloat; + } + dataForUpload.set(data); + if (env().getNumber('WEBGL_VERSION') === 2) { + callAndCheck(gl, () => gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, texelDataType, dataForUpload)); + } + else { + callAndCheck(gl, () => gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, width, height, 0, gl.RGBA, texelDataType, dataForUpload)); + } + callAndCheck(gl, () => gl.bindTexture(gl.TEXTURE_2D, null)); + } + function uploadPixelDataToTexture(gl, texture, pixels) { + callAndCheck(gl, () => gl.bindTexture(gl.TEXTURE_2D, texture)); + if (pixels.data instanceof Uint8Array) { + if (env().getNumber('WEBGL_VERSION') === 2) { + callAndCheck(gl, () => gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, pixels.width, pixels.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.data)); + } + else { + callAndCheck(gl, () => gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, pixels.width, pixels.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels.data)); + } + } + else { + if (env().getNumber('WEBGL_VERSION') === 2) { + callAndCheck(gl, () => gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels)); + } + else { + callAndCheck(gl, () => gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels)); + } + } + callAndCheck(gl, () => gl.bindTexture(gl.TEXTURE_2D, null)); + } + function createBufferFromOutputTexture(gl2, rows, columns, textureConfig) { + // Create and bind the buffer. + const buffer = gl2.createBuffer(); + callAndCheck(gl2, () => gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer)); + // Initialize the buffer to the size of the texture in bytes. + const bytesPerFloat = 4; + const valuesPerTexel = 4; + const bufferSizeBytes = bytesPerFloat * valuesPerTexel * rows * columns; + callAndCheck(gl2, () => gl2.bufferData(gl2.PIXEL_PACK_BUFFER, bufferSizeBytes, gl2.STREAM_READ)); + // Enqueue a command on the GPU command queue to copy of texture into the + // buffer. + callAndCheck(gl2, () => gl2.readPixels(0, 0, columns, rows, gl2.RGBA, gl2.FLOAT, 0)); + callAndCheck(gl2, () => gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, null)); + return buffer; + } + function downloadFloat32MatrixFromBuffer(gl, buffer, size) { + const gl2 = gl; + const downloadTarget = new Float32Array(size); + gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer); + gl2.getBufferSubData(gl2.PIXEL_PACK_BUFFER, 0, downloadTarget); + gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, null); + return downloadTarget; + } + function downloadByteEncodedFloatMatrixFromOutputTexture(gl, rows, columns, textureConfig) { + const [w, h] = getUnpackedMatrixTextureShapeWidthHeight(rows, columns); + const numChannels = 4; + const downloadTarget = new Uint8Array(getUnpackedArraySizeFromMatrixSize(rows * columns, numChannels)); + callAndCheck(gl, () => gl.readPixels(0, 0, w, h, textureConfig.downloadTextureFormat, gl.UNSIGNED_BYTE, downloadTarget)); + // By wrapping the buffer in a Float32Array, we use native browser IEEE 754 + // decoding of the 4 bytes that back each 32 bit float. + return new Float32Array(downloadTarget.buffer); + } + function downloadPackedMatrixFromBuffer(gl, buffer, batch, rows, cols, physicalRows, physicalCols, textureConfig) { + const gl2 = gl; + const downloadTarget = new Float32Array(getPackedRGBAArraySizeFromMatrixShape(physicalRows, physicalCols)); + gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer); + gl2.getBufferSubData(gl2.PIXEL_PACK_BUFFER, 0, downloadTarget); + gl2.bindBuffer(gl2.PIXEL_PACK_BUFFER, null); + return downloadTarget; + } + function downloadMatrixFromPackedOutputTexture(gl, physicalRows, physicalCols) { + const packedRGBA = new Float32Array(physicalRows * physicalCols * 4); + callAndCheck(gl, () => gl.readPixels(0, 0, physicalCols, physicalRows, gl.RGBA, gl.FLOAT, packedRGBA)); + return packedRGBA; + } + + var gpgpu_util = /*#__PURE__*/Object.freeze({ + __proto__: null, + bindVertexProgramAttributeStreams: bindVertexProgramAttributeStreams, + createBufferFromOutputTexture: createBufferFromOutputTexture, + createFloat16MatrixTexture: createFloat16MatrixTexture, + createFloat16PackedMatrixTexture: createFloat16PackedMatrixTexture, + createFloat32MatrixTexture: createFloat32MatrixTexture, + createIndexBuffer: createIndexBuffer, + createPackedMatrixTexture: createPackedMatrixTexture, + createUnsignedBytesMatrixTexture: createUnsignedBytesMatrixTexture, + createVertexBuffer: createVertexBuffer, + createVertexShader: createVertexShader, + downloadByteEncodedFloatMatrixFromOutputTexture: downloadByteEncodedFloatMatrixFromOutputTexture, + downloadFloat32MatrixFromBuffer: downloadFloat32MatrixFromBuffer, + downloadMatrixFromPackedOutputTexture: downloadMatrixFromPackedOutputTexture, + downloadPackedMatrixFromBuffer: downloadPackedMatrixFromBuffer, + getInternalFormatForFloat16MatrixTexture: getInternalFormatForFloat16MatrixTexture, + getInternalFormatForFloat16PackedMatrixTexture: getInternalFormatForFloat16PackedMatrixTexture, + getInternalFormatForFloat32MatrixTexture: getInternalFormatForFloat32MatrixTexture, + getInternalFormatForPackedMatrixTexture: getInternalFormatForPackedMatrixTexture, + getInternalFormatForUnsignedBytesMatrixTexture: getInternalFormatForUnsignedBytesMatrixTexture, + uploadDenseMatrixToTexture: uploadDenseMatrixToTexture, + uploadPixelDataToTexture: uploadPixelDataToTexture + }); + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class GPGPUContext { + constructor(gl) { + this.outputTexture = null; + this.program = null; + this.disposed = false; + this.itemsToPoll = []; + const glVersion = env().getNumber('WEBGL_VERSION'); + if (gl != null) { + this.gl = gl; + setWebGLContext(glVersion, gl); + } + else { + this.gl = getWebGLContext(glVersion); + } + gl = this.gl; + if (env().getNumber('WEBGL_VERSION') === 2) { + const gl2 = gl; + this.createVertexArray = () => { + return callAndCheck(gl2, () => gl2.createVertexArray()); + }; + this.bindVertexArray = (vao) => { + return callAndCheck(gl2, () => gl2.bindVertexArray(vao)); + }; + this.deleteVertexArray = (vao) => { + return callAndCheck(gl2, () => gl2.deleteVertexArray(vao)); + }; + this.getVertexArray = () => { + return callAndCheck(gl2, () => gl2.getParameter(gl2.VERTEX_ARRAY_BINDING)); + }; + } + else if (gl != null) { + const ext = gl.getExtension('OES_vertex_array_object'); + if (ext == null) { + throw new Error('All WebGL1 implementations are expected to offer' + + ' OES_vertex_array_object.'); + } + this.createVertexArray = () => { + return callAndCheck(gl, () => ext.createVertexArrayOES()); + }; + this.bindVertexArray = (vao) => { + return callAndCheck(gl, () => ext.bindVertexArrayOES(vao)); + }; + this.deleteVertexArray = (vao) => { + return callAndCheck(gl, () => ext.deleteVertexArrayOES(vao)); + }; + this.getVertexArray = () => { + return callAndCheck(gl, () => gl.getParameter(ext.VERTEX_ARRAY_BINDING_OES)); + }; + } + // WebGL 2.0 enables texture floats without an extension. + let COLOR_BUFFER_FLOAT = 'WEBGL_color_buffer_float'; + const COLOR_BUFFER_HALF_FLOAT = 'EXT_color_buffer_half_float'; + this.parallelCompilationExtension = + this.gl.getExtension('KHR_parallel_shader_compile'); + if (env().getNumber('WEBGL_VERSION') === 1) { + const TEXTURE_FLOAT = 'OES_texture_float'; + const TEXTURE_HALF_FLOAT = 'OES_texture_half_float'; + this.textureFloatExtension = + getExtensionOrThrow(this.gl, TEXTURE_FLOAT); + if (hasExtension(this.gl, TEXTURE_HALF_FLOAT)) { + this.textureHalfFloatExtension = + getExtensionOrThrow(this.gl, TEXTURE_HALF_FLOAT); + } + else if (env().get('WEBGL_FORCE_F16_TEXTURES')) { + throw new Error('GL context does not support half float textures, yet the ' + + 'environment flag WEBGL_FORCE_F16_TEXTURES is set to true.'); + } + this.colorBufferFloatExtension = this.gl.getExtension(COLOR_BUFFER_FLOAT); + if (hasExtension(this.gl, COLOR_BUFFER_HALF_FLOAT)) { + this.colorBufferHalfFloatExtension = + getExtensionOrThrow(this.gl, COLOR_BUFFER_HALF_FLOAT); + } + else if (env().get('WEBGL_FORCE_F16_TEXTURES')) { + throw new Error('GL context does not support color renderable half floats, yet ' + + 'the environment flag WEBGL_FORCE_F16_TEXTURES is set to true.'); + } + } + else { + COLOR_BUFFER_FLOAT = 'EXT_color_buffer_float'; + if (hasExtension(this.gl, COLOR_BUFFER_FLOAT)) { + this.colorBufferFloatExtension = + this.gl.getExtension(COLOR_BUFFER_FLOAT); + } + else if (hasExtension(this.gl, COLOR_BUFFER_HALF_FLOAT)) { + this.colorBufferHalfFloatExtension = + this.gl.getExtension(COLOR_BUFFER_HALF_FLOAT); + } + else { + throw new Error('GL context does not support color renderable floats'); + } + } + this.vertexBuffer = createVertexBuffer(this.gl); + this.indexBuffer = createIndexBuffer(this.gl); + this.framebuffer = createFramebuffer(this.gl); + this.textureConfig = + getTextureConfig(this.gl, this.textureHalfFloatExtension); + } + get debug() { + return env().getBool('DEBUG'); + } + dispose() { + if (this.disposed) { + return; + } + if (this.program != null) { + console.warn('Disposing a GPGPUContext that still has a bound WebGLProgram.' + + ' This is probably a resource leak, delete the program with ' + + 'GPGPUContext.deleteProgram before disposing.'); + } + if (this.outputTexture != null) { + console.warn('Disposing a GPGPUContext that still has a bound output matrix ' + + 'texture. This is probably a resource leak, delete the output ' + + 'matrix texture with GPGPUContext.deleteMatrixTexture before ' + + 'disposing.'); + } + const gl = this.gl; + callAndCheck(gl, () => gl.finish()); + callAndCheck(gl, () => gl.bindFramebuffer(gl.FRAMEBUFFER, null)); + callAndCheck(gl, () => gl.deleteFramebuffer(this.framebuffer)); + callAndCheck(gl, () => gl.bindBuffer(gl.ARRAY_BUFFER, null)); + callAndCheck(gl, () => gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null)); + callAndCheck(gl, () => gl.deleteBuffer(this.indexBuffer)); + this.disposed = true; + } + createFloat32MatrixTexture(rows, columns) { + this.throwIfDisposed(); + return createFloat32MatrixTexture(this.gl, rows, columns, this.textureConfig); + } + createFloat16MatrixTexture(rows, columns) { + this.throwIfDisposed(); + return createFloat16MatrixTexture(this.gl, rows, columns, this.textureConfig); + } + createUnsignedBytesMatrixTexture(rows, columns) { + this.throwIfDisposed(); + return createUnsignedBytesMatrixTexture(this.gl, rows, columns, this.textureConfig); + } + uploadPixelDataToTexture(texture, pixels) { + this.throwIfDisposed(); + uploadPixelDataToTexture(this.gl, texture, pixels); + } + uploadDenseMatrixToTexture(texture, width, height, data) { + this.throwIfDisposed(); + uploadDenseMatrixToTexture(this.gl, texture, width, height, data, this.textureConfig); + } + createFloat16PackedMatrixTexture(rows, columns) { + this.throwIfDisposed(); + return createFloat16PackedMatrixTexture(this.gl, rows, columns, this.textureConfig); + } + createPackedMatrixTexture(rows, columns) { + this.throwIfDisposed(); + return createPackedMatrixTexture(this.gl, rows, columns, this.textureConfig); + } + deleteMatrixTexture(texture) { + this.throwIfDisposed(); + if (this.outputTexture === texture) { + unbindColorTextureFromFramebuffer(this.gl, this.framebuffer); + this.outputTexture = null; + } + callAndCheck(this.gl, () => this.gl.deleteTexture(texture)); + } + downloadByteEncodedFloatMatrixFromOutputTexture(texture, rows, columns) { + return this.downloadMatrixDriver(texture, () => downloadByteEncodedFloatMatrixFromOutputTexture(this.gl, rows, columns, this.textureConfig)); + } + downloadPackedMatrixFromBuffer(buffer, batch, rows, columns, physicalRows, physicalCols) { + return downloadPackedMatrixFromBuffer(this.gl, buffer, batch, rows, columns, physicalRows, physicalCols, this.textureConfig); + } + downloadFloat32MatrixFromBuffer(buffer, size) { + return downloadFloat32MatrixFromBuffer(this.gl, buffer, size); + } + createBufferFromTexture(texture, rows, columns) { + this.bindTextureToFrameBuffer(texture); + const result = createBufferFromOutputTexture(this.gl, rows, columns, this.textureConfig); + this.unbindTextureToFrameBuffer(); + return result; + } + createAndWaitForFence() { + const fenceContext = this.createFence(this.gl); + return this.pollFence(fenceContext); + } + createFence(gl) { + let query; + let isFencePassed; + if (env().getBool('WEBGL_FENCE_API_ENABLED')) { + const gl2 = gl; + const sync = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0); + gl.flush(); + isFencePassed = () => { + const status = gl2.clientWaitSync(sync, 0, 0); + return status === gl2.ALREADY_SIGNALED || + status === gl2.CONDITION_SATISFIED; + }; + query = sync; + } + else if (env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION') > 0) { + query = this.beginQuery(); + this.endQuery(); + isFencePassed = () => this.isQueryAvailable(query, env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION')); + } + else { + // If we have no way to fence, return true immediately. This will fire in + // WebGL 1.0 when there is no disjoint query timer. In this case, because + // the fence passes immediately, we'll immediately ask for a download of + // the texture, which will cause the UI thread to hang. + isFencePassed = () => true; + } + return { query, isFencePassed }; + } + downloadMatrixFromPackedTexture(texture, physicalRows, physicalCols) { + return this.downloadMatrixDriver(texture, () => downloadMatrixFromPackedOutputTexture(this.gl, physicalRows, physicalCols)); + } + createProgram(fragmentShader) { + this.throwIfDisposed(); + const gl = this.gl; + if (this.vertexShader == null) { + this.vertexShader = createVertexShader(gl); + } + const program = createProgram(gl); + callAndCheck(gl, () => gl.attachShader(program, this.vertexShader)); + callAndCheck(gl, () => gl.attachShader(program, fragmentShader)); + linkProgram(gl, program); + const program2 = Object.assign(program, { vao: this.createVertexArray() }); + if (this.debug) { + validateProgram(gl, program2); + } + return program2; + } + buildVao(program) { + this.setProgram(program); + this.bindVertexArray(program.vao); + const gl = this.gl; + // Bind index buffer, and vertex buffers based on program attrib + // locations. + callAndCheck(gl, () => gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer)); + bindVertexProgramAttributeStreams(gl, program, this.vertexBuffer); + } + deleteProgram(program) { + this.throwIfDisposed(); + if (program === this.program) { + this.program = null; + } + if (program != null) { + callAndCheck(this.gl, () => this.gl.deleteProgram(program)); + this.deleteVertexArray(program.vao); + } + } + setProgram(program) { + this.throwIfDisposed(); + this.program = program; + if (this.program != null) { + if (this.debug) { + validateProgram(this.gl, this.program); + } + } + callAndCheck(this.gl, () => this.gl.useProgram(program)); + } + getUniformLocation(program, uniformName, shouldThrow = true) { + this.throwIfDisposed(); + if (shouldThrow) { + return getProgramUniformLocationOrThrow(this.gl, program, uniformName); + } + else { + return getProgramUniformLocation(this.gl, program, uniformName); + } + } + getAttributeLocation(program, attribute) { + this.throwIfDisposed(); + return callAndCheck(this.gl, () => this.gl.getAttribLocation(program, attribute)); + } + getUniformLocationNoThrow(program, uniformName) { + this.throwIfDisposed(); + return this.gl.getUniformLocation(program, uniformName); + } + setInputMatrixTexture(inputMatrixTexture, uniformLocation, textureUnit) { + this.throwIfDisposed(); + this.throwIfNoProgram(); + bindTextureToProgramUniformSampler(this.gl, inputMatrixTexture, uniformLocation, textureUnit); + } + setOutputMatrixTexture(outputMatrixTexture, rows, columns) { + this.setOutputMatrixTextureDriver(outputMatrixTexture, columns, rows); + } + setOutputPackedMatrixTexture(outputPackedMatrixTexture, rows, columns) { + this.throwIfDisposed(); + const [width, height] = getPackedMatrixTextureShapeWidthHeight(rows, columns); + this.setOutputMatrixTextureDriver(outputPackedMatrixTexture, width, height); + } + setOutputMatrixWriteRegion(startRow, numRows, startColumn, numColumns) { + this.setOutputMatrixWriteRegionDriver(startColumn, startRow, numColumns, numRows); + } + setOutputPackedMatrixWriteRegion(startRow, numRows, startColumn, numColumns) { + throw new Error('setOutputPackedMatrixWriteRegion not implemented.'); + } + debugValidate() { + if (this.program != null) { + validateProgram(this.gl, this.program); + } + validateFramebuffer(this.gl); + } + executeProgram() { + this.throwIfDisposed(); + this.throwIfNoProgram(); + const gl = this.gl; + if (this.debug) { + const boundVao = this.getVertexArray(); + console.assert(boundVao === this.program.vao, 'VAO changed between setProgram and executeProgram!'); + this.debugValidate(); + } + callAndCheck(gl, () => gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0)); + } + blockUntilAllProgramsCompleted() { + this.throwIfDisposed(); + callAndCheck(this.gl, () => this.gl.finish()); + } + getQueryTimerExtension() { + if (this.disjointQueryTimerExtension == null) { + this.disjointQueryTimerExtension = + getExtensionOrThrow(this.gl, env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION') === 2 ? + 'EXT_disjoint_timer_query_webgl2' : + 'EXT_disjoint_timer_query'); + } + return this.disjointQueryTimerExtension; + } + getQueryTimerExtensionWebGL2() { + return this.getQueryTimerExtension(); + } + getQueryTimerExtensionWebGL1() { + return this.getQueryTimerExtension(); + } + beginQuery() { + if (env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION') === 2) { + const gl2 = this.gl; + const ext = this.getQueryTimerExtensionWebGL2(); + const query = gl2.createQuery(); + gl2.beginQuery(ext.TIME_ELAPSED_EXT, query); + return query; + } + const ext = this.getQueryTimerExtensionWebGL1(); + const query = ext.createQueryEXT(); + ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query); + return query; + } + endQuery() { + if (env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION') === 2) { + const gl2 = this.gl; + const ext = this.getQueryTimerExtensionWebGL2(); + gl2.endQuery(ext.TIME_ELAPSED_EXT); + return; + } + const ext = this.getQueryTimerExtensionWebGL1(); + ext.endQueryEXT(ext.TIME_ELAPSED_EXT); + } + async waitForQueryAndGetTime(query) { + await repeatedTry(() => this.disposed || // while testing contexts are created / disposed + // in rapid succession, so without this check we + // may poll for the query timer indefinitely + this.isQueryAvailable(query, env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION'))); + return this.getQueryTime(query, env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION')); + } + getQueryTime(query, queryTimerVersion) { + if (queryTimerVersion === 0) { + return null; + } + if (queryTimerVersion === 2) { + const gl2 = this.gl; + const timeElapsedNanos = gl2.getQueryParameter(query, gl2.QUERY_RESULT); + // Return milliseconds. + return timeElapsedNanos / 1000000; + } + else { + const ext = this.getQueryTimerExtensionWebGL1(); + const timeElapsedNanos = ext.getQueryObjectEXT(query, ext.QUERY_RESULT_EXT); + // Return milliseconds. + return timeElapsedNanos / 1000000; + } + } + isQueryAvailable(query, queryTimerVersion) { + if (queryTimerVersion === 0) { + return true; + } + if (queryTimerVersion === 2) { + const gl2 = this.gl; + const ext = this.getQueryTimerExtensionWebGL2(); + const available = gl2.getQueryParameter(query, gl2.QUERY_RESULT_AVAILABLE); + if (this.disjoint == null) { + this.disjoint = this.gl.getParameter(ext.GPU_DISJOINT_EXT); + } + return available && !this.disjoint; + } + else { + const ext = this.getQueryTimerExtensionWebGL1(); + const available = ext.getQueryObjectEXT(query, ext.QUERY_RESULT_AVAILABLE_EXT); + if (this.disjoint == null) { + this.disjoint = this.gl.getParameter(ext.GPU_DISJOINT_EXT); + } + return available && !this.disjoint; + } + } + pollFence(fenceContext) { + return new Promise(resolve => { + this.addItemToPoll(() => fenceContext.isFencePassed(), () => resolve()); + }); + } + pollItems() { + // Find the last query that has finished. + const index = linearSearchLastTrue(this.itemsToPoll.map(x => x.isDoneFn)); + for (let i = 0; i <= index; ++i) { + const { resolveFn } = this.itemsToPoll[i]; + resolveFn(); + } + this.itemsToPoll = this.itemsToPoll.slice(index + 1); + } + addItemToPoll(isDoneFn, resolveFn) { + this.itemsToPoll.push({ isDoneFn, resolveFn }); + if (this.itemsToPoll.length > 1) { + // We already have a running loop that polls. + return; + } + // Start a new loop that polls. + let scheduleFn = undefined; + if ('setTimeoutCustom' in env().platform) { + scheduleFn = env().platform.setTimeoutCustom.bind(env().platform); + } + repeatedTry(() => { + this.pollItems(); + // End the loop if no more items to poll. + return this.itemsToPoll.length === 0; + }, () => 0, null, scheduleFn); + } + bindTextureToFrameBuffer(texture) { + this.throwIfDisposed(); + bindColorTextureToFramebuffer(this.gl, texture, this.framebuffer); + if (this.debug) { + validateFramebuffer(this.gl); + } + } + unbindTextureToFrameBuffer() { + if (this.outputTexture != null) { + bindColorTextureToFramebuffer(this.gl, this.outputTexture, this.framebuffer); + if (this.debug) { + validateFramebuffer(this.gl); + } + } + else { + unbindColorTextureFromFramebuffer(this.gl, this.framebuffer); + } + } + downloadMatrixDriver(texture, downloadAndDecode) { + this.bindTextureToFrameBuffer(texture); + const result = downloadAndDecode(); + this.unbindTextureToFrameBuffer(); + return result; + } + setOutputMatrixTextureDriver(outputMatrixTextureMaybePacked, width, height) { + this.throwIfDisposed(); + const gl = this.gl; + bindColorTextureToFramebuffer(gl, outputMatrixTextureMaybePacked, this.framebuffer); + if (this.debug) { + validateFramebuffer(gl); + } + this.outputTexture = outputMatrixTextureMaybePacked; + callAndCheck(gl, () => gl.viewport(0, 0, width, height)); + callAndCheck(gl, () => gl.scissor(0, 0, width, height)); + } + setOutputMatrixWriteRegionDriver(x, y, width, height) { + this.throwIfDisposed(); + callAndCheck(this.gl, () => this.gl.scissor(x, y, width, height)); + } + throwIfDisposed() { + if (this.disposed) { + throw new Error('Attempted to use disposed GPGPUContext.'); + } + } + throwIfNoProgram() { + if (this.program == null) { + throw new Error('No GPU program is currently set.'); + } + } + } + /** + * Finds the index of the last true element using linear search. + * Note: We can't do binary search because Chrome expects us to explicitly + * test all fences before download: + * https://github.com/tensorflow/tfjs/issues/1145 + */ + function linearSearchLastTrue(arr) { + let i = 0; + for (; i < arr.length; ++i) { + const isDone = arr[i](); + if (!isDone) { + break; + } + } + return i - 1; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const { addImpl: addImplCPU, bincountImpl: bincountImplCPU, bincountReduceImpl: bincountReduceImplCPU, bitwiseAndImpl: bitwiseAndImplCPU, castImpl: castImplCPU, ceilImpl: ceilImplCPU, concatImpl: concatImplCPU, equalImpl: equalImplCPU, expImpl: expImplCPU, expm1Impl: expm1ImplCPU, floorImpl: floorImplCPU, gatherNdImpl: gatherNdImplCPU, gatherV2Impl: gatherV2ImplCPU, greaterImpl: greaterImplCPU, greaterEqualImpl: greaterEqualImplCPU, lessImpl: lessImplCPU, lessEqualImpl: lessEqualImplCPU, linSpaceImpl: linSpaceImplCPU, logImpl: logImplCPU, maxImpl: maxImplCPU, maximumImpl: maximumImplCPU, minimumImpl: minimumImplCPU, multiplyImpl: multiplyImplCPU, negImpl: negImplCPU, notEqualImpl: notEqualImplCPU, prodImpl: prodImplCPU, raggedGatherImpl: raggedGatherImplCPU, raggedRangeImpl: raggedRangeImplCPU, raggedTensorToTensorImpl: raggedTensorToTensorImplCPU, rangeImpl: rangeImplCPU, rsqrtImpl: rsqrtImplCPU, scatterImpl: scatterImplCPU, sigmoidImpl: sigmoidImplCPU, simpleAbsImpl: simpleAbsImplCPU, sliceImpl: sliceImplCPU, sparseFillEmptyRowsImpl: sparseFillEmptyRowsImplCPU, sparseReshapeImpl: sparseReshapeImplCPU, sparseSegmentReductionImpl: sparseSegmentReductionImplCPU, sqrtImpl: sqrtImplCPU, staticRegexReplaceImpl: staticRegexReplaceImplCPU, stridedSliceImpl: stridedSliceImplCPU, stringNGramsImpl: stringNGramsImplCPU, stringSplitImpl: stringSplitImplCPU, stringToHashBucketFastImpl: stringToHashBucketFastImplCPU, subImpl: subImplCPU, tileImpl: tileImplCPU, topKImpl: topKImplCPU, transposeImpl: transposeImplCPU, uniqueImpl: uniqueImplCPU, } = shared; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function getVecChannels(name, rank) { + return ['x', 'y', 'z', 'w', 'u', 'v'].slice(0, rank).map(d => `${name}.${d}`); + } + function getChannels(name, rank) { + if (rank === 1) { + return [name]; + } + return getVecChannels(name, rank); + } + function getSourceCoords$2(rank, dims) { + if (rank === 1) { + return 'rc'; + } + let coords = ''; + for (let i = 0; i < rank; i++) { + coords += dims[i]; + if (i < rank - 1) { + coords += ','; + } + } + return coords; + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class PackProgram { + constructor(outputShape) { + this.variableNames = ['A']; + this.packedInputs = false; + this.packedOutput = true; + // Only input / output 3D tensors. + this.outputShape = outputShape; + this.rank = outputShape.length; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + if (this.rank === 0) { + this.userCode = ` + void main() { + setOutput(vec4(getA(), 0., 0., 0.)); + } + `; + } + else { + const channels = getChannels('rc', this.rank); + const dtype = getCoordsDataType(this.rank); + const outOfBoundsCondition = this.getOutOfBoundsCondition(channels); + const setup = this.getSetup(channels); + const output = this.getOutput(channels); + this.userCode = ` + void main() { + ${dtype} rc = getOutputCoords(); + + if(${outOfBoundsCondition}) { + setOutput(vec4(0)); + } else { + ${setup} + + setOutput(vec4(${output})); + } + } + `; + } + } + getSourceCoordsArr(dims) { + const coords = []; + for (let row = 0; row <= 1; row++) { + for (let col = 0; col <= 1; col++) { + let coord = `${row === 0 ? 'r' : 'rp1'}, ${col === 0 ? 'c' : 'cp1'}`; + for (let d = 2; d < this.rank; d++) { + coord = `${dims[dims.length - 1 - d]},` + coord; + } + coords.push(coord); + } + } + return coords; + } + getOutOfBoundsCondition(dims) { + if (this.rank === 1) { + return `rc > ${this.enableShapeUniforms ? 'outShape' : this.outputShape[0]}`; + } + let cond = ''; + for (let i = this.rank - 2; i < this.rank; i++) { + cond += `${dims[i]} >= ${this.enableShapeUniforms ? `outShape[${i}]` : this.outputShape[i]}`; + if (i < this.rank - 1) { + cond += '||'; + } + } + return cond; + } + getSetup(dims) { + if (this.rank === 1) { + return ''; + } + const innerDims = dims.slice(-2); + const col = this.enableShapeUniforms ? `outShape[${this.rank} - 1]` : + this.outputShape[this.rank - 1]; + const row = this.enableShapeUniforms ? `outShape[${this.rank} - 2]` : + this.outputShape[this.rank - 2]; + return ` + int r = ${innerDims[0]}; + int c = ${innerDims[1]}; + int rp1 = r + 1; + int cp1 = c + 1; + + bool cEdge = cp1 >= ${col}; + bool rEdge = rp1 >= ${row}; + `; + } + getOutput(dims) { + const sourceCoords = this.getSourceCoordsArr(dims); + if (this.rank === 1) { + const outShape = this.enableShapeUniforms ? 'outShape' : this.outputShape[0]; + return `getA(rc), (rc + 1 >= ${outShape} ? 0. : getA(rc + 1)), 0, 0`; + } + return `getA(${sourceCoords[0]}), + cEdge ? 0. : getA(${sourceCoords[1]}), + rEdge ? 0. : getA(${sourceCoords[2]}), + rEdge || cEdge ? 0. : getA(${sourceCoords[3]})`; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ReshapePackedProgram { + constructor(outputShape, inputShape) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = true; + this.customUniforms = [{ name: 'inputShape', type: 'ivec3' }]; + this.outputShape = outputShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + let mainLoop = ``; + for (let i = 0; i < 4; i++) { + let thisRC = `thisRC = rc;`; + if (i % 2 === 1) { + thisRC += `thisRC.z += 1;`; + } + if (i > 1) { + thisRC += `thisRC.y += 1;`; + } + mainLoop += ` + ${thisRC} + ${i > 0 ? `if(thisRC.y < rows && thisRC.z < cols){` : ''} + int flatIndex = getFlatIndex(thisRC); + + ivec3 inputRC = inputCoordsFromReshapedOutCoords(flatIndex); + vec2 inputRCInnerDims = vec2(float(inputRC.y),float(inputRC.z)); + + result[${i}] = + getChannel(getA(inputRC.x, inputRC.y, inputRC.z), inputRCInnerDims); + ${i > 0 ? '}' : ''} + `; + } + this.userCode = ` + ${getReshapedInputCoords(inputShape, this.enableShapeUniforms)} + ${this.enableShapeUniforms ? getFlatIndexFrom3DOutput() : + getFlatIndexFrom3D(outputShape)} + + void main() { + ivec3 rc = getOutputCoords(); + + vec4 result = vec4(0.); + + ivec3 thisRC; + int rows = ${this.enableShapeUniforms ? 'outShape[1]' : outputShape[1]}; + int cols = ${this.enableShapeUniforms ? 'outShape[2]' : outputShape[2]}; + + ${mainLoop} + + setOutput(result); + } + `; + } + } + function getReshapedInputCoords(shape, enableShapeUniforms) { + const coordsFromIndexSnippet = enableShapeUniforms ? + getLogicalCoordinatesFromFlatIndexByUniform(['r', 'c', 'd'], 'inputShape') : + getLogicalCoordinatesFromFlatIndex(['r', 'c', 'd'], shape); + return ` + ivec3 inputCoordsFromReshapedOutCoords(int index) { + ${coordsFromIndexSnippet} + return ivec3(r, c, d); + } + `; + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class TextureManager { + constructor(gpgpu) { + this.gpgpu = gpgpu; + this.numUsedTextures = 0; + this.numFreeTextures = 0; + this._numBytesAllocated = 0; + // Number of bytes that have been allocated and available for reuse. + this._numBytesFree = 0; + this.freeTextures = {}; + this.usedTextures = {}; + this.logEnabled = false; + } + acquireTexture(shapeRC, usage, isPacked) { + const physicalTexType = getPhysicalFromLogicalTextureType(usage, isPacked); + const shapeKey = getKeyFromTextureShape(shapeRC, physicalTexType, isPacked); + if (!(shapeKey in this.freeTextures)) { + this.freeTextures[shapeKey] = []; + } + if (!(shapeKey in this.usedTextures)) { + this.usedTextures[shapeKey] = []; + } + const texBytes = computeBytes(shapeRC, physicalTexType, this.gpgpu.gl, this.gpgpu.textureConfig, isPacked); + if (this.freeTextures[shapeKey].length > 0) { + this.numFreeTextures--; + this.numUsedTextures++; + this._numBytesFree -= texBytes; + this.log(); + const newTexture = this.freeTextures[shapeKey].pop(); + this.usedTextures[shapeKey].push(newTexture); + return newTexture; + } + let newTexture; + if (physicalTexType === PhysicalTextureType.PACKED_2X2_FLOAT32) { + newTexture = this.gpgpu.createPackedMatrixTexture(shapeRC[0], shapeRC[1]); + } + else if (physicalTexType === PhysicalTextureType.PACKED_2X2_FLOAT16) { + newTexture = + this.gpgpu.createFloat16PackedMatrixTexture(shapeRC[0], shapeRC[1]); + } + else if (physicalTexType === PhysicalTextureType.UNPACKED_FLOAT32) { + newTexture = + this.gpgpu.createFloat32MatrixTexture(shapeRC[0], shapeRC[1]); + } + else if (physicalTexType === PhysicalTextureType.UNPACKED_FLOAT16) { + newTexture = + this.gpgpu.createFloat16MatrixTexture(shapeRC[0], shapeRC[1]); + } + else if (physicalTexType === PhysicalTextureType.PACKED_4X1_UNSIGNED_BYTE) { + newTexture = + this.gpgpu.createUnsignedBytesMatrixTexture(shapeRC[0], shapeRC[1]); + } + this.usedTextures[shapeKey].push(newTexture); + this.numUsedTextures++; + this._numBytesAllocated += texBytes; + this.log(); + return newTexture; + } + releaseTexture(texture, shape, logicalTexType, isPacked) { + if (this.freeTextures == null) { + // Already disposed. + return; + } + const physicalTexType = getPhysicalFromLogicalTextureType(logicalTexType, isPacked); + const shapeKey = getKeyFromTextureShape(shape, physicalTexType, isPacked); + if (!(shapeKey in this.freeTextures)) { + this.freeTextures[shapeKey] = []; + } + const texBytes = computeBytes(shape, physicalTexType, this.gpgpu.gl, this.gpgpu.textureConfig, isPacked); + const deleteTexThreshold = env() + .getNumber('WEBGL_DELETE_TEXTURE_THRESHOLD'); + if (deleteTexThreshold !== -1 && + this._numBytesAllocated > deleteTexThreshold) { + this.gpgpu.deleteMatrixTexture(texture.texture); + this._numBytesAllocated -= texBytes; + } + else { + this.freeTextures[shapeKey].push(texture); + this.numFreeTextures++; + this._numBytesFree += texBytes; + } + this.numUsedTextures--; + const texList = this.usedTextures[shapeKey]; + const texIndex = texList && texList.indexOf(texture); + if (texIndex == null || texIndex < 0) { + throw new Error('Cannot release a texture that was never provided by this ' + + 'texture manager'); + } + texList[texIndex] = texList[texList.length - 1]; + texList.pop(); + this.log(); + } + log() { + if (!this.logEnabled) { + return; + } + const total = this.numFreeTextures + this.numUsedTextures; + console.log('Free/Used', `${this.numFreeTextures} / ${this.numUsedTextures}`, `(${total})`); + const freeRatio = this._numBytesFree / this._numBytesAllocated; + console.log(`Bytes allocated: ${this._numBytesAllocated}`); + console.log(`Bytes unused: ${this._numBytesFree} (${Math.round(100 * freeRatio)}%)`); + } + get numBytesAllocated() { + return this._numBytesAllocated; + } + get numBytesFree() { + return this._numBytesFree; + } + getNumUsedTextures() { + return this.numUsedTextures; + } + getNumFreeTextures() { + return this.numFreeTextures; + } + dispose() { + if (this.freeTextures == null) { + // Already disposed. + return; + } + for (const texShape in this.freeTextures) { + this.freeTextures[texShape].forEach(tex => { + this.gpgpu.deleteMatrixTexture(tex.texture); + }); + } + for (const texShape in this.usedTextures) { + this.usedTextures[texShape].forEach(tex => { + this.gpgpu.deleteMatrixTexture(tex.texture); + }); + } + // TODO: Assign non-null value (empty object) to textures after disposed. + this.freeTextures = null; + this.usedTextures = null; + this.numUsedTextures = 0; + this.numFreeTextures = 0; + this._numBytesAllocated = 0; + this._numBytesFree = 0; + } + } + function numBytesForInternalFormat(gl, internalFormat) { + // tslint:disable-next-line:no-any + const glany = gl; + if (internalFormat === glany.R32F) { + return 4; + } + else if (internalFormat === glany.R16F) { + return 2; + } + else if (internalFormat === glany.RGBA32F) { + return 16; + } + else if (internalFormat === gl.RGBA) { + return 16; + } + else if (internalFormat === glany.RGBA16F) { + return 8; + } + else if (internalFormat === glany.RGBA8) { + return 4; + } + throw new Error(`Unknown internal format ${internalFormat}`); + } + function computeBytes(shape, physicalTexType, gl, textureConfig, isPacked) { + // It is not possible to infer packed status from the texture type because + // depending on the textureConfig, different texture types may resolve to the + // same internal format (e.g. in WebGL1, the internal format for + // UNPACKED_FLOAT16 textures is gl.RGBA). Therefore we pass in `isPacked` + // explicitly. + const internalFormat = internalFormatForPhysicalTexType(physicalTexType, textureConfig); + let numElements; + if (isPacked) { + const [packedWidth, packedHeight] = getPackedMatrixTextureShapeWidthHeight(shape[0], shape[1]); + numElements = packedWidth * packedHeight; + } + else { + const [width, height] = getUnpackedMatrixTextureShapeWidthHeight(shape[0], shape[1]); + numElements = width * height; + } + const bytesPerElement = numBytesForInternalFormat(gl, internalFormat); + return numElements * bytesPerElement; + } + function internalFormatForPhysicalTexType(physicalTexType, textureConfig) { + switch (physicalTexType) { + case PhysicalTextureType.PACKED_2X2_FLOAT32: + return getInternalFormatForPackedMatrixTexture(textureConfig); + case PhysicalTextureType.PACKED_2X2_FLOAT16: + return getInternalFormatForFloat16PackedMatrixTexture(textureConfig); + case PhysicalTextureType.UNPACKED_FLOAT32: + return getInternalFormatForFloat32MatrixTexture(textureConfig); + case PhysicalTextureType.UNPACKED_FLOAT16: + return getInternalFormatForFloat16MatrixTexture(textureConfig); + case PhysicalTextureType.PACKED_4X1_UNSIGNED_BYTE: + return getInternalFormatForUnsignedBytesMatrixTexture(textureConfig); + default: + throw new Error(`Unknown physical texture type ${physicalTexType}`); + } + } + function getPhysicalTextureForRendering(isPacked) { + if (env().getBool('WEBGL_RENDER_FLOAT32_ENABLED')) { + if (isPacked) { + return PhysicalTextureType.PACKED_2X2_FLOAT32; + } + return PhysicalTextureType.UNPACKED_FLOAT32; + } + if (isPacked) { + return PhysicalTextureType.PACKED_2X2_FLOAT16; + } + return PhysicalTextureType.UNPACKED_FLOAT16; + } + function getPhysicalFromLogicalTextureType(logicalTexType, isPacked) { + if (logicalTexType === TextureUsage.UPLOAD) { + return PhysicalTextureType.PACKED_2X2_FLOAT32; + } + else if (logicalTexType === TextureUsage.RENDER || logicalTexType == null) { + return getPhysicalTextureForRendering(isPacked); + } + else if (logicalTexType === TextureUsage.DOWNLOAD || + logicalTexType === TextureUsage.PIXELS) { + return PhysicalTextureType.PACKED_4X1_UNSIGNED_BYTE; + } + throw new Error(`Unknown logical texture type ${logicalTexType}`); + } + function getKeyFromTextureShape(shapeRowsCol, physicalTexType, isPacked) { + return `${shapeRowsCol[0]}_${shapeRowsCol[1]}_${physicalTexType}_${isPacked}`; + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class UnaryOpProgram { + constructor(aShape, opSnippet) { + this.variableNames = ['A']; + this.outputShape = aShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + this.userCode = ` + float unaryOperation(float x) { + ${opSnippet} + } + + void main() { + float x = getAAtOutCoords(); + float y = unaryOperation(x); + + setOutput(y); + } + `; + } + } + const CHECK_NAN_SNIPPET$1 = `if (isnan(x)) return x;`; + const LINEAR$1 = `return x;`; + const ABS$1 = `return abs(x);`; + function STEP(alpha = 0.0) { + return CHECK_NAN_SNIPPET$1 + ` + return x > 0.0 ? 1.0 : float(${alpha}); + `; + } + const ELU$2 = `return (x >= 0.0) ? x : (exp(x) - 1.0);`; + const RELU$2 = CHECK_NAN_SNIPPET$1 + ` + return (x < 0.0) ? 0.0 : x; +`; + const RELU6$2 = CHECK_NAN_SNIPPET$1 + ` + return (x < 0.0) ? 0.0 : min(6.0, x); +`; + const CLONE = 'return x;'; + const SIGMOID$2 = `return 1.0 / (1.0 + exp(-1.0 * x));`; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const LINEAR = `return x;`; + const ELU$1 = ` + vec4 result; + + result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0); + result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0); + result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0); + result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0); + + return result; +`; + const RELU$1 = ` + vec4 result = x * vec4(greaterThanEqual(x, vec4(0.0))); + bvec4 isNaN = isnan(x); + + result.r = isNaN.r ? x.r : result.r; + result.g = isNaN.g ? x.g : result.g; + result.b = isNaN.b ? x.b : result.b; + result.a = isNaN.a ? x.a : result.a; + + return result; +`; + const RELU6$1 = ` + vec4 result = min(x, vec4(6.)) * vec4(greaterThanEqual(x, vec4(0.0))); + bvec4 isNaN = isnan(x); + + result.r = isNaN.r ? x.r : result.r; + result.g = isNaN.g ? x.g : result.g; + result.b = isNaN.b ? x.b : result.b; + result.a = isNaN.a ? x.a : result.a; + + return result; +`; + const SIGMOID$1 = `return 1.0 / (1.0 + exp(-1.0 * x));`; + class UnaryOpPackedProgram { + constructor(aShape, opSnippet) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = aShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + this.userCode = ` + vec4 unaryOperation(vec4 x) { + ${opSnippet} + } + + void main() { + vec4 x = getAAtOutCoords(); + vec4 y = unaryOperation(x); + + setOutput(y); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class UnpackProgram { + constructor(outputShape) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = false; + this.outputShape = outputShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + const rank = outputShape.length; + const channels = getChannels('rc', rank); + const dtype = getCoordsDataType(rank); + const sourceCoords = getSourceCoords$2(rank, channels); + const innerDims = channels.slice(-2); + const coords = rank <= 1 ? 'rc' : `vec2(${innerDims.join(',')})`; + this.userCode = ` + void main() { + ${dtype} rc = getOutputCoords(); + vec4 packedInput = getA(${sourceCoords}); + + setOutput(getChannel(packedInput, ${coords})); + } + `; + } + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const whereImpl = whereImpl$2; + const EPSILON_FLOAT32 = 1e-7; + const EPSILON_FLOAT16 = 1e-4; + const binaryCaches = {}; + function getBinaryCache(webGLVersion) { + if (webGLVersion in binaryCaches) { + return binaryCaches[webGLVersion]; + } + binaryCaches[webGLVersion] = {}; + return binaryCaches[webGLVersion]; + } + // Empirically determined constant used to determine size threshold for handing + // off execution to the CPU. + const CPU_HANDOFF_SIZE_THRESHOLD = env().getNumber('CPU_HANDOFF_SIZE_THRESHOLD'); + // Empirically determined constant used to decide the number of MB on GPU + // before we warn about high memory use. The MB are this constant * screen area + // * dpi / 1024 / 1024. + const BEFORE_PAGING_CONSTANT = 600; + function numMBBeforeWarning() { + if (env().global.screen == null) { + return 1024; // 1 GB. + } + return (env().global.screen.height * env().global.screen.width * + window.devicePixelRatio) * + BEFORE_PAGING_CONSTANT / 1024 / 1024; + } + class MathBackendWebGL extends KernelBackend { + nextDataId() { + return MathBackendWebGL.nextDataId++; + } + constructor(gpuResource) { + super(); + // Maps data ids that have a pending read operation, to list of subscribers. + this.pendingRead = new WeakMap(); + // List of data ids that are scheduled for disposal, but are waiting on a + // pending read operation. + this.pendingDisposal = new WeakSet(); + // Used to count the number of 'shallow' sliced tensors that point to the + // same data id. + this.dataRefCount = new WeakMap(); + this.numBytesInGPU = 0; + // Accumulated time spent (including blocking) in uploading data to webgl. + this.uploadWaitMs = 0; + // Accumulated time spent (including blocking in downloading data from webgl. + this.downloadWaitMs = 0; + // record the last manual GL Flush time. + this.lastGlFlushTime = 0; + this.warnedAboutMemory = false; + this.pendingDeletes = 0; + this.disposed = false; + if (!env().getBool('HAS_WEBGL')) { + throw new Error('WebGL is not supported on this device'); + } + let newGPGPU; + if (gpuResource != null) { + if (gpuResource instanceof GPGPUContext) { + newGPGPU = gpuResource; + } + else { + const gl = getWebGLContext(env().getNumber('WEBGL_VERSION'), gpuResource); + newGPGPU = new GPGPUContext(gl); + } + this.binaryCache = {}; + this.gpgpuCreatedLocally = false; + } + else { + const gl = getWebGLContext(env().getNumber('WEBGL_VERSION')); + newGPGPU = new GPGPUContext(gl); + this.binaryCache = getBinaryCache(env().getNumber('WEBGL_VERSION')); + this.gpgpuCreatedLocally = true; + } + this.gpgpu = newGPGPU; + this.canvas = this.gpgpu.gl.canvas; + this.textureManager = new TextureManager(this.gpgpu); + this.numMBBeforeWarning = numMBBeforeWarning(); + this.texData = new DataStorage(this, engine()); + } + numDataIds() { + return this.texData.numDataIds() - this.pendingDeletes; + } + // Writes a new entry to the data store with a WebGL texture, and registers it + // to the texture manager. + writeTexture(texture, shape, dtype, texHeight, texWidth, channels) { + // Temporarily create an tensor info to make the texture compatible with + // the runWebGLProgram's input. + const input = this.makeTensorInfo(shape, dtype); + const inData = this.texData.get(input.dataId); + // Even though the input texture could be unpacked or dense packed, it is + // always considered as unpacked for EncodeMatrixProgram. + inData.isPacked = false; + // Bind texture to the input tensor. + inData.texture = { texture, texShape: [texHeight, texWidth] }; + inData.texShape = [texHeight, texWidth]; + const shapeAs3D = getShapeAs3D(shape); + const program = new EncodeMatrixProgram(shapeAs3D, false /* isByteArray */, channels); + const output = this.runWebGLProgram(program, [input], dtype, [[texHeight, texWidth]]); + output.shape = shape; + // Unbind the texture from the input tensor to avoid the texture being + // released. + inData.texture = null; + this.disposeIntermediateTensorInfo(input); + return output.dataId; + } + write(values, shape, dtype) { + if (env().getBool('WEBGL_CHECK_NUMERICAL_PROBLEMS') || + env().getBool('DEBUG')) { + this.checkNumericalProblems(values); + } + if (dtype === 'complex64' && values != null) { + throw new Error(`Cannot write to a complex64 dtype. ` + + `Please use tf.complex(real, imag).`); + } + const dataId = { id: this.nextDataId() }; + this.texData.set(dataId, { shape, dtype, values, usage: TextureUsage.UPLOAD, refCount: 1 }); + return dataId; + } + /** Return refCount of a `TensorData`. */ + refCount(dataId) { + if (this.texData.has(dataId)) { + const tensorData = this.texData.get(dataId); + return tensorData.refCount; + } + return 0; + } + /** Increase refCount of a `TextureData`. */ + incRef(dataId) { + const texData = this.texData.get(dataId); + texData.refCount++; + } + /** Decrease refCount of a `TextureData`. */ + decRef(dataId) { + if (this.texData.has(dataId)) { + const texData = this.texData.get(dataId); + texData.refCount--; + } + } + move(dataId, values, shape, dtype, refCount) { + if (env().getBool('DEBUG')) { + this.checkNumericalProblems(values); + } + if (dtype === 'complex64') { + throw new Error(`Cannot write to a complex64 dtype. ` + + `Please use tf.complex(real, imag).`); + } + this.texData.set(dataId, { shape, dtype, values, usage: TextureUsage.UPLOAD, refCount }); + } + disposeIntermediateTensorInfo(tensorInfo) { + this.disposeData(tensorInfo.dataId); + } + readSync(dataId) { + const texData = this.texData.get(dataId); + const { values, dtype, complexTensorInfos, slice, shape, isPacked } = texData; + // The presence of `slice` indicates this tensor is a shallow slice of a + // different tensor, and is using that original tensor's texture. Run + // `clone` in order to copy that texture and read from it. + if (slice != null) { + let program; + if (isPacked) { + program = new UnaryOpPackedProgram(shape, CLONE); + } + else { + program = new UnaryOpProgram(shape, CLONE); + } + const res = this.runWebGLProgram(program, [{ dataId, shape, dtype }], dtype); + const data = this.readSync(res.dataId); + this.disposeIntermediateTensorInfo(res); + return data; + } + if (values != null) { + return this.convertAndCacheOnCPU(dataId); + } + if (dtype === 'string') { + return values; + } + const shouldTimeProgram = this.activeTimers != null; + let start; + if (shouldTimeProgram) { + start = now(); + } + let result; + if (dtype === 'complex64') { + const realValues = this.readSync(complexTensorInfos.real.dataId); + const imagValues = this.readSync(complexTensorInfos.imag.dataId); + result = mergeRealAndImagArrays(realValues, imagValues); + } + else { + result = this.getValuesFromTexture(dataId); + } + if (shouldTimeProgram) { + this.downloadWaitMs += now() - start; + } + return this.convertAndCacheOnCPU(dataId, result); + } + async read(dataId) { + if (this.pendingRead.has(dataId)) { + const subscribers = this.pendingRead.get(dataId); + return new Promise(resolve => subscribers.push(resolve)); + } + const texData = this.texData.get(dataId); + const { values, shape, slice, dtype, complexTensorInfos, isPacked } = texData; + // The presence of `slice` indicates this tensor is a shallow slice of a + // different tensor, and is using that original tensor's texture. Run + // `clone` in order to copy that texture and read from it. + if (slice != null) { + let program; + if (isPacked) { + program = new UnaryOpPackedProgram(shape, CLONE); + } + else { + program = new UnaryOpProgram(shape, CLONE); + } + const res = this.runWebGLProgram(program, [{ dataId, shape, dtype }], dtype); + const data = this.read(res.dataId); + this.disposeIntermediateTensorInfo(res); + return data; + } + if (values != null) { + return this.convertAndCacheOnCPU(dataId); + } + if (env().getBool('DEBUG')) { + // getBool('WEBGL_DOWNLOAD_FLOAT_ENABLED') caused a blocking GPU call. + // For performance reason, only check it for debugging. In production, + // it doesn't handle this use case anyway, so behavior is not changed. + if (!env().getBool('WEBGL_DOWNLOAD_FLOAT_ENABLED') && + env().getNumber('WEBGL_VERSION') === 2) { + throw new Error(`tensor.data() with WEBGL_DOWNLOAD_FLOAT_ENABLED=false and ` + + `WEBGL_VERSION=2 not yet supported.`); + } + } + let buffer = null; + let tmpDownloadTarget; + if (dtype !== 'complex64' && env().get('WEBGL_BUFFER_SUPPORTED')) { + // Possibly copy the texture into a buffer before inserting a fence. + tmpDownloadTarget = this.decode(dataId); + const tmpData = this.texData.get(tmpDownloadTarget.dataId); + buffer = this.gpgpu.createBufferFromTexture(tmpData.texture.texture, ...getDenseTexShape(shape)); + } + this.pendingRead.set(dataId, []); + if (dtype !== 'complex64') { + // Create a fence and wait for it to resolve. + await this.gpgpu.createAndWaitForFence(); + } + // Download the values from the GPU. + let vals; + if (dtype === 'complex64') { + const ps = await Promise.all([ + this.read(complexTensorInfos.real.dataId), + this.read(complexTensorInfos.imag.dataId) + ]); + const realValues = ps[0]; + const imagValues = ps[1]; + vals = mergeRealAndImagArrays(realValues, imagValues); + } + else if (buffer == null) { + vals = this.getValuesFromTexture(dataId); + } + else { + const size = sizeFromShape(shape); + vals = this.gpgpu.downloadFloat32MatrixFromBuffer(buffer, size); + } + if (tmpDownloadTarget != null) { + this.disposeIntermediateTensorInfo(tmpDownloadTarget); + } + if (buffer != null) { + const gl = this.gpgpu.gl; + callAndCheck(gl, () => gl.deleteBuffer(buffer)); + } + const dTypeVals = this.convertAndCacheOnCPU(dataId, vals); + const subscribers = this.pendingRead.get(dataId); + this.pendingRead.delete(dataId); + // Notify all pending reads. + subscribers.forEach(resolve => resolve(dTypeVals)); + if (this.pendingDisposal.has(dataId)) { + this.pendingDisposal.delete(dataId); + if (this.disposeData(dataId)) { + engine().removeDataId(dataId, this); + } + this.pendingDeletes--; + } + return dTypeVals; + } + /** + * Read tensor to a new texture that is densely packed for ease of use. + * @param dataId The source tensor. + * @param options + * customTexShape: Optional. If set, will use the user defined texture + * shape to create the texture. + */ + readToGPU(dataId, options = {}) { + const texData = this.texData.get(dataId); + const { values, shape, slice, dtype, isPacked, texture } = texData; + if (dtype === 'complex64') { + throw new Error('Does not support reading texture for complex64 dtype.'); + } + // The presence of `slice` indicates this tensor is a shallow slice of a + // different tensor, and is using that original tensor's texture. Run + // `clone` in order to copy that texture and read from it. + if (slice != null) { + let program; + if (isPacked) { + program = new UnaryOpPackedProgram(shape, CLONE); + } + else { + program = new UnaryOpProgram(shape, CLONE); + } + const res = this.runWebGLProgram(program, [{ dataId, shape, dtype }], dtype); + const gpuResouorce = this.readToGPU(res, options); + this.disposeIntermediateTensorInfo(res); + return gpuResouorce; + } + if (texture == null) { + if (values != null) { + throw new Error('Data is not on GPU but on CPU.'); + } + else { + throw new Error('There is no data on GPU or CPU.'); + } + } + // Decode the texture so that it is stored densely (using four channels). + const tmpTarget = this.decode(dataId, options.customTexShape); + // Make engine track this tensor, so that we can dispose it later. + const tensorRef = engine().makeTensorFromTensorInfo(tmpTarget); + const tmpData = this.texData.get(tmpTarget.dataId); + return Object.assign({ tensorRef }, tmpData.texture); + } + bufferSync(t) { + const data = this.readSync(t.dataId); + if (t.dtype === 'string') { + try { + // Decode the bytes into string. + const strings = data.map(d => decodeString(d)); + return buffer(t.shape, t.dtype, strings); + } + catch (_a) { + throw new Error('Failed to decode encoded string bytes into utf-8'); + } + } + return buffer(t.shape, t.dtype, data); + } + checkNumericalProblems(values) { + if (values == null) { + return; + } + for (let i = 0; i < values.length; i++) { + const num = values[i]; + if (!canBeRepresented(num)) { + if (env().getBool('WEBGL_RENDER_FLOAT32_CAPABLE')) { + throw Error(`The value ${num} cannot be represented with your ` + + `current settings. Consider enabling float32 rendering: ` + + `'tf.env().set('WEBGL_RENDER_FLOAT32_ENABLED', true);'`); + } + throw Error(`The value ${num} cannot be represented on this device.`); + } + } + } + getValuesFromTexture(dataId) { + const { shape, dtype, isPacked } = this.texData.get(dataId); + const size = sizeFromShape(shape); + if (env().getBool('WEBGL_DOWNLOAD_FLOAT_ENABLED')) { + const tmpTarget = this.decode(dataId); + const tmpData = this.texData.get(tmpTarget.dataId); + const vals = this.gpgpu + .downloadMatrixFromPackedTexture(tmpData.texture.texture, ...getDenseTexShape(shape)) + .subarray(0, size); + this.disposeIntermediateTensorInfo(tmpTarget); + return vals; + } + const shouldUsePackedProgram = env().getBool('WEBGL_PACK') && isPacked === true; + const outputShape = shouldUsePackedProgram ? getShapeAs3D(shape) : shape; + const program = shouldUsePackedProgram ? + new EncodeFloatPackedProgram(outputShape) : + new EncodeFloatProgram(outputShape); + const output = this.runWebGLProgram(program, [{ shape: outputShape, dtype, dataId }], 'float32'); + const tmpData = this.texData.get(output.dataId); + const vals = this.gpgpu + .downloadByteEncodedFloatMatrixFromOutputTexture(tmpData.texture.texture, tmpData.texShape[0], tmpData.texShape[1]) + .subarray(0, size); + this.disposeIntermediateTensorInfo(output); + return vals; + } + timerAvailable() { + return env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE') > 0; + } + time(f) { + const oldActiveTimers = this.activeTimers; + const newActiveTimers = []; + let outerMostTime = false; + if (this.programTimersStack == null) { + this.programTimersStack = newActiveTimers; + outerMostTime = true; + } + else { + this.activeTimers.push(newActiveTimers); + } + this.activeTimers = newActiveTimers; + f(); + // needing to split these up because util.flatten only accepts certain types + const flattenedActiveTimerQueries = flatten$2(this.activeTimers.map((d) => d.query)) + .filter(d => d != null); + const flattenedActiveTimerNames = flatten$2(this.activeTimers.map((d) => d.name)) + .filter(d => d != null); + this.activeTimers = oldActiveTimers; + if (outerMostTime) { + this.programTimersStack = null; + } + const res = { + uploadWaitMs: this.uploadWaitMs, + downloadWaitMs: this.downloadWaitMs, + kernelMs: null, + wallMs: null // will be filled by the engine + }; + return (async () => { + if (env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE') > + 0) { + const kernelMs = await Promise.all(flattenedActiveTimerQueries); + res['kernelMs'] = sum$4(kernelMs); + res['getExtraProfileInfo'] = () => kernelMs + .map((d, i) => ({ name: flattenedActiveTimerNames[i], ms: d })) + .map(d => `${d.name}: ${d.ms}`) + .join(', '); + } + else { + res['kernelMs'] = { + error: 'WebGL query timers are not supported in this environment.' + }; + } + this.uploadWaitMs = 0; + this.downloadWaitMs = 0; + return res; + })(); + } + memory() { + return { + unreliable: false, + numBytesInGPU: this.numBytesInGPU, + numBytesInGPUAllocated: this.textureManager.numBytesAllocated, + numBytesInGPUFree: this.textureManager.numBytesFree + }; + } + startTimer() { + if (env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE') > 0) { + return this.gpgpu.beginQuery(); + } + return { startMs: now(), endMs: null }; + } + endTimer(query) { + if (env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE') > 0) { + this.gpgpu.endQuery(); + return query; + } + query.endMs = now(); + return query; + } + async getQueryTime(query) { + if (env().getNumber('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE') > 0) { + return this.gpgpu.waitForQueryAndGetTime(query); + } + const timerQuery = query; + return timerQuery.endMs - timerQuery.startMs; + } + /** + * Decrease the RefCount on the dataId and dispose the memory if the dataId + * has 0 refCount. If there are pending read on the data, the disposal would + * added to the pending delete queue. Return true if the dataId is removed + * from backend or the backend does not contain the dataId, false if the + * dataId is not removed. Memory may or may not be released even when dataId + * is removed, which also depends on dataRefCount, see `releaseGPU`. + * @param dataId + * @oaram force Optional, remove the data regardless of refCount + */ + disposeData(dataId, force = false) { + if (this.pendingDisposal.has(dataId)) { + return false; + } + // No-op if already disposed. + if (!this.texData.has(dataId)) { + return true; + } + // if force flag is set, change refCount to 0, this would ensure disposal + // when added to the pendingDisposal queue. Memory may or may not be + // released, which also depends on dataRefCount, see `releaseGPU`. + if (force) { + this.texData.get(dataId).refCount = 0; + } + else { + this.texData.get(dataId).refCount--; + } + if (!force && this.texData.get(dataId).refCount > 0) { + return false; + } + if (this.pendingRead.has(dataId)) { + this.pendingDisposal.add(dataId); + this.pendingDeletes++; + return false; + } + this.releaseGPUData(dataId); + const { complexTensorInfos } = this.texData.get(dataId); + if (complexTensorInfos != null) { + this.disposeData(complexTensorInfos.real.dataId, force); + this.disposeData(complexTensorInfos.imag.dataId, force); + } + this.texData.delete(dataId); + return true; + } + releaseGPUData(dataId) { + const { texture, dtype, texShape, usage, isPacked, slice } = this.texData.get(dataId); + const key = slice && slice.origDataId || dataId; + const refCount = this.dataRefCount.get(key); + if (refCount > 1) { + this.dataRefCount.set(key, refCount - 1); + } + else { + this.dataRefCount.delete(key); + if (texture != null) { + this.numBytesInGPU -= this.computeBytes(texShape, dtype); + this.textureManager.releaseTexture(texture, texShape, usage, isPacked); + } + } + const texData = this.texData.get(dataId); + texData.texture = null; + texData.texShape = null; + texData.isPacked = false; + texData.slice = null; + } + getTexture(dataId) { + this.uploadToGPU(dataId); + return this.texData.get(dataId).texture.texture; + } + /** + * Returns internal information for the specific data bucket. Used in unit + * tests. + */ + getDataInfo(dataId) { + return this.texData.get(dataId); + } + /* + Tests whether all the inputs to an op are small and on the CPU. This heuristic + determines when it would be faster to execute a kernel on the CPU. WebGL + kernels opt into running this check and forwarding when appropriate. + TODO(https://github.com/tensorflow/tfjs/issues/872): Develop a more + sustainable strategy for optimizing backend execution of ops. + */ + shouldExecuteOnCPU(inputs, sizeThreshold = CPU_HANDOFF_SIZE_THRESHOLD) { + return env().getBool('WEBGL_CPU_FORWARD') && + inputs.every(input => this.texData.get(input.dataId).texture == null && + sizeFromShape(input.shape) < sizeThreshold); + } + getGPGPUContext() { + return this.gpgpu; + } + where(condition) { + warn('tf.where() in webgl locks the UI thread. ' + + 'Call tf.whereAsync() instead'); + const condVals = condition.dataSync(); + return whereImpl(condition.shape, condVals); + } + packedUnaryOp(x, op, dtype) { + const program = new UnaryOpPackedProgram(x.shape, op); + const outInfo = this.compileAndRun(program, [x], dtype); + return engine().makeTensorFromTensorInfo(outInfo); + } + // TODO(msoulanille) remove this once the backend has been modularized + // a copy is needed here to break a circular dependency. + // Also remove the op from unary_op. + abs(x) { + // TODO: handle cases when x is complex. + if (this.shouldExecuteOnCPU([x]) && x.dtype !== 'complex64') { + const outValues = simpleAbsImplCPU(this.texData.get(x.dataId).values); + return this.makeOutput(x.shape, x.dtype, outValues); + } + if (env().getBool('WEBGL_PACK_UNARY_OPERATIONS')) { + return this.packedUnaryOp(x, ABS$1, x.dtype); + } + const program = new UnaryOpProgram(x.shape, ABS$1); + const outInfo = this.compileAndRun(program, [x]); + return engine().makeTensorFromTensorInfo(outInfo); + } + makeTensorInfo(shape, dtype, values) { + let dataId; + if (dtype === 'string' && values != null && values.length > 0 && + isString(values[0])) { + const encodedValues = values.map(d => encodeString(d)); + dataId = this.write(encodedValues, shape, dtype); + } + else { + dataId = this.write(values, shape, dtype); + } + this.texData.get(dataId).usage = null; + return { dataId, shape, dtype }; + } + makeOutput(shape, dtype, values) { + return engine().makeTensorFromTensorInfo(this.makeTensorInfo(shape, dtype, values), this); + } + unpackTensor(input) { + const program = new UnpackProgram(input.shape); + return this.runWebGLProgram(program, [input], input.dtype); + } + packTensor(input) { + const program = new PackProgram(input.shape); + const preventEagerUnpackingOutput = true; + return this.runWebGLProgram(program, [input], input.dtype, null /* customUniformValues */, preventEagerUnpackingOutput); + } + packedReshape(input, afterShape) { + const input3DShape = [ + getBatchDim(input.shape), + ...getRowsCols(input.shape) + ]; + const input3D = { + dtype: input.dtype, + shape: input3DShape, + dataId: input.dataId + }; + const afterShapeAs3D = [ + getBatchDim(afterShape), ...getRowsCols(afterShape) + ]; + const program = new ReshapePackedProgram(afterShapeAs3D, input3DShape); + const preventEagerUnpackingOfOutput = true; + const customValues = [input3DShape]; + const output = this.runWebGLProgram(program, [input3D], input.dtype, customValues, preventEagerUnpackingOfOutput); + return { dataId: output.dataId, shape: afterShape, dtype: output.dtype }; + } + decode(dataId, customTexShape) { + const texData = this.texData.get(dataId); + const { isPacked, shape, dtype } = texData; + if (customTexShape != null) { + const size = sizeFromShape(shape); + const texSize = customTexShape[0] * customTexShape[1] * 4; + assert$1(size <= texSize, () => 'customTexShape is too small. ' + + 'Row * Column * 4 should be equal or larger than the ' + + 'size of the tensor data.'); + } + const shapeAs3D = getShapeAs3D(shape); + let program; + if (isPacked) { + program = new DecodeMatrixPackedProgram(shapeAs3D); + } + else { + program = new DecodeMatrixProgram(shapeAs3D); + } + const preventEagerUnpackingOfOutput = true; + const customValues = [customTexShape != null ? customTexShape : + getDenseTexShape(shapeAs3D)]; + const out = this.runWebGLProgram(program, [{ shape: shapeAs3D, dtype, dataId }], dtype, customValues, preventEagerUnpackingOfOutput, customTexShape); + return { dtype, shape, dataId: out.dataId }; + } + runWebGLProgram(program, inputs, outputDtype, customUniformValues, preventEagerUnpackingOfOutput = false, customTexShape) { + const output = this.makeTensorInfo(program.outputShape, outputDtype); + const outData = this.texData.get(output.dataId); + if (program.packedOutput) { + outData.isPacked = true; + } + if (program.outPackingScheme === PackingScheme.DENSE) { + const texelShape = customTexShape != null ? + customTexShape : + getDenseTexShape(program.outputShape); + // For a densely packed output, we explicitly set texShape + // so it doesn't get assigned later according to our typical packing + // scheme wherein a single texel can only contain values from adjacent + // rows/cols. + outData.texShape = texelShape.map(d => d * 2); + } + if (program.outTexUsage != null) { + outData.usage = program.outTexUsage; + } + if (sizeFromShape(output.shape) === 0) { + // Short-circuit the computation since the result is empty (has 0 in its + // shape). + outData.values = + getTypedArrayFromDType(output.dtype, 0); + return output; + } + const dataToDispose = []; + const inputsData = inputs.map(input => { + if (input.dtype === 'complex64') { + throw new Error(`GPGPUProgram does not support complex64 input. For complex64 ` + + `dtypes, please separate the program into real and imaginary ` + + `parts.`); + } + let texData = this.texData.get(input.dataId); + if (texData.texture == null) { + if (!program.packedInputs && + sizeFromShape(input.shape) <= + env().getNumber('WEBGL_SIZE_UPLOAD_UNIFORM')) { + // Upload small tensors that live on the CPU as uniforms, not as + // textures. Do this only when the environment supports 32bit floats + // due to problems when comparing 16bit floats with 32bit floats. + // TODO(https://github.com/tensorflow/tfjs/issues/821): Make it + // possible for packed shaders to sample from uniforms. + return { + shape: input.shape, + texData: null, + isUniform: true, + uniformValues: texData.values + }; + } + // This ensures that if a packed program's inputs have not yet been + // uploaded to the GPU, they get uploaded as packed right off the bat. + if (program.packedInputs) { + texData.isPacked = true; + texData.shape = input.shape; + } + } + this.uploadToGPU(input.dataId); + if (!!texData.isPacked !== !!program.packedInputs) { + input = texData.isPacked ? this.unpackTensor(input) : + this.packTensor(input); + dataToDispose.push(input); + texData = this.texData.get(input.dataId); + } + else if (texData.isPacked && + !isReshapeFree(texData.shape, input.shape)) { + // This is a special case where a texture exists for a tensor + // but the shapes are incompatible (due to packing constraints) because + // the tensor did not have a chance to go through the packed reshape + // shader. This only happens when we reshape the *same* tensor to form + // *distinct* inputs to an op, e.g. dotting a vector with itself. This + // case will disappear once packed uploading is the default. + const savedInput = input; + const targetShape = input.shape; + input.shape = texData.shape; + input = this.packedReshape(input, targetShape); + dataToDispose.push(input); + texData = this.texData.get(input.dataId); + savedInput.shape = targetShape; + } + return { shape: input.shape, texData, isUniform: false }; + }); + this.uploadToGPU(output.dataId); + const outputData = { shape: output.shape, texData: outData, isUniform: false }; + const key = makeShaderKey(program, inputsData, outputData); + const binary = this.getAndSaveBinary(key, () => { + return compileProgram(this.gpgpu, program, inputsData, outputData); + }); + const shouldTimeProgram = this.activeTimers != null; + let query; + if (shouldTimeProgram) { + query = this.startTimer(); + } + if (!env().get('ENGINE_COMPILE_ONLY')) { + runProgram(this.gpgpu, binary, inputsData, outputData, customUniformValues); + } + dataToDispose.forEach(info => this.disposeIntermediateTensorInfo(info)); + if (shouldTimeProgram) { + query = this.endTimer(query); + this.activeTimers.push({ name: program.constructor.name, query: this.getQueryTime(query) }); + } + const glFlushThreshold = env().getNumber('WEBGL_FLUSH_THRESHOLD'); + // Manually GL flush requested + if (glFlushThreshold > 0) { + const time = now(); + if ((time - this.lastGlFlushTime) > glFlushThreshold) { + this.gpgpu.gl.flush(); + this.lastGlFlushTime = time; + } + } + if (!env().getBool('WEBGL_LAZILY_UNPACK') && outData.isPacked && + preventEagerUnpackingOfOutput === false) { + const unpacked = this.unpackTensor(output); + this.disposeIntermediateTensorInfo(output); + return unpacked; + } + return output; + } + compileAndRun(program, inputs, outputDtype, customUniformValues, preventEagerUnpackingOfOutput = false) { + outputDtype = outputDtype || inputs[0].dtype; + const outInfo = this.runWebGLProgram(program, inputs, outputDtype, customUniformValues, preventEagerUnpackingOfOutput); + return outInfo; + } + getAndSaveBinary(key, getBinary) { + if (!(key in this.binaryCache)) { + this.binaryCache[key] = getBinary(); + } + return this.binaryCache[key]; + } + getTextureManager() { + return this.textureManager; + } + dispose() { + if (this.disposed) { + return; + } + // Avoid disposing the compiled webgl programs during unit testing because + // it slows down test execution. + if (!env().getBool('IS_TEST')) { + const allKeys = Object.keys(this.binaryCache); + allKeys.forEach(key => { + this.gpgpu.deleteProgram(this.binaryCache[key].webGLProgram); + delete this.binaryCache[key]; + }); + } + this.textureManager.dispose(); + if (this.canvas != null && + (typeof (HTMLCanvasElement) !== 'undefined' && + this.canvas instanceof HTMLCanvasElement)) { + this.canvas.remove(); + } + else { + this.canvas = null; + } + if (this.gpgpuCreatedLocally) { + this.gpgpu.program = null; + this.gpgpu.dispose(); + } + this.disposed = true; + } + floatPrecision() { + if (this.floatPrecisionValue == null) { + this.floatPrecisionValue = tidy(() => { + if (!env().get('WEBGL_RENDER_FLOAT32_ENABLED')) { + // Momentarily switching DEBUG flag to false so we don't throw an + // error trying to upload a small value. + const debugFlag = env().getBool('DEBUG'); + env().set('DEBUG', false); + const underflowCheckValue = this.abs(scalar(1e-8)).dataSync()[0]; + env().set('DEBUG', debugFlag); + if (underflowCheckValue > 0) { + return 32; + } + } + return 16; + }); + } + return this.floatPrecisionValue; + } + /** Returns the smallest representable number. */ + epsilon() { + return this.floatPrecision() === 32 ? EPSILON_FLOAT32 : EPSILON_FLOAT16; + } + uploadToGPU(dataId) { + const texData = this.texData.get(dataId); + const { shape, dtype, values, texture, usage, isPacked } = texData; + if (texture != null) { + // Array is already on GPU. No-op. + return; + } + const shouldTimeProgram = this.activeTimers != null; + let start; + if (shouldTimeProgram) { + start = now(); + } + let texShape = texData.texShape; + if (texShape == null) { + // This texShape may not be the final texture shape. For packed or dense + // textures, the texShape will be changed when textures are created. + texShape = getTextureShapeFromLogicalShape(shape, isPacked); + texData.texShape = texShape; + } + if (values != null) { + const shapeAs3D = getShapeAs3D(shape); + let program; + let width = texShape[1], height = texShape[0]; + const isByteArray = values instanceof Uint8Array || values instanceof Uint8ClampedArray; + // texture for float array is PhysicalTextureType.PACKED_2X2_FLOAT32, we + // need to make sure the upload uses the same packed size + if (isPacked || !isByteArray) { + [width, height] = getPackedMatrixTextureShapeWidthHeight(texShape[0], texShape[1]); + } + if (isPacked) { + program = new EncodeMatrixPackedProgram(shapeAs3D, isByteArray); + } + else { + program = new EncodeMatrixProgram(shapeAs3D, isByteArray); + } + // TexShape for float array needs to be the original shape, which byte + // array needs to be packed size. This allow the data upload shape to be + // matched with texture creation logic. + const tempDenseInputTexShape = isByteArray ? [height, width] : texShape; + const tempDenseInputHandle = this.makeTensorInfo(tempDenseInputTexShape, dtype); + const tempDenseInputTexData = this.texData.get(tempDenseInputHandle.dataId); + if (isByteArray) { + tempDenseInputTexData.usage = TextureUsage.PIXELS; + } + else { + tempDenseInputTexData.usage = TextureUsage.UPLOAD; + } + tempDenseInputTexData.texShape = tempDenseInputTexShape; + this.gpgpu.uploadDenseMatrixToTexture(this.getTexture(tempDenseInputHandle.dataId), width, height, values); + const customValues = [[height, width]]; + // We want the output to remain packed regardless of the value of + // WEBGL_PACK. + const preventEagerUnpacking = true; + const encodedOutputTarget = this.runWebGLProgram(program, [tempDenseInputHandle], dtype, customValues, preventEagerUnpacking); + // Have the original texture assume the identity of the encoded output. + const outputTexData = this.texData.get(encodedOutputTarget.dataId); + texData.texShape = outputTexData.texShape; + texData.isPacked = outputTexData.isPacked; + texData.usage = outputTexData.usage; + if (!env().get('ENGINE_COMPILE_ONLY')) { + texData.texture = outputTexData.texture; + // Once uploaded, don't store the values on cpu. + texData.values = null; + this.texData.delete(encodedOutputTarget.dataId); + } + else { + this.disposeData(encodedOutputTarget.dataId); + } + this.disposeIntermediateTensorInfo(tempDenseInputHandle); + if (shouldTimeProgram) { + this.uploadWaitMs += now() - start; + } + } + else { + const newTexture = this.acquireTexture(texShape, usage, dtype, isPacked); + texData.texture = newTexture; + } + } + convertAndCacheOnCPU(dataId, float32Values) { + const texData = this.texData.get(dataId); + const { dtype } = texData; + if (float32Values != null) { + texData.values = float32ToTypedArray(float32Values, dtype); + } + return texData.values; + } + acquireTexture(texShape, texType, dtype, isPacked) { + this.numBytesInGPU += this.computeBytes(texShape, dtype); + if (!this.warnedAboutMemory && + this.numBytesInGPU > this.numMBBeforeWarning * 1024 * 1024) { + const mb = (this.numBytesInGPU / 1024 / 1024).toFixed(2); + this.warnedAboutMemory = true; + console.warn(`High memory usage in GPU: ${mb} MB, ` + + `most likely due to a memory leak`); + } + return this.textureManager.acquireTexture(texShape, texType, isPacked); + } + computeBytes(shape, dtype) { + return shape[0] * shape[1] * bytesPerElement(dtype); + } + checkCompileCompletion() { + for (const [, binary] of Object.entries(this.binaryCache)) { + this.checkCompletion_(binary); + } + } + async checkCompileCompletionAsync() { + const ps = []; + if (this.gpgpu.parallelCompilationExtension) { + for (const [, binary] of Object.entries(this.binaryCache)) { + ps.push(this.checkCompletionAsync_(binary)); + } + return Promise.all(ps); + } + else { + for (const [, binary] of Object.entries(this.binaryCache)) { + const p = new Promise((resolve) => { + try { + this.checkCompletion_(binary); + resolve(true); + } + catch (error) { + throw error; + } + }); + ps.push(p); + } + return Promise.all(ps); + } + } + async checkCompletionAsync_(binary) { + if (this.gpgpu.gl.getProgramParameter(binary.webGLProgram, this.gpgpu.parallelCompilationExtension.COMPLETION_STATUS_KHR)) { + return this.checkCompletion_(binary); + } + else { + await nextFrame(); + return this.checkCompletionAsync_(binary); + } + } + checkCompletion_(binary) { + if (this.gpgpu.gl.getProgramParameter(binary.webGLProgram, this.gpgpu.gl.LINK_STATUS) === false) { + console.log(this.gpgpu.gl.getProgramInfoLog(binary.webGLProgram)); + if (this.gpgpu.gl.getShaderParameter(binary.fragmentShader, this.gpgpu.gl.COMPILE_STATUS) === false) { + logShaderSourceAndInfoLog(binary.source, this.gpgpu.gl.getShaderInfoLog(binary.fragmentShader)); + throw new Error('Failed to compile fragment shader.'); + } + throw new Error('Failed to link vertex and fragment shaders.'); + } + return true; + } + getUniformLocations() { + for (const binary of Object.values(this.binaryCache)) { + // TODO: Iterating through all binaries to build VAOs is supposed to be in + // a seperate function, like 'setVaos'. However, to avoid breaking changes + // for the users using parallel compile feature now, buildVao is silently + // added here. + this.gpgpu.buildVao(binary.webGLProgram); + const { variablesLocations, customUniformLocations, infLoc, nanLoc, outShapeLocation, outShapeStridesLocation, outTexShapeLocation } = getUniformLocations(this.gpgpu, binary.program, binary.webGLProgram); + binary.variablesLocations = variablesLocations; + binary.customUniformLocations = customUniformLocations; + binary.infLoc = infLoc; + binary.nanLoc = nanLoc; + binary.outShapeLocation = outShapeLocation; + binary.outShapeStridesLocation = outShapeStridesLocation; + binary.outTexShapeLocation = outTexShapeLocation; + } + } + /** + * Create a TF.js tensor out of an existing WebGL texture. A new texture will + * be created. + */ + createTensorFromGPUData(values, shape, dtype) { + values.channels = values.channels || 'RGBA'; + const { texture, height, width, channels } = values; + const backend = engine().backend; + // Have to throw an error, otherwise WebGL just warns and returns wrong + // values. + if (!backend.gpgpu.gl.isTexture(texture)) { + throw new Error(`The texture is invalid. Also, please make sure the texture and ` + + `the TFJS WebGL backend are using the same canvas. If you want to ` + + `use your own custom canvas, you have to create and use the custom ` + + `TFJS WebGL backend created from the canvas through ` + + `'new tf.MathBackendWebGL(customCanvas)'.`); + } + const dataId = backend.writeTexture(texture, shape, dtype, height, width, channels); + return engine().makeTensorFromDataId(dataId, shape, dtype, backend); + } + } + MathBackendWebGL.nextDataId = 0; + function float32ToTypedArray(a, dtype) { + if (dtype === 'float32' || dtype === 'complex64') { + return a; + } + else if (dtype === 'int32' || dtype === 'bool') { + const result = (dtype === 'int32') ? new Int32Array(a.length) : + new Uint8Array(a.length); + for (let i = 0; i < result.length; ++i) { + result[i] = Math.round(a[i]); + } + return result; + } + else { + throw new Error(`Unknown dtype ${dtype}`); + } + } + + /** @license See the LICENSE file. */ + // This code is auto-generated, do not modify this file! + const version$2 = '4.22.0'; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Enforce use of half precision textures if available on the platform. + * + * @doc {heading: 'Environment', namespace: 'webgl'} + */ + function forceHalfFloat() { + env().set('WEBGL_FORCE_F16_TEXTURES', true); + } + + /** + * @license + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + if (isBrowser()) { + registerBackend('webgl', () => new MathBackendWebGL(), 2 /* priority */); + } + const webgl = { forceHalfFloat }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const CHECK_NAN_SNIPPET = ` + if (isnan(a)) return a; + if (isnan(b)) return b; +`; + const SQUARED_DIFFERENCE$1 = 'return (a - b) * (a - b);'; + class BinaryOpProgram { + constructor(op, aShape, bShape) { + this.variableNames = ['A', 'B']; + this.outputShape = assertAndGetBroadcastShape(aShape, bShape); + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + this.userCode = ` + float binaryOperation(float a, float b) { + ${op} + } + + void main() { + float a = getAAtOutCoords(); + float b = getBAtOutCoords(); + setOutput(binaryOperation(a, b)); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const CHECK_NAN_SNIPPET_PACKED = ` + result.r = isNaN.r ? NAN : result.r; + result.g = isNaN.g ? NAN : result.g; + result.b = isNaN.b ? NAN : result.b; + result.a = isNaN.a ? NAN : result.a; +`; + const ELU_DER$1 = ` + vec4 bGTEZero = vec4(greaterThanEqual(b, vec4(0.))); + return (bGTEZero * a) + ((vec4(1.0) - bGTEZero) * (a * (b + vec4(1.0)))); +`; + const NOT_EQUAL$1 = ` + return vec4(notEqual(a, b)); +`; + class BinaryOpPackedProgram { + constructor(op, aShape, bShape, checkOutOfBounds = false) { + this.variableNames = ['A', 'B']; + this.supportsBroadcasting = true; + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = assertAndGetBroadcastShape(aShape, bShape); + const rank = this.outputShape.length; + this.enableShapeUniforms = useShapeUniforms(rank); + let checkOutOfBoundsString = ''; + if (checkOutOfBounds) { + if (rank === 0 || sizeFromShape(this.outputShape) === 1) { + checkOutOfBoundsString = ` + result.y = 0.; + result.z = 0.; + result.w = 0.; + `; + } + else { + const dtype = getCoordsDataType(rank); + checkOutOfBoundsString = ` + ${dtype} coords = getOutputCoords(); + `; + if (rank === 1) { + if (this.enableShapeUniforms) { + checkOutOfBoundsString += ` + result.y = (coords + 1) >= outShape ? 0. : result.y; + result.z = 0.; + result.w = 0.; + `; + } + else { + checkOutOfBoundsString += ` + result.y = (coords + 1) >= ${this.outputShape[0]} ? 0. : result.y; + result.z = 0.; + result.w = 0.; + `; + } + } + else { + const channels = getChannels('coords', rank); + if (this.enableShapeUniforms) { + checkOutOfBoundsString += ` + bool nextRowOutOfBounds = + (${channels[rank - 2]} + 1) >= outShape[${rank} - 2]; + bool nextColOutOfBounds = + (${channels[rank - 1]} + 1) >= outShape[${rank} - 1]; + result.y = nextColOutOfBounds ? 0. : result.y; + result.z = nextRowOutOfBounds ? 0. : result.z; + result.w = nextColOutOfBounds || nextRowOutOfBounds ? 0. : result.w; + `; + } + else { + checkOutOfBoundsString += ` + bool nextRowOutOfBounds = + (${channels[rank - 2]} + 1) >= ${this.outputShape[rank - 2]}; + bool nextColOutOfBounds = + (${channels[rank - 1]} + 1) >= ${this.outputShape[rank - 1]}; + result.y = nextColOutOfBounds ? 0. : result.y; + result.z = nextRowOutOfBounds ? 0. : result.z; + result.w = nextColOutOfBounds || nextRowOutOfBounds ? 0. : result.w; + `; + } + } + } + } + this.userCode = ` + vec4 binaryOperation(vec4 a, vec4 b) { + ${op} + } + + void main() { + vec4 a = getAAtOutCoords(); + vec4 b = getBAtOutCoords(); + + vec4 result = binaryOperation(a, b); + ${checkOutOfBoundsString} + + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function identity(args) { + const { inputs, backend } = args; + const { x } = inputs; + backend.incRef(x.dataId); + return { dataId: x.dataId, shape: x.shape, dtype: x.dtype }; + } + const identityConfig = { + kernelName: Identity$1, + backendName: 'webgl', + kernelFunc: identity + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * In WebGL data is stored in GPU textures which can't be efficiently copied, so + * complex tensors share data with their real and imaginary components. Complex + * tensors' reference to the components is tracked by refCount on the individual + * component. The refCounts are increased by the identity call. + * + * When a complex tensor is disposed, it will reduce the refCount on the + * components by calling disposeData on each. + */ + function complex(args) { + const { inputs, backend } = args; + const { real, imag } = inputs; + const complexInfo = backend.makeTensorInfo(real.shape, 'complex64'); + const complex = backend.texData.get(complexInfo.dataId); + const realTensorInfo = identity({ inputs: { x: real }, backend }); + const imagTensorInfo = identity({ inputs: { x: imag }, backend }); + complex.complexTensorInfos = { real: realTensorInfo, imag: imagTensorInfo }; + return complexInfo; + } + const complexConfig = { + kernelName: Complex, + backendName: 'webgl', + kernelFunc: complex + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const LEAKYRELU = `return (a < 0.) ? b * a : a;`; + const LEAKYRELU_PACKED = ` + vec4 aLessThanZero = vec4(lessThan(a, vec4(0.))); + return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a); +`; + function leakyRelu(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { alpha } = attrs; + const $alpha = backend.makeTensorInfo([], 'float32', createScalarValue(alpha, 'float32')); + const program = env().getBool('WEBGL_PACK_BINARY_OPERATIONS') ? + new BinaryOpPackedProgram(LEAKYRELU_PACKED, x.shape, $alpha.shape) : + new BinaryOpProgram(LEAKYRELU, x.shape, $alpha.shape); + const result = backend.runWebGLProgram(program, [x, $alpha], 'float32'); + backend.disposeIntermediateTensorInfo($alpha); + return result; + } + const leakyReluConfig = { + kernelName: LeakyRelu, + backendName: 'webgl', + kernelFunc: leakyRelu + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const PRELU = `return (a < 0.) ? b * a : a;`; + const PRELU_PACKED = ` + vec4 aLessThanZero = vec4(lessThan(a, vec4(0.))); + return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a); +`; + function prelu(args) { + const { inputs, backend } = args; + const { x, alpha } = inputs; + const program = env().getBool('WEBGL_PACK_BINARY_OPERATIONS') ? + new BinaryOpPackedProgram(PRELU_PACKED, x.shape, alpha.shape) : + new BinaryOpProgram(PRELU, x.shape, alpha.shape); + return backend.runWebGLProgram(program, [x, alpha], 'float32'); + } + const preluConfig = { + kernelName: Prelu, + backendName: 'webgl', + kernelFunc: prelu + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const CHECK_NAN_SNIPPET_UNARY = `if (isnan(x)) return x;`; + /** + * Template that creates a `KernelFunc` for unary ops. + * @param opSnippet Op snippet to create `UnaryOpProgram`. + * @param packedOpSnippet Op snippet to create `UnaryOpPackedProgram`. + * @param dtype Optional. If set, the result has this dtype. Otherwise, the + * result has the same dtype as the first input. This is mainly used in + * comparison kernels, such as Equal, Less, Greater, etc. + */ + function unaryKernelFunc({ opSnippet, packedOpSnippet, cpuKernelImpl, dtype }) { + return ({ inputs, backend }) => { + const { x } = inputs; + const webglBackend = backend; + const $dtype = dtype || x.dtype; + if (webglBackend.shouldExecuteOnCPU([x]) && cpuKernelImpl != null) { + const xData = webglBackend.texData.get(x.dataId); + const outValues = cpuKernelImpl(xData.values, $dtype); + return webglBackend.makeTensorInfo(x.shape, $dtype, outValues); + } + const shouldUsePackedProgram = env().getBool('WEBGL_PACK_UNARY_OPERATIONS') && packedOpSnippet != null; + let program; + if (shouldUsePackedProgram) { + program = new UnaryOpPackedProgram(x.shape, packedOpSnippet); + } + else { + program = new UnaryOpProgram(x.shape, opSnippet); + } + return webglBackend.runWebGLProgram(program, [x], $dtype); + }; + } + /** + * Template that creates a `KernelFunc` for binary ops. + * @param opSnippet Op snippet to create `BinaryOpProgram`. + * @param packedOpSnippet Op snippet to create `BinaryOpPackedProgram`. + * @param checkOutOfBoundsForPackedProgram Whether to set checkOutOfBounds=true + * when creating BinaryOpPackedProgram. + * @param dtype Optional. If set, the result has this dtype. Otherwise, the + * result has the same dtype as the first input. This is mainly used in + * comparison kernels, such as Equal, Less, Greater, etc. + */ + function binaryKernelFunc({ opSnippet, packedOpSnippet, checkOutOfBounds = false, supportsComplex = false, cpuKernelImpl, dtype }) { + return ({ inputs, backend }) => { + const { a, b } = inputs; + const webglBackend = backend; + if (supportsComplex && a.dtype === 'complex64') { + const aData = webglBackend.texData.get(a.dataId); + const bData = webglBackend.texData.get(b.dataId); + const [real, imag] = [ + [aData.complexTensorInfos.real, bData.complexTensorInfos.real], + [aData.complexTensorInfos.imag, bData.complexTensorInfos.imag] + ].map(complexParts => { + const [aPart, bPart] = complexParts; + const aHandle = { + dataId: aPart.dataId, + dtype: aPart.dtype, + shape: a.shape + }; + const bHandle = { + dataId: bPart.dataId, + dtype: bPart.dtype, + shape: b.shape + }; + const program = new BinaryOpProgram(opSnippet, a.shape, b.shape); + return webglBackend.runWebGLProgram(program, [aHandle, bHandle], upcastType(aPart.dtype, bPart.dtype)); + }); + const complexOutput = complex({ inputs: { real, imag }, backend: webglBackend }); + webglBackend.disposeIntermediateTensorInfo(real); + webglBackend.disposeIntermediateTensorInfo(imag); + // TODO(annxingyuan): Implement CPU forwarding for complex inputs. + return complexOutput; + } + const $dtype = dtype || upcastType(a.dtype, b.dtype); + if ((a.dtype === 'string' || b.dtype === 'string' || + webglBackend.shouldExecuteOnCPU([a, b])) && + cpuKernelImpl != null) { + const aVals = webglBackend.texData.get(a.dataId).values; + const bVals = webglBackend.texData.get(b.dataId).values; + const decodedAVals = a.dtype === 'string' ? + // tslint:disable-next-line: no-any + fromUint8ToStringArray(aVals) : + aVals; + const decodedBVals = a.dtype === 'string' ? + // tslint:disable-next-line: no-any + fromUint8ToStringArray(bVals) : + bVals; + const [outValues, outShape] = cpuKernelImpl(a.shape, b.shape, decodedAVals, decodedBVals, $dtype); + const out = webglBackend.makeTensorInfo(outShape, $dtype); + const outData = webglBackend.texData.get(out.dataId); + outData.values = outValues; + return out; + } + const shouldUsePackedProgram = env().getBool('WEBGL_PACK_BINARY_OPERATIONS') && + packedOpSnippet != null; + let program; + if (shouldUsePackedProgram) { + program = new BinaryOpPackedProgram(packedOpSnippet, a.shape, b.shape, checkOutOfBounds); + } + else { + program = new BinaryOpProgram(opSnippet, a.shape, b.shape); + } + return webglBackend.runWebGLProgram(program, [a, b], $dtype); + }; + } + function mapActivationToShaderProgram(activation, packed = false) { + if (activation === 'linear') { + if (packed) { + return LINEAR; + } + return LINEAR$1; + } + else if (activation === 'relu') { + if (packed) { + return RELU$1; + } + return RELU$2; + } + else if (activation === 'elu') { + if (packed) { + return ELU$1; + } + return ELU$2; + } + else if (activation === 'relu6') { + if (packed) { + return RELU6$1; + } + return RELU6$2; + } + else if (activation === 'prelu') { + if (packed) { + return PRELU_PACKED; + } + return PRELU; + } + else if (activation === 'leakyrelu') { + if (packed) { + return LEAKYRELU_PACKED; + } + return LEAKYRELU; + } + else if (activation === 'sigmoid') { + if (packed) { + return SIGMOID$1; + } + return SIGMOID$2; + } + throw new Error(`Activation ${activation} has not been implemented for the WebGL backend.`); + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class MatMulPackedProgram { + constructor(aShape, bShape, outputShape, transposeA = false, transposeB = false, addBias = false, activation = null, hasPreluActivation = false, hasLeakyreluActivation = false) { + this.variableNames = ['matrixA', 'matrixB']; + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = outputShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + const sharedDim = transposeA ? aShape[1] : aShape[2]; + const sharedDimensionPacked = Math.ceil(sharedDim / 2); + const aSample = transposeA ? 'i * 2, rc.y' : 'rc.y, i * 2'; + const bSample = transposeB ? 'rc.z, i * 2' : 'i * 2, rc.z'; + const aSwizzle = transposeA ? ['a.xxyy', 'a.zzww'] : ['a.xxzz', 'a.yyww']; + const bSwizzle = transposeB ? ['b.xzxz', 'b.ywyw'] : ['b.xyxy', 'b.zwzw']; + let activationSnippet = '', applyActivationSnippet = ''; + if (activation) { + if (hasPreluActivation) { + activationSnippet = `vec4 activation(vec4 a) { + vec4 b = getPreluActivationWeightsAtOutCoords(); + ${activation} + }`; + } + else if (hasLeakyreluActivation) { + activationSnippet = `vec4 activation(vec4 a) { + vec4 b = getLeakyreluAlphaAtOutCoords(); + ${activation} + }`; + } + else { + activationSnippet = `vec4 activation(vec4 x) { + ${activation} + }`; + } + applyActivationSnippet = `result = activation(result);`; + } + const addBiasSnippet = addBias ? 'result += getBiasAtOutCoords();' : ''; + if (addBias) { + this.variableNames.push('bias'); + } + if (hasPreluActivation) { + this.variableNames.push('preluActivationWeights'); + } + if (hasLeakyreluActivation) { + this.variableNames.push('leakyreluAlpha'); + } + let batchASnippet = 'rc.x'; + let batchBSnippet = 'rc.x'; + if (aShape[0] < bShape[0]) { + batchASnippet = `imod(rc.x, ${aShape[0]})`; + } + else if (bShape[0] < aShape[0]) { + batchBSnippet = `imod(rc.x, ${bShape[0]})`; + } + this.userCode = ` + ${activationSnippet} + // Don't use uniform for sharedDimensionPacked for performance. + const float sharedDimension = ${sharedDimensionPacked}.0; + + vec4 dot2x2ARowBCol(ivec3 rc) { + vec4 result = vec4(0); + int batchA = ${batchASnippet}; + int batchB = ${batchBSnippet}; + for (int i = 0; i < ${sharedDimensionPacked}; i++) { + vec4 a = getMatrixA(batchA, ${aSample}); + vec4 b = getMatrixB(batchB, ${bSample}); + + // These swizzled products need to be separately added. + // See: https://github.com/tensorflow/tfjs/issues/1735 + result += (${aSwizzle[0]} * ${bSwizzle[0]}); + result += (${aSwizzle[1]} * ${bSwizzle[1]}); + } + return result; + } + + void main() { + ivec3 rc = getOutputCoords(); + vec4 result = dot2x2ARowBCol(rc); + + ${addBiasSnippet} + + ${applyActivationSnippet} + + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // (Ar + Ai)(Br + Bi) = + // ArBr + ArBi + AiBr + AiBi = ArBr - AB + ArBi + AiBr + // Yr = ArBr - AB + // Yi = ArBi + AiBr + const COMPLEX_MULTIPLY = { + REAL: 'return areal * breal - aimag * bimag;', + IMAG: 'return areal * bimag + aimag * breal;' + }; + class BinaryOpComplexProgram { + constructor(op, aShape, bShape) { + this.variableNames = ['AReal', 'AImag', 'BReal', 'BImag']; + this.outputShape = assertAndGetBroadcastShape(aShape, bShape); + this.userCode = ` + float binaryOpComplex( + float areal, float aimag, float breal, float bimag) { + ${op} + } + + void main() { + float areal = getARealAtOutCoords(); + float aimag = getAImagAtOutCoords(); + float breal = getBRealAtOutCoords(); + float bimag = getBImagAtOutCoords(); + setOutput(binaryOpComplex(areal, aimag, breal, bimag)); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const MUL = 'return a * b;'; + function multiply(args) { + const { inputs, backend } = args; + const { a, b } = inputs; + const dtype = upcastType(a.dtype, b.dtype); + if (a.dtype === 'complex64') { + const aData = backend.texData.get(a.dataId); + const bData = backend.texData.get(b.dataId); + const realProgram = new BinaryOpComplexProgram(COMPLEX_MULTIPLY.REAL, a.shape, b.shape); + const imagProgram = new BinaryOpComplexProgram(COMPLEX_MULTIPLY.IMAG, a.shape, b.shape); + const inputs = [ + { + dataId: aData.complexTensorInfos.real.dataId, + dtype: aData.complexTensorInfos.real.dtype, + shape: a.shape + }, + { + dataId: aData.complexTensorInfos.imag.dataId, + dtype: aData.complexTensorInfos.imag.dtype, + shape: a.shape + }, + { + dataId: bData.complexTensorInfos.real.dataId, + dtype: bData.complexTensorInfos.real.dtype, + shape: b.shape + }, + { + dataId: bData.complexTensorInfos.imag.dataId, + dtype: bData.complexTensorInfos.imag.dtype, + shape: b.shape + } + ]; + const realPart = backend.runWebGLProgram(realProgram, inputs, 'float32'); + const imagPart = backend.runWebGLProgram(imagProgram, inputs, 'float32'); + const complexOutput = complex({ inputs: { real: realPart, imag: imagPart }, backend }); + backend.disposeIntermediateTensorInfo(realPart); + backend.disposeIntermediateTensorInfo(imagPart); + // TODO(annxingyuan): CPU forwarding for complex inputs. + return complexOutput; + } + if (backend.shouldExecuteOnCPU([a, b])) { + const aData = backend.texData.get(a.dataId); + const bData = backend.texData.get(b.dataId); + const [outValues, outShape] = multiplyImplCPU(a.shape, b.shape, aData.values, bData.values, dtype); + const out = backend.makeTensorInfo(outShape, dtype); + const outData = backend.texData.get(out.dataId); + outData.values = outValues; + return out; + } + let program; + if (env().getBool('WEBGL_PACK_BINARY_OPERATIONS')) { + program = new BinaryOpPackedProgram(MUL, a.shape, b.shape); + } + else { + program = new BinaryOpProgram(MUL, a.shape, b.shape); + } + return backend.runWebGLProgram(program, [a, b], dtype); + } + const multiplyConfig = { + kernelName: Multiply$1, + backendName: 'webgl', + kernelFunc: multiply + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function packedReshape(input, afterShape, backend) { + const input3DShape = [getBatchDim(input.shape), + ...getRowsCols(input.shape)]; + const input3D = { + dtype: input.dtype, + shape: input3DShape, + dataId: input.dataId + }; + const afterShapeAs3D = [getBatchDim(afterShape), + ...getRowsCols(afterShape)]; + const program = new ReshapePackedProgram(afterShapeAs3D, input3DShape); + const preventEagerUnpackingOfOutput = true; + const customValues = [input3DShape]; + const output = backend.runWebGLProgram(program, [input3D], input.dtype, customValues, preventEagerUnpackingOfOutput); + return { dataId: output.dataId, shape: afterShape, dtype: output.dtype }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function reshape(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { shape } = attrs; + const webglBackend = backend; + const xSize = sizeFromShape(x.shape); + const $shape = inferFromImplicitShape(shape, xSize); + const $xSize = sizeFromShape($shape); + assert$1(xSize === $xSize, () => `The new shape (${$shape}) has ${$xSize} elements and the old ` + + `shape (${x.shape}) has ${xSize} elements. The new shape and old ` + + `shape must have the same number of elements.`); + const xTexData = webglBackend.texData.get(x.dataId); + if (xTexData.isPacked && !isReshapeFree(x.shape, $shape) && + !(xTexData.texture !== null && isReshapeFree(xTexData.shape, $shape))) { + return packedReshape(x, $shape, webglBackend); + } + webglBackend.incRef(x.dataId); + return { dataId: x.dataId, shape: $shape, dtype: x.dtype }; + } + const reshapeConfig = { + kernelName: Reshape$1, + backendName: 'webgl', + kernelFunc: reshape + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class MeanProgram { + constructor(reduceInfo, divisor) { + this.variableNames = ['x']; + const { windowSize, batchSize, inSize, outSize } = reduceInfo; + this.outputShape = [batchSize, outSize]; + const windowSizeNearestVec4 = Math.floor(windowSize / 4) * 4; + const windowSizeVec4Remainder = windowSize % 4; + let updateSnippet = `sumValue += dot(values, ones);`; + if (divisor != null) { + const denominator = 1 / divisor; + updateSnippet = `sumValue += dot(values * ${isInt(denominator) ? denominator.toPrecision(2) : + denominator}, ones);`; + } + let checkOutOfBounds = ''; + if (inSize % windowSize > 0) { + checkOutOfBounds = ` + if (inIdx < 0 || inIdx >= ${inSize}) { + return 0.0; + } + `; + } + this.userCode = ` + const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0); + + float getValue(int batch, int inIdx) { + ${checkOutOfBounds} + return getX(batch, inIdx); + } + + void main() { + ivec2 coords = getOutputCoords(); + int batch = coords[0]; + int outIdx = coords[1]; + int inOffset = outIdx * ${windowSize}; + + float sumValue = 0.0; + + for (int i = 0; i < ${windowSizeNearestVec4}; i += 4) { + int inIdx = inOffset + i; + vec4 values = vec4( + getValue(batch, inIdx), + getValue(batch, inIdx + 1), + getValue(batch, inIdx + 2), + getValue(batch, inIdx + 3) + ); + + ${updateSnippet} + } + + int inIdx = inOffset + ${windowSizeNearestVec4}; + if (${windowSizeVec4Remainder === 1}) { + vec4 values = vec4(getValue(batch, inIdx), 0.0, 0.0, 0.0); + + ${updateSnippet} + } else if (${windowSizeVec4Remainder === 2}) { + vec4 values = vec4( + getValue(batch, inIdx), + getValue(batch, inIdx + 1), 0.0, 0.0); + + ${updateSnippet} + } else if (${windowSizeVec4Remainder === 3}) { + vec4 values = vec4( + getValue(batch, inIdx), + getValue(batch, inIdx + 1), + getValue(batch, inIdx + 2), 0.0); + + ${updateSnippet} + } + setOutput(sumValue); + } + `; + } + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ReduceProgram { + constructor(reduceInfo, reduceType) { + this.variableNames = ['x']; + const { windowSize, batchSize, inSize, outSize } = reduceInfo; + this.outputShape = [batchSize, outSize]; + let initializationValue = '0.0'; + let compareOp = ``; + if (reduceType === 'prod') { + initializationValue = '1.0'; + } + else if (reduceType === 'min') { + // WebGL on Firefox Linux can't compile 1/0 so we do 1/eps. + initializationValue = '1.0 / 1e-20'; + compareOp = `min`; + } + else if (reduceType === 'max') { + // WebGL on Firefox Linux can't compile 1/0 so we do 1/eps. + initializationValue = '-1.0 / 1e-20'; + compareOp = `max`; + } + let returnValue = `${reduceType}(${reduceType}(${reduceType}(` + + 'minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])'; + if (reduceType === 'sum') { + returnValue = `sumValue`; + } + else if (reduceType === 'prod') { + returnValue = `prodValue`; + } + else if (reduceType === 'all') { + returnValue = `allValue`; + } + else if (reduceType === 'any') { + returnValue = `anyValue`; + } + const windowSizeNearestVec4 = Math.floor(windowSize / 4) * 4; + const windowSizeVec4Remainder = windowSize % 4; + let updateSnippet = ` + if (${reduceType === 'sum'}) { + sumValue += dot(values, ones); + } else if (${reduceType === 'prod'}) { + vec2 tmp = vec2(values[0], values[1]) * vec2(values[2], values[3]); + prodValue *= tmp[0] * tmp[1]; + } else { + minMaxValue = ${compareOp}(values, minMaxValue); + if (${reduceType === 'min'} || ${reduceType === 'max'}) { + minMaxValue = ${compareOp}(values, minMaxValue); + bvec4 isNaN = isnan(values); + if (isNaN.r || isNaN.g || isNaN.b || isNaN.a) { + minMaxValue = vec4(NAN); + } + } + } + `; + let vecType = `vec4`; + if (reduceType === 'all') { + initializationValue = '1.0'; + updateSnippet = ` + bool reducedAllValue = all(values); + float floatedReducedAllValue = float(reducedAllValue); + allValue = float(allValue >= 1.0 && floatedReducedAllValue >= 1.0); + `; + vecType = `bvec4`; + } + else if (reduceType === 'any') { + initializationValue = '0.0'; + updateSnippet = ` + bool reducedAnyValue = any(values); + float floatedReducedAnyValue = float(reducedAnyValue); + anyValue = float(anyValue >= 1.0 || floatedReducedAnyValue >= 1.0); + `; + vecType = `bvec4`; + } + let checkOutOfBounds = ''; + if (inSize % windowSize > 0) { + checkOutOfBounds = ` + if (inIdx < 0 || inIdx >= ${inSize}) { + return initializationValue; + } + `; + } + this.userCode = ` + const float initializationValue = ${initializationValue}; + const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0); + + float getValue(int batch, int inIdx) { + ${checkOutOfBounds} + return getX(batch, inIdx); + } + + void main() { + ivec2 coords = getOutputCoords(); + int batch = coords[0]; + int outIdx = coords[1]; + int inOffset = outIdx * ${windowSize}; + + vec4 minMaxValue = vec4(${initializationValue}); + float prodValue = 1.0; + float sumValue = 0.0; + float allValue = 1.0; + float anyValue = 0.0; + + for (int i = 0; i < ${windowSizeNearestVec4}; i += 4) { + int inIdx = inOffset + i; + ${vecType} values = ${vecType}( + getValue(batch, inIdx), + getValue(batch, inIdx + 1), + getValue(batch, inIdx + 2), + getValue(batch, inIdx + 3) + ); + + ${updateSnippet} + } + + int inIdx = inOffset + ${windowSizeNearestVec4}; + if (${windowSizeVec4Remainder === 1}) { + ${vecType} values = ${vecType}( + getValue(batch, inIdx), + initializationValue, + initializationValue, + initializationValue + ); + + ${updateSnippet} + } else if (${windowSizeVec4Remainder === 2}) { + ${vecType} values = ${vecType}( + getValue(batch, inIdx), + getValue(batch, inIdx + 1), + initializationValue, + initializationValue + ); + + ${updateSnippet} + } else if (${windowSizeVec4Remainder === 3}) { + ${vecType} values = ${vecType}( + getValue(batch, inIdx), + getValue(batch, inIdx + 1), + getValue(batch, inIdx + 2), + initializationValue + ); + + ${updateSnippet} + } + setOutput(${returnValue}); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Returns an array of configuration objects that describe each stage of the + // reduction. + function getReductionStages(inShape) { + const stages = []; + while (stages.length === 0 || stages[stages.length - 1].outSize !== 1) { + const outSize = stages.length ? stages[stages.length - 1].outSize : inShape[1]; + const windowSize = computeOptimalWindowSize(outSize); + stages.push({ + inSize: outSize, + windowSize, + outSize: Math.ceil(outSize / windowSize) + }); + } + return stages; + } + function reduce(x, dtype, reductionType, backend) { + const reductionStages = getReductionStages(x.shape); + let result = x; + for (let i = 0; i < reductionStages.length; i++) { + const { inSize, windowSize, outSize } = reductionStages[i]; + let program; + let previousResult; + if (reductionType === 'mean') { + program = i === 0 ? + new MeanProgram({ windowSize, inSize, batchSize: x.shape[0], outSize }, inSize) : + new MeanProgram({ windowSize, inSize, batchSize: x.shape[0], outSize }); + } + else { + program = new ReduceProgram({ windowSize, inSize, batchSize: x.shape[0], outSize }, reductionType); + } + previousResult = result; + result = backend.runWebGLProgram(program, [result], dtype); + if (previousResult.dataId !== x.dataId) { + backend.disposeIntermediateTensorInfo(previousResult); + } + } + return result; + } + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class TransposeProgram { + constructor(aShape, newDim) { + this.variableNames = ['A']; + const outputShape = new Array(aShape.length); + for (let i = 0; i < outputShape.length; i++) { + outputShape[i] = aShape[newDim[i]]; + } + this.outputShape = outputShape; + this.rank = outputShape.length; + const dtype = getCoordsDataType(this.rank); + const switched = getSwitchedCoords(newDim); + this.userCode = ` + void main() { + ${dtype} resRC = getOutputCoords(); + setOutput(getA(${switched})); + } + `; + } + } + function getSwitchedCoords(newDim) { + const rank = newDim.length; + if (rank > 6) { + throw Error(`Transpose for rank ${rank} is not yet supported`); + } + const originalOrder = ['resRC.x', 'resRC.y', 'resRC.z', 'resRC.w', 'resRC.u', 'resRC.v']; + const switchedCoords = new Array(rank); + for (let i = 0; i < newDim.length; i++) { + switchedCoords[newDim[i]] = originalOrder[i]; + } + return switchedCoords.join(); + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class TransposePackedProgram { + constructor(aShape, newDim) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = true; + const outputShape = new Array(aShape.length); + for (let i = 0; i < outputShape.length; i++) { + outputShape[i] = aShape[newDim[i]]; + } + this.outputShape = outputShape; + this.rank = outputShape.length; + if (this.rank > 6) { + throw Error(`Packed transpose for rank ${this.rank} is not yet supported.`); + } + const dtype = getCoordsDataType(this.rank); + const outputOrder = getVecChannels('rc', this.rank); + const switchedOrder = new Array(this.rank); + for (let i = 0; i < newDim.length; i++) { + switchedOrder[newDim[i]] = outputOrder[i]; + } + const innerDims = `vec2(${switchedOrder.slice(-2).join()})`; + const nextColumn = `++${outputOrder[this.rank - 1]} < ${outputShape[this.rank - 1]}`; + const getc = `getChannel(getA(${switchedOrder.join()}), ${innerDims})`; + this.userCode = ` + void main() { + ${dtype} rc = getOutputCoords(); + vec4 result = vec4(0.); + result[0] = ${getc}; + if(${nextColumn}) { + result[1] = ${getc}; + } + --${outputOrder[this.rank - 1]}; + if(++${outputOrder[this.rank - 2]} < ${outputShape[this.rank - 2]}) { + result[2] = ${getc}; + if(${nextColumn}) { + result[3] = ${getc}; + } + } + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function transposeImpl(x, perm, backend) { + const program = env().getBool('WEBGL_PACK_ARRAY_OPERATIONS') ? + new TransposePackedProgram(x.shape, perm) : + new TransposeProgram(x.shape, perm); + return backend.runWebGLProgram(program, [x], x.dtype); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sumImpl(x, axis, keepDims, backend) { + const reductionIndices = axis; + const xRank = x.shape.length; + const origAxes = parseAxisParam(reductionIndices, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, xRank); + const sumInputIsTransposed = permutedAxes != null; + let sumInput = x; + if (sumInputIsTransposed) { + sumInput = transposeImpl(x, permutedAxes, backend); + axes = getInnerMostAxes(axes.length, xRank); + } + assertAxesAreInnerMostDims('sum', axes, xRank); + const [sumOutShape, reduceShape] = computeOutAndReduceShapes(sumInput.shape, axes); + let outShape = sumOutShape; + if (keepDims) { + // rather than reshape at the end, set the target shape here. + outShape = expandShapeToKeepDim(sumOutShape, origAxes); + } + const inSize = sizeFromShape(reduceShape); + const xSize = sizeFromShape(x.shape); + const batchSize = xSize / inSize; + const reshapedInput = reshape({ inputs: { x: sumInput }, attrs: { shape: [batchSize, inSize] }, backend }); + const outType = sumOutType(x.dtype); + const reduced = reduce(reshapedInput, outType, 'sum', backend); + const out = reshape({ inputs: { x: reduced }, attrs: { shape: outShape }, backend }); + backend.disposeIntermediateTensorInfo(reshapedInput); + backend.disposeIntermediateTensorInfo(reduced); + if (sumInputIsTransposed) { + backend.disposeIntermediateTensorInfo(sumInput); + } + return out; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sum(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + return sumImpl(x, axis, keepDims, backend); + } + const sumConfig = { + kernelName: Sum, + backendName: 'webgl', + kernelFunc: sum + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function transpose(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { perm } = attrs; + const webglBackend = backend; + const xRank = x.shape.length; + const newShape = new Array(xRank); + for (let i = 0; i < newShape.length; i++) { + newShape[i] = x.shape[perm[i]]; + } + let out; + if (webglBackend.shouldExecuteOnCPU([x])) { + const xTexData = webglBackend.texData.get(x.dataId); + const values = xTexData.values; + const outValues = transposeImplCPU(values, x.shape, x.dtype, perm, newShape); + out = webglBackend.makeTensorInfo(newShape, x.dtype); + const outData = webglBackend.texData.get(out.dataId); + outData.values = outValues; + } + else { + out = transposeImpl(x, perm, webglBackend); + } + return out; + } + const transposeConfig = { + kernelName: Transpose, + backendName: 'webgl', + kernelFunc: transpose + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Empirically determined minimal shared dimension in matmul before we forward + // to a.mul(b).sum() in order to take advantage of GPU parallelism. See + // https://github.com/tensorflow/tfjs-core/pull/1379 for benchmarks. + const MATMUL_SHARED_DIM_THRESHOLD = 1000; + function batchMatMulImpl({ a, b, transposeA, transposeB, backend, bias = null, preluActivationWeights = null, leakyreluAlpha = 0, activation = null }) { + const aRank = a.shape.length; + const bRank = b.shape.length; + const innerShapeA = transposeA ? a.shape[aRank - 2] : a.shape[aRank - 1]; + const innerShapeB = transposeB ? b.shape[bRank - 1] : b.shape[bRank - 2]; + const outerShapeA = transposeA ? a.shape[aRank - 1] : a.shape[aRank - 2]; + const outerShapeB = transposeB ? b.shape[bRank - 2] : b.shape[bRank - 1]; + const outerDimsA = a.shape.slice(0, -2); + const outerDimsB = b.shape.slice(0, -2); + const batchDimA = sizeFromShape(outerDimsA); + const batchDimB = sizeFromShape(outerDimsB); + const outShapeOuterDims = assertAndGetBroadcastShape(a.shape.slice(0, -2), b.shape.slice(0, -2)); + const outShape = outShapeOuterDims.concat([outerShapeA, outerShapeB]); + assert$1(innerShapeA === innerShapeB, () => `Error in matMul: inner shapes (${innerShapeA}) and (` + + `${innerShapeB}) of Tensors with shapes ${a.shape} and ` + + `${b.shape} and transposeA=${transposeA}` + + ` and transposeB=${transposeB} must match.`); + const a3dShape = transposeA ? + [batchDimA, innerShapeA, outerShapeA] : + [batchDimA, outerShapeA, innerShapeA]; + const b3dShape = transposeB ? + [batchDimB, outerShapeB, innerShapeB] : + [batchDimB, innerShapeB, outerShapeB]; + // The rest of the implementation is designed to operate on rank-3 tensors + const a3d = reshape({ inputs: { x: a }, backend, attrs: { shape: a3dShape } }); + const b3d = reshape({ inputs: { x: b }, backend, attrs: { shape: b3dShape } }); + const intermediates = [a3d, b3d]; + const batchDim = Math.max(batchDimA, batchDimB); + const sharedDim = transposeA ? a3d.shape[1] : a3d.shape[2]; + const hasBias = bias != null; + const hasPreluActivationWeights = preluActivationWeights != null; + const hasLeakyreluAlpha = activation === 'leakyrelu'; + const fusedActivation = activation != null ? + mapActivationToShaderProgram(activation, true) : + null; + const containsFusedOps = hasBias || hasPreluActivationWeights || + hasLeakyreluAlpha || fusedActivation != null; + let out; + // Since the matrices are vectors, it is faster to call mul().sum() + // because sum() is O(sqrt(N)) due to divide-and-conquer. + if ((outerShapeA === 1 || outerShapeB === 1) && + sharedDim > MATMUL_SHARED_DIM_THRESHOLD && containsFusedOps === false) { + let aVec = a3d; + let bVec = b3d; + if (transposeA) { + aVec = transpose({ inputs: { x: a3d }, backend, attrs: { perm: [0, 2, 1] } }); + intermediates.push(aVec); + } + if (transposeB) { + bVec = transpose({ inputs: { x: b3d }, backend, attrs: { perm: [0, 2, 1] } }); + intermediates.push(bVec); + } + const shouldReshapeA = outerShapeB !== 1; + const shouldReshapeB = outerShapeB === 1; + let aVec3d = aVec; + if (shouldReshapeA) { + aVec3d = reshape({ + inputs: { x: aVec }, + backend, + attrs: { shape: [batchDim, sharedDim, 1] } + }); + intermediates.push(aVec3d); + } + const axis = outerShapeB === 1 ? 2 : 1; + let bVec3d = bVec; + if (shouldReshapeB) { + bVec3d = reshape({ + inputs: { x: bVec }, + backend, + attrs: { shape: [batchDim, 1, sharedDim] } + }); + intermediates.push(bVec3d); + } + const product = multiply({ inputs: { a: aVec3d, b: bVec3d }, backend }); + out = sum({ inputs: { x: product }, backend, attrs: { axis, keepDims: true } }); + intermediates.push(product); + } + else { + const dtype = upcastType(a.dtype, b.dtype); + const program = new MatMulPackedProgram(a3dShape, b3dShape, [batchDim, outerShapeA, outerShapeB], transposeA, transposeB, hasBias, fusedActivation, hasPreluActivationWeights, hasLeakyreluAlpha); + const inputs = [a3d, b3d]; + if (bias != null) { + inputs.push(bias); + } + if (hasPreluActivationWeights) { + inputs.push(preluActivationWeights); + } + if (hasLeakyreluAlpha) { + const $leakyreluAlpha = backend.makeTensorInfo([], 'float32', createScalarValue(leakyreluAlpha, 'float32')); + inputs.push($leakyreluAlpha); + intermediates.push($leakyreluAlpha); + } + out = backend.runWebGLProgram(program, inputs, dtype); + } + const outReshaped = reshape({ inputs: { x: out }, backend, attrs: { shape: outShape } }); + intermediates.push(out); + for (const i of intermediates) { + backend.disposeIntermediateTensorInfo(i); + } + return outReshaped; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function _fusedMatMul(args) { + const { inputs, backend, attrs } = args; + const { a, b, bias, preluActivationWeights } = inputs; + const { transposeA, transposeB, activation, leakyreluAlpha } = attrs; + return batchMatMulImpl({ + a, + b, + transposeA, + transposeB, + backend, + bias, + preluActivationWeights, + leakyreluAlpha, + activation + }); + } + const _fusedMatMulConfig = { + kernelName: _FusedMatMul, + backendName: 'webgl', + kernelFunc: _fusedMatMul, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ABS = `return abs(x);`; + function abs(args) { + const { inputs, backend } = args; + const { x } = inputs; + // TODO: handle cases when x is complex. Once the cpu implementation + // can handle complex values, refactor to use unaryKernelFunc. + if (backend.shouldExecuteOnCPU([x]) && x.dtype !== 'complex64') { + const xData = backend.texData.get(x.dataId); + const outValues = simpleAbsImplCPU(xData.values); + return backend.makeTensorInfo(x.shape, x.dtype, outValues); + } + let program; + if (env().getBool('WEBGL_PACK_UNARY_OPERATIONS')) { + program = new UnaryOpPackedProgram(x.shape, ABS); + } + else { + program = new UnaryOpProgram(x.shape, ABS); + } + return backend.runWebGLProgram(program, [x], x.dtype); + } + const absConfig = { + kernelName: Abs, + backendName: 'webgl', + kernelFunc: abs + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ACOS = CHECK_NAN_SNIPPET$1 + ` + if (abs(x) > 1.) { + return NAN; + } + return acos(x); +`; + const acos = unaryKernelFunc({ opSnippet: ACOS }); + const acosConfig = { + kernelName: Acos, + backendName: 'webgl', + kernelFunc: acos, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ACOSH = CHECK_NAN_SNIPPET$1 + ` + if (x < 1.0) return NAN; +return log(x + sqrt(x * x - 1.0));`; + const acosh = unaryKernelFunc({ opSnippet: ACOSH }); + const acoshConfig = { + kernelName: Acosh, + backendName: 'webgl', + kernelFunc: acosh, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ADD = 'return a + b;'; + const addKernelFunc = binaryKernelFunc({ + opSnippet: ADD, + packedOpSnippet: ADD, + supportsComplex: true, + cpuKernelImpl: addImplCPU + }); + const addConfig = { + kernelName: Add$1, + backendName: 'webgl', + kernelFunc: addKernelFunc + }; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class AddNProgram { + constructor(outputShape, shapes) { + this.outputShape = []; + this.outputShape = outputShape; + this.variableNames = shapes.map((_, i) => `T${i}`); + const snippets = []; + // Get target elements from every input tensor. + this.variableNames.forEach(variable => { + snippets.push(`float v${variable} = get${variable}AtOutCoords();`); + }); + // Calculate the sum of all elements. + const operation = this.variableNames + .map(variable => { + return `v${variable}`; + }) + .join(' + '); + this.userCode = ` + void main() { + ${snippets.join('\n ')} + + float result = ${operation}; + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class AddNPackedProgram { + constructor(outputShape, shapes) { + this.outputShape = []; + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = outputShape; + this.variableNames = shapes.map((_, i) => `T${i}`); + const snippets = []; + // Get target elements from every input tensor. + this.variableNames.forEach(variable => { + snippets.push(`vec4 v${variable} = get${variable}AtOutCoords();`); + }); + // Calculate the sum of all elements. + const operation = this.variableNames + .map(variable => { + return `v${variable}`; + }) + .join(' + '); + this.userCode = ` + void main() { + ${snippets.join('\n ')} + + vec4 result = ${operation}; + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function addN(args) { + const { inputs, backend } = args; + const tensors = inputs; + if (tensors.length === 1) { + return identity({ inputs: { x: tensors[0] }, backend }); + } + // Limit the number of uploaded textures for optimization. + if (tensors.length > env().getNumber('WEBGL_MAX_TEXTURES_IN_SHADER')) { + const midIndex = Math.floor(tensors.length / 2); + const leftSide = addN({ inputs: tensors.slice(0, midIndex), backend }); + const rightSide = addN({ inputs: tensors.slice(midIndex), backend }); + return addN({ inputs: [leftSide, rightSide], backend }); + } + const dtype = tensors.map(t => t.dtype).reduce((d1, d2) => upcastType(d1, d2)); + const shapes = tensors.map(t => t.shape); + // We can make sure shapes are identical in op level. + const usePackedOp = env().getBool('WEBGL_PACK'); + const program = usePackedOp ? + new AddNPackedProgram(tensors[0].shape, shapes) : + new AddNProgram(tensors[0].shape, shapes); + return backend.runWebGLProgram(program, tensors, dtype); + } + const addNConfig = { + kernelName: AddN, + backendName: 'webgl', + kernelFunc: addN + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function all(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + const xRank = x.shape.length; + const origAxes = parseAxisParam(axis, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, xRank); + let permutedX = x; + if (permutedAxes != null) { + permutedX = transpose({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + axes = getInnerMostAxes(axes.length, xRank); + } + assertAxesAreInnerMostDims('all', axes, xRank); + const [outShape, reduceShape] = computeOutAndReduceShapes(permutedX.shape, axes); + const inSize = sizeFromShape(reduceShape); + const a2D = reshape({ inputs: { x: permutedX }, backend, attrs: { shape: [-1, inSize] } }); + const reduced = reduce(a2D, a2D.dtype, 'all', backend); + let res; + if (keepDims) { + const newShape = expandShapeToKeepDim(outShape, origAxes); + res = reshape({ inputs: { x: reduced }, backend, attrs: { shape: newShape } }); + } + else { + res = reshape({ inputs: { x: reduced }, backend, attrs: { shape: outShape } }); + } + backend.disposeIntermediateTensorInfo(a2D); + backend.disposeIntermediateTensorInfo(reduced); + if (permutedAxes != null) { + backend.disposeIntermediateTensorInfo(permutedX); + } + return res; + } + const allConfig = { + kernelName: All, + backendName: 'webgl', + kernelFunc: all + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function any(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + const xRank = x.shape.length; + const origAxes = parseAxisParam(axis, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, xRank); + let permutedX = x; + if (permutedAxes != null) { + permutedX = transpose({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + axes = getInnerMostAxes(axes.length, xRank); + } + assertAxesAreInnerMostDims('any', axes, xRank); + const [outShape, reduceShape] = computeOutAndReduceShapes(permutedX.shape, axes); + const inSize = sizeFromShape(reduceShape); + const a2D = reshape({ inputs: { x: permutedX }, backend, attrs: { shape: [-1, inSize] } }); + const reduced = reduce(a2D, a2D.dtype, 'any', backend); + let res; + if (keepDims) { + const newShape = expandShapeToKeepDim(outShape, origAxes); + res = reshape({ inputs: { x: reduced }, backend, attrs: { shape: newShape } }); + } + else { + res = reshape({ inputs: { x: reduced }, backend, attrs: { shape: outShape } }); + } + backend.disposeIntermediateTensorInfo(a2D); + backend.disposeIntermediateTensorInfo(reduced); + if (permutedAxes != null) { + backend.disposeIntermediateTensorInfo(permutedX); + } + return res; + } + const anyConfig = { + kernelName: Any, + backendName: 'webgl', + kernelFunc: any + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ArgMinMaxProgram { + constructor(reduceInfo, op, firstPass) { + this.variableNames = ['A']; + const { windowSize, batchSize, outSize } = reduceInfo; + if (!firstPass) { + this.variableNames.push('bestIndicesA'); + } + this.outputShape = [batchSize, outSize]; + const compOp = (op === 'max') ? '>' : '<'; + const indexSnippet = firstPass ? + 'inOffset + i;' : + 'round(getBestIndicesA(batch, inOffset + i));'; + this.userCode = ` + void main() { + ivec2 coords = getOutputCoords(); + int batch = coords[0]; + int outIdx = coords[1]; + int inOffset = outIdx * ${windowSize}; + + int bestIndex = inOffset; + float bestValue = getA(batch, bestIndex); + + for (int i = 0; i < ${windowSize}; i++) { + int inIdx = ${indexSnippet}; + float candidate = getA(batch, inIdx); + if (candidate ${compOp} bestValue) { + bestValue = candidate; + bestIndex = inIdx; + } + } + setOutput(float(bestIndex)); + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ArgMinMaxPackedProgram { + constructor(shape, windowSize, op, firstPass) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = true; + assert$1(shape.length > 2, () => `Packed arg${op.charAt(0).toUpperCase() + + op.slice(1)} supports only inputs with rank above 2.`); + const inSize = shape[shape.length - 1]; + const outSize = Math.ceil(inSize / windowSize); + this.outputShape = shape.slice(0, -1); + if (outSize > 1) { + this.outputShape.push(outSize); + } + if (!firstPass) { + this.variableNames.push('bestIndicesA'); + } + const outShape = this.outputShape; + const rank = outShape.length; + const dtype = getCoordsDataType(rank); + const coords = getChannels('coords', rank); + let sourceLocSetup; + let sourceRank; + if (outSize === 1) { + sourceRank = rank + 1; + const sourceLocDType = getCoordsDataType(sourceRank); + sourceLocSetup = ` + ${sourceLocDType} sourceLocR = ${sourceLocDType}(${coords.join()}, 0); + ++${coords[rank - 1]}; + ${sourceLocDType} sourceLocG = ${sourceLocDType}(${coords.join()}, 0); + ++${coords[rank - 2]}; + ${sourceLocDType} sourceLocA = ${sourceLocDType}(${coords.join()}, 0); + --${coords[rank - 1]}; + ${sourceLocDType} sourceLocB = ${sourceLocDType}(${coords.join()}, 0); + --${coords[rank - 2]};`; + } + else { + sourceRank = rank; + sourceLocSetup = ` + ${dtype} sourceLocR = coords; + ++${coords[rank - 1]}; + ${dtype} sourceLocG = coords; + ++${coords[rank - 2]}; + ${dtype} sourceLocA = coords; + --${coords[rank - 1]}; + ${dtype} sourceLocB = coords; + --${coords[rank - 2]};`; + } + const channels = ['x', 'y', 'z', 'w', 'u', 'v'].slice(0, sourceRank); + const inChannel = '.' + channels[sourceRank - 1]; // e.g. ".b" for rank 3. + const intChannels = channels.map(x => 'int ' + x); + const srcRCoords = getChannels('sourceLocR', sourceRank - 1).concat('inIdx.r'); + const srcGCoords = getChannels('sourceLocG', sourceRank - 1).concat('inIdx.g'); + const srcBCoords = getChannels('sourceLocB', sourceRank - 1).concat('inIdx.b'); + const srcACoords = getChannels('sourceLocA', sourceRank - 1).concat('inIdx.a'); + const compOp = (op === 'max') ? 'greaterThan' : 'lessThan'; + const fetchCandidateIdx = firstPass ? '' : ` + inIdx = round(vec4(getBestIndicesAChannel(${srcRCoords.join()}), + getBestIndicesAChannel(${srcGCoords.join()}), + getBestIndicesAChannel(${srcBCoords.join()}), + getBestIndicesAChannel(${srcACoords.join()})));`; + const fetchValue = `vec4( + getAChannel(${srcRCoords.join()}), + hasNextCol ? getAChannel(${srcGCoords.join()}) : 0., + hasNextRow ? getAChannel(${srcBCoords.join()}) : 0., + hasNextRow && hasNextCol ? getAChannel(${srcACoords.join()}) : 0.)`; + const getBestIndicesAChannelSnippet = firstPass ? '' : ` + float getBestIndicesAChannel(${intChannels.join()}) { + return getChannel(getBestIndicesA(${channels.join()}), + vec2(${channels.slice(-2).join()})); + }`; + this.userCode = ` + float getAChannel(${intChannels.join()}) { + return getChannel(getA(${channels.join()}), + vec2(${channels.slice(-2).join()})); + } + ${getBestIndicesAChannelSnippet} + void main() { + ${dtype} coords = getOutputCoords(); + bool hasNextCol = ${coords[rank - 1]} < ${outShape[rank - 1] - 1}; + bool hasNextRow = ${coords[rank - 2]} < ${outShape[rank - 2] - 1}; + ${sourceLocSetup} + ivec4 srcIdx = ivec4(sourceLocR${inChannel}, sourceLocG${inChannel}, + sourceLocB${inChannel}, sourceLocA${inChannel}) * ${windowSize}; + ivec4 inIdx = srcIdx; + vec4 bestIndex = vec4(inIdx); + vec4 bestValue = ${fetchValue}; + + for (int i = 0; i < ${windowSize}; i++) { + inIdx = srcIdx; + ${fetchCandidateIdx} + vec4 candidate = ${fetchValue}; + bvec4 nan = isnan(candidate); + bvec4 replace = bvec4( + vec4(${compOp}(candidate, bestValue)) * (vec4(1.0) - vec4(nan))); + + bestValue = vec4(replace.x ? candidate.x : bestValue.x, + replace.y ? candidate.y : bestValue.y, + replace.z ? candidate.z : bestValue.z, + replace.w ? candidate.w : bestValue.w); + bestIndex = mix(bestIndex, vec4(inIdx), vec4(replace)); + srcIdx++; + } + setOutput(bestIndex); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function argReduce(backend, x, reduceType, bestIndicesA = null) { + let batchSize = x.shape[0]; + let inSize = x.shape[1]; + if (bestIndicesA != null) { + batchSize = bestIndicesA.shape[0]; + inSize = bestIndicesA.shape[1]; + } + const windowSize = computeOptimalWindowSize(inSize); + const reduceInfo = { windowSize, inSize, batchSize, outSize: Math.ceil(inSize / windowSize) }; + const program = new ArgMinMaxProgram(reduceInfo, reduceType, bestIndicesA == null); + const inputs = [x]; + if (bestIndicesA != null) { + inputs.push(bestIndicesA); + } + const output = backend.runWebGLProgram(program, inputs, 'int32'); + // No need to run another GPGPU program. + if (output.shape[1] === 1) { + return output; + } + const result = argReduce(backend, x, reduceType, output); + backend.disposeIntermediateTensorInfo(output); + return result; + } + function argReducePacked(backend, x, reduceType, bestIndicesA = null) { + const inShape = bestIndicesA != null ? bestIndicesA.shape : x.shape; + const inSize = inShape[inShape.length - 1]; + const windowSize = computeOptimalWindowSize(inSize); + const program = new ArgMinMaxPackedProgram(inShape, windowSize, reduceType, bestIndicesA == null); + const inputs = bestIndicesA == null ? [x] : [x, bestIndicesA]; + const output = backend.runWebGLProgram(program, inputs, 'int32'); + if (output.shape.length === x.shape.length) { + const result = argReducePacked(backend, x, reduceType, output); + backend.disposeIntermediateTensorInfo(output); + return result; + } + return output; + } + function argMinMaxReduce(backend, x, axis, reduceType) { + const axes = [axis]; + assertAxesAreInnerMostDims('arg' + reduceType.charAt(0).toUpperCase() + reduceType.slice(1), axes, x.shape.length); + if (!env().getBool('WEBGL_PACK_REDUCE') || x.shape.length <= 2) { + const intermediateTensorInfos = []; + // Eagerly unpack x input since it is passed in to all the shaders which + // require unpacked inputs. + const xtexData = backend.texData.get(x.dataId); + const xIsPacked = xtexData !== null && xtexData.isPacked; + let xUnPacked = x; + if (xIsPacked) { + xUnPacked = backend.unpackTensor(x); + intermediateTensorInfos.push(xUnPacked); + } + const [outShape, reduceShape] = computeOutAndReduceShapes(xUnPacked.shape, axes); + const inSize = sizeFromShape(reduceShape); + const a2D = reshape({ inputs: { x: xUnPacked }, backend, attrs: { shape: [-1, inSize] } }); + intermediateTensorInfos.push(a2D); + const reduced = argReduce(backend, a2D, reduceType); + intermediateTensorInfos.push(reduced); + const reshaped = reshape({ inputs: { x: reduced }, backend, attrs: { shape: outShape } }); + intermediateTensorInfos.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return reshaped; + } + return argReducePacked(backend, x, reduceType); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function argMax(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis } = attrs; + let axes = parseAxisParam(axis, x.shape); + const permutedAxes = getAxesPermutation(axes, x.shape.length); + let $x = x; + const intermediateTensorInfos = []; + if (permutedAxes != null) { + $x = transpose({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + intermediateTensorInfos.push($x); + axes = getInnerMostAxes(axes.length, $x.shape.length); + } + assertAxesAreInnerMostDims('argMax', [axes[0]], $x.shape.length); + const out = argMinMaxReduce(backend, $x, axes[0], 'max'); + intermediateTensorInfos.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return out; + } + const argMaxConfig = { + kernelName: ArgMax, + backendName: 'webgl', + kernelFunc: argMax + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function argMin(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis } = attrs; + let axes = parseAxisParam(axis, x.shape); + const permutedAxes = getAxesPermutation(axes, x.shape.length); + let $x = x; + const intermediateTensorInfos = []; + if (permutedAxes != null) { + $x = transpose({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + intermediateTensorInfos.push($x); + axes = getInnerMostAxes(axes.length, $x.shape.length); + } + assertAxesAreInnerMostDims('argMin', [axes[0]], $x.shape.length); + const out = argMinMaxReduce(backend, $x, axes[0], 'min'); + intermediateTensorInfos.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return out; + } + const argMinConfig = { + kernelName: ArgMin, + backendName: 'webgl', + kernelFunc: argMin + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ASIN = CHECK_NAN_SNIPPET$1 + ` + if (abs(x) > 1.) { + return NAN; + } + return asin(x); +`; + const asin = unaryKernelFunc({ opSnippet: ASIN }); + const asinConfig = { + kernelName: Asin, + backendName: 'webgl', + kernelFunc: asin, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ASINH = CHECK_NAN_SNIPPET$1 + `return log(x + sqrt(x * x + 1.0));`; + const asinh = unaryKernelFunc({ opSnippet: ASINH }); + const asinhConfig = { + kernelName: Asinh, + backendName: 'webgl', + kernelFunc: asinh, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ATAN = CHECK_NAN_SNIPPET$1 + ` + return atan(x); +`; + const atan = unaryKernelFunc({ opSnippet: ATAN }); + const atanConfig = { + kernelName: Atan, + backendName: 'webgl', + kernelFunc: atan, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ATAN2 = CHECK_NAN_SNIPPET + ` + return atan(a, b); +`; + const ATAN2_PACKED = ` + vec4 result = atan(a, b); + bvec4 isNaNA = isnan(a); + bvec4 isNaNB = isnan(b); + bvec4 isNaN = bvec4(isNaNA.x || isNaNB.x, isNaNA.y || isNaNB.y, isNaNA.z || isNaNB.z, isNaNA.w || isNaNB.w); + ` + + CHECK_NAN_SNIPPET_PACKED + ` + return result; +`; + const atan2 = binaryKernelFunc({ opSnippet: ATAN2, packedOpSnippet: ATAN2_PACKED }); + const atan2Config = { + kernelName: Atan2, + backendName: 'webgl', + kernelFunc: atan2, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ATANH = CHECK_NAN_SNIPPET$1 + ` + if ((x < -1.0) || (x > 1.0)) return NAN; +return (log(1.0 + x) - log(1.0 - x)) / 2.0;`; + const atanh = unaryKernelFunc({ opSnippet: ATANH }); + const atanhConfig = { + kernelName: Atanh, + backendName: 'webgl', + kernelFunc: atanh, + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class Pool2DProgram { + constructor(convInfo, poolType, computePositions, flattenPositions = false, includeBatchInIndex = false) { + this.variableNames = ['x']; + if (poolType === 'avg' && computePositions) { + throw new Error('Cannot compute positions for average pool.'); + } + const filterWidth = convInfo.filterWidth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + this.outputShape = convInfo.outShape; + const isAvgPool = poolType === 'avg'; + const batchFlattenPositionStr = `((batch * ${convInfo.inHeight} + xR) * ${convInfo.inWidth} + xC) * ${convInfo.inChannels} + d`; + const flattenPositionStr = `(xR * ${convInfo.inWidth} + xC) * ${convInfo.inChannels} + d`; + let initializationValue = '0.0'; + if (!isAvgPool) { + // WebGL on Firefox Linux can't compile 1/0 so we do 1/eps. + initializationValue = '-1.0 / 1e-20'; + } + if (computePositions) { + const compareOp = '>='; + this.userCode = ` + const ivec2 strides = ivec2(${strideHeight}, ${strideWidth}); + const ivec2 pads = ivec2(${padTop}, ${padLeft}); + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords[0]; + int d = coords[3]; + + ivec2 xRCCorner = coords.yz * strides - pads; + int xRCorner = xRCCorner.x; + int xCCorner = xRCCorner.y; + + // max/min x(?, ?, d) to get y(yR, yC, d). + // ? = to be determined + float minMaxValue = 0.0; + float minMaxValueFound = 0.0; + int minMaxPosition = 0; + float avgValue = 0.0; + + for (int wR = 0; wR < ${effectiveFilterHeight}; + wR += ${dilationHeight}) { + int xR = xRCorner + wR; + + if (xR < 0 || xR >= ${convInfo.inHeight}) { + continue; + } + + for (int wC = 0; wC < ${effectiveFilterWidth}; + wC += ${dilationWidth}) { + int xC = xCCorner + wC; + + if (xC < 0 || xC >= ${convInfo.inWidth}) { + continue; + } + + float value = getX(batch, xR, xC, d); + + // If a min / max value has already been found, use it. If not, + // use the current value. + float currMinMaxValue = mix( + value, minMaxValue, minMaxValueFound); + if (value ${compareOp} currMinMaxValue) { + minMaxValue = value; + minMaxValueFound = 1.0; + minMaxPosition = ${flattenPositions ? (includeBatchInIndex ? batchFlattenPositionStr : + flattenPositionStr) : + `wR * ${effectiveFilterWidth} + wC`}; + } + } + } + setOutput(float(minMaxPosition)); + } + `; + return; + } + const compareOp = 'max'; + let returnValue = `${poolType}(${poolType}(${poolType}(` + + 'minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])'; + if (poolType === 'avg') { + returnValue = `avgValue / max(count, 1.0)`; + } + const filterWidthNearestVec4 = Math.floor(filterWidth / 4) * 4; + const filterWidthVec4Remainder = filterWidth % 4; + const updateSnippet = ` + if (${isAvgPool}) { + avgValue += dot(values, ones); + } else { + minMaxValue = ${compareOp}(values, minMaxValue); + } + `; + this.userCode = ` + const ivec2 strides = ivec2(${strideHeight}, ${strideWidth}); + const ivec2 pads = ivec2(${padTop}, ${padLeft}); + const float initializationValue = ${initializationValue}; + const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0); + + float count = 0.0; + + float getValue(int batch, int xR, int xC, int d) { + if (xC < 0 || xC >= ${convInfo.inWidth}) { + return initializationValue; + } + count += 1.0; + return getX(batch, xR, xC, d); + } + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords[0]; + int d = coords[3]; + + ivec2 xRCCorner = coords.yz * strides - pads; + int xRCorner = xRCCorner.x; + int xCCorner = xRCCorner.y; + + // max/min x(?, ?, d) to get y(yR, yC, d). + // ? = to be determined + vec4 minMaxValue = vec4(${initializationValue}); + float avgValue = 0.0; + count = 0.0; + + for (int wR = 0; wR < ${effectiveFilterHeight}; + wR += ${dilationHeight}) { + int xR = xRCorner + wR; + + if (xR < 0 || xR >= ${convInfo.inHeight}) { + continue; + } + + for (int wC = 0; wC < ${filterWidthNearestVec4}; wC += 4) { + int xC = xCCorner + wC * ${dilationWidth}; + + vec4 values = vec4( + getValue(batch, xR, xC, d), + getValue(batch, xR, xC + ${dilationWidth}, d), + getValue(batch, xR, xC + 2 * ${dilationWidth}, d), + getValue(batch, xR, xC + 3 * ${dilationWidth}, d) + ); + + ${updateSnippet} + } + + int xC = xCCorner + ${filterWidthNearestVec4}; + if (${filterWidthVec4Remainder === 1}) { + vec4 values = vec4( + getValue(batch, xR, xC, d), + initializationValue, + initializationValue, + initializationValue + ); + + ${updateSnippet} + } else if (${filterWidthVec4Remainder === 2}) { + vec4 values = vec4( + getValue(batch, xR, xC, d), + getValue(batch, xR, xC + ${dilationWidth}, d), + initializationValue, + initializationValue + ); + + ${updateSnippet} + } else if (${filterWidthVec4Remainder === 3}) { + vec4 values = vec4( + getValue(batch, xR, xC, d), + getValue(batch, xR, xC + ${dilationWidth}, d), + getValue(batch, xR, xC + 2 * ${dilationWidth}, d), + initializationValue + ); + + ${updateSnippet} + } + } + setOutput(${returnValue}); + } + `; + } + } + class Pool3DProgram { + constructor(convInfo, poolType, computePositions, flattenPositions = false, includeBatchInIndex = false) { + this.variableNames = ['x']; + if (poolType === 'avg' && computePositions) { + throw new Error('Cannot compute positions for average pool.'); + } + const filterWidth = convInfo.filterWidth; + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationDepth = convInfo.dilationDepth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterDepth = convInfo.effectiveFilterDepth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padFront = convInfo.padInfo.front; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + this.outputShape = convInfo.outShape; + const isAvgPool = poolType === 'avg'; + let initializationValue = '0.0'; + if (!isAvgPool) { + // WebGL on Firefox Linux can't compile 1/0 so we do 1/eps. + initializationValue = '-1.0 / 1e-20'; + } + if (computePositions) { + const compareOp = '>='; + this.userCode = ` + const ivec3 strides = + ivec3(${strideDepth}, ${strideHeight}, ${strideWidth}); + const ivec3 pads = ivec3(${padFront}, ${padTop}, ${padLeft}); + + void main() { + ivec5 coords = getOutputCoords(); + int batch = coords.x; + int ch = coords.u; + + ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads; + int xDCorner = xCorner.x; + int xRCorner = xCorner.y; + int xCCorner = xCorner.z; + + // max/min x(?, ?, ?, ch) to get y(yD, yR, yC, ch). + // ? = to be determined + float minMaxValue = 0.0; + float minMaxValueFound = 0.0; + int minMaxPosition = 0; + + for (int wD = 0; wD < ${effectiveFilterDepth}; + wD += ${dilationDepth}) { + int xD = xDCorner + wD; + + if (xD < 0 || xD >= ${convInfo.inDepth}) { + continue; + } + + for (int wR = 0; wR < ${effectiveFilterHeight}; + wR += ${dilationHeight}) { + int xR = xRCorner + wR; + + if (xR < 0 || xR >= ${convInfo.inHeight}) { + continue; + } + + for (int wC = 0; wC < ${effectiveFilterWidth}; + wC += ${dilationWidth}) { + int xC = xCCorner + wC; + + if (xC < 0 || xC >= ${convInfo.inWidth}) { + continue; + } + + float value = getX(batch, xD, xR, xC, ch); + + // If a min / max value has already been found, use it. If not, + // use the current value. + float currMinMaxValue = mix( + value, minMaxValue, minMaxValueFound); + if (value ${compareOp} currMinMaxValue) { + minMaxValue = value; + minMaxValueFound = 1.0; + minMaxPosition = ${flattenPositions ? + (includeBatchInIndex ? + `(((batch * ${convInfo.inDepth} + xD) * ${convInfo.inHeight} + xR) * ${convInfo.inWidth} + xC) * ${convInfo.inChannels} + ch` : + `((xD * ${convInfo.inHeight} + xR) * ${convInfo.inWidth} + xC) * ${convInfo.inChannels} + ch`) : + `wD * ${effectiveFilterHeight} * ${effectiveFilterWidth} + + wR * ${effectiveFilterWidth} + wC`}; + } + } + } + } + setOutput(float(minMaxPosition)); + } + `; + return; + } + const compareOp = 'max'; + let returnValue = `${poolType}(${poolType}(${poolType}(` + + 'minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])'; + if (poolType === 'avg') { + // Use `max(count, 1.0)` instead of `count` in case count === 0.0. + // If count === 0.0, `avgValue` is always 0.0 and we change `count`'s + // value to avoid dividing zero. + returnValue = `avgValue / max(count, 1.0)`; + } + const filterWidthNearestVec4 = Math.floor(filterWidth / 4) * 4; + const filterWidthVec4Remainder = filterWidth % 4; + const updateSnippet = ` + if (${isAvgPool}) { + avgValue += dot(values, ones); + } else { + minMaxValue = ${compareOp}(values, minMaxValue); + } + `; + this.userCode = ` + const ivec3 strides = + ivec3(${strideDepth}, ${strideHeight}, ${strideWidth}); + const ivec3 pads = ivec3(${padFront}, ${padTop}, ${padLeft}); + const float initializationValue = ${initializationValue}; + const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0); + + float count = 0.0; + + float getValue(int batch, int xD, int xR, int xC, int ch) { + if (xC < 0 || xC >= ${convInfo.inWidth}) { + return initializationValue; + } + count += 1.0; + return getX(batch, xD, xR, xC, ch); + } + + void main() { + ivec5 coords = getOutputCoords(); + int batch = coords.x; + int ch = coords.u; + + ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads; + int xDCorner = xCorner.x; + int xRCorner = xCorner.y; + int xCCorner = xCorner.z; + + // max/min x(?, ?, ?, d) to get y(yD, yR, yC, ch). + // ? = to be determined + vec4 minMaxValue = vec4(${initializationValue}); + float avgValue = 0.0; + count = 0.0; + + for (int wD = 0; wD < ${effectiveFilterDepth}; + wD += ${dilationDepth}) { + int xD = xDCorner + wD; + + if (xD < 0 || xD >= ${convInfo.inDepth}) { + continue; + } + + for (int wR = 0; wR < ${effectiveFilterHeight}; + wR += ${dilationHeight}) { + int xR = xRCorner + wR; + + if (xR < 0 || xR >= ${convInfo.inHeight}) { + continue; + } + + for (int wC = 0; wC < ${filterWidthNearestVec4}; wC += 4) { + int xC = xCCorner + wC * ${dilationWidth}; + + vec4 values = vec4( + getValue(batch, xD, xR, xC, ch), + getValue(batch, xD, xR, xC + ${dilationWidth}, ch), + getValue(batch, xD, xR, xC + 2 * ${dilationWidth}, ch), + getValue(batch, xD, xR, xC + 3 * ${dilationWidth}, ch) + ); + + ${updateSnippet} + } + + int xC = xCCorner + ${filterWidthNearestVec4}; + if (${filterWidthVec4Remainder === 1}) { + vec4 values = vec4( + getValue(batch, xD, xR, xC, ch), + initializationValue, + initializationValue, + initializationValue + ); + + ${updateSnippet} + } else if (${filterWidthVec4Remainder === 2}) { + vec4 values = vec4( + getValue(batch, xD, xR, xC, ch), + getValue(batch, xD, xR, xC + ${dilationWidth}, ch), + initializationValue, + initializationValue + ); + + ${updateSnippet} + } else if (${filterWidthVec4Remainder === 3}) { + vec4 values = vec4( + getValue(batch, xD, xR, xC, ch), + getValue(batch, xD, xR, xC + ${dilationWidth}, ch), + getValue(batch, xD, xR, xC + 2 * ${dilationWidth}, ch), + initializationValue + ); + + ${updateSnippet} + } + } + } + setOutput(${returnValue}); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function avgPool(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + assertNotComplex(x, 'avgPool'); + const { filterSize, strides, pad, dimRoundingMode } = attrs; + const dilations = 1; + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in avgPool: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + const convInfo = computePool2DInfo(x.shape, filterSize, strides, dilations, pad, dimRoundingMode); + if (convInfo.filterWidth === 1 && convInfo.filterHeight === 1 && + arraysEqual(convInfo.inShape, convInfo.outShape)) { + return identity({ inputs: { x }, backend }); + } + const avgPoolProgram = new Pool2DProgram(convInfo, 'avg', false); + return backend.runWebGLProgram(avgPoolProgram, [x], 'float32'); + } + const avgPoolConfig = { + kernelName: AvgPool, + backendName: 'webgl', + kernelFunc: avgPool + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function avgPool3D(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { filterSize, strides, pad, dimRoundingMode, dataFormat } = attrs; + const dilations = [1, 1, 1]; + const convInfo = computePool3DInfo(x.shape, filterSize, strides, dilations, pad, dimRoundingMode, dataFormat); + const avgPoolProgram = new Pool3DProgram(convInfo, 'avg', false); + return backend.runWebGLProgram(avgPoolProgram, [x], 'float32'); + } + const avgPool3DConfig = { + kernelName: AvgPool3D, + backendName: 'webgl', + kernelFunc: avgPool3D + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class AvgPool2DBackpropProgram { + constructor(convInfo) { + this.variableNames = ['dy']; + this.outputShape = convInfo.inShape; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padTop = effectiveFilterHeight - 1 - convInfo.padInfo.top; + const padLeft = effectiveFilterWidth - 1 - convInfo.padInfo.left; + const avgMultiplier = 1 / (filterHeight * filterWidth); + this.userCode = ` + const ivec2 pads = ivec2(${padTop}, ${padLeft}); + const float avgMultiplier = float(${avgMultiplier}); + + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int d = coords[3]; + + ivec2 dyRCCorner = coords.yz - pads; + int dyRCorner = dyRCCorner.x; + int dyCCorner = dyRCCorner.y; + + // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d). + // ? = to be determined. : = across all values in that axis. + float dotProd = 0.0; + for (int wR = 0; wR < ${effectiveFilterHeight}; + wR += ${dilationHeight}) { + float dyR = float(dyRCorner + wR) / ${strideHeight}.0; + + if (dyR < 0.0 || dyR >= ${convInfo.outHeight}.0 || fract(dyR) > 0.0) { + continue; + } + int idyR = int(dyR); + + for (int wC = 0; wC < ${effectiveFilterWidth}; + wC+= ${dilationWidth}) { + float dyC = float(dyCCorner + wC) / ${strideWidth}.0; + + if (dyC < 0.0 || dyC >= ${convInfo.outWidth}.0 || + fract(dyC) > 0.0) { + continue; + } + int idyC = int(dyC); + + float dyValue = getDy(b, idyR, idyC, d); + + dotProd += dyValue * avgMultiplier; + } + } + setOutput(dotProd); + } + `; + } + } + class AvgPool3DBackpropProgram { + constructor(convInfo) { + this.variableNames = ['dy']; + this.outputShape = convInfo.inShape; + const filterDepth = convInfo.filterDepth; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationDepth = convInfo.dilationDepth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterDepth = convInfo.effectiveFilterDepth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padFront = effectiveFilterDepth - 1 - convInfo.padInfo.front; + const padTop = effectiveFilterHeight - 1 - convInfo.padInfo.top; + const padLeft = effectiveFilterWidth - 1 - convInfo.padInfo.left; + const avgMultiplier = 1 / (filterDepth * filterHeight * filterWidth); + this.userCode = ` + const ivec3 pads = ivec3(${padFront}, ${padTop}, ${padLeft}); + const float avgMultiplier = float(${avgMultiplier}); + + void main() { + ivec5 coords = getOutputCoords(); + int batch = coords.x; + int ch = coords.u; + + ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads; + int dyDCorner = dyCorner.x; + int dyRCorner = dyCorner.y; + int dyCCorner = dyCorner.z; + + // Convolve dy(?, ?, ?, d) with pos mask(:, :, :, ch) to get + // dx(xD, xR, xC, ch). + // ? = to be determined. : = across all values in that axis. + float dotProd = 0.0; + + for (int wD = 0; wD < ${effectiveFilterDepth}; + wD += ${dilationDepth}) { + float dyD = float(dyDCorner + wD) / ${strideDepth}.0; + + if (dyD < 0.0 || dyD >= ${convInfo.outDepth}.0 || fract(dyD) > 0.0) { + continue; + } + int idyD = int(dyD); + + for (int wR = 0; wR < ${effectiveFilterHeight}; + wR += ${dilationHeight}) { + float dyR = float(dyRCorner + wR) / ${strideHeight}.0; + + if (dyR < 0.0 || dyR >= ${convInfo.outHeight}.0 || + fract(dyR) > 0.0) { + continue; + } + int idyR = int(dyR); + + for (int wC = 0; wC < ${effectiveFilterWidth}; + wC += ${dilationWidth}) { + float dyC = float(dyCCorner + wC) / ${strideWidth}.0; + + if (dyC < 0.0 || dyC >= ${convInfo.outWidth}.0 || + fract(dyC) > 0.0) { + continue; + } + int idyC = int(dyC); + + float dyValue = getDy(batch, idyD, idyR, idyC, ch); + + dotProd += dyValue * avgMultiplier; + } + } + } + setOutput(dotProd); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function avgPool3DGrad(args) { + const { inputs, backend, attrs } = args; + const { dy, input } = inputs; + const x = input; + const { filterSize, strides, pad, dimRoundingMode } = attrs; + const dilations = [1, 1, 1]; + const convInfo = computePool3DInfo(x.shape, filterSize, strides, dilations, pad, dimRoundingMode); + const avgPoolBackpropProgram = new AvgPool3DBackpropProgram(convInfo); + return backend.runWebGLProgram(avgPoolBackpropProgram, [dy], x.dtype); + } + const avgPool3DGradConfig = { + kernelName: AvgPool3DGrad, + backendName: 'webgl', + kernelFunc: avgPool3DGrad + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function avgPoolGrad(args) { + const { inputs, backend, attrs } = args; + const { dy, input } = inputs; + const x = input; + assertNotComplex([dy, input], 'avgPoolGrad'); + const { filterSize, strides, pad } = attrs; + const convInfo = computePool2DInfo(x.shape, filterSize, strides, 1 /* dilations */, pad); + const avgPoolBackpropProgram = new AvgPool2DBackpropProgram(convInfo); + return backend.runWebGLProgram(avgPoolBackpropProgram, [dy], x.dtype); + } + const avgPoolGradConfig = { + kernelName: AvgPoolGrad, + backendName: 'webgl', + kernelFunc: avgPoolGrad + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function batchMatMul(args) { + const { inputs, backend, attrs } = args; + const { a, b } = inputs; + const { transposeA, transposeB } = attrs; + return batchMatMulImpl({ a, b, transposeA, transposeB, backend }); + } + const batchMatMulConfig = { + kernelName: BatchMatMul, + backendName: 'webgl', + kernelFunc: batchMatMul, + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class BatchNormProgram { + constructor(xShape, meanShape, varianceShape, offsetShape, scaleShape, varianceEpsilon) { + this.outputShape = []; + this.variableNames = ['x', 'mean', 'variance']; + assertAndGetBroadcastShape(xShape, meanShape); + assertAndGetBroadcastShape(xShape, varianceShape); + let offsetSnippet = '0.0'; + if (offsetShape != null) { + assertAndGetBroadcastShape(xShape, offsetShape); + this.variableNames.push('offset'); + offsetSnippet = 'getOffsetAtOutCoords()'; + } + let scaleSnippet = '1.0'; + if (scaleShape != null) { + assertAndGetBroadcastShape(xShape, scaleShape); + this.variableNames.push('scale'); + scaleSnippet = 'getScaleAtOutCoords()'; + } + this.outputShape = xShape; + this.userCode = ` + void main() { + float x = getXAtOutCoords(); + float mean = getMeanAtOutCoords(); + float variance = getVarianceAtOutCoords(); + float offset = ${offsetSnippet}; + float scale = ${scaleSnippet}; + float inv = scale * inversesqrt(variance + float(${varianceEpsilon})); + setOutput(dot(vec3(x, -mean, offset), vec3(inv, inv, 1))); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class BatchNormPackedProgram { + constructor(xShape, meanShape, varianceShape, offsetShape, scaleShape, varianceEpsilon) { + this.packedInputs = true; + this.packedOutput = true; + this.variableNames = ['x', 'mean', 'variance']; + assertAndGetBroadcastShape(xShape, meanShape); + assertAndGetBroadcastShape(xShape, varianceShape); + let offsetSnippet = 'vec4(0.0)'; + if (offsetShape != null) { + assertAndGetBroadcastShape(xShape, offsetShape); + this.variableNames.push('offset'); + offsetSnippet = 'getOffsetAtOutCoords()'; + } + let scaleSnippet = 'vec4(1.0)'; + if (scaleShape != null) { + assertAndGetBroadcastShape(xShape, scaleShape); + this.variableNames.push('scale'); + scaleSnippet = 'getScaleAtOutCoords()'; + } + this.outputShape = xShape; + this.userCode = ` + void main() { + vec4 offset = ${offsetSnippet}; + vec4 scale = ${scaleSnippet}; + + vec4 x = getXAtOutCoords(); + vec4 mean = getMeanAtOutCoords(); + vec4 variance = getVarianceAtOutCoords(); + + vec4 inv = scale * inversesqrt(variance + vec4(${varianceEpsilon})); + + setOutput((x - mean) * inv + offset); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const batchNorm = ({ inputs, backend, attrs }) => { + const { x, mean, variance, offset, scale } = inputs; + assert$1(mean.shape.length === variance.shape.length, () => 'Batch normalization gradient requires mean and variance to have ' + + 'equal ranks.'); + assert$1(offset == null || mean.shape.length === offset.shape.length, () => 'Batch normalization gradient requires mean and offset to have ' + + 'equal ranks.'); + assert$1(scale == null || mean.shape.length === scale.shape.length, () => 'Batch normalization gradient requires mean and scale to have ' + + 'equal ranks.'); + let { varianceEpsilon } = attrs; + if (varianceEpsilon == null) { + varianceEpsilon = 0.001; + } + const finalInputs = [x, mean, variance]; + let offsetShape = null; + if (offset != null) { + offsetShape = offset.shape; + finalInputs.push(offset); + } + let scaleShape = null; + if (scale != null) { + scaleShape = scale.shape; + finalInputs.push(scale); + } + const program = env().getBool('WEBGL_PACK_NORMALIZATION') ? + new BatchNormPackedProgram(x.shape, mean.shape, variance.shape, offsetShape, scaleShape, varianceEpsilon) : + new BatchNormProgram(x.shape, mean.shape, variance.shape, offsetShape, scaleShape, varianceEpsilon); + const output = backend.runWebGLProgram(program, finalInputs, finalInputs[0].dtype); + return output; + }; + const batchNormConfig = { + kernelName: FusedBatchNorm, + backendName: 'webgl', + kernelFunc: batchNorm, + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class SliceProgram { + constructor(destSize) { + this.variableNames = ['source']; + this.outputShape = destSize; + this.rank = destSize.length; + const dtype = getCoordsDataType(this.rank); + this.customUniforms = [{ name: 'start', arrayIndex: this.rank, type: 'int' }]; + const sourceCoords = getCoords$1(this.rank); + let body; + const coordSum = destSize.map((_, i) => { + return `sourceLoc.${coords[i]} = start[${i}] + coords.${coords[i]};`; + }); + body = ` + ${dtype} sourceLoc; + ${dtype} coords = getOutputCoords(); + ${coordSum.join('\n')} + `; + this.userCode = ` + void main() { + ${body} + setOutput(getSource(${sourceCoords})); + } + `; + } + } + const coords = ['x', 'y', 'z', 'w', 'u', 'v']; + function getCoords$1(rank) { + if (rank === 1) { + return 'sourceLoc'; + } + else if (rank <= 6) { + return coords.slice(0, rank).map(x => 'sourceLoc.' + x).join(','); + } + else { + throw Error(`Slicing for rank ${rank} is not yet supported`); + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class SlicePackedProgram { + constructor(destSize) { + this.variableNames = ['source']; + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = destSize; + this.rank = destSize.length; + this.customUniforms = [{ name: 'start', arrayIndex: this.rank, type: 'int' }]; + const dtype = getCoordsDataType(this.rank); + const coords = getChannels('coords', this.rank); + const sourceLoc = getChannels('sourceLoc', this.rank); + const innerDims = this.rank === 1 ? 'sourceLoc' : `vec2(${sourceLoc.slice(-2).join()})`; + const getChannel = `getChannel(getSource(${sourceLoc.join()}), ${innerDims})`; + const upperRow = ` + result.x = ${getChannel}; + if (++${coords[this.rank - 1]} < ${destSize[this.rank - 1]}) { + ++${sourceLoc[this.rank - 1]}; + result.y = ${getChannel}; + --${sourceLoc[this.rank - 1]}; + } + `; + const lowerRow = this.rank === 1 ? '' : ` + --${coords[this.rank - 1]}; + if (++${coords[this.rank - 2]} < ${destSize[this.rank - 2]}) { + ++${sourceLoc[this.rank - 2]}; + result.z = ${getChannel}; + if (++${coords[this.rank - 1]} < ${destSize[this.rank - 1]}) { + ++${sourceLoc[this.rank - 1]}; + result.w = ${getChannel}; + } + } + `; + const sourceLocSetup = this.rank <= 4 ? + `sourceLoc = coords + + ${dtype}(${destSize.map((_, i) => `start[${i}]`).join()});` : + destSize.map((_, i) => `${sourceLoc[i]} = ${coords[i]} + start[${i}];`) + .join('\n'); + this.userCode = ` + void main() { + ${dtype} coords = getOutputCoords(); + ${dtype} sourceLoc; + ${sourceLocSetup} + vec4 result = vec4(0.); + ${upperRow} + ${lowerRow} + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function shallowSlice(x, begin, size, backend) { + const xTexData = backend.texData.get(x.dataId); + const t = backend.makeTensorInfo(size, x.dtype); + const newTexData = backend.texData.get(t.dataId); + // Copy texture data from the original tensor. + Object.assign(newTexData, xTexData); + newTexData.refCount = 1; + newTexData.shape = size; + newTexData.dtype = x.dtype; + let flatOffset = computeFlatOffset(begin, computeStrides(x.shape)); + if (xTexData.slice) { + // We are slicing an already sliced tensor, so we have to accumulate + // the offset. + flatOffset += xTexData.slice.flatOffset; + } + newTexData.slice = { + flatOffset, + // Point to the original dataId, which is used to do ref counting. + origDataId: xTexData.slice && xTexData.slice.origDataId || x.dataId + }; + // Increase the ref count for that data bucket. + const refCount = backend.dataRefCount.get(newTexData.slice.origDataId) || 1; + backend.dataRefCount.set(newTexData.slice.origDataId, refCount + 1); + return t; + } + function slice(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { begin, size } = attrs; + const [$begin, $size] = parseSliceParams(x, begin, size); + assertParamsValid(x, $begin, $size); + if (sizeFromShape($size) === 0) { + return backend.makeTensorInfo($size, x.dtype, []); + } + // Run on cpu if dtype is string. For string, the backend represents it + // as Uint8Array[], where each Uint8Array is a character. Given that the + // computation is only on the outer array, uploading the whole data onto + // gpu is wasteful. Also, currently webgl doesn't have a design to + // upload and retrieve Uint8Array[] between cpu and gpu. Therefore, we + // just run the kernel on cpu if dtype is string. + if (backend.shouldExecuteOnCPU([x]) || x.dtype === 'string') { + const xTexData = backend.texData.get(x.dataId); + const outValues = sliceImplCPU(xTexData.values, $begin, $size, x.shape, x.dtype); + return backend.makeTensorInfo($size, x.dtype, outValues); + } + const { isPacked } = backend.texData.get(x.dataId); + const isContinous = isSliceContinous(x.shape, $begin, $size); + if (isPacked || !isContinous) { + const program = env().getBool('WEBGL_PACK_ARRAY_OPERATIONS') ? + new SlicePackedProgram($size) : + new SliceProgram($size); + const customValues = [$begin]; + return backend.runWebGLProgram(program, [x], x.dtype, customValues); + } + backend.uploadToGPU(x.dataId); + return shallowSlice(x, $begin, $size, backend); + } + const sliceConfig = { + kernelName: Slice, + backendName: 'webgl', + kernelFunc: slice + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const batchToSpaceND = (args) => { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { blockShape, crops } = attrs; + assert$1(x.shape.length <= 4, () => 'batchToSpaceND for rank > 4 with a WebGL backend not ' + + 'implemented yet'); + const prod = blockShape.reduce((a, b) => a * b); + const reshaped = getReshaped(x.shape, blockShape, prod); + const permuted = getPermuted(reshaped.length, blockShape.length); + const reshapedPermuted = getReshapedPermuted(x.shape, blockShape, prod); + const sliceBeginCoords = getSliceBeginCoords(crops, blockShape.length); + const sliceSize = getSliceSize(reshapedPermuted, crops, blockShape.length); + const toDispose = []; + const reshapedIntermediate = reshape({ inputs: { x }, backend, attrs: { shape: reshaped } }); + const transposedIntermediate = transpose({ inputs: { x: reshapedIntermediate }, backend, attrs: { perm: permuted } }); + const reshapedIntermediate2 = reshape({ + inputs: { x: transposedIntermediate }, + backend, + attrs: { shape: reshapedPermuted } + }); + const sliced = slice({ + inputs: { x: reshapedIntermediate2 }, + backend, + attrs: { begin: sliceBeginCoords, size: sliceSize } + }); + toDispose.push(reshapedIntermediate); + toDispose.push(transposedIntermediate); + toDispose.push(reshapedIntermediate2); + toDispose.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return sliced; + }; + const batchToSpaceNDConfig = { + kernelName: BatchToSpaceND, + backendName: 'webgl', + kernelFunc: batchToSpaceND + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function bincount(args) { + const { inputs, backend, attrs } = args; + const { x, weights } = inputs; + const { size } = attrs; + const xVals = backend.readSync(x.dataId); + const weightsVals = backend.readSync(weights.dataId); + const outVals = bincountImplCPU(xVals, weightsVals, weights.dtype, weights.shape, size); + return backend.makeTensorInfo([size], weights.dtype, outVals); + } + const bincountConfig = { + kernelName: Bincount, + backendName: 'webgl', + kernelFunc: bincount + }; + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const BITWISEAND = ` + int r = int(a.r) & int(b.r); + int g = int(a.g) & int(b.g); + int rb = int(a.b) & int(b.b); + int ra = int(a.a) & int(b.a); + return vec4(r, g, rb, ra); +`; + const BITWISEAND_UNPACKED = ` + return float(int(a.r) & int(b.r)); +`; + function bitwiseAnd(args) { + const { inputs, backend } = args; + const { a, b } = inputs; + const shouldUsePackedProgram = env().getBool('WEBGL_PACK_BINARY_OPERATIONS'); + const versionNumber = env().getNumber('WEBGL_VERSION'); + // The type of a and b are ensured to be `int32` in core, therefore no need to + // consider other type situations. + if ((backend.shouldExecuteOnCPU([a, b])) || versionNumber === 1) { + const aVals = backend.texData.get(a.dataId).values; + const bVals = backend.texData.get(b.dataId).values; + const [outValues, outShape] = bitwiseAndImplCPU(a.shape, b.shape, aVals, bVals, a.dtype); + const out = backend.makeTensorInfo(outShape, a.dtype); + const outData = backend.texData.get(out.dataId); + outData.values = outValues; + return out; + } + let program; + if (shouldUsePackedProgram) { + program = new BinaryOpPackedProgram(BITWISEAND, a.shape, b.shape, false); + } + else { + program = new BinaryOpProgram(BITWISEAND_UNPACKED, a.shape, b.shape); + } + return backend.runWebGLProgram(program, [a, b], a.dtype); + } + const bitwiseAndConfig = { + kernelName: BitwiseAnd, + backendName: 'webgl', + kernelFunc: bitwiseAnd + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function broadcastArgs(args) { + const { inputs, backend } = args; + const { s0, s1 } = inputs; + const s0Vals = backend.readSync(s0.dataId); + const s1Vals = backend.readSync(s1.dataId); + const broadcastShape = assertAndGetBroadcastShape(Array.from(s0Vals), Array.from(s1Vals)); + return backend.makeTensorInfo([broadcastShape.length], 'int32', Int32Array.from(broadcastShape)); + } + const broadcastArgsConfig = { + kernelName: BroadcastArgs, + backendName: 'webgl', + kernelFunc: broadcastArgs + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const NOT_EQUAL = `return float(a != b);`; + const notEqual = binaryKernelFunc({ opSnippet: NOT_EQUAL, cpuKernelImpl: notEqualImplCPU, dtype: 'bool' }); + const notEqualConfig = { + kernelName: NotEqual, + backendName: 'webgl', + kernelFunc: notEqual, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function real(args) { + const { inputs, backend } = args; + const { input } = inputs; + const inputData = backend.texData.get(input.dataId); + return identity({ inputs: { x: inputData.complexTensorInfos.real }, backend }); + } + const realConfig = { + kernelName: Real, + backendName: 'webgl', + kernelFunc: real + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const TO_INT = `return float(int(x));`; + function int(input, backend) { + const program = new UnaryOpProgram(input.shape, TO_INT); + const output = backend.runWebGLProgram(program, [input], 'int32'); + return { dataId: output.dataId, shape: output.shape, dtype: output.dtype }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function cast(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { dtype } = attrs; + // Casting to complex64. + if (dtype === 'complex64') { + if (x.dtype === 'complex64') { + return identity({ inputs: { x }, backend }); + } + // TODO(annxingyuan): Import kernel function once zeros is modularized. + const zerosTensor = zeros$2(x.shape); + const floatX = cast({ inputs: { x }, backend, attrs: { dtype: 'float32' } }); + const result = complex({ inputs: { real: floatX, imag: zerosTensor }, backend }); + zerosTensor.dispose(); + backend.disposeIntermediateTensorInfo(floatX); + return result; + } + // Casting from complex64 + if (x.dtype === 'complex64') { + const realPart = real({ inputs: { input: x }, backend }); + const result = cast({ inputs: { x: realPart }, backend, attrs: { dtype } }); + backend.disposeIntermediateTensorInfo(realPart); + return result; + } + if (!hasEncodingLoss(x.dtype, dtype)) { + // We don't change the underlying data, since we cast to higher + // precision. + const result = identity({ inputs: { x }, backend }); + return { dataId: result.dataId, shape: result.shape, dtype }; + } + if (backend.shouldExecuteOnCPU([x])) { + const values = backend.texData.get(x.dataId).values; + const [resultShape, resultType, resultData] = castImplCPU(values, x.shape, x.dtype, dtype); + return backend.makeTensorInfo(resultShape, resultType, resultData); + } + if (dtype === 'int32') { + return int(x, backend); + } + if (dtype === 'bool') { + const zerosTensorInfo = backend.makeTensorInfo([], 'bool', getTypedArrayFromDType('bool', 1)); + const binaryInputs = { a: x, b: zerosTensorInfo }; + const result = notEqual({ inputs: binaryInputs, backend }); + backend.disposeIntermediateTensorInfo(zerosTensorInfo); + return result; + } + throw new Error(`Error in Cast: failed to cast ${x.dtype} to ${dtype}`); + } + const castConfig = { + kernelName: Cast, + backendName: 'webgl', + kernelFunc: cast + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const CEIL = `return ceil(x);`; + const ceil = unaryKernelFunc({ opSnippet: CEIL, packedOpSnippet: CEIL, cpuKernelImpl: ceilImplCPU }); + const ceilConfig = { + kernelName: Ceil, + backendName: 'webgl', + kernelFunc: ceil + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ClipProgram { + constructor(aShape) { + this.variableNames = ['A']; + this.customUniforms = [ + { name: 'minVal', type: 'float' }, + { name: 'maxVal', type: 'float' } + ]; + this.outputShape = aShape; + this.userCode = ` + + void main() { + float value = getAAtOutCoords(); + if (isnan(value)) { + setOutput(value); + return; + } + + setOutput(clamp(value, minVal, maxVal)); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ClipPackedProgram { + constructor(aShape) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = true; + this.customUniforms = [ + { name: 'minVal', type: 'float' }, + { name: 'maxVal', type: 'float' } + ]; + this.outputShape = aShape; + this.userCode = ` + void main() { + vec4 value = getAAtOutCoords(); + + if (any(isnan(value))) { + setOutput(value); + return; + } + + setOutput(clamp(value, vec4(minVal), vec4(maxVal))); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function clipByValue(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { clipValueMin, clipValueMax } = attrs; + let program; + if (env().getBool('WEBGL_PACK_CLIP')) { + program = new ClipPackedProgram(x.shape); + } + else { + program = new ClipProgram(x.shape); + } + const customValues = [[clipValueMin], [clipValueMax]]; + return backend.runWebGLProgram(program, [x], x.dtype, customValues); + } + const clipByValueConfig = { + kernelName: ClipByValue, + backendName: 'webgl', + kernelFunc: clipByValue + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ComplexAbsProgram { + constructor(shape) { + this.variableNames = ['real', 'imag']; + this.outputShape = shape; + this.userCode = ` + void main() { + float re = abs(getRealAtOutCoords()); + float im = abs(getImagAtOutCoords()); + float mx = max(re, im); + + // sadly the length function in glsl is not underflow-safe + // (at least not on Intel GPUs). So the safe solution is + // to ensure underflow-safety in all cases. + setOutput( + mx == 0.0 ? 0.0 : mx * length(vec2(1, min(re, im)/mx)) + ); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Returns a TensorInfo with the complex shape and the dataId of the + // underlying part. We need to do this because a reshaped complex tensor is + // not reflected in its parts. + function makeComplexComponentTensorInfo(complexTensor, complexPart) { + return { + dataId: complexPart.dataId, + dtype: complexPart.dtype, + shape: complexTensor.shape + }; + } + function complexAbs(args) { + const { inputs, backend } = args; + const { x } = inputs; + const xData = backend.texData.get(x.dataId); + const program = new ComplexAbsProgram(x.shape); + const programInputs = [ + makeComplexComponentTensorInfo(x, xData.complexTensorInfos.real), + makeComplexComponentTensorInfo(x, xData.complexTensorInfos.imag), + ]; + return backend.runWebGLProgram(program, programInputs, programInputs[0].dtype); + } + const complexAbsConfig = { + kernelName: ComplexAbs, + backendName: 'webgl', + kernelFunc: complexAbs + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ConcatProgram { + // Concats 2d tensors along axis=1. See comments in MathBackendWebGL.concat(). + constructor(shapes) { + this.outputShape = []; + this.outputShape = computeOutShape$1(shapes, 1 /* axis */); + this.variableNames = shapes.map((_, i) => `T${i}`); + const offsets = new Array(shapes.length - 1); + offsets[0] = shapes[0][1]; + for (let i = 1; i < offsets.length; i++) { + offsets[i] = offsets[i - 1] + shapes[i][1]; + } + const snippets = [`if (yC < ${offsets[0]}) setOutput(getT0(yR, yC));`]; + for (let i = 1; i < offsets.length; i++) { + const shift = offsets[i - 1]; + snippets.push(`else if (yC < ${offsets[i]}) ` + + `setOutput(getT${i}(yR, yC-${shift}));`); + } + const lastIndex = offsets.length; + const lastShift = offsets[offsets.length - 1]; + snippets.push(`else setOutput(getT${lastIndex}(yR, yC-${lastShift}));`); + this.userCode = ` + void main() { + ivec2 coords = getOutputCoords(); + int yR = coords.x; + int yC = coords.y; + + ${snippets.join('\n ')} + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ConcatPackedProgram { + constructor(shapes, axis) { + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = []; + this.outputShape = computeOutShape$1(shapes, axis); + const shape = this.outputShape; + const rank = shape.length; + const dtype = getCoordsDataType(rank); + const coords = getChannels('coords', rank); + const channels = ['x', 'y', 'z', 'w', 'u', 'v'].slice(0, rank); + this.variableNames = shapes.map((_, i) => `T${i}`); + const offsets = new Array(shapes.length - 1); + offsets[0] = shapes[0][axis]; + for (let i = 1; i < offsets.length; i++) { + offsets[i] = offsets[i - 1] + shapes[i][axis]; + } + const channel = channels[axis]; + const lastChannels = channels.slice(-2); + const allChannels = channels.join(); + let getValueSnippet = `if (${channel} < ${offsets[0]}) { + return getChannel( + getT0(${allChannels}), vec2(${lastChannels.join()})); + }`; + for (let i = 1; i < offsets.length; i++) { + const shift = offsets[i - 1]; + // Note: the >= comparison below may seem unnecessary given the check + // above but is needed to workaround branch execution issues on some + // devices. It makes all the conditions exclusive without relying on + // execution order. + getValueSnippet += ` + if (${channel} < ${offsets[i]} && ${channel} >= ${offsets[i - 1]}) { + return getChannel( + getT${i}(${shiftedChannels(channels, channel, shift)}), + vec2(${shiftedChannels(lastChannels, channel, shift)})); + }`; + } + const lastIndex = offsets.length; + const shift = offsets[offsets.length - 1]; + getValueSnippet += ` + return getChannel( + getT${lastIndex}(${shiftedChannels(channels, channel, shift)}), + vec2(${shiftedChannels(lastChannels, channel, shift)}));`; + this.userCode = ` + float getValue(${channels.map(x => 'int ' + x)}) { + ${getValueSnippet} + } + + void main() { + ${dtype} coords = getOutputCoords(); + vec4 result = vec4(getValue(${coords}), 0., 0., 0.); + + ${coords[rank - 1]} = ${coords[rank - 1]} + 1; + if (${coords[rank - 1]} < ${shape[rank - 1]}) { + result.g = getValue(${coords}); + } + + ${coords[rank - 2]} = ${coords[rank - 2]} + 1; + if (${coords[rank - 2]} < ${shape[rank - 2]}) { + result.a = getValue(${coords}); + } + + ${coords[rank - 1]} = ${coords[rank - 1]} - 1; + if (${coords[rank - 2]} < ${shape[rank - 2]} && + ${coords[rank - 1]} < ${shape[rank - 1]}) { + result.b = getValue(${coords}); + } + setOutput(result); + } + `; + } + } + /** + * Return an expression for coordinates into a vector where a given channel + * will be offset by [shift]. + * + * @param channels the channels to consider + * @param channel the channel we want shifted + * @param shift the amount to subtract from the channel. + * + * @returns a string of the form 'x, y-[shift], z' where any one channel can + * have the shift applied. + */ + function shiftedChannels(channels, channel, shift) { + const channelIdx = channels.indexOf(channel); + const res = channels.map((c, idx) => { + if (idx === channelIdx) { + return `${c} - ${shift}`; + } + else { + return c; + } + }); + return res.join(); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function imag(args) { + const { inputs, backend } = args; + const { input } = inputs; + const inputData = backend.texData.get(input.dataId); + return identity({ inputs: { x: inputData.complexTensorInfos.imag }, backend }); + } + const imagConfig = { + kernelName: Imag, + backendName: 'webgl', + kernelFunc: imag + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function concatImpl(inputs, axis, backend) { + const dtype = inputs[0].dtype; + if (dtype === 'complex64') { + const reals = inputs.map((t) => real({ inputs: { input: t }, backend })); + const imags = inputs.map((t) => imag({ inputs: { input: t }, backend })); + const realConcated = concatImpl(reals, axis, backend); + const imagConcated = concatImpl(imags, axis, backend); + const result = complex({ inputs: { real: realConcated, imag: imagConcated }, backend }); + reals.forEach(r => backend.disposeIntermediateTensorInfo(r)); + imags.forEach(i => backend.disposeIntermediateTensorInfo(i)); + backend.disposeIntermediateTensorInfo(realConcated); + backend.disposeIntermediateTensorInfo(imagConcated); + return result; + } + let runOnCpu = backend.shouldExecuteOnCPU(inputs); + // Run on cpu if dtype is string. For string, the backend represents it + // as Uint8Array[], where each Uint8Array is a character. Given that the + // computation is only on the outer array, uploading the whole data onto + // gpu is wasteful. Also, currently webgl doesn't have a design to + // upload and retrieve Uint8Array[] between cpu and gpu. Therefore, we + // just run the kernel on cpu if dtype is string. + if (dtype === 'string') { + runOnCpu = true; + } + if (runOnCpu) { + // Any concat of n-dimensional tensors across any axis can be reduced to + // a concatenation of two-dimensional tensors across the axis 1 by first + // partitioning the axes of the original tensors into those less than the + // axis to be concatenated and the rest. Then reshape the tensors + // into a two-dimensional tensor by collapsing these two sets of axes and + // concatenate the resulting matrices across the axis 1, finally reshaping + // the result to have the proper shape. + const tensors2D = inputs.map(t => { + const innerSize = sizeFromShape(t.shape.slice(axis)); + const shape = [-1, innerSize]; + return reshape({ inputs: { x: t }, backend, attrs: { shape } }); + }); + const inputsValShapes = tensors2D.map(t => { + return { vals: backend.readSync(t.dataId), shape: t.shape }; + }); + // Concats 2d tensors along axis=1. + const outShape = computeOutShape$1(tensors2D.map(t => t.shape), 1 /* axis */); + const simplyConcat = tensors2D[0].shape[0] === 1; + const outVals = concatImplCPU(inputsValShapes, outShape, dtype, simplyConcat); + const finalOutShape = computeOutShape$1(inputs.map(t => t.shape), axis); + const outInfo = backend.makeTensorInfo(finalOutShape, dtype, outVals); + tensors2D.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return outInfo; + } + // Keep only non-empty tensors (ignore tensors with 0 in their shape). + const $inputs = inputs.filter(t => sizeFromShape(t.shape) > 0); + const shouldPack = env().getBool('WEBGL_PACK_ARRAY_OPERATIONS') && + $inputs[0].shape.length > 1; + if ($inputs.length === 1) { + // Clone tensor. + const program = shouldPack ? + new UnaryOpProgram(inputs[0].shape, CLONE) : + new UnaryOpPackedProgram(inputs[0].shape, CLONE); + return backend.runWebGLProgram(program, inputs, dtype); + } + const maxTexturesInShader = env().getNumber('WEBGL_MAX_TEXTURES_IN_SHADER'); + if ($inputs.length > maxTexturesInShader) { + const reducedInputs = []; + for (let i = 0; i < $inputs.length; i += maxTexturesInShader) { + const subArray = $inputs.slice(i, i + maxTexturesInShader); + reducedInputs.push(concatImpl(subArray, axis, backend)); + } + const result = concatImpl(reducedInputs, axis, backend); + for (const i of reducedInputs) { + backend.disposeIntermediateTensorInfo(i); + } + return result; + } + if (shouldPack) { + const program = new ConcatPackedProgram($inputs.map(t => t.shape), axis); + return backend.runWebGLProgram(program, $inputs, dtype); + } + const { tensors2D, outShape } = computeTensors2D($inputs, axis, backend); + const program = new ConcatProgram(tensors2D.map(t => t.shape)); + const result = backend.runWebGLProgram(program, tensors2D, dtype); + tensors2D.forEach(r => backend.disposeIntermediateTensorInfo(r)); + const reshapedResult = reshape({ inputs: { x: result }, attrs: { shape: outShape }, backend }); + backend.disposeIntermediateTensorInfo(result); + return reshapedResult; + } + function computeTensors2D(inputs, axis, backend) { + // Any concat of n-dimensional tensors across any axis can be reduced to + // a concatenation of two-dimensional tensors across the axis 1 by first + // partitioning the axes of the original tensors into those less than the + // axis to be concatenated and the rest. Then reshape the tensors + // into a two-dimensional tensor by collapsing these two sets of axes and + // concatenate the resulting matrices across the axis 1, finally reshaping + // the result to have the proper shape. + const outShape = computeOutShape$1(inputs.map(t => t.shape), axis); + const tensors2D = inputs.map(x => reshape({ + inputs: { x }, + attrs: { shape: [-1, sizeFromShape(x.shape.slice(axis))] }, + backend + })); + return { tensors2D, outShape }; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function concat(args) { + const { inputs, backend, attrs } = args; + const { axis } = attrs; + const $axis = parseAxisParam(axis, inputs[0].shape)[0]; + const shapes = inputs.map(t => t.shape); + assertParamsConsistent(shapes, $axis); + const outShape = computeOutShape$1(inputs.map(t => t.shape), $axis); + if (sizeFromShape(outShape) === 0) { + return backend.makeTensorInfo(outShape, inputs[0].dtype, []); + } + // Keep only non-empty tensors (ignore tensors with 0 in their shape). + const $inputs = inputs.filter(t => sizeFromShape(t.shape) > 0); + if ($inputs.length === 1) { + return identity({ inputs: { x: $inputs[0] }, backend }); + } + return concatImpl($inputs, $axis, backend); + } + const concatConfig = { + kernelName: Concat, + backendName: 'webgl', + kernelFunc: concat + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class Conv2DProgram { + constructor(convInfo, addBias = false, activation = null, hasPreluActivationWeights = false, hasLeakyreluAlpha = false) { + this.variableNames = ['x', 'W']; + this.outputShape = convInfo.outShape; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const inputDepthNearestVec4 = Math.floor(convInfo.inChannels / 4) * 4; + const inputDepthVec4Remainder = convInfo.inChannels % 4; + const isChannelsLast = convInfo.dataFormat === 'channelsLast'; + const rowDim = isChannelsLast ? 1 : 2; + const colDim = isChannelsLast ? 2 : 3; + const channelDim = isChannelsLast ? 3 : 1; + let activationSnippet = '', applyActivationSnippet = ''; + if (activation) { + if (hasPreluActivationWeights) { + activationSnippet = `float activation(float a) { + float b = getPreluActivationWeightsAtOutCoords(); + ${activation} + }`; + } + else if (hasLeakyreluAlpha) { + activationSnippet = `float activation(float a) { + float b = getLeakyreluAlphaAtOutCoords(); + ${activation} + }`; + } + else { + activationSnippet = ` + float activation(float x) { + ${activation} + } + `; + } + applyActivationSnippet = `result = activation(result);`; + } + const addBiasSnippet = addBias ? 'result += getBiasAtOutCoords();' : ''; + if (addBias) { + this.variableNames.push('bias'); + } + if (hasPreluActivationWeights) { + this.variableNames.push('preluActivationWeights'); + } + if (hasLeakyreluAlpha) { + this.variableNames.push('leakyreluAlpha'); + } + this.userCode = ` + ${activationSnippet} + + const ivec2 strides = ivec2(${strideHeight}, ${strideWidth}); + const ivec2 pads = ivec2(${padTop}, ${padLeft}); + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords[0]; + int d2 = coords[${channelDim}]; + + ivec2 xRCCorner = + ivec2(coords[${rowDim}], coords[${colDim}]) * strides - pads; + int xRCorner = xRCCorner.x; + int xCCorner = xRCCorner.y; + + // Convolve x(?, ?, d1) with w(:, :, d1, d2) to get y(yR, yC, d2). + // ? = to be determined. : = across all values in that axis. + float dotProd = 0.0; + for (int wR = 0; wR < ${filterHeight}; wR++) { + int xR = xRCorner + wR * ${dilationHeight}; + + if (xR < 0 || xR >= ${convInfo.inHeight}) { + continue; + } + + for (int wC = 0; wC < ${filterWidth}; wC++) { + int xC = xCCorner + wC * ${dilationWidth}; + + if (xC < 0 || xC >= ${convInfo.inWidth}) { + continue; + } + + for (int d1 = 0; d1 < ${inputDepthNearestVec4}; d1 += 4) { + vec4 wValues = vec4( + getW(wR, wC, d1, d2), + getW(wR, wC, d1 + 1, d2), + getW(wR, wC, d1 + 2, d2), + getW(wR, wC, d1 + 3, d2) + ); + + if (${isChannelsLast}) { + vec4 xValues = vec4( + getX(batch, xR, xC, d1), + getX(batch, xR, xC, d1 + 1), + getX(batch, xR, xC, d1 + 2), + getX(batch, xR, xC, d1 + 3) + ); + dotProd += dot(xValues, wValues); + } else { + vec4 xValues = vec4( + getX(batch, d1, xR, xC), + getX(batch, d1 + 1, xR, xC), + getX(batch, d1 + 2, xR, xC), + getX(batch, d1 + 3, xR, xC) + ); + dotProd += dot(xValues, wValues); + } + } + + if (${inputDepthVec4Remainder === 1}) { + + if (${isChannelsLast}) { + dotProd += + getX(batch, xR, xC, ${inputDepthNearestVec4}) * + getW(wR, wC, ${inputDepthNearestVec4}, d2); + } else { + dotProd += + getX(batch, ${inputDepthNearestVec4}, xR, xC) * + getW(wR, wC, ${inputDepthNearestVec4}, d2); + } + + } else if (${inputDepthVec4Remainder === 2}) { + vec2 wValues = vec2( + getW(wR, wC, ${inputDepthNearestVec4}, d2), + getW(wR, wC, ${inputDepthNearestVec4} + 1, d2) + ); + + if (${isChannelsLast}) { + vec2 xValues = vec2( + getX(batch, xR, xC, ${inputDepthNearestVec4}), + getX(batch, xR, xC, ${inputDepthNearestVec4} + 1) + ); + dotProd += dot(xValues, wValues); + } else { + vec2 xValues = vec2( + getX(batch, ${inputDepthNearestVec4}, xR, xC), + getX(batch, ${inputDepthNearestVec4} + 1, xR, xC) + ); + dotProd += dot(xValues, wValues); + } + + } else if (${inputDepthVec4Remainder === 3}) { + vec3 wValues = vec3( + getW(wR, wC, ${inputDepthNearestVec4}, d2), + getW(wR, wC, ${inputDepthNearestVec4} + 1, d2), + getW(wR, wC, ${inputDepthNearestVec4} + 2, d2) + ); + + if (${isChannelsLast}) { + vec3 xValues = vec3( + getX(batch, xR, xC, ${inputDepthNearestVec4}), + getX(batch, xR, xC, ${inputDepthNearestVec4} + 1), + getX(batch, xR, xC, ${inputDepthNearestVec4} + 2) + ); + dotProd += dot(xValues, wValues); + } else { + vec3 xValues = vec3( + getX(batch, ${inputDepthNearestVec4}, xR, xC), + getX(batch, ${inputDepthNearestVec4} + 1, xR, xC), + getX(batch, ${inputDepthNearestVec4} + 2, xR, xC) + ); + dotProd += dot(xValues, wValues); + } + + } + } + } + + float result = dotProd; + ${addBiasSnippet} + ${applyActivationSnippet} + setOutput(result); + } + `; + } + } + class Conv3DProgram { + constructor(convInfo) { + this.variableNames = ['x', 'W']; + this.outputShape = convInfo.outShape; + const padFront = convInfo.padInfo.front; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationDepth = convInfo.dilationDepth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const filterDepth = convInfo.filterDepth; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const inputDepthNearestVec4 = Math.floor(convInfo.inChannels / 4) * 4; + const inputDepthVec4Remainder = convInfo.inChannels % 4; + this.userCode = ` + const ivec3 strides = ivec3(${strideDepth}, ${strideHeight}, ${strideWidth}); + const ivec3 pads = ivec3(${padFront}, ${padTop}, ${padLeft}); + + void main() { + ivec5 coords = getOutputCoords(); + int batch = coords.x; + int d2 = coords.u; + + ivec3 xFRCCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads; + int xFCorner = xFRCCorner.x; + int xRCorner = xFRCCorner.y; + int xCCorner = xFRCCorner.z; + + // Convolve x(?, ?, ?, d1) with w(:, :, :, d1, d2) to get + // y(yF, yR, yC, d2). ? = to be determined. : = across all + // values in that axis. + float dotProd = 0.0; + for (int wF = 0; wF < ${filterDepth}; wF++) { + int xF = xFCorner + wF * ${dilationDepth}; + + if (xF < 0 || xF >= ${convInfo.inDepth}) { + continue; + } + + for (int wR = 0; wR < ${filterHeight}; wR++) { + int xR = xRCorner + wR * ${dilationHeight}; + + if (xR < 0 || xR >= ${convInfo.inHeight}) { + continue; + } + + for (int wC = 0; wC < ${filterWidth}; wC++) { + int xC = xCCorner + wC * ${dilationWidth}; + + if (xC < 0 || xC >= ${convInfo.inWidth}) { + continue; + } + + for (int d1 = 0; d1 < ${inputDepthNearestVec4}; d1 += 4) { + vec4 xValues = vec4( + getX(batch, xF, xR, xC, d1), + getX(batch, xF, xR, xC, d1 + 1), + getX(batch, xF, xR, xC, d1 + 2), + getX(batch, xF, xR, xC, d1 + 3) + ); + vec4 wValues = vec4( + getW(wF, wR, wC, d1, d2), + getW(wF, wR, wC, d1 + 1, d2), + getW(wF, wR, wC, d1 + 2, d2), + getW(wF, wR, wC, d1 + 3, d2) + ); + + dotProd += dot(xValues, wValues); + } + + if (${inputDepthVec4Remainder === 1}) { + dotProd += + getX(batch, xF, xR, xC, ${inputDepthNearestVec4}) * + getW(wF, wR, wC, ${inputDepthNearestVec4}, d2); + } else if (${inputDepthVec4Remainder === 2}) { + vec2 xValues = vec2( + getX(batch, xF, xR, xC, ${inputDepthNearestVec4}), + getX(batch, xF, xR, xC, ${inputDepthNearestVec4} + 1) + ); + vec2 wValues = vec2( + getW(wF, wR, wC, ${inputDepthNearestVec4}, d2), + getW(wF, wR, wC, ${inputDepthNearestVec4} + 1, d2) + ); + dotProd += dot(xValues, wValues); + } else if (${inputDepthVec4Remainder === 3}) { + vec3 xValues = vec3( + getX(batch, xF, xR, xC, ${inputDepthNearestVec4}), + getX(batch, xF, xR, xC, ${inputDepthNearestVec4} + 1), + getX(batch, xF, xR, xC, ${inputDepthNearestVec4} + 2) + ); + vec3 wValues = vec3( + getW(wF, wR, wC, ${inputDepthNearestVec4}, d2), + getW(wF, wR, wC, ${inputDepthNearestVec4} + 1, d2), + getW(wF, wR, wC, ${inputDepthNearestVec4} + 2, d2) + ); + dotProd += dot(xValues, wValues); + } + } + } + } + setOutput(dotProd); + } + `; + } + } + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class Conv2DPackedProgram { + constructor(convInfo, addBias = false, activation = null, hasPreluActivation = false, hasLeakyReluAlpha = false) { + this.variableNames = ['x', 'W']; + this.packedInputs = true; + this.packedOutput = true; + this.customUniforms = [ + { name: 'pads', type: 'ivec2' }, + { name: 'strides', type: 'ivec2' }, + { name: 'dilations', type: 'ivec2' }, + { name: 'inDims', type: 'ivec2' }, + ]; + this.outputShape = convInfo.outShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + const padLeft = convInfo.padInfo.left; + const strideWidth = convInfo.strideWidth; + const dilationWidth = convInfo.dilationWidth; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const texelsAcross = filterWidth; + let mainLoop = ` + int xR; int xC; int xCOffset; + vec4 wTexel; vec4 previous; vec4 final;`; + for (let c = 0; c < filterWidth; c++) { + mainLoop += ` + vec4 xTexelC${c * 2}; + int xTexelC${c * 2}Ready; + vec4 xTexelC${c * 2 + 1}; + int xTexelC${c * 2 + 1}Ready; + vec4 xC${c};`; + } + /** + * This vectorized implementation works by gathering the values needed for + * each output channel's dot product into vec4's and then multiplying them + * all together (this happens in the final double for-loop below). Most of + * the main loop consists of constructing these vec4's with the minimum + * number of texture2D calls, which means making use of all four returned + * values from a texture2D call at once. + */ + mainLoop += ` + for (int r = 0; r < ${filterHeight}; r++) { + for (int d1 = 0; d1 < ${convInfo.inChannels}; d1 += 2) { + `; + for (let c = 0; c < filterWidth; c++) { + mainLoop += ` + xTexelC${c * 2} = vec4(0.0); + xTexelC${c * 2}Ready = 0; + xTexelC${c * 2 + 1} = vec4(0.0); + xTexelC${c * 2 + 1}Ready = 0; + xC${c} = vec4(0.0);`; + } + mainLoop += ` + xR = xRCorner + r * dilations[0]; + if (xR >=0 && xR < inDims[0]) { + `; + for (let texelC = 0; texelC < (texelsAcross + 1) / 2; texelC++) { + const colIndex = texelC * 2; + mainLoop += ` + xC = xCCorner + ${colIndex * dilationWidth}; + `; + if (strideWidth === 1) { + if (colIndex < filterWidth) { + // If padding is odd, the outer texels have to be composed. + if (padLeft % 2 === 1) { + // TODO: Ensure vec4 previous does not result in redundant sample, + // and avoid setting xTexelRC's that exceed the boundary in the + // first place rather than resetting them to vec4(0)). + // To compute xCOffset: + // - If padding is odd, we must add 1 to ensure we ask for an + // even-numbered row. + // - We subtract 2 to access the previous texel. + mainLoop += ` + xCOffset = xC + 1; + if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex}Ready == 0) { + xTexelC${colIndex} = getX(batch, xR, xCOffset, d1); + + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex}.zw = vec2(0.0); + } + xTexelC${colIndex}Ready = 1; + } + `; + // This texel has been read in previous iteration if the dilation + // is 1. + if (dilationWidth === 1 && colIndex > 0) { + mainLoop += ` + xC${colIndex} = vec4(xTexelC${colIndex - 2}.zw, xTexelC${colIndex}.xy); + `; + } + else { + mainLoop += ` + xCOffset = xC + 1 - 2; + + if (xCOffset >= 0 && xCOffset < inDims[1]) { + previous = getX(batch, xR, xCOffset, d1); + + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xCOffset + 1 >= inDims[1]) { + previous.zw = vec2(0.0); + } + + xC${colIndex} = vec4(previous.zw, xTexelC${colIndex}.xy); + } else { + xC${colIndex} = vec4(0.0, 0.0, xTexelC${colIndex}.xy); + } + `; + } + } + else { + // Padding is even, so xRC corresponds to a single texel. + mainLoop += ` + if (xC >= 0 && xC < inDims[1] && xTexelC${colIndex}Ready == 0) { + xTexelC${colIndex} = getX(batch, xR, xC, d1); + if (xC + 1 >= inDims[1]) { + xTexelC${colIndex}.zw = vec2(0.0); + } + xTexelC${colIndex}Ready = 1; + } + + xC${colIndex} = xTexelC${colIndex}; + `; + } + if (colIndex + 1 < filterWidth) { + // If dilation is even, the second entry should match the first + // (either both are composed or both are single samples). But if + // dilation is odd, then the second entry should be the opposite + // of the first (if the first is composed, the second is a single + // sample, and vice versa.) + const nextTexelOffset = padLeft % 2 === 0 ? + nearestLargerEven(dilationWidth) : + dilationWidth; + if ((dilationWidth % 2 === 0 && padLeft % 2 === 1) || + (dilationWidth % 2 !== 0 && padLeft % 2 !== 1)) { + mainLoop += ` + xCOffset = xC + imod(pads[1], 2) + ${nextTexelOffset}; + + if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex + 1}Ready == 0) { + xTexelC${colIndex + 1} = getX(batch, xR, xCOffset, d1); + + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex + 1}.zw = vec2(0.0); + } + xTexelC${colIndex + 1}Ready = 1; + } + `; + // If dilation > 1 then the xRC's will not be able to share any + // values, so each xRC will require two unique calls to getX. + if (dilationWidth > 1) { + mainLoop += ` + xCOffset -= 2; + if (xCOffset >= 0 && xCOffset < inDims[1]) { + previous = getX(batch, xR, xCOffset, d1); + xC${colIndex + 1} = vec4(previous.zw, xTexelC${colIndex + 1}.xy); + } else { + xC${colIndex + 1} = vec4(0.0, 0.0, xTexelC${colIndex + 1}.xy); + } + `; + } + else { + mainLoop += ` + xC${colIndex + 1} = vec4(xTexelC${colIndex}.zw, xTexelC${colIndex + 1}.xy); + `; + } + } + else { + // If dilation is 1 and padding is odd, we have already read the + // texel when constructing the previous x value. Here we can + // simply skip the texture read. + if (nextTexelOffset === 1) { + mainLoop += ` + xC${colIndex + 1} = xTexelC${colIndex}; + `; + } + else { + mainLoop += ` + xCOffset = xC + ${nextTexelOffset}; + + if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex + 1}Ready == 0) { + xTexelC${colIndex + 1} = getX(batch, xR, xCOffset, d1); + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex + 1}.zw = vec2(0.0); + } + xTexelC${colIndex + 1}Ready = 1; + } + + xC${colIndex + 1} = xTexelC${colIndex + 1}; + `; + } + } + } + } + } + else { // stride === 2 + if (colIndex < filterWidth) { + // Depending on whether padLeft is even or odd, we want either the + // xy or zw channels from X texels for xC${colIndex}. If padLeft is + // even, xC${colIndex +1} is simply the zw channels of texels we've + // already sampled. But if padLeft is odd, xC{$c + 1}.zw will + // need to come from the xy channels of a new texel, hence the ` + // vec4 + // final` initialized below. + if (padLeft % 2 === 1) { + mainLoop += ` + xCOffset = xC + 1 - strides[1]; + if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex}Ready == 0) { + xTexelC${colIndex} = getX(batch, xR, xCOffset, d1); + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex}.zw = vec2(0.0); + } + xTexelC${colIndex}Ready = 1; + } + + if(xC + 1 >= 0 && xC + 1 < inDims[1] && xTexelC${colIndex + 1}Ready == 0) { + xTexelC${colIndex + 1} = getX(batch, xR, xC + 1, d1); + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xC + 2 >= inDims[1]) { + xTexelC${colIndex + 1}.zw = vec2(0.0); + } + xTexelC${colIndex + 1}Ready = 1; + } + + xC${colIndex} = vec4(xTexelC${colIndex}.zw, xTexelC${colIndex + 1}.zw); + `; + if (colIndex + 1 < filterWidth) { + mainLoop += ` + final = vec4(0.0); + xCOffset = xC + 1 + strides[1]; + if(xCOffset >= 0 && xCOffset < inDims[1]) { + final = getX(batch, xR, xCOffset, d1); + } + xC${colIndex + 1} = vec4(xTexelC${colIndex + 1}.xy, final.xy); + `; + } + } + else { + mainLoop += ` + if(xC >= 0 && xC < inDims[1] && xTexelC${colIndex}Ready == 0) { + xTexelC${colIndex} = getX(batch, xR, xC, d1); + if (xC + 1 >= inDims[1]) { + xTexelC${colIndex}.zw = vec2(0.0); + } + xTexelC${colIndex}Ready = 1; + } + + xCOffset = xC + strides[1]; + if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex + 1}Ready == 0) { + xTexelC${colIndex + 1} = getX(batch, xR, xCOffset, d1); + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex + 1}.zw = vec2(0.); + } + xTexelC${colIndex + 1}Ready = 1; + } + + xC${colIndex} = vec4( + xTexelC${colIndex}.xy, xTexelC${colIndex + 1}.xy); + `; + if (colIndex + 1 < filterWidth) { + mainLoop += ` + xC${colIndex + 1} = vec4(xTexelC${colIndex}.zw, xTexelC${colIndex + 1}.zw); + `; + } + } + } + } + // localize the dotProd accumulation within the loop, the theory is for + // GPU with limited cache, accumulate sum across large amount of + // veriables will cause lots of cache misses. (i.e. 5x5 filter will have + // 50 variables) + if (colIndex < filterWidth) { + mainLoop += ` + wTexel = getW(r, ${colIndex}, d1, d2); + dotProd += xC${colIndex}.xxzz * vec4(wTexel.xy, wTexel.xy); + if(d1 + 1 < ${convInfo.inChannels}) { + dotProd += xC${colIndex}.yyww * vec4(wTexel.zw, wTexel.zw); + } + `; + if (colIndex + 1 < filterWidth) { + mainLoop += ` + wTexel = getW(r, ${colIndex + 1}, d1, d2); + dotProd += xC${colIndex + 1}.xxzz * vec4(wTexel.xy, wTexel.xy); + if(d1 + 1 < ${convInfo.inChannels}) { + dotProd += xC${colIndex + 1}.yyww * vec4(wTexel.zw, wTexel.zw); + } + `; + } + } + } + mainLoop += ` + } + `; + mainLoop += ` + } + `; + mainLoop += ` + } + `; + let activationSnippet = '', applyActivationSnippet = ''; + if (activation) { + if (hasPreluActivation) { + activationSnippet = `vec4 activation(vec4 a) { + vec4 b = getPreluActivationWeightsAtOutCoords(); + ${activation} + }`; + } + else if (hasLeakyReluAlpha) { + activationSnippet = `vec4 activation(vec4 a) { + vec4 b = getLeakyreluAlphaAtOutCoords(); + ${activation} + }`; + } + else { + activationSnippet = `vec4 activation(vec4 x) { + ${activation} + }`; + } + applyActivationSnippet = `result = activation(result);`; + } + const addBiasSnippet = addBias ? 'result += getBiasAtOutCoords();' : ''; + if (addBias) { + this.variableNames.push('bias'); + } + if (hasPreluActivation) { + this.variableNames.push('preluActivationWeights'); + } + if (hasLeakyReluAlpha) { + this.variableNames.push('leakyreluAlpha'); + } + this.userCode = ` + ${activationSnippet} + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + ivec2 xRCCorner = coords.yz * strides - pads; + int d2 = coords.w; + int xRCorner = xRCCorner.x; + int xCCorner = xRCCorner.y; + + //intialize dotProd with a small epsilon seems to reduce GPU accuracy loss. + vec4 dotProd = vec4(0.000000000000001); + + ${mainLoop} + + vec4 result = dotProd - vec4(0.000000000000001); + ${addBiasSnippet} + ${applyActivationSnippet} + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class Im2ColPackedProgram { + constructor(outputShape, convInfo) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = true; + this.customUniforms = [ + { name: 'inputShape', type: 'ivec4' }, + { name: 'pad', type: 'ivec2' }, + { name: 'stride', type: 'ivec2' }, + { name: 'dilation', type: 'ivec2' }, + { name: 'inChannels', type: 'int' }, + { name: 'itemsPerBlockRow', type: 'int' }, + { name: 'outWidth', type: 'int' }, + ]; + this.outputShape = outputShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + const { dataFormat } = convInfo; + const glsl = getGlslDifferences(); + const isChannelsLast = dataFormat === 'channelsLast'; + const rowDim = isChannelsLast ? 1 : 2; + const colDim = isChannelsLast ? 2 : 3; + const boundsCheckingSnippet = this.enableShapeUniforms ? + 'if(blockIndex < outShape[2] && pos < outShape[1]) {' : + `if(blockIndex < ${outputShape[2]} && pos < ${outputShape[1]}) {`; + let unrolled = ``; + for (let row = 0; row <= 1; row++) { + for (let col = 0; col <= 1; col++) { + unrolled += ` + blockIndex = rc.z + ${col}; + pos = rc.y + ${row}; + + ${boundsCheckingSnippet} + offsetY = int(blockIndex / outWidth) * stride[0] - pad[0]; + d0 = offsetY + dilation[0] * (pos / itemsPerBlockRow); + + if(d0 < inputShape[${rowDim}] && d0 >= 0) { + // Use custom imod instead mod. On Intel GPU, mod may generate + // unexpected value. + // https://github.com/tensorflow/tfjs/issues/5447 + offsetX = imod(blockIndex, outWidth) * stride[1] - pad[1]; + d1 = offsetX + dilation[1] * (imod(pos, itemsPerBlockRow) / + inChannels); + + if(d1 < inputShape[${colDim}] && d1 >= 0) { + + ch = imod(pos, inChannels); + + if (${isChannelsLast}) { + innerDims = vec2(d1, ch); + result[${row * 2 + col}] = getChannel( + getA(rc.x, d0, int(innerDims.x), + int(innerDims.y)), innerDims); + } else { + innerDims = vec2(d0, d1); + result[${row * 2 + col}] = getChannel( + getA(rc.x, ch, int(innerDims.x), + int(innerDims.y)), innerDims); + } + } + } + } + `; + } + } + this.userCode = ` + void main() { + ivec3 rc = getOutputCoords(); + + vec4 result = vec4(0); + + int blockIndex, pos, offsetY, d0, offsetX, d1, ch; + vec2 innerDims; + + ${unrolled} + + ${glsl.output} = result; + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Both conv2dByMatMul and conv2dWithIm2Row fuse height and width into one + // dimension to compute batchMatMul, so bias and activation weights are also + // supposed to fuse the two dimensions into one. + // + // This function computes the target shape for fusing height and width + // dimensions. Returning null means the shape is already compatible. + // + // Even though the bias is not supposed to be a 3-D or a 4-D (including + // batch) tensor and PReLU activiation weights is not supposed to be a 4-D + // tensor, we still need to support them, because we haven't disabled + // them for NHWC format. + // https://github.com/tensorflow/tfjs/blob/b53bd47e880367ae57493f0ea628abaf08db2d5d/tfjs-core/src/ops/fused/conv2d.ts#L181-L196 + function getShapeForBatchMatMul(shape, isChannelsLast) { + const length = shape.length; + if (length >= 3) { + return isChannelsLast ? + [ + ...shape.slice(0, -3) /* batch */, + shape[length - 3] * shape[length - 2] /* height * width */, + shape[length - 1] /* channel */ + ] : + [ + ...shape.slice(0, -3) /* batch */, shape[length - 3] /* channel */, + shape[length - 2] * shape[length - 1] /* height * width */ + ]; + } + else if (!isChannelsLast && length === 1 && shape[0] > 1) { + return [shape[0], 1]; + } + else { + return null; + } + } + // For 1x1 kernels that iterate through every point in the input, convolution + // can be expressed as matrix multiplication (without need for memory + // remapping). + function conv2dByMatMul({ x, filter, convInfo, backend, bias = null, preluActivationWeights = null, leakyreluAlpha = 0, activation = null }) { + // Reshapes conv2D input to 2D tensors, uses matMul and then reshape the + // result from 2D to 4D. + const xShape = x.shape; + const xTexData = backend.texData.get(x.dataId); + const sharedMatMulDim = convInfo.inChannels; + const outerShapeX = xShape[0] * xShape[1] * xShape[2]; + const outerShapeFilter = convInfo.outChannels; + const isChannelsLast = convInfo.dataFormat === 'channelsLast'; + const transposeA = false; + const transposeB = false; + let out; + const intermediates = []; + if (preluActivationWeights != null) { + const targetShape = getShapeForBatchMatMul(preluActivationWeights.shape, isChannelsLast); + if (targetShape != null) { + preluActivationWeights = reshape({ + inputs: { x: preluActivationWeights }, + backend, + attrs: { shape: targetShape } + }); + intermediates.push(preluActivationWeights); + } + } + if (bias != null) { + const targetShape = getShapeForBatchMatMul(bias.shape, isChannelsLast); + if (targetShape != null) { + bias = reshape({ inputs: { x: bias }, backend, attrs: { shape: targetShape } }); + intermediates.push(bias); + } + } + // TODO: Once reduction ops are packed, batchMatMul will always be packed + // and we can remove this condition. + const batchMatMulWillBeUnpacked = (outerShapeX === 1 || outerShapeFilter === 1) && + sharedMatMulDim > MATMUL_SHARED_DIM_THRESHOLD; + // The algorithm in the if condition assumes (1) the output will be packed, + // (2) x is packed, (3) x isChannelsLast, (4) x's packed texture is already + // on GPU, (5) col is odd, (6) the width, height and inChannels are the same + // for xTexData.shape and xShape. + const canOptimize = !batchMatMulWillBeUnpacked && xTexData.isPacked && + isChannelsLast && xTexData.texture != null && xShape[2] % 2 !== 0 && + arraysEqual(xTexData.shape.slice(-3), xShape.slice(-3)); + if (canOptimize) { + // We avoid expensive packed 2x2 reshape by padding col count to next, + // even number. When col is odd, the result of packed batchMatMul is + // the same (has the same texture layout and and values in the texture) as + // it is for next even col. We make the odd-cols tensor to look like + // even-cols tensor before the operation and, after the batchMatMul, + // fix the even-cols result to have odd number of cols. + const targetShape = xShape[0] * xShape[1] * (xShape[2] + 1); + const xReshaped = { + dataId: x.dataId, + shape: [1, targetShape, convInfo.inChannels], + dtype: x.dtype + }; + // xTexData.shape gets referenced from GPGPUBinary.inShapeInfos. + // Decrementing col count, after batchMatMul->...->compileProgram leads to + // invalid col count within the reference in GPGPUBinary.inShapeInfos. + // Alternative fix would be to provide a copy to GPGPUBinary.inShapeInfos + // in compileProgram method, but that would affect compilation of all + // programs - instead, provide a copy here, with even col count, before + // calling batchMatMul->...->compileProgram and after that, the original + // xTexData.shape is restored. + const originalXTexDataShape = xTexData.shape; + xTexData.shape = xTexData.shape.slice(); + xTexData.shape[xTexData.shape.length - 2]++; + assert$1(isReshapeFree(xTexData.shape, xReshaped.shape), () => `packed reshape ${xTexData.shape} to ${xReshaped.shape} isn't free`); + const filterReshaped = reshape({ + inputs: { x: filter }, + backend, + attrs: { shape: [1, convInfo.inChannels, convInfo.outChannels] } + }); + intermediates.push(filterReshaped); + const pointwiseConv = batchMatMulImpl({ + a: xReshaped, + b: filterReshaped, + backend, + transposeA, + transposeB, + bias, + activation, + preluActivationWeights, + leakyreluAlpha + }); + const pointwiseConvTexData = backend.texData.get(pointwiseConv.dataId); + assert$1(pointwiseConvTexData.isPacked, () => 'batchMatMul result is expected to be packed'); + // Restore the input shape to original. + xTexData.shape = originalXTexDataShape; + // Set the output shape - there is no need for expensive reshape as data + // layout is already correct. + pointwiseConvTexData.shape = convInfo.outShape; + out = identity({ inputs: { x: pointwiseConv }, backend }); + out.shape = convInfo.outShape; + intermediates.push(pointwiseConv); + } + else { + const numCols = convInfo.outHeight * convInfo.outWidth; + const xReshaped = reshape({ + inputs: { x }, + backend, + attrs: { + shape: isChannelsLast ? + [convInfo.batchSize, numCols, convInfo.inChannels] : + [convInfo.batchSize, convInfo.inChannels, numCols] + } + }); + const filterReshaped = reshape({ + inputs: { x: filter }, + backend, + attrs: { shape: [1, convInfo.inChannels, convInfo.outChannels] } + }); + const result = batchMatMulImpl({ + a: isChannelsLast ? xReshaped : filterReshaped, + b: isChannelsLast ? filterReshaped : xReshaped, + transposeA: !isChannelsLast, + transposeB, + backend, + bias, + activation, + preluActivationWeights, + leakyreluAlpha + }); + out = reshape({ inputs: { x: result }, backend, attrs: { shape: convInfo.outShape } }); + intermediates.push(xReshaped); + intermediates.push(filterReshaped); + intermediates.push(result); + } + for (const i of intermediates) { + backend.disposeIntermediateTensorInfo(i); + } + return out; + } + // Implements the im2row algorithm as outlined in "High Performance + // Convolutional Neural Networks for Document Processing" (Suvisoft, 2006) + function conv2dWithIm2Row({ x, filter, convInfo, backend, bias = null, preluActivationWeights = null, leakyreluAlpha = 0, activation = null }) { + // Rearranges conv2d input so each block to be convolved over forms the + // column of a new matrix with shape [filterWidth * filterHeight * + // inChannels, outHeight * outWidth]. The filter is also rearranged so each + // output channel forms a row of a new matrix with shape [outChannels, + // filterWidth * filterHeight * inChannels]. The convolution is then + // computed by multiplying these matrices and reshaping the result. + const { filterWidth, filterHeight, inChannels, outWidth, outHeight, dataFormat } = convInfo; + const isChannelsLast = dataFormat === 'channelsLast'; + const sharedDim = filterWidth * filterHeight * inChannels; + const numCols = outHeight * outWidth; + const x2ColShape = [convInfo.batchSize, sharedDim, numCols]; + const transposeA = true; + const transposeB = false; + const intermediates = []; + if (preluActivationWeights != null) { + const targetShape = getShapeForBatchMatMul(preluActivationWeights.shape, isChannelsLast); + if (targetShape != null) { + preluActivationWeights = reshape({ + inputs: { x: preluActivationWeights }, + backend, + attrs: { shape: targetShape } + }); + intermediates.push(preluActivationWeights); + } + } + if (bias != null) { + const targetShape = getShapeForBatchMatMul(bias.shape, isChannelsLast); + if (targetShape != null) { + bias = reshape({ inputs: { x: bias }, backend, attrs: { shape: targetShape } }); + intermediates.push(bias); + } + } + const w2Row = reshape({ + inputs: { x: filter }, + backend, + attrs: { shape: [1, sharedDim, sizeFromShape(filter.shape) / sharedDim] } + }); + intermediates.push(w2Row); + const im2ColProgram = new Im2ColPackedProgram(x2ColShape, convInfo); + const customValues = [ + x.shape, [convInfo.padInfo.top, convInfo.padInfo.left], + [convInfo.strideHeight, convInfo.strideWidth], + [convInfo.dilationHeight, convInfo.dilationWidth], [convInfo.inChannels], + [convInfo.filterWidth * convInfo.inChannels], [convInfo.outWidth] + ]; + const im2Col = backend.runWebGLProgram(im2ColProgram, [x], 'float32', customValues); + const im2ColReshaped = reshape({ inputs: { x: im2Col }, backend, attrs: { shape: x2ColShape } }); + intermediates.push(im2Col); + intermediates.push(im2ColReshaped); + const hasBias = bias != null; + const hasPreluActivationWeights = preluActivationWeights != null; + const hasLeakyreluAlpha = activation === 'leakyrelu'; + const fusedActivation = activation ? mapActivationToShaderProgram(activation, true) : null; + const matmulProgram = new MatMulPackedProgram(isChannelsLast ? im2ColReshaped.shape : + w2Row.shape, isChannelsLast ? w2Row.shape : + im2ColReshaped.shape, isChannelsLast ? [convInfo.batchSize, numCols, convInfo.outChannels] : + [convInfo.batchSize, convInfo.outChannels, numCols], transposeA, transposeB, hasBias, fusedActivation, hasPreluActivationWeights, hasLeakyreluAlpha); + const inputs = isChannelsLast ? [im2ColReshaped, w2Row] : [w2Row, im2ColReshaped]; + if (bias) { + inputs.push(bias); + } + if (hasPreluActivationWeights) { + inputs.push(preluActivationWeights); + } + if (hasLeakyreluAlpha) { + const $leakyreluAlpha = backend.makeTensorInfo([], 'float32', createScalarValue(leakyreluAlpha, 'float32')); + inputs.push($leakyreluAlpha); + intermediates.push($leakyreluAlpha); + } + const product = backend.runWebGLProgram(matmulProgram, inputs, 'float32'); + const out = reshape({ inputs: { x: product }, backend, attrs: { shape: convInfo.outShape } }); + intermediates.push(product); + for (const i of intermediates) { + backend.disposeIntermediateTensorInfo(i); + } + return out; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv2d(args) { + const { inputs, backend, attrs } = args; + const { x, filter } = inputs; + const { strides, pad, dataFormat, dilations, dimRoundingMode } = attrs; + const $dataFormat = convertConv2DDataFormat(dataFormat); + const convInfo = computeConv2DInfo(x.shape, filter.shape, strides, dilations, pad, dimRoundingMode, false /* depthwise */, $dataFormat); + let out; + if (convInfo.filterHeight === 1 && convInfo.filterWidth === 1 && + convInfo.dilationHeight === 1 && convInfo.dilationWidth === 1 && + convInfo.strideHeight === 1 && convInfo.strideWidth === 1 && + (convInfo.padInfo.type === 'SAME' || convInfo.padInfo.type === 'VALID')) { + out = conv2dByMatMul({ x, filter, convInfo, backend }); + } + else if (convInfo.strideWidth <= 2 && $dataFormat === 'channelsLast' + && env().getBool('WEBGL_EXP_CONV')) { + const program = new Conv2DPackedProgram(convInfo); + const customValues = [ + [convInfo.padInfo.top, convInfo.padInfo.left], + [convInfo.strideHeight, convInfo.strideWidth], + [convInfo.dilationHeight, convInfo.dilationWidth], + [convInfo.inHeight, convInfo.inWidth] + ]; + out = + backend.runWebGLProgram(program, [x, filter], 'float32', customValues); + } + else if (env().getBool('WEBGL_CONV_IM2COL')) { + out = conv2dWithIm2Row({ x, filter, convInfo, backend }); + } + else { + const program = new Conv2DProgram(convInfo); + out = backend.runWebGLProgram(program, [x, filter], 'float32'); + } + const outReshaped = reshape({ inputs: { x: out }, backend, attrs: { shape: convInfo.outShape } }); + backend.disposeIntermediateTensorInfo(out); + return outReshaped; + } + const conv2DConfig = { + kernelName: Conv2D$1, + backendName: 'webgl', + kernelFunc: conv2d, + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class Conv2DDerFilterProgram { + constructor(convInfo) { + this.variableNames = ['x', 'dy']; + this.outputShape = convInfo.filterShape; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + const isChannelsLast = convInfo.dataFormat === 'channelsLast'; + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int wR = coords.x; + int wC = coords.y; + int d1 = coords.z; + int d2 = coords.w; + + // Convolve x(?, ?, d1) with dy(:, :, d2) to get dw(wR, wC, d1, d2). + // ? = to be determined. : = across all values in that axis. + float dotProd = 0.0; + + for (int b = 0; b < ${convInfo.batchSize}; b++) { + for (int yR = 0; yR < ${convInfo.outHeight}; yR++) { + int xR = wR + yR * ${strideHeight} - ${padTop}; + + if (xR < 0 || xR >= ${convInfo.inHeight}) { + continue; + } + + for (int yC = 0; yC < ${convInfo.outWidth}; yC++) { + int xC = wC + yC * ${strideWidth} - ${padLeft}; + + if (xC < 0 || xC >= ${convInfo.inWidth}) { + continue; + } + + ${isChannelsLast ? + `float dyValue = getDy(b, yR, yC, d2); + float xValue = getX(b, xR, xC, d1); + dotProd += (xValue * dyValue);` : + `float dyValue = getDy(b, d2, yR, yC); + float xValue = getX(b, d1, xR, xC); + dotProd += (xValue * dyValue);`} + } + } + } + setOutput(dotProd); + } + `; + } + } + class Conv2DDerInputProgram { + constructor(convInfo) { + this.variableNames = ['dy', 'W']; + this.outputShape = convInfo.inShape; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const isChannelsLast = convInfo.dataFormat === 'channelsLast'; + const padTop = filterHeight - 1 - convInfo.padInfo.top; + const padLeft = filterWidth - 1 - convInfo.padInfo.left; + const rowDim = isChannelsLast ? 1 : 2; + const colDim = isChannelsLast ? 2 : 3; + const channelDim = isChannelsLast ? 3 : 1; + this.userCode = ` + const ivec2 pads = ivec2(${padTop}, ${padLeft}); + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords[0]; + int d1 = coords[${channelDim}]; + + ivec2 dyCorner = ivec2(coords[${rowDim}], coords[${colDim}]) - pads; + int dyRCorner = dyCorner.x; + int dyCCorner = dyCorner.y; + + // Convolve dy(?, ?, d2) with w(:, :, d1, d2) to compute dx(xR, xC, d1). + // ? = to be determined. : = across all values in that axis. + float dotProd = 0.0; + for (int wR = 0; wR < ${filterHeight}; wR++) { + float dyR = float(dyRCorner + wR) / ${strideHeight}.0; + + if (dyR < 0.0 || dyR >= ${convInfo.outHeight}.0 || fract(dyR) > 0.0) { + continue; + } + int idyR = int(dyR); + + int wRPerm = ${filterHeight} - 1 - wR; + + for (int wC = 0; wC < ${filterWidth}; wC++) { + float dyC = float(dyCCorner + wC) / ${strideWidth}.0; + + if (dyC < 0.0 || dyC >= ${convInfo.outWidth}.0 || + fract(dyC) > 0.0) { + continue; + } + int idyC = int(dyC); + + int wCPerm = ${filterWidth} - 1 - wC; + + for (int d2 = 0; d2 < ${convInfo.outChannels}; d2++) { + + if (${isChannelsLast}) { + float xValue = getDy(batch, idyR, idyC, d2); + float wValue = getW(wRPerm, wCPerm, d1, d2); + dotProd += xValue * wValue; + } else { + float xValue = getDy(batch, d2, idyR, idyC); + float wValue = getW(wRPerm, wCPerm, d1, d2); + dotProd += xValue * wValue; + } + + } + } + } + setOutput(dotProd); + } + `; + } + } + class Conv3DDerFilterProgram { + constructor(convInfo) { + this.variableNames = ['x', 'dy']; + this.outputShape = convInfo.filterShape; + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const padFront = convInfo.padInfo.front; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + this.userCode = ` + void main() { + ivec5 coords = getOutputCoords(); + int wF = coords.x; + int wR = coords.y; + int wC = coords.z; + int d1 = coords.w; + int d2 = coords.u; + + float dotProd = 0.0; + + for (int b = 0; b < ${convInfo.batchSize}; b++) { + for (int yF = 0; yF < ${convInfo.outDepth}; yF++) { + int xF = wF + yF * ${strideDepth} - ${padFront}; + + if (xF < 0 || xF >= ${convInfo.inDepth}) { + continue; + } + + for (int yR = 0; yR < ${convInfo.outHeight}; yR++) { + int xR = wR + yR * ${strideHeight} - ${padTop}; + + if (xR < 0 || xR >= ${convInfo.inHeight}) { + continue; + } + + for (int yC = 0; yC < ${convInfo.outWidth}; yC++) { + int xC = wC + yC * ${strideWidth} - ${padLeft}; + + if (xC < 0 || xC >= ${convInfo.inWidth}) { + continue; + } + + float dyValue = getDy(b, yF, yR, yC, d2); + float xValue = getX(b, xF, xR, xC, d1); + dotProd += (xValue * dyValue); + } + } + } + } + setOutput(dotProd); + } + `; + } + } + class Conv3DDerInputProgram { + constructor(convInfo) { + this.variableNames = ['dy', 'W']; + this.outputShape = convInfo.inShape; + const filterDepth = convInfo.filterDepth; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const padFront = filterDepth - 1 - convInfo.padInfo.front; + const padTop = filterHeight - 1 - convInfo.padInfo.top; + const padLeft = filterWidth - 1 - convInfo.padInfo.left; + this.userCode = ` + const ivec3 pads = ivec3(${padFront}, ${padTop}, ${padLeft}); + + void main() { + ivec5 coords = getOutputCoords(); + int batch = coords.x; + int d1 = coords.u; + + + ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads; + int dyFCorner = dyCorner.x; + int dyRCorner = dyCorner.y; + int dyCCorner = dyCorner.z; + + float dotProd = 0.0; + for (int wF = 0; wF < ${filterDepth}; wF++) { + float dyF = float(dyFCorner + wF) / ${strideDepth}.0; + + if (dyF < 0.0 || dyF >= ${convInfo.outDepth}.0 || fract(dyF) > 0.0) { + continue; + } + int idyF = int(dyF); + + int wFPerm = ${filterDepth} - 1 - wF; + + for (int wR = 0; wR < ${filterHeight}; wR++) { + float dyR = float(dyRCorner + wR) / ${strideHeight}.0; + + if (dyR < 0.0 || dyR >= ${convInfo.outHeight}.0 || + fract(dyR) > 0.0) { + continue; + } + int idyR = int(dyR); + + int wRPerm = ${filterHeight} - 1 - wR; + + for (int wC = 0; wC < ${filterWidth}; wC++) { + float dyC = float(dyCCorner + wC) / ${strideWidth}.0; + + if (dyC < 0.0 || dyC >= ${convInfo.outWidth}.0 || + fract(dyC) > 0.0) { + continue; + } + int idyC = int(dyC); + + int wCPerm = ${filterWidth} - 1 - wC; + + for (int d2 = 0; d2 < ${convInfo.outChannels}; d2++) { + float xValue = getDy(batch, idyF, idyR, idyC, d2); + float wValue = getW(wFPerm, wRPerm, wCPerm, d1, d2); + dotProd += xValue * wValue; + } + } + } + } + setOutput(dotProd); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv2DBackpropFilter(args) { + const { inputs, backend, attrs } = args; + const { x, dy } = inputs; + const { strides, pad, dataFormat, dimRoundingMode, filterShape } = attrs; + const $dataFormat = convertConv2DDataFormat(dataFormat); + const convInfo = computeConv2DInfo(x.shape, filterShape, strides, 1 /* dilations */, pad, dimRoundingMode, false /* depthwise */, $dataFormat); + const program = new Conv2DDerFilterProgram(convInfo); + return backend.runWebGLProgram(program, [x, dy], 'float32'); + } + const conv2DBackpropFilterConfig = { + kernelName: Conv2DBackpropFilter, + backendName: 'webgl', + kernelFunc: conv2DBackpropFilter, + }; + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class Conv2DDerInputPackedProgram { + constructor(convInfo) { + this.variableNames = ['dy', 'W']; + this.packedInputs = true; + this.packedOutput = true; + this.customUniforms = [ + { name: 'strides', type: 'vec2' }, + ]; + this.outputShape = convInfo.inShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const padTop = filterHeight - 1 - convInfo.padInfo.top; + const padLeft = filterWidth - 1 - convInfo.padInfo.left; + this.userCode = ` + const ivec2 pads = ivec2(${padTop}, ${padLeft}); + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords[0]; + int d1 = coords[3]; + + ivec2 dyCorner = ivec2(coords[1], coords[2]) - pads; + int dyRCorner = dyCorner.x; + int dyCCorner = dyCorner.y; + + vec4 result = vec4(0.); + for (int wR = 0; wR < ${filterHeight}; wR++) { + float dyR = float(dyRCorner + wR) / strides[0]; + if (dyR < 0.0 || dyR >= ${convInfo.outHeight}.0 || fract(dyR) > 0.0) { + continue; + } + int idyR = int(dyR); + int wRPerm = ${filterHeight} - 1 - wR; + + for (int wC = 0; wC < ${filterWidth}; wC++) { + int wCPerm = ${filterWidth} - 1 - wC; + + float dyC = float(dyCCorner + wC) / strides[1]; + bool idyCVal = (dyC >= 0.0) && (dyC < ${convInfo.outWidth}.0) + && (fract(dyC) == 0.0); + int idyC = int(dyC); + + float dyC2 = float(dyCCorner + wC + 1) / strides[1]; + bool idyCVal2 = (dyC2 >= 0.0) && (dyC2 < ${convInfo.outWidth}.0) + && (fract(dyC2) == 0.0); + int idyC2 = int(dyC2); + + if (idyCVal && idyCVal2) { + for (int d2 = 0; d2 < ${convInfo.outChannels}; d2 += 2) { + vec4 wValue = getW(wRPerm, wCPerm, d1, d2); + vec4 dySample = getDy(batch, idyR, idyC, d2); + vec4 dySample2 = (idyC / 2 == idyC2 / 2) ? + dySample : getDy(batch, idyR, idyC2, d2); + + vec2 dyValue = mod(float(idyC), 2.) == 0. ? + dySample.xy : dySample.zw; + result.xy += vec2(dot(dyValue, wValue.xy), + dot(dyValue, wValue.zw)); + + dyValue = mod(float(idyC2), 2.) == 0. ? + dySample2.xy : dySample2.zw; + result.zw += vec2(dot(dyValue, wValue.xy), + dot(dyValue, wValue.zw)); + } + } else if (idyCVal) { + for (int d2 = 0; d2 < ${convInfo.outChannels}; d2 += 2) { + vec4 wValue = getW(wRPerm, wCPerm, d1, d2); + vec4 dySample = getDy(batch, idyR, idyC, d2); + vec2 dyValue = mod(float(idyC), 2.) == 0. ? + dySample.xy : dySample.zw; + result.xy += vec2(dot(dyValue, wValue.xy), + dot(dyValue, wValue.zw)); + } + } else if (idyCVal2) { + for (int d2 = 0; d2 < ${convInfo.outChannels}; d2 += 2) { + vec4 wValue = getW(wRPerm, wCPerm, d1, d2); + vec4 dySample = getDy(batch, idyR, idyC2, d2); + vec2 dyValue = mod(float(idyC2), 2.) == 0. ? + dySample.xy : dySample.zw; + result.zw += vec2(dot(dyValue, wValue.xy), + dot(dyValue, wValue.zw)); + } + } + } + } + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv2DBackpropInput(args) { + const { inputs, backend, attrs } = args; + const { dy, filter } = inputs; + const { inputShape, strides, pad, dataFormat, dimRoundingMode } = attrs; + const $dataFormat = convertConv2DDataFormat(dataFormat); + const convInfo = computeConv2DInfo(inputShape, filter.shape, strides, 1 /* dilations */, pad, dimRoundingMode, false, $dataFormat); + if (env().getBool('WEBGL_PACK_CONV2DTRANSPOSE') && + $dataFormat === 'channelsLast') { + const customValues = [ + [convInfo.strideHeight, convInfo.strideWidth], + ]; + const program = new Conv2DDerInputPackedProgram(convInfo); + return backend.runWebGLProgram(program, [dy, filter], 'float32', customValues); + } + else { + const program = new Conv2DDerInputProgram(convInfo); + return backend.runWebGLProgram(program, [dy, filter], 'float32'); + } + } + const conv2DBackpropInputConfig = { + kernelName: Conv2DBackpropInput, + backendName: 'webgl', + kernelFunc: conv2DBackpropInput, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv3D(args) { + const { inputs, backend, attrs } = args; + const { x, filter } = inputs; + const { strides, pad, dilations } = attrs; + const convInfo = computeConv3DInfo(x.shape, filter.shape, strides, dilations, pad); + const program = new Conv3DProgram(convInfo); + return backend.runWebGLProgram(program, [x, filter], 'float32'); + } + const conv3DConfig = { + kernelName: Conv3D$1, + backendName: 'webgl', + kernelFunc: conv3D, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv3DBackpropFilterV2(args) { + const { inputs, backend, attrs } = args; + const { x, dy } = inputs; + const { strides, pad, filterShape } = attrs; + const convInfo = computeConv3DInfo(x.shape, filterShape, strides, 1 /* dilations */, pad); + const program = new Conv3DDerFilterProgram(convInfo); + return backend.runWebGLProgram(program, [x, dy], 'float32'); + } + const conv3DBackpropFilterV2Config = { + kernelName: Conv3DBackpropFilterV2, + backendName: 'webgl', + kernelFunc: conv3DBackpropFilterV2 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function conv3DBackpropInput(args) { + const { inputs, backend, attrs } = args; + const { dy, filter } = inputs; + const { pad, strides, inputShape } = attrs; + const convInfo = computeConv3DInfo(inputShape, filter.shape, strides, 1 /* dilations */, pad); + const program = new Conv3DDerInputProgram(convInfo); + return backend.runWebGLProgram(program, [dy, filter], 'float32'); + } + const conv3DBackpropInputConfig = { + kernelName: Conv3DBackpropInputV2, + backendName: 'webgl', + kernelFunc: conv3DBackpropInput, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const COS = CHECK_NAN_SNIPPET_UNARY + ` + return cos(x); +`; + const COS_PACKED = ` + vec4 result = cos(x); + bvec4 isNaN = isnan(x); + ${CHECK_NAN_SNIPPET_PACKED} + return result; +`; + const cos = unaryKernelFunc({ opSnippet: COS, packedOpSnippet: COS_PACKED }); + const cosConfig = { + kernelName: Cos, + backendName: 'webgl', + kernelFunc: cos, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const COSH = ` + float e2x = exp(-x); + return (e2x + 1.0 / e2x) / 2.0; +`; + const cosh = unaryKernelFunc({ opSnippet: COSH }); + const coshConfig = { + kernelName: Cosh, + backendName: 'webgl', + kernelFunc: cosh, + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class CropAndResizeProgram { + constructor(imageShape, boxShape, cropSize, method, extrapolationValue) { + this.variableNames = ['Image', 'Boxes', 'BoxInd']; + this.outputShape = []; + const [batch, imageHeight, imageWidth, depth] = imageShape; + const [numBoxes,] = boxShape; + const [cropHeight, cropWidth] = cropSize; + this.outputShape = [numBoxes, cropHeight, cropWidth, depth]; + const methodId = method === 'bilinear' ? 1 : 0; + const [inputHeightFloat, inputWidthFloat] = [`${imageHeight - 1}.0`, `${imageWidth - 1}.0`]; + const [heightRatio, heightScale, inY] = cropHeight > 1 ? + [ + `${(imageHeight - 1) / (cropHeight - 1)}`, + '(y2-y1) * height_ratio', + `y1*${inputHeightFloat} + float(y)*(height_scale)`, + ] : + [ + '0.0', + '0.0', + `0.5 * (y1+y2) * ${inputHeightFloat}`, + ]; + const [widthRatio, widthScale, inX] = cropWidth > 1 ? + [ + `${(imageWidth - 1) / (cropWidth - 1)}`, + '(x2-x1) * width_ratio', + `x1*${inputWidthFloat} + float(x)*(width_scale)`, + ] : + [ + '0.0', + '0.0', + `0.5 * (x1+x2) * ${inputWidthFloat}`, + ]; + // Reference implementation + // tslint:disable-next-line:max-line-length + // https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/crop_and_resize_op_gpu.cu.cc + this.userCode = ` + const float height_ratio = float(${heightRatio}); + const float width_ratio = float(${widthRatio}); + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int y = coords[1]; + int x = coords[2]; + int d = coords[3]; + + // get box vals + float y1 = getBoxes(b,0); + float x1 = getBoxes(b,1); + float y2 = getBoxes(b,2); + float x2 = getBoxes(b,3); + + // get image in batch index + int bInd = round(getBoxInd(b)); + if(bInd < 0 || bInd >= ${batch}) { + return; + } + + float height_scale = ${heightScale}; + float width_scale = ${widthScale}; + + float in_y = ${inY}; + if( in_y < 0.0 || in_y > ${inputHeightFloat} ) { + setOutput(float(${extrapolationValue})); + return; + } + float in_x = ${inX}; + if( in_x < 0.0 || in_x > ${inputWidthFloat} ) { + setOutput(float(${extrapolationValue})); + return; + } + + vec2 sourceFracIndexCR = vec2(in_x,in_y); + if(${methodId} == 1) { + // Compute the four integer indices. + ivec2 sourceFloorCR = ivec2(sourceFracIndexCR); + ivec2 sourceCeilCR = ivec2(ceil(sourceFracIndexCR)); + + float topLeft = getImage(b, sourceFloorCR.y, sourceFloorCR.x, d); + float bottomLeft = getImage(b, sourceCeilCR.y, sourceFloorCR.x, d); + float topRight = getImage(b, sourceFloorCR.y, sourceCeilCR.x, d); + float bottomRight = getImage(b, sourceCeilCR.y, sourceCeilCR.x, d); + + vec2 fracCR = sourceFracIndexCR - vec2(sourceFloorCR); + + float top = topLeft + (topRight - topLeft) * fracCR.x; + float bottom = bottomLeft + (bottomRight - bottomLeft) * fracCR.x; + float newValue = top + (bottom - top) * fracCR.y; + setOutput(newValue); + } else { + // Compute the coordinators of nearest neighbor point. + ivec2 sourceNearestCR = ivec2(floor( + sourceFracIndexCR + vec2(0.5,0.5))); + float newValue = getImage(b, sourceNearestCR.y, sourceNearestCR.x, d); + setOutput(newValue); + } + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const cropAndResize = (args) => { + const { inputs, backend, attrs } = args; + const { image, boxes, boxInd } = inputs; + const { cropSize, method, extrapolationValue } = attrs; + const program = new CropAndResizeProgram(image.shape, boxes.shape, cropSize, method, extrapolationValue); + return backend.runWebGLProgram(program, [image, boxes, boxInd], 'float32'); + }; + const cropAndResizeConfig = { + kernelName: CropAndResize, + backendName: 'webgl', + kernelFunc: cropAndResize + }; + + var CumOpType; + (function (CumOpType) { + CumOpType["Prod"] = "*"; + CumOpType["Sum"] = "+"; + })(CumOpType || (CumOpType = {})); + class CumProgram { + constructor(op, outputShape, exclusive, reverse) { + this.op = op; + this.outputShape = outputShape; + this.variableNames = ['x']; + this.customUniforms = [{ name: 'index', type: 'float' }]; + const rank = this.outputShape.length; + const initVal = this.op === CumOpType.Prod ? '1.0' : '0.0'; + const val = exclusive ? initVal : `getX(${getCoords(rank, 'coords', this.op)})`; + const length = this.outputShape[this.outputShape.length - 1]; + let condition = ''; + let idxString = ''; + // When exclusive is set, the cum op becomes roll op that copies the + // value from the previous index based on the direction specified by the + // reverse flag. + if (exclusive) { + condition = reverse ? `end != ${length - 1}` : 'end != 0'; + idxString = reverse ? 'end + 1' : 'end - 1'; + } + else { + condition = reverse ? `end + pow2 < ${length}` : 'end >= pow2'; + idxString = (reverse ? 'end + pow2' : 'end - pow2'); + } + this.userCode = ` + void main() { + ${getCoordsDataType(rank)} coords = getOutputCoords(); + int end = ${getFinalCoord(rank, 'coords', this.op)}; + float val = ${val}; + int pow2 = int(pow(2.0, index)); + if (${condition}) { + int idx = ${idxString}; + ${getFinalCoord(rank, 'coords', this.op)} = idx; + val ${this.op}= getX(${getCoords(rank, 'coords', this.op)}); + } + setOutput(val); + } + `; + } + } + function getCoords(rank, name, op) { + if (rank === 1) { + return `${name}`; + } + else if (rank === 2) { + return `${name}.x, ${name}.y`; + } + else if (rank === 3) { + return `${name}.x, ${name}.y, ${name}.z`; + } + else if (rank === 4) { + return `${name}.x, ${name}.y, ${name}.z, ${name}.w`; + } + else { + throw new Error(`Cumulative ${op} for rank ${rank} is not yet supported`); + } + } + function getFinalCoord(rank, name, op) { + if (rank === 1) { + return `${name}`; + } + else if (rank === 2) { + return `${name}.y`; + } + else if (rank === 3) { + return `${name}.z`; + } + else if (rank === 4) { + return `${name}.w`; + } + else { + throw new Error(`Cumulative ${op} for rank ${rank} is not yet supported`); + } + } + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function cumImpl(op, x, backend, axis, exclusive, reverse) { + const xRank = x.shape.length; + const permutation = getAxesPermutation([axis], xRank); + let permutedX = x; + if (permutation != null) { + permutedX = transpose({ inputs: { x }, backend, attrs: { perm: permutation } }); + } + const permutedAxis = getInnerMostAxes(1, xRank)[0]; + if (permutedAxis !== xRank - 1) { + throw new Error(`WebGL cumprod shader expects an inner-most axis=${x.shape.length - 1} ` + + `but got axis=${axis}`); + } + const size = permutedX.shape[permutedAxis]; + let result = identity({ inputs: { x: permutedX }, backend }); + // Use cum parallel algorithm, inspired by: + // https://developer.nvidia.com/gpugems/gpugems3/part-vi-gpu-computing/chapter-39-parallel-prefix-sum-scan-cuda + // Note: although the algorithm is called sum, it works for any associtative + // operator with an identity. + for (let i = 0; i <= Math.ceil(Math.log2(size)) - 1; i++) { + const program = new CumProgram(op, permutedX.shape, false, reverse); + const customValues = [[i]]; + const prevResult = result; + result = + backend.runWebGLProgram(program, [result], result.dtype, customValues); + backend.disposeIntermediateTensorInfo(prevResult); + } + // For exclusive cum, shift the end result in the direction of product or sum + // and add 1 for product or 0 for sum to the front index. + if (exclusive) { + const program = new CumProgram(op, permutedX.shape, exclusive, reverse); + const prevResult = result; + result = backend.runWebGLProgram(program, [result], result.dtype); + backend.disposeIntermediateTensorInfo(prevResult); + } + if (permutation != null) { + const reversePermutation = getUndoAxesPermutation(permutation); + const reverseTransposedResult = transpose({ inputs: { x: result }, backend, attrs: { perm: reversePermutation } }); + backend.disposeIntermediateTensorInfo(result); + backend.disposeIntermediateTensorInfo(permutedX); + return reverseTransposedResult; + } + return result; + } + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function cumprod(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, exclusive, reverse } = attrs; + return cumImpl(CumOpType.Prod, x, backend, axis, exclusive, reverse); + } + const cumprodConfig = { + kernelName: Cumprod, + backendName: 'webgl', + kernelFunc: cumprod + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function cumsum(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, exclusive, reverse } = attrs; + return cumImpl(CumOpType.Sum, x, backend, axis, exclusive, reverse); + } + const cumsumConfig = { + kernelName: Cumsum, + backendName: 'webgl', + kernelFunc: cumsum + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function denseBincount(args) { + const { inputs, backend, attrs } = args; + const { x, weights } = inputs; + const { size, binaryOutput } = attrs; + if (x.shape.length === 1) { + const xVals = backend.readSync(x.dataId); + const weightsVals = backend.readSync(weights.dataId); + const outVals = bincountImplCPU(xVals, weightsVals, weights.dtype, weights.shape, size); + return backend.makeTensorInfo([size], weights.dtype, outVals); + } + else if (x.shape.length === 2) { + const xBuf = backend.bufferSync(x); + const weightsBuf = backend.bufferSync(weights); + const outBuf = bincountReduceImplCPU(xBuf, weightsBuf, size, binaryOutput); + return backend.makeTensorInfo(outBuf.shape, weights.dtype, outBuf.values); + } + throw new Error(`Error in denseBincount: input must be at most rank 2, but got rank` + + `${x.shape.length}.`); + } + const denseBincountConfig = { + kernelName: DenseBincount, + backendName: 'webgl', + kernelFunc: denseBincount + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class DepthToSpaceProgram { + constructor(outputShape, blockSize, dataFormat) { + this.variableNames = ['x']; + this.outputShape = []; + this.outputShape = outputShape; + this.blockSize = blockSize; + this.dataFormat = dataFormat; + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int h = ${this.getHeightCoordString()}; + int w = ${this.getWidthCoordString()}; + int d = ${this.getDepthCoordString()}; + + int in_h = h / ${blockSize}; + int offset_h = imod(h, ${blockSize}); + int in_w = w / ${blockSize}; + int offset_w = imod(w, ${blockSize}); + int offset_d = (offset_h * ${blockSize} + offset_w) * + ${this.getOutputDepthSize()}; + int in_d = d + offset_d; + + float result = ${this.getInputSamplingString()}; + setOutput(result); + } + `; + } + getHeightCoordString() { + if (this.dataFormat === 'NHWC') { + return `coords[1]`; + } + else { + return `coords[2]`; + } + } + getWidthCoordString() { + if (this.dataFormat === 'NHWC') { + return `coords[2]`; + } + else { + return `coords[3]`; + } + } + getDepthCoordString() { + if (this.dataFormat === 'NHWC') { + return `coords[3]`; + } + else { + return `coords[1]`; + } + } + getOutputDepthSize() { + if (this.dataFormat === 'NHWC') { + return this.outputShape[3]; + } + else { + return this.outputShape[1]; + } + } + getInputSamplingString() { + if (this.dataFormat === 'NHWC') { + return `getX(b, in_h, in_w, in_d)`; + } + else { + return `getX(b, in_d, in_h, in_w)`; + } + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthToSpace(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { blockSize, dataFormat } = attrs; + const batchSize = x.shape[0]; + const inputHeight = (dataFormat === 'NHWC') ? x.shape[1] : x.shape[2]; + const inputWidth = (dataFormat === 'NHWC') ? x.shape[2] : x.shape[3]; + const inputDepth = (dataFormat === 'NHWC') ? x.shape[3] : x.shape[1]; + const outputHeight = inputHeight * blockSize; + const outputWidth = inputWidth * blockSize; + const outputDepth = inputDepth / (blockSize * blockSize); + const outputShape = (dataFormat === 'NHWC') ? + [batchSize, outputHeight, outputWidth, outputDepth] : + [batchSize, outputDepth, outputHeight, outputWidth]; + const program = new DepthToSpaceProgram(outputShape, blockSize, dataFormat); + return backend.runWebGLProgram(program, [x], x.dtype); + } + const depthToSpaceConfig = { + kernelName: DepthToSpace, + backendName: 'webgl', + kernelFunc: depthToSpace + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class DepthwiseConv2DProgram { + constructor(convInfo, addBias = false, activation = null, hasPreluActivation = false, hasLeakyReluAlpha = false) { + this.variableNames = ['x', 'W']; + this.customUniforms = [ + { name: 'pads', type: 'ivec2' }, + { name: 'strides', type: 'ivec2' }, + { name: 'dilations', type: 'ivec2' }, + { name: 'inDims', type: 'ivec2' }, + ]; + this.outputShape = convInfo.outShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const channelMul = convInfo.outChannels / convInfo.inChannels; + let activationSnippet = '', applyActivationSnippet = ''; + if (activation) { + if (hasPreluActivation) { + activationSnippet = `float activation(float a) { + float b = getPreluActivationWeightsAtOutCoords(); + ${activation} + }`; + } + else if (hasLeakyReluAlpha) { + activationSnippet = `float activation(float a) { + float b = getLeakyreluAlphaAtOutCoords(); + ${activation} + }`; + } + else { + activationSnippet = ` + float activation(float x) { + ${activation} + } + `; + } + applyActivationSnippet = `result = activation(result);`; + } + const addBiasSnippet = addBias ? 'result += getBiasAtOutCoords();' : ''; + if (addBias) { + this.variableNames.push('bias'); + } + if (hasPreluActivation) { + this.variableNames.push('preluActivationWeights'); + } + if (hasLeakyReluAlpha) { + this.variableNames.push('leakyreluAlpha'); + } + this.userCode = ` + ${activationSnippet} + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + ivec2 xRCCorner = coords.yz * strides - pads; + int d2 = coords.w; + int d1 = d2 / ${channelMul}; + int q = d2 - d1 * ${channelMul}; + + int xRCorner = xRCCorner.x; + int xCCorner = xRCCorner.y; + + // Convolve x(?, ?, d1) with w(:, :, d1, q) to get y(yR, yC, d2). + // ? = to be determined. : = across all values in that axis. + float dotProd = 0.0; + // TO DO(dsmilkov): Flatten the two for loops and vec4 the operations. + for (int wR = 0; wR < ${filterHeight}; wR++) { + int xR = xRCorner + wR * dilations[0]; + + if (xR < 0 || xR >= inDims[0]) { + continue; + } + + for (int wC = 0; wC < ${filterWidth}; wC++) { + int xC = xCCorner + wC * dilations[1]; + + if (xC < 0 || xC >= inDims[1]) { + continue; + } + + float xVal = getX(batch, xR, xC, d1); + float wVal = getW(wR, wC, d1, q); + dotProd += xVal * wVal; + } + } + + float result = dotProd; + ${addBiasSnippet} + ${applyActivationSnippet} + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class DepthwiseConvPacked2DProgram { + constructor(convInfo, addBias = false, activation = null, hasPreluActivation = false, hasLeakyReluAlpha = false) { + this.variableNames = ['x', 'W']; + this.packedInputs = true; + this.packedOutput = true; + this.customUniforms = [ + { name: 'pads', type: 'ivec2' }, + { name: 'strides', type: 'ivec2' }, + { name: 'dilations', type: 'ivec2' }, + { name: 'inDims', type: 'ivec2' }, + ]; + this.outputShape = convInfo.outShape; + this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); + const channelMul = convInfo.outChannels / convInfo.inChannels; + const padLeft = convInfo.padInfo.left; + const strideWidth = convInfo.strideWidth; + const dilationWidth = convInfo.dilationWidth; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const texelsAcross = filterWidth; + let mainLoop = ` + int xR; int xC; int xCOffset; + vec4 wTexel; vec4 previous; vec4 final;`; + for (let c = 0; c < filterWidth; c++) { + mainLoop += ` + vec4 xTexelC${c * 2}; + int xTexelC${c * 2}Ready; + vec4 xTexelC${c * 2 + 1}; + int xTexelC${c * 2 + 1}Ready; + vec4 xC${c};`; + } + /** + * This vectorized implementation works by gathering the values needed for + * each output channel's dot product into vec4's and then multiplying them + * all together (this happens in the final double for-loop below). Most of + * the main loop consists of constructing these vec4's with the minimum + * number of texture2D calls, which means making use of all four returned + * values from a texture2D call at once. + */ + mainLoop += ` + for (int r = 0; r < ${filterHeight}; r++) { + `; + for (let c = 0; c < filterWidth; c++) { + mainLoop += ` + xTexelC${c * 2} = vec4(0.0); + xTexelC${c * 2}Ready = 0; + xTexelC${c * 2 + 1} = vec4(0.0); + xTexelC${c * 2 + 1}Ready = 0; + xC${c} = vec4(0.0);`; + } + mainLoop += ` + xR = xRCorner + r * dilations[0]; + if (xR >=0 && xR < inDims[0]) { + `; + for (let texelC = 0; texelC < (texelsAcross + 1) / 2; texelC++) { + const colIndex = texelC * 2; + mainLoop += ` + xC = xCCorner + ${colIndex * dilationWidth}; + `; + if (strideWidth === 1) { + if (colIndex < filterWidth) { + // If padding is odd, the outer texels have to be composed. + if (padLeft % 2 === 1) { + // TODO: Ensure vec4 previous does not result in redundant sample, + // and avoid setting xTexelRC's that exceed the boundary in the + // first place rather than resetting them to vec4(0)). + // To compute xCOffset: + // - If padding is odd, we must add 1 to ensure we ask for an + // even-numbered row. + // - We subtract 2 to access the previous texel. + mainLoop += ` + xCOffset = xC + 1; + if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex}Ready == 0) { + xTexelC${colIndex} = getX(batch, xR, xCOffset, d1); + + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex}.zw = vec2(0.0); + } + xTexelC${colIndex}Ready = 1; + } + `; + // This texel has been read in previous iteration if the dilation + // is 1. + if (dilationWidth === 1 && colIndex > 0) { + mainLoop += ` + xC${colIndex} = vec4(xTexelC${colIndex - 2}.zw, xTexelC${colIndex}.xy); + `; + } + else { + mainLoop += ` + xCOffset = xC + 1 - 2; + + if (xCOffset >= 0 && xCOffset < inDims[1]) { + previous = getX(batch, xR, xCOffset, d1); + + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xCOffset + 1 >= inDims[1]) { + previous.zw = vec2(0.0); + } + + xC${colIndex} = vec4(previous.zw, xTexelC${colIndex}.xy); + } else { + xC${colIndex} = vec4(0.0, 0.0, xTexelC${colIndex}.xy); + } + `; + } + } + else { + // Padding is even, so xRC corresponds to a single texel. + mainLoop += ` + if (xC >= 0 && xC < inDims[1] && xTexelC${colIndex}Ready == 0) { + xTexelC${colIndex} = getX(batch, xR, xC, d1); + if (xC + 1 >= inDims[1]) { + xTexelC${colIndex}.zw = vec2(0.0); + } + xTexelC${colIndex}Ready = 1; + } + + xC${colIndex} = xTexelC${colIndex}; + `; + } + if (colIndex + 1 < filterWidth) { + // If dilation is even, the second entry should match the first + // (either both are composed or both are single samples). But if + // dilation is odd, then the second entry should be the opposite + // of the first (if the first is composed, the second is a single + // sample, and vice versa.) + const nextTexelOffset = padLeft % 2 === 0 ? + nearestLargerEven(dilationWidth) : + dilationWidth; + if ((dilationWidth % 2 === 0 && padLeft % 2 === 1) || + (dilationWidth % 2 !== 0 && padLeft % 2 !== 1)) { + mainLoop += ` + xCOffset = xC + imod(pads[1], 2) + ${nextTexelOffset}; + + if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex + 1}Ready == 0) { + xTexelC${colIndex + 1} = getX(batch, xR, xCOffset, d1); + + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex + 1}.zw = vec2(0.0); + } + xTexelC${colIndex + 1}Ready = 1; + } + `; + // If dilation > 1 then the xRC's will not be able to share any + // values, so each xRC will require two unique calls to getX. + if (dilationWidth > 1) { + mainLoop += ` + xCOffset -= 2; + if (xCOffset >= 0 && xCOffset < inDims[1]) { + previous = getX(batch, xR, xCOffset, d1); + xC${colIndex + 1} = vec4(previous.zw, xTexelC${colIndex + 1}.xy); + } else { + xC${colIndex + 1} = vec4(0.0, 0.0, xTexelC${colIndex + 1}.xy); + } + `; + } + else { + mainLoop += ` + xC${colIndex + 1} = vec4(xTexelC${colIndex}.zw, xTexelC${colIndex + 1}.xy); + `; + } + } + else { + // If dilation is 1 and padding is odd, we have already read the + // texel when constructing the previous x value. Here we can + // simply skip the texture read. + if (nextTexelOffset === 1) { + mainLoop += ` + xC${colIndex + 1} = xTexelC${colIndex}; + `; + } + else { + mainLoop += ` + xCOffset = xC + ${nextTexelOffset}; + + if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex + 1}Ready == 0) { + xTexelC${colIndex + 1} = getX(batch, xR, xCOffset, d1); + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex + 1}.zw = vec2(0.0); + } + xTexelC${colIndex + 1}Ready = 1; + } + + xC${colIndex + 1} = xTexelC${colIndex + 1}; + `; + } + } + } + } + } + else { // stride === 2 + if (colIndex < filterWidth) { + // Depending on whether padLeft is even or odd, we want either the + // xy or zw channels from X texels for xC${colIndex}. If padLeft is + // even, xC${colIndex +1} is simply the zw channels of texels we've + // already sampled. But if padLeft is odd, xC{$c + 1}.zw will + // need to come from the xy channels of a new texel, hence the ` + // vec4 + // final` initialized below. + if (padLeft % 2 === 1) { + mainLoop += ` + xCOffset = xC + 1 - strides[1]; + if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex}Ready == 0) { + xTexelC${colIndex} = getX(batch, xR, xCOffset, d1); + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex}.zw = vec2(0.0); + } + xTexelC${colIndex}Ready = 1; + } + + if(xC + 1 >= 0 && xC + 1 < inDims[1] && xTexelC${colIndex + 1}Ready == 0) { + xTexelC${colIndex + 1} = getX(batch, xR, xC + 1, d1); + // Need to manually clear unused channels in case + // we're reading from recycled texture. + if (xC + 2 >= inDims[1]) { + xTexelC${colIndex + 1}.zw = vec2(0.0); + } + xTexelC${colIndex + 1}Ready = 1; + } + + xC${colIndex} = vec4(xTexelC${colIndex}.zw, xTexelC${colIndex + 1}.zw); + `; + if (colIndex + 1 < filterWidth) { + mainLoop += ` + final = vec4(0.0); + xCOffset = xC + 1 + strides[1]; + if(xCOffset >= 0 && xCOffset < inDims[1]) { + final = getX(batch, xR, xCOffset, d1); + } + xC${colIndex + 1} = vec4(xTexelC${colIndex + 1}.xy, final.xy); + `; + } + } + else { + mainLoop += ` + if(xC >= 0 && xC < inDims[1] && xTexelC${colIndex}Ready == 0) { + xTexelC${colIndex} = getX(batch, xR, xC, d1); + if (xC + 1 >= inDims[1]) { + xTexelC${colIndex}.zw = vec2(0.0); + } + xTexelC${colIndex}Ready = 1; + } + + xCOffset = xC + strides[1]; + if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${colIndex + 1}Ready == 0) { + xTexelC${colIndex + 1} = getX(batch, xR, xCOffset, d1); + if (xCOffset + 1 >= inDims[1]) { + xTexelC${colIndex + 1}.zw = vec2(0.); + } + xTexelC${colIndex + 1}Ready = 1; + } + + xC${colIndex} = vec4( + xTexelC${colIndex}.xy, xTexelC${colIndex + 1}.xy); + `; + if (colIndex + 1 < filterWidth) { + mainLoop += ` + xC${colIndex + 1} = vec4(xTexelC${colIndex}.zw, xTexelC${colIndex + 1}.zw); + `; + } + } + } + } + // localize the dotProd accumulation within the loop, the theory is for + // GPU with limited cache, accumulate sum across large amount of + // veriables will cause lots of cache misses. (i.e. 5x5 filter will have + // 50 variables) + if (colIndex < filterWidth) { + mainLoop += ` + wTexel = getW(r, ${colIndex}, d1, q); + dotProd += xC${colIndex} * vec4(wTexel.xz, wTexel.xz); + `; + if (colIndex + 1 < filterWidth) { + mainLoop += ` + wTexel = getW(r, ${colIndex + 1}, d1, q); + dotProd += xC${colIndex + 1} * vec4(wTexel.xz, wTexel.xz); + `; + } + } + } + mainLoop += ` + } + `; + mainLoop += ` + } + `; + let activationSnippet = '', applyActivationSnippet = ''; + if (activation) { + if (hasPreluActivation) { + activationSnippet = `vec4 activation(vec4 a) { + vec4 b = getPreluActivationWeightsAtOutCoords(); + ${activation} + }`; + } + else if (hasLeakyReluAlpha) { + activationSnippet = `vec4 activation(vec4 a) { + vec4 b = getLeakyreluAlphaAtOutCoords(); + ${activation} + }`; + } + else { + activationSnippet = `vec4 activation(vec4 x) { + ${activation} + }`; + } + applyActivationSnippet = `result = activation(result);`; + } + const addBiasSnippet = addBias ? 'result += getBiasAtOutCoords();' : ''; + if (addBias) { + this.variableNames.push('bias'); + } + if (hasPreluActivation) { + this.variableNames.push('preluActivationWeights'); + } + if (hasLeakyReluAlpha) { + this.variableNames.push('leakyreluAlpha'); + } + this.userCode = ` + ${activationSnippet} + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + ivec2 xRCCorner = coords.yz * strides - pads; + int d2 = coords.w; + int d1 = d2 / ${channelMul}; + int q = d2 - d1 * ${channelMul}; + int xRCorner = xRCCorner.x; + int xCCorner = xRCCorner.y; + + //intialize dotProd with a small epsilon seems to reduce GPU accuracy loss. + vec4 dotProd = vec4(0.000000000000001); + + ${mainLoop} + + vec4 result = dotProd - vec4(0.000000000000001); + ${addBiasSnippet} + ${applyActivationSnippet} + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthwiseConv2dNative(args) { + const { inputs, backend, attrs } = args; + const { x, filter } = inputs; + const { strides, pad, dilations, dimRoundingMode } = attrs; + let $dilations = dilations; + if ($dilations == null) { + $dilations = [1, 1]; + } + assert$1(eitherStridesOrDilationsAreOne(strides, $dilations), () => 'Error in depthwiseConv2d: Either strides or dilations must be ' + + `1. Got strides ${strides} and dilations '${$dilations}'`); + const convInfo = computeConv2DInfo(x.shape, filter.shape, strides, $dilations, pad, dimRoundingMode, true /* depthwise */); + let program; + if (env().getBool('WEBGL_PACK_DEPTHWISECONV') && convInfo.strideWidth <= 2 && + convInfo.outChannels / convInfo.inChannels === 1) { + program = new DepthwiseConvPacked2DProgram(convInfo); + } + else { + program = new DepthwiseConv2DProgram(convInfo); + } + const customValues = [ + [convInfo.padInfo.top, convInfo.padInfo.left], + [convInfo.strideHeight, convInfo.strideWidth], + [convInfo.dilationHeight, convInfo.dilationWidth], + [convInfo.inHeight, convInfo.inWidth] + ]; + return backend.runWebGLProgram(program, [x, filter], 'float32', customValues); + } + const depthwiseConv2dNativeConfig = { + kernelName: DepthwiseConv2dNative, + backendName: 'webgl', + kernelFunc: depthwiseConv2dNative, + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class DepthwiseConv2DDerFilterProgram { + constructor(convInfo) { + this.variableNames = ['x', 'dy']; + this.outputShape = convInfo.filterShape; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const padTop = convInfo.padInfo.top; + const padLeft = convInfo.padInfo.left; + const channelMul = convInfo.outChannels / convInfo.inChannels; + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int wR = coords.x; + int wC = coords.y; + int d1 = coords.z; + int dm = coords.w; + int d2 = d1 * ${channelMul} + dm; + + float dotProd = 0.0; + + // TO DO: Vec4 over the batch size + for (int b = 0; b < ${convInfo.batchSize}; b++) { + for (int yR = 0; yR < ${convInfo.outHeight}; yR++) { + int xR = wR + yR * ${strideHeight} - ${padTop}; + + if (xR < 0 || xR >= ${convInfo.inHeight}) { + continue; + } + + for (int yC = 0; yC < ${convInfo.outWidth}; yC++) { + int xC = wC + yC * ${strideWidth} - ${padLeft}; + + if (xC < 0 || xC >= ${convInfo.inWidth}) { + continue; + } + + float dyValue = getDy(b, yR, yC, d2); + float xValue = getX(b, xR, xC, d1); + dotProd += (xValue * dyValue); + } + } + } + setOutput(dotProd); + } + `; + } + } + class DepthwiseConv2DDerInputProgram { + constructor(convInfo) { + this.variableNames = ['dy', 'W']; + this.outputShape = convInfo.inShape; + const filterHeight = convInfo.filterHeight; + const filterWidth = convInfo.filterWidth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const padTop = filterHeight - 1 - convInfo.padInfo.top; + const padLeft = filterWidth - 1 - convInfo.padInfo.left; + const channelMul = convInfo.outChannels / convInfo.inChannels; + this.userCode = ` + const ivec2 pads = ivec2(${padTop}, ${padLeft}); + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords[0]; + int d1 = coords[3]; + ivec2 dyCorner = coords.yz - pads; + int dyRCorner = dyCorner.x; + int dyCCorner = dyCorner.y; + + float dotProd = 0.0; + + for (int wR = 0; wR < ${filterHeight}; wR++) { + float dyR = float(dyRCorner + wR) / ${strideHeight}.0; + + if (dyR < 0.0 || dyR >= ${convInfo.outHeight}.0 || fract(dyR) > 0.0) { + continue; + } + int idyR = int(dyR); + + int wRPerm = ${filterHeight} - 1 - wR; + + for (int wC = 0; wC < ${filterWidth}; wC++) { + float dyC = float(dyCCorner + wC) / ${strideWidth}.0; + + if (dyC < 0.0 || dyC >= ${convInfo.outWidth}.0 || + fract(dyC) > 0.0) { + continue; + } + int idyC = int(dyC); + + int wCPerm = ${filterWidth} - 1 - wC; + + // TO DO: Vec4 over the channelMul + for (int dm = 0; dm < ${channelMul}; dm++) { + int d2 = d1 * ${channelMul} + dm; + float xValue = getDy(batch, idyR, idyC, d2); + float wValue = getW(wRPerm, wCPerm, d1, dm); + dotProd += xValue * wValue; + } + } + } + setOutput(dotProd); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthwiseConv2dNativeBackpropFilter(args) { + const { inputs, backend, attrs } = args; + const { x, dy } = inputs; + const { strides, dilations, pad, dimRoundingMode, filterShape } = attrs; + const convInfo = computeConv2DInfo(x.shape, filterShape, strides, dilations, pad, dimRoundingMode, true /* depthwise */); + const program = new DepthwiseConv2DDerFilterProgram(convInfo); + return backend.runWebGLProgram(program, [x, dy], 'float32'); + } + const depthwiseConv2dNativeBackpropFilterConfig = { + kernelName: DepthwiseConv2dNativeBackpropFilter, + backendName: 'webgl', + kernelFunc: depthwiseConv2dNativeBackpropFilter + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function depthwiseConv2dNativeBackpropInput(args) { + const { inputs, backend, attrs } = args; + const { dy, filter } = inputs; + const { strides, dilations, pad, dimRoundingMode, inputShape } = attrs; + const convInfo = computeConv2DInfo(inputShape, filter.shape, strides, dilations, pad, dimRoundingMode, true /* depthwise */); + const program = new DepthwiseConv2DDerInputProgram(convInfo); + return backend.runWebGLProgram(program, [dy, filter], 'float32'); + } + const depthwiseConv2dNativeBackpropInputConfig = { + kernelName: DepthwiseConv2dNativeBackpropInput, + backendName: 'webgl', + kernelFunc: depthwiseConv2dNativeBackpropInput + }; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class DiagProgram { + constructor(size) { + this.variableNames = ['X']; + this.outputShape = [size, size]; + this.userCode = ` + void main() { + ivec2 coords = getOutputCoords(); + float val = coords[0] == coords[1] ? getX(coords[0]) : 0.0; + setOutput(val); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function diag(args) { + const { inputs, backend } = args; + const { x } = inputs; + const outShape = [...x.shape, ...x.shape]; + const xSize = sizeFromShape(x.shape); + const flat = reshape({ inputs: { x }, backend, attrs: { shape: [xSize] } }); + const program = new DiagProgram(xSize); + const res = backend.runWebGLProgram(program, [flat], flat.dtype); + const out = reshape({ inputs: { x: res }, backend, attrs: { shape: outShape } }); + backend.disposeIntermediateTensorInfo(flat); + backend.disposeIntermediateTensorInfo(res); + return out; + } + const diagConfig = { + kernelName: Diag, + backendName: 'webgl', + kernelFunc: diag + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class Dilation2DProgram { + constructor(convInfo) { + this.variableNames = ['x', 'W']; + this.outputShape = convInfo.outShape; + const { inHeight, inWidth, padInfo, strideHeight, strideWidth, filterHeight, filterWidth, dilationHeight, dilationWidth } = convInfo; + const { top: padTop, left: padLeft } = padInfo; + this.userCode = ` + const ivec2 strides = ivec2(${strideHeight}, ${strideWidth}); + const ivec2 pads = ivec2(${padTop}, ${padLeft}); + const float neg_infinity = -3.4e38; + + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + int d1 = coords.w; + ivec2 outTopLeftCorner = + coords.yz * strides - pads; + int hBeg = outTopLeftCorner.x; + int wBeg = outTopLeftCorner.y; + + float curVal = neg_infinity; + for (int h = 0; h < ${filterHeight}; h++) { + int hIn = hBeg + h * ${dilationHeight}; + + if (hIn >= 0 && hIn < ${inHeight}) { + for (int w = 0; w < ${filterWidth}; w++) { + int wIn = wBeg + w * ${dilationWidth}; + + if (wIn >= 0 && wIn < ${inWidth}) { + float xVal = getX(batch, hIn, wIn, d1); + float wVal = getW(h, w, d1); + + float val = xVal + wVal; + if (val > curVal) { + curVal = val; + } + } + } + } + } + + float result = curVal; + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function dilation2D(args) { + const { inputs, backend, attrs } = args; + const { x, filter } = inputs; + const { strides, pad, dilations } = attrs; + const convInfo = computeDilation2DInfo(x.shape, filter.shape, strides, pad, 'NHWC' /* dataFormat */, dilations); + let out; + const program = new Dilation2DProgram(convInfo); + out = backend.runWebGLProgram(program, [x, filter], 'float32'); + const outReshaped = reshape({ inputs: { x: out }, backend, attrs: { shape: convInfo.outShape } }); + backend.disposeIntermediateTensorInfo(out); + return outReshaped; + } + const dilation2DConfig = { + kernelName: Dilation2D, + backendName: 'webgl', + kernelFunc: dilation2D, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function einsum(args) { + const { inputs, backend, attrs } = args; + const { equation } = attrs; + const tensors = inputs; + const { allDims, summedDims, idDims } = decodeEinsumEquation(equation, tensors.length); + checkEinsumDimSizes(allDims.length, idDims, tensors); + const { path, steps } = getEinsumComputePath(summedDims, idDims); + const nSteps = steps.length; + let out = null; + let numDimsRemaining = allDims.length; + const tensorsToDispose = []; + for (let i = 0; i < nSteps; ++i) { + for (const idTerm of steps[i]) { + const { permutationIndices: perm, expandDims: dimsToExpand } = getEinsumPermutation(numDimsRemaining, idDims[idTerm]); + let x; + if (isIdentityPermutation(perm)) { + x = tensors[idTerm]; + } + else { + x = transpose({ inputs: { x: tensors[idTerm] }, backend, attrs: { perm } }); + tensorsToDispose.push(x); + } + const targetShape = x.shape.slice(); + for (let k = 0; k < dimsToExpand.length; ++k) { + targetShape.splice(dimsToExpand[k], 0, 1); + } + if (!arraysEqual(x.shape, targetShape)) { + x = reshape({ inputs: { x }, backend, attrs: { shape: targetShape } }); + tensorsToDispose.push(x); + } + if (out === null) { + out = x; + } + else { + // tslint:disable-next-line: no-unnecessary-type-assertion + out = multiply({ inputs: { a: x, b: out }, backend }); + tensorsToDispose.push(out); + } + } + if (i < nSteps - 1) { + if (path[i] >= 0) { + out = sum({ + inputs: { x: out }, + backend, + attrs: { + axis: path[i] - (allDims.length - numDimsRemaining), + keepDims: false + } + }); + tensorsToDispose.push(out); + } + numDimsRemaining--; + } + } + // Clean up intermediate tensors. + for (const tensorInfo of tensorsToDispose) { + if (tensorInfo === out) { + continue; + } + backend.disposeIntermediateTensorInfo(tensorInfo); + } + return out; + } + const einsumConfig = { + kernelName: Einsum, + backendName: 'webgl', + kernelFunc: einsum + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ELU = `return (x >= 0.0) ? x : (exp(x) - 1.0);`; + const ELU_PACKED = ` + vec4 result; + + result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0); + result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0); + result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0); + result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0); + + return result; +`; + const elu = unaryKernelFunc({ opSnippet: ELU, packedOpSnippet: ELU_PACKED }); + const eluConfig = { + kernelName: Elu$1, + backendName: 'webgl', + kernelFunc: elu + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ELU_DER = `return (b >= 0.0) ? a : a * (b + 1.0);`; + const ELU_DER_PACKED = ` + vec4 bGTEZero = vec4(greaterThanEqual(b, vec4(0.))); + return (bGTEZero * a) + ((vec4(1.0) - bGTEZero) * (a * (b + vec4(1.0)))); +`; + const eluGrad = (args) => { + const { inputs, backend } = args; + const { dy, y } = inputs; + const program = env().getBool('WEBGL_PACK_BINARY_OPERATIONS') ? + new BinaryOpPackedProgram(ELU_DER_PACKED, dy.shape, y.shape) : + new BinaryOpProgram(ELU_DER, dy.shape, y.shape); + return backend.runWebGLProgram(program, [dy, y], dy.dtype); + }; + const eluGradConfig = { + kernelName: EluGrad, + backendName: 'webgl', + kernelFunc: eluGrad + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const PACKED_EQUAL = ` + return vec4(equal(a, b)); +`; + const EQUAL = `return float(a == b);`; + const equal = binaryKernelFunc({ + opSnippet: EQUAL, + packedOpSnippet: PACKED_EQUAL, + dtype: 'bool', + cpuKernelImpl: equalImplCPU, + }); + const equalConfig = { + kernelName: Equal, + backendName: 'webgl', + kernelFunc: equal + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ERF = ` + // Error function is calculated approximately with elementary function. + // See "Handbook of Mathematical Functions with Formulas, + // Graphs, and Mathematical Tables", Abramowitz and Stegun. + float p = ${ERF_P}; + float a1 = ${ERF_A1}; + float a2 = ${ERF_A2}; + float a3 = ${ERF_A3}; + float a4 = ${ERF_A4}; + float a5 = ${ERF_A5}; + + float sign = sign(x); + x = abs(x); + float t = 1.0 / (1.0 + p * x); + return sign * (1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x)); +`; + const erf = unaryKernelFunc({ opSnippet: ERF }); + const erfConfig = { + kernelName: Erf, + backendName: 'webgl', + kernelFunc: erf, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const EXP = CHECK_NAN_SNIPPET_UNARY + ` + return exp(x); +`; + const EXP_PACKED = ` + vec4 result = exp(x); + bvec4 isNaN = isnan(x); + result.r = isNaN.r ? x.r : result.r; + result.g = isNaN.g ? x.g : result.g; + result.b = isNaN.b ? x.b : result.b; + result.a = isNaN.a ? x.a : result.a; + + return result; +`; + const exp = unaryKernelFunc({ + opSnippet: EXP, + packedOpSnippet: EXP_PACKED, + cpuKernelImpl: expImplCPU, + dtype: 'float32', + }); + const expConfig = { + kernelName: Exp, + backendName: 'webgl', + kernelFunc: exp + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function expandDims(args) { + const { inputs, attrs, backend } = args; + const { dim } = attrs; + const { input } = inputs; + const inputRank = input.shape.length; + const newShape = input.shape.slice(); + let $dim = dim; + if (dim < 0) { + // Negative value is counted from the tail of rank. + assert$1(-(inputRank + 1) <= dim, () => `Axis must be in the interval [${-(inputRank + 1)}, ${inputRank}]`); + $dim = inputRank + dim + 1; + } + newShape.splice($dim, 0, 1); + return reshape({ inputs: { x: input }, backend, attrs: { shape: newShape } }); + } + const expandDimsConfig = { + kernelName: ExpandDims, + backendName: 'webgl', + kernelFunc: expandDims, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const EXPM1 = `return exp(x) - 1.0;`; + const expm1 = unaryKernelFunc({ opSnippet: EXPM1, packedOpSnippet: EXPM1, cpuKernelImpl: expm1ImplCPU }); + const expm1Config = { + kernelName: Expm1, + backendName: 'webgl', + kernelFunc: expm1 + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class FFTProgram { + constructor(component, inputShape, inverse) { + this.variableNames = ['real', 'imag']; + const innerDim = inputShape[1]; + this.outputShape = inputShape; + const exponentMultiplierSnippet = inverse ? `2.0 * ${Math.PI}` : `-2.0 * ${Math.PI}`; + const resultDenominator = inverse ? `${innerDim}.0` : '1.0'; + let opString; + if (component === 'real') { + opString = 'return real * expR - imag * expI;'; + } + else if (component === 'imag') { + opString = 'return real * expI + imag * expR;'; + } + else { + throw new Error(`FFT component must be either "real" or "imag", got ${component}.`); + } + this.userCode = ` + const float exponentMultiplier = ${exponentMultiplierSnippet}; + + float unaryOpComplex(float real, float expR, float imag, float expI) { + ${opString} + } + + float mulMatDFT(int batch, int index) { + float indexRatio = float(index) / float(${innerDim}); + float exponentMultiplierTimesIndexRatio = + exponentMultiplier * indexRatio; + + float result = 0.0; + + for (int i = 0; i < ${innerDim}; i++) { + // x = (-2|2 * PI / N) * index * i; + float x = exponentMultiplierTimesIndexRatio * float(i); + float expR = cos(x); + float expI = sin(x); + float real = getReal(batch, i); + float imag = getImag(batch, i); + + result += + unaryOpComplex(real, expR, imag, expI) / ${resultDenominator}; + } + + return result; + } + + void main() { + ivec2 coords = getOutputCoords(); + setOutput(mulMatDFT(coords[0], coords[1])); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fftImpl(x, inverse, backend) { + const xData = backend.texData.get(x.dataId); + const inputSize = sizeFromShape(x.shape); + // Collapse all outer dimensions to a single batch dimension. + const innerDimensionSize = x.shape[x.shape.length - 1]; + const batch = inputSize / innerDimensionSize; + const input2D = reshape({ inputs: { x }, backend, attrs: { shape: [batch, innerDimensionSize] } }); + const xShape = input2D.shape; + const realProgram = new FFTProgram('real', xShape, inverse); + const imagProgram = new FFTProgram('imag', xShape, inverse); + const inputs = [ + { + dataId: xData.complexTensorInfos.real.dataId, + dtype: xData.complexTensorInfos.real.dtype, + shape: xShape + }, + { + dataId: xData.complexTensorInfos.imag.dataId, + dtype: xData.complexTensorInfos.imag.dtype, + shape: xShape + } + ]; + const realPart = backend.runWebGLProgram(realProgram, inputs, 'float32'); + const imagPart = backend.runWebGLProgram(imagProgram, inputs, 'float32'); + const complexOutput = complex({ inputs: { real: realPart, imag: imagPart }, backend }); + backend.disposeIntermediateTensorInfo(realPart); + backend.disposeIntermediateTensorInfo(imagPart); + const complexOutputReshaped = reshape({ inputs: { x: complexOutput }, backend, attrs: { shape: x.shape } }); + backend.disposeIntermediateTensorInfo(input2D); + backend.disposeIntermediateTensorInfo(complexOutput); + return complexOutputReshaped; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fft(args) { + const { inputs, backend } = args; + const { input } = inputs; + return fftImpl(input, false /* inverse */, backend); + } + const fftConfig = { + kernelName: FFT, + backendName: 'webgl', + kernelFunc: fft + }; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class FillProgram { + constructor(shape, value) { + this.outputShape = []; + this.customUniforms = [{ name: 'value', type: 'float' }]; + this.variableNames = ['x']; + this.outputShape = shape; + this.userCode = ` + void main() { + // Input can be obtained from uniform value. + setOutput(value); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fill(args) { + const { backend, attrs } = args; + const { shape, value } = attrs; + let { dtype } = attrs; + dtype = dtype || inferDtype(value); + if (dtype === 'string') { + // String type should be handled in CPU memory. + const values = getArrayFromDType(dtype, sizeFromShape(shape)); + values.fill(value); + return backend.makeTensorInfo(shape, dtype, values); + } + else { + const program = new FillProgram(shape, value); + const customValues = [[value]]; + return backend.runWebGLProgram(program, [], dtype, customValues); + } + } + const fillConfig = { + kernelName: Fill, + backendName: 'webgl', + kernelFunc: fill + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class FlipLeftRightProgram { + constructor(imageShape) { + this.variableNames = ['Image']; + this.outputShape = []; + const imageWidth = imageShape[2]; + this.outputShape = imageShape; + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int x = coords[2]; + + int coordX = ${imageWidth} - x - 1; + float outputValue; + if(coordX >= 0 && coordX < ${imageWidth}) { + outputValue = getImage(coords[0], coords[1], coordX, coords[3]); + } else { + outputValue = getImage(coords[0], coords[1], coords[2], coords[3]); + } + setOutput(outputValue); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const flipLeftRightConfig = { + kernelName: FlipLeftRight, + backendName: 'webgl', + kernelFunc: ({ inputs, backend }) => { + const { image } = inputs; + const webglBackend = backend; + const program = new FlipLeftRightProgram(image.shape); + const output = webglBackend.runWebGLProgram(program, [image], image.dtype); + return output; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const FLOOR = `return floor(x);`; + const floor = unaryKernelFunc({ opSnippet: FLOOR, packedOpSnippet: FLOOR, cpuKernelImpl: floorImplCPU }); + const floorConfig = { + kernelName: Floor, + backendName: 'webgl', + kernelFunc: floor, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // We use native integer division to deal with floating point imprecision. Since + // we implement floor division and glsl implements truncated division, we + // correct for this by subtracting 1 from result when the result is negative and + // there is a remainder. + const INT_DIV = ` + float s = sign(a) * sign(b); + int ia = round(a); + int ib = round(b); + if (ib != 0) { + // Windows (D3D) wants guaranteed non-zero int division at compile-time. + return float(idiv(ia, ib, s)); + } else { + return NAN; + } +`; + const INT_DIV_PACKED = ` + ivec4 ia = round(a); + ivec4 ib = round(b); + bvec4 cond = notEqual(ib, ivec4(0)); + ivec4 result = ivec4(0); + vec4 s = sign(a) * sign(b); + + // Windows (D3D) wants guaranteed non-zero int division at compile-time. + if (cond[0]) { + result[0] = idiv(ia[0], ib[0], s[0]); + } + if (cond[1]) { + result[1] = idiv(ia[1], ib[1], s[1]); + } + if (cond[2]) { + result[2] = idiv(ia[2], ib[2], s[2]); + } + if (cond[3]) { + result[3] = idiv(ia[3], ib[3], s[3]); + } + return vec4(result); +`; + const floorDiv = binaryKernelFunc({ opSnippet: INT_DIV, packedOpSnippet: INT_DIV_PACKED, dtype: 'int32' }); + const floorDivConfig = { + kernelName: FloorDiv, + backendName: 'webgl', + kernelFunc: floorDiv + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class FromPixelsProgram { + constructor(outputShape) { + this.variableNames = ['A']; + const glsl = getGlslDifferences(); + const [height, width,] = outputShape; + this.outputShape = outputShape; + this.userCode = ` + void main() { + ivec3 coords = getOutputCoords(); + int texR = coords[0]; + int texC = coords[1]; + int depth = coords[2]; + vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${width}.0, ${height}.0); + + vec4 values = ${glsl.texture2D}(A, uv); + float value; + if (depth == 0) { + value = values.r; + } else if (depth == 1) { + value = values.g; + } else if (depth == 2) { + value = values.b; + } else if (depth == 3) { + value = values.a; + } + + setOutput(floor(value * 255.0 + 0.5)); + } + `; + } + } + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class FromPixelsPackedProgram { + constructor(outputShape) { + this.variableNames = ['A']; + this.packedInputs = false; + this.packedOutput = true; + const glsl = getGlslDifferences(); + const [height, width,] = outputShape; + this.outputShape = outputShape; + this.userCode = ` + void main() { + ivec3 coords = getOutputCoords(); + int texR = coords[0]; + int texC = coords[1]; + int depth = coords[2]; + + vec4 result = vec4(0.); + + for(int row=0; row<=1; row++) { + for(int col=0; col<=1; col++) { + texC = coords[1] + row; + depth = coords[2] + col; + + vec2 uv = (vec2(texC, texR) + halfCR) / + vec2(${width}.0, ${height}.0); + vec4 values = ${glsl.texture2D}(A, uv); + float value; + if (depth == 0) { + value = values.r; + } else if (depth == 1) { + value = values.g; + } else if (depth == 2) { + value = values.b; + } else if (depth == 3) { + value = values.a; + } + + result[row * 2 + col] = floor(value * 255.0 + 0.5); + } + } + + ${glsl.output} = result; + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const fromPixelsConfig = { + kernelName: FromPixels, + backendName: 'webgl', + kernelFunc: fromPixels, + }; + let fromPixels2DContext; + let willReadFrequently = env().getBool('CANVAS2D_WILL_READ_FREQUENTLY_FOR_GPU'); + function fromPixels(args) { + const { inputs, backend, attrs } = args; + let { pixels } = inputs; + const { numChannels } = attrs; + const isVideo = typeof (HTMLVideoElement) !== 'undefined' && + pixels instanceof HTMLVideoElement; + const isImage = typeof (HTMLImageElement) !== 'undefined' && + pixels instanceof HTMLImageElement; + const [width, height] = isVideo ? + [ + pixels.videoWidth, + pixels.videoHeight + ] : + [pixels.width, pixels.height]; + const texShape = [height, width]; + const outShape = [height, width, numChannels]; + if (isImage || isVideo) { + const newWillReadFrequently = env().getBool('CANVAS2D_WILL_READ_FREQUENTLY_FOR_GPU'); + if (fromPixels2DContext == null || + newWillReadFrequently !== willReadFrequently) { + willReadFrequently = newWillReadFrequently; + fromPixels2DContext = + document.createElement('canvas').getContext('2d', { willReadFrequently }); + } + fromPixels2DContext.canvas.width = width; + fromPixels2DContext.canvas.height = height; + fromPixels2DContext.drawImage(pixels, 0, 0, width, height); + pixels = fromPixels2DContext.canvas; + } + const tempPixelHandle = backend.makeTensorInfo(texShape, 'int32'); + // This is a byte texture with pixels. + backend.texData.get(tempPixelHandle.dataId).usage = TextureUsage.PIXELS; + backend.gpgpu.uploadPixelDataToTexture(backend.getTexture(tempPixelHandle.dataId), pixels); + const program = env().getBool('WEBGL_PACK') ? + new FromPixelsPackedProgram(outShape) : + new FromPixelsProgram(outShape); + const res = backend.runWebGLProgram(program, [tempPixelHandle], 'int32'); + backend.disposeData(tempPixelHandle.dataId); + return res; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fusedConv2d(args) { + const { inputs, backend, attrs } = args; + const { x, filter, bias, preluActivationWeights } = inputs; + const { strides, pad, dataFormat, dilations, dimRoundingMode, activation, leakyreluAlpha } = attrs; + const $dataFormat = convertConv2DDataFormat(dataFormat); + const convInfo = computeConv2DInfo(x.shape, filter.shape, strides, dilations, pad, dimRoundingMode, false /* depthwise */, $dataFormat); + let out; + const intermediates = []; + const hasBias = bias != null; + const hasPreluActivationWeights = preluActivationWeights != null; + const hasLeakyreluAlpha = activation === 'leakyrelu'; + const prepareInputs = () => { + const inputs = [x, filter]; + // If the input is a 1-D tensor, align it with the channels. + // + // For fusedConv2d, the inputs (x, W, bias, preluActivationWeights) are + // supposed to be aligned with the dataFormat. The 4-D tensor inputs or + // scalar inputs are originally aligned, but the 1-D tensor inputs are + // supposed to be aligned with the channels (only bias and PReLU activation + // weights could be a 1-D tensor). + const alignInputWithDataFormat = (input, dataFormat) => { + if (dataFormat === 'NCHW' && input.shape.length === 1 && + input.shape[0] !== 1) { + const alignedInput = reshape({ + inputs: { x: input }, + backend, + attrs: { shape: [input.shape[0], 1, 1] } + }); + intermediates.push(alignedInput); + return alignedInput; + } + return input; + }; + if (hasBias) { + inputs.push(alignInputWithDataFormat(bias, dataFormat)); + } + if (hasPreluActivationWeights) { + inputs.push(alignInputWithDataFormat(preluActivationWeights, dataFormat)); + } + if (hasLeakyreluAlpha) { + const $leakyreluAlpha = backend.makeTensorInfo([], 'float32', createScalarValue(leakyreluAlpha, 'float32')); + inputs.push($leakyreluAlpha); + intermediates.push($leakyreluAlpha); + } + return inputs; + }; + if (convInfo.filterHeight === 1 && convInfo.filterWidth === 1 && + convInfo.dilationHeight === 1 && convInfo.dilationWidth === 1 && + convInfo.strideHeight === 1 && convInfo.strideWidth === 1 && + (convInfo.padInfo.type === 'SAME' || convInfo.padInfo.type === 'VALID')) { + out = conv2dByMatMul({ + x, + filter, + convInfo, + backend, + bias, + activation, + preluActivationWeights, + leakyreluAlpha + }); + } + else if (convInfo.strideWidth <= 2 && $dataFormat === 'channelsLast' + && env().getBool('WEBGL_EXP_CONV')) { + const fusedActivation = activation ? mapActivationToShaderProgram(activation, true) : null; + const program = new Conv2DPackedProgram(convInfo, hasBias, fusedActivation, hasPreluActivationWeights, hasLeakyreluAlpha); + const customValues = [ + [convInfo.padInfo.top, convInfo.padInfo.left], + [convInfo.strideHeight, convInfo.strideWidth], + [convInfo.dilationHeight, convInfo.dilationWidth], + [convInfo.inHeight, convInfo.inWidth] + ]; + const inputs = prepareInputs(); + out = backend.runWebGLProgram(program, inputs, 'float32', customValues); + } + else if (env().getBool('WEBGL_CONV_IM2COL')) { + out = conv2dWithIm2Row({ + x, + filter, + convInfo, + backend, + bias, + activation, + preluActivationWeights, + leakyreluAlpha + }); + } + else { + const fusedActivation = activation ? mapActivationToShaderProgram(activation, false) : null; + const program = new Conv2DProgram(convInfo, hasBias, fusedActivation, hasPreluActivationWeights, hasLeakyreluAlpha); + const inputs = prepareInputs(); + out = backend.runWebGLProgram(program, inputs, 'float32'); + } + const outReshaped = reshape({ inputs: { x: out }, backend, attrs: { shape: convInfo.outShape } }); + intermediates.push(out); + intermediates.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return outReshaped; + } + const fusedConv2DConfig = { + kernelName: FusedConv2D, + backendName: 'webgl', + kernelFunc: fusedConv2d, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function fusedDepthwiseConv2D(args) { + const { inputs, backend, attrs } = args; + const { x, filter, bias, preluActivationWeights } = inputs; + const { strides, pad, dilations, dimRoundingMode, activation, leakyreluAlpha } = attrs; + const intermediates = []; + let $dilations = dilations; + if ($dilations == null) { + $dilations = [1, 1]; + } + assert$1(eitherStridesOrDilationsAreOne(strides, $dilations), () => 'Error in depthwiseConv2d: Either strides or dilations must be ' + + `1. Got strides ${strides} and dilations '${$dilations}'`); + const convInfo = computeConv2DInfo(x.shape, filter.shape, strides, $dilations, pad, dimRoundingMode, true /* depthwise */); + const shouldPackDepthwiseConv = env().getBool('WEBGL_PACK_DEPTHWISECONV') && + convInfo.strideWidth <= 2 && + convInfo.outChannels / convInfo.inChannels === 1; + const fusedActivation = activation ? + mapActivationToShaderProgram(activation, shouldPackDepthwiseConv) : + null; + const programInputs = [x, filter]; + const hasBias = bias != null; + const hasPreluActivationWeights = preluActivationWeights != null; + const hasLeakyreluAlpha = activation === 'leakyrelu'; + if (hasBias) { + programInputs.push(bias); + } + if (hasPreluActivationWeights) { + programInputs.push(preluActivationWeights); + } + if (hasLeakyreluAlpha) { + const $leakyreluAlpha = backend.makeTensorInfo([], 'float32', createScalarValue(leakyreluAlpha, 'float32')); + programInputs.push($leakyreluAlpha); + intermediates.push($leakyreluAlpha); + } + let program; + if (shouldPackDepthwiseConv) { + program = new DepthwiseConvPacked2DProgram(convInfo, hasBias, fusedActivation, hasPreluActivationWeights, hasLeakyreluAlpha); + } + else { + program = new DepthwiseConv2DProgram(convInfo, hasBias, fusedActivation, hasPreluActivationWeights, hasLeakyreluAlpha); + } + const customValues = [ + [convInfo.padInfo.top, convInfo.padInfo.left], + [convInfo.strideHeight, convInfo.strideWidth], + [convInfo.dilationHeight, convInfo.dilationWidth], + [convInfo.inHeight, convInfo.inWidth] + ]; + const result = backend.runWebGLProgram(program, programInputs, 'float32', customValues); + intermediates.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return result; + } + const fusedDepthwiseConv2DConfig = { + kernelName: FusedDepthwiseConv2D, + backendName: 'webgl', + kernelFunc: fusedDepthwiseConv2D, + }; + + class GatherNDProgram { + constructor(sliceDim, strides, shape, paramsShape) { + this.sliceDim = sliceDim; + this.strides = strides; + this.paramsShape = paramsShape; + this.variableNames = ['x', 'indices']; + this.outputShape = shape; + const dtype = getCoordsDataType(shape.length); + let mainLoop = ` + int index;`; + for (let j = 0; j < this.sliceDim; j++) { + mainLoop += ` + index = round(getIndices(coords[0], ${j})); + out_of_bounds = out_of_bounds || index < 0; + out_of_bounds = out_of_bounds || index >= ${this.paramsShape[j]}; + flattenIndex += index * ${this.strides[j]};`; + } + this.userCode = ` + void main() { + ${dtype} coords = getOutputCoords(); + int flattenIndex = 0; + bool out_of_bounds = false; + + ${mainLoop} + + setOutput(out_of_bounds ? 0.0 : getX(flattenIndex, coords[1])); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function gatherNd(args) { + const { inputs, backend } = args; + const { params, indices } = inputs; + const indicesShape = indices.shape; + const sliceRank = indicesShape[indicesShape.length - 1]; + const paramsSize = sizeFromShape(params.shape); + const [resultShape, numSlices, sliceSize, strides] = prepareAndValidate(params, indices); + const flattenIndices = reshape({ inputs: { x: indices }, backend, attrs: { shape: [numSlices, sliceRank] } }); + const flattenX = reshape({ + inputs: { x: params }, + backend, + attrs: { shape: [(sizeFromShape(params.shape) / sliceSize), sliceSize] } + }); + if (backend.shouldExecuteOnCPU([params, indices]) || + params.dtype === 'string') { + const indicesData = backend.readSync(indices.dataId); + const paramsBuf = backend.bufferSync(params); + const outValue = gatherNdImplCPU(indicesData, paramsBuf, params.dtype, numSlices, sliceRank, sliceSize, strides, params.shape, paramsSize); + return backend.makeTensorInfo(resultShape, params.dtype, outValue.values); + } + const program = new GatherNDProgram(sliceRank, strides, [numSlices, sliceSize], params.shape); + const res = backend.runWebGLProgram(program, [flattenX, flattenIndices], flattenX.dtype); + const reshaped = reshape({ inputs: { x: res }, backend, attrs: { shape: resultShape } }); + backend.disposeIntermediateTensorInfo(flattenIndices); + backend.disposeIntermediateTensorInfo(flattenX); + backend.disposeIntermediateTensorInfo(res); + return reshaped; + } + const gatherNdConfig = { + kernelName: GatherNd, + backendName: 'webgl', + kernelFunc: gatherNd + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class GatherProgram { + constructor(aShape, outputShape) { + this.variableNames = ['A', 'indices']; + this.outputShape = outputShape; + this.rank = outputShape.length; + const dtype = getCoordsDataType(this.rank); + const sourceCoords = getSourceCoords$1(aShape, 2); + this.userCode = ` + void main() { + ${dtype} resRC = getOutputCoords(); + int index = int(getIndices(resRC.x, resRC.z)); + float inBounds = (index >= 0) && (index < ${aShape[2]}) ? 1.0 : 0.0; + setOutput(inBounds * getA(${sourceCoords})); + } + `; + } + } + // The input and output are always flattened into rank 4 tensors. + function getSourceCoords$1(aShape, axis) { + const currentCoords = ['resRC.x', 'resRC.y', 'resRC.z', 'resRC.w']; + const sourceCoords = []; + for (let i = 0; i < aShape.length; i++) { + if (i === 2) { + sourceCoords.push('index'); + } + else { + sourceCoords.push(`${currentCoords[i]}`); + } + } + return sourceCoords.join(); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function gatherV2(args) { + const { inputs, backend, attrs } = args; + const { x, indices } = inputs; + const { axis, batchDims } = attrs; + const parsedAxis = parseAxisParam(axis, x.shape)[0]; + if (env().get('DEBUG')) { + // In debug mode, throw error when any index is out of bound. + // Otherwise, just fill out of bounds with zeroes. + const indicesVals = backend.readSync(indices.dataId); + const axisDim = x.shape[parsedAxis]; + for (let i = 0; i < indicesVals.length; ++i) { + const index = indicesVals[i]; + assert$1(index <= axisDim - 1 && index >= 0, () => `GatherV2: the index value ${index} is not in [0, ${axisDim - 1}]`); + } + } + const shapeInfo = collectGatherOpShapeInfo(x, indices, parsedAxis, batchDims); + const indicesSize = sizeFromShape(indices.shape); + const toDispose = []; + const flattenX = reshape({ + inputs: { x }, + backend, + attrs: { + shape: [ + shapeInfo.batchSize, shapeInfo.outerSize, shapeInfo.dimSize, + shapeInfo.sliceSize + ] + } + }); + const flattenIndex = reshape({ + inputs: { x: indices }, + backend, + attrs: { shape: [shapeInfo.batchSize, indicesSize / shapeInfo.batchSize] } + }); + toDispose.push(flattenX); + toDispose.push(flattenIndex); + const flattenOutputShape = [ + shapeInfo.batchSize, shapeInfo.outerSize, indicesSize / shapeInfo.batchSize, + shapeInfo.sliceSize + ]; + if (backend.shouldExecuteOnCPU([x, indices]) || x.dtype === 'string') { + const indicesBuf = backend.bufferSync(flattenIndex); + const xBuf = backend.bufferSync(flattenX); + const outBuf = gatherV2ImplCPU(xBuf, indicesBuf, flattenOutputShape); + toDispose.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return backend.makeTensorInfo(shapeInfo.outputShape, outBuf.dtype, outBuf.values); + } + const program = new GatherProgram(flattenX.shape, flattenOutputShape); + const res = backend.runWebGLProgram(program, [flattenX, flattenIndex], flattenX.dtype); + toDispose.push(res); + const reshaped = reshape({ inputs: { x: res }, backend, attrs: { shape: shapeInfo.outputShape } }); + toDispose.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return reshaped; + } + const gatherV2Config = { + kernelName: GatherV2, + backendName: 'webgl', + kernelFunc: gatherV2 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const GREATER = `return float(a > b);`; + const GREATER_PACKED = ` + return vec4(greaterThan(a, b)); +`; + const greater = binaryKernelFunc({ + opSnippet: GREATER, + packedOpSnippet: GREATER_PACKED, + cpuKernelImpl: greaterImplCPU, + dtype: 'bool' + }); + const greaterConfig = { + kernelName: Greater, + backendName: 'webgl', + kernelFunc: greater + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const GREATER_EQUAL = `return float(a >= b);`; + const GREATER_EQUAL_PACKED = ` + return vec4(greaterThanEqual(a, b)); +`; + const greaterEqual = binaryKernelFunc({ + opSnippet: GREATER_EQUAL, + packedOpSnippet: GREATER_EQUAL_PACKED, + dtype: 'bool', + cpuKernelImpl: greaterEqualImplCPU + }); + const greaterEqualConfig = { + kernelName: GreaterEqual, + backendName: 'webgl', + kernelFunc: greaterEqual + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function ifft(args) { + const { inputs, backend } = args; + const { input } = inputs; + return fftImpl(input, true /* inverse */, backend); + } + const ifftConfig = { + kernelName: IFFT, + backendName: 'webgl', + kernelFunc: ifft + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const IS_FINITE = `return float(!isnan(x) && !isinf(x));`; + const isFinite$1 = unaryKernelFunc({ opSnippet: IS_FINITE, dtype: 'bool' }); + const isFiniteConfig = { + kernelName: IsFinite, + backendName: 'webgl', + kernelFunc: isFinite$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const IS_INF = `return float(isinf(x));`; + const isInf = unaryKernelFunc({ opSnippet: IS_INF, dtype: 'bool' }); + const isInfConfig = { + kernelName: IsInf, + backendName: 'webgl', + kernelFunc: isInf, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const IS_NAN = `return float(isnan(x));`; + const isNaN$1 = unaryKernelFunc({ opSnippet: IS_NAN, dtype: 'bool' }); + const isNaNConfig = { + kernelName: IsNan, + backendName: 'webgl', + kernelFunc: isNaN$1, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const LESS = `return float(a < b);`; + const LESS_PACKED = ` + return vec4(lessThan(a, b)); +`; + const less = binaryKernelFunc({ + opSnippet: LESS, + packedOpSnippet: LESS_PACKED, + cpuKernelImpl: lessImplCPU, + dtype: 'bool' + }); + const lessConfig = { + kernelName: Less, + backendName: 'webgl', + kernelFunc: less + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const LESS_EQUAL = `return float(a <= b);`; + const LESS_EQUAL_PACKED = ` + return vec4(lessThanEqual(a, b)); +`; + const lessEqual = binaryKernelFunc({ + opSnippet: LESS_EQUAL, + packedOpSnippet: LESS_EQUAL_PACKED, + cpuKernelImpl: lessEqualImplCPU, + dtype: 'bool' + }); + const lessEqualConfig = { + kernelName: LessEqual, + backendName: 'webgl', + kernelFunc: lessEqual + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function linSpace(args) { + const { backend, attrs } = args; + const { start, stop, num } = attrs; + // TODO: Use CPU implementation due to the precision problem in Safari. + const outVals = linSpaceImplCPU(start, stop, num); + return backend.makeTensorInfo([outVals.length], 'float32', outVals); + } + const linSpaceConfig = { + kernelName: LinSpace, + backendName: 'webgl', + kernelFunc: linSpace + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Windows chrome return 0 if the input is negative value. We will specifically + // return NaN if the input is 0 to solve compatiblity issue. + const LOG = CHECK_NAN_SNIPPET_UNARY + ` + return x < 0.0 ? 0./0. : log(x); +`; + const LOG_PACKED = ` + vec4 result = log(x); + bvec4 isNaN = isnan(x); + result.r = isNaN.r ? x.r : (x.r < 0.0 ? 0./0. : result.r); + result.g = isNaN.g ? x.g : (x.g < 0.0 ? 0./0. : result.g); + result.b = isNaN.b ? x.b : (x.b < 0.0 ? 0./0. : result.b); + result.a = isNaN.a ? x.a : (x.a < 0.0 ? 0./0. : result.a); + return result; +`; + const log = unaryKernelFunc({ opSnippet: LOG, packedOpSnippet: LOG_PACKED, cpuKernelImpl: logImplCPU }); + const logConfig = { + kernelName: Log, + backendName: 'webgl', + kernelFunc: log + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const LOG1P = CHECK_NAN_SNIPPET_UNARY + ` + return log(1.0 + x); +`; + const log1p = unaryKernelFunc({ opSnippet: LOG1P }); + const log1pConfig = { + kernelName: Log1p, + backendName: 'webgl', + kernelFunc: log1p, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const LOGICAL_AND = `return float(a >= 1.0 && b >= 1.0);`; + const LOGICAL_AND_PACKED = ` + return vec4( + vec4(greaterThanEqual(a, vec4(1.0))) * + vec4(greaterThanEqual(b, vec4(1.0)))); +`; + const logicalAnd = binaryKernelFunc({ + opSnippet: LOGICAL_AND, + packedOpSnippet: LOGICAL_AND_PACKED, + dtype: 'bool' + }); + const logicalAndConfig = { + kernelName: LogicalAnd, + backendName: 'webgl', + kernelFunc: logicalAnd + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const LOGICAL_NOT = `return float(!(x >= 1.0));`; + const logicalNot = unaryKernelFunc({ opSnippet: LOGICAL_NOT }); + const logicalNotConfig = { + kernelName: LogicalNot, + backendName: 'webgl', + kernelFunc: logicalNot, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const LOGICAL_OR = `return float(a >= 1.0 || b >= 1.0);`; + const LOGICAL_OR_PACKED = ` + return min( + vec4(greaterThanEqual(a, vec4(1.0))) + + vec4(greaterThanEqual(b, vec4(1.0))), + vec4(1.0)); +`; + const logicalOr = binaryKernelFunc({ opSnippet: LOGICAL_OR, packedOpSnippet: LOGICAL_OR_PACKED, dtype: 'bool' }); + const logicalOrConfig = { + kernelName: LogicalOr, + backendName: 'webgl', + kernelFunc: logicalOr + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class LRNProgram { + constructor(xShape, radius, bias, alpha, beta) { + this.variableNames = ['x']; + this.outputShape = []; + const rad = radius; + const maxD = xShape[3] - 1; + this.outputShape = xShape; + // optimize pow(bias + alpha * sum, -beta) + // src: https://github.com/tensorflow/tensorflow/.. + // blob/26033a1644a9c4a5fbe3170ab2e864b6a4ccd4ca/.. + // tensorflow/core/kernels/mkl_lrn_op.cc#L320 + let powOperator; + const basis = `float(${bias}) + float(${alpha}) * sum`; + if (beta === 0.5) { + powOperator = `inversesqrt(${basis})`; + } + else if (beta === 1.0) { + powOperator = `1.0/(${basis})`; + } + else { + powOperator = `exp(log(${basis}) * float(-${beta}));`; + } + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int r = coords[1]; + int c = coords[2]; + int d = coords[3]; + float x = getX(b, r, c, d); + float sum = 0.0; + for (int j = -${rad}; j <= ${rad}; j++) { + int idx = d + j; + if (idx >= 0 && idx <= ${maxD}) { + float z = getX(b, r, c, idx); + sum += z * z; + } + } + float val = x * ${powOperator}; + setOutput(val); + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class LRNPackedProgram { + constructor(xShape, radius, bias, alpha, beta) { + this.variableNames = ['x']; + this.outputShape = []; + this.packedInputs = true; + this.packedOutput = true; + const rad = radius; + const maxD = xShape[3] - 1; + this.outputShape = xShape; + // optimize pow(bias + alpha * sum, -beta) + // src: https://github.com/tensorflow/tensorflow/.. + // blob/26033a1644a9c4a5fbe3170ab2e864b6a4ccd4ca/.. + // tensorflow/core/kernels/mkl_lrn_op.cc#L320 + let powOperator; + const basis = `float(${bias}) + float(${alpha}) * sum`; + if (beta === 0.5) { + powOperator = `inversesqrt(${basis})`; + } + else if (beta === 1.0) { + powOperator = `1.0/(${basis})`; + } + else { + powOperator = `exp(log(${basis}) * float(-${beta}));`; + } + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int b = coords.x; + int r = coords.y; + int c = coords.z; + int d = coords.w; + + bool hasNextCol = d < ${this.outputShape[3]}; + bool hasNextRow = c < ${this.outputShape[2]}; + + vec4 sum = vec4(0.); + vec4 xFragAtOutputCoords = getX(b, r, c, d); + + vec4 xAtOutputCoords = vec4( + getChannel(xFragAtOutputCoords, vec2(c, d)), + hasNextCol ? + getChannel(xFragAtOutputCoords, vec2(c, d + 1)) : 0.0, + hasNextRow ? + getChannel(xFragAtOutputCoords , vec2(c + 1, d)) : 0.0, + (hasNextRow && hasNextCol) ? + getChannel(xFragAtOutputCoords, vec2(c + 1, d + 1)) : 0.0 + ); + + int firstChannel = d - ${rad}; + vec2 cache = vec2(0.); + if(firstChannel >= 0){ + vec4 firstChannelFrag = getX(b, r, c, firstChannel); + cache.x = getChannel(firstChannelFrag, vec2(c, firstChannel)); + if(hasNextRow){ + cache.y = getChannel(firstChannelFrag, vec2(c + 1, firstChannel)); + } + } + + ivec2 depth = ivec2(d, d + 1); + for (int j = - ${rad}; j <= ${rad}; j++) { + ivec2 idx = depth + j; + bvec2 aboveLowerBound = greaterThanEqual(idx, ivec2(0)); + bvec2 belowUpperBound = lessThanEqual(idx, ivec2(${maxD})); + + bool depthInRange = aboveLowerBound.x && belowUpperBound.x; + bool depthPlusOneInRange = aboveLowerBound.y && belowUpperBound.y; + + if(depthInRange || depthPlusOneInRange){ + vec4 z = vec4(0.); + vec4 xFragAtCurrentDepth; + z.xz = cache.xy; + if(depthPlusOneInRange && hasNextCol){ + xFragAtCurrentDepth = idx.y != d ? + getX(b, r, c, idx.y) : xFragAtOutputCoords; + z.y = getChannel(xFragAtCurrentDepth, vec2(c, idx.y)); + if(hasNextRow){ + z.w = getChannel(xFragAtCurrentDepth, vec2(c + 1, idx.y)); + } + } + cache.xy = z.yw; + sum += z * z; + } + } + vec4 result = xAtOutputCoords * ${powOperator}; + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const lrn = (args) => { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { depthRadius, bias, alpha, beta } = attrs; + const program = env().getBool('WEBGL_PACK_NORMALIZATION') ? + new LRNPackedProgram(x.shape, depthRadius, bias, alpha, beta) : + new LRNProgram(x.shape, depthRadius, bias, alpha, beta); + return backend.runWebGLProgram(program, [x], x.dtype); + }; + // tslint:disable-next-line: variable-name + const LRNConfig = { + kernelName: LRN, + backendName: 'webgl', + kernelFunc: lrn + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class LRNGradProgram { + constructor(inputShape, depthRadius, bias, alpha, beta) { + this.variableNames = ['inputImage', 'outputImage', 'dy']; + this.outputShape = []; + this.outputShape = inputShape; + this.depth = inputShape[3]; + this.depthRadius = depthRadius; + this.bias = bias; + this.alpha = alpha; + this.beta = beta; + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int r = coords[1]; + int c = coords[2]; + + float result = 0.0; + for (int d = 0; d < ${this.depth}; ++d) { + int depthBegin = int(max(0.0, float(d - ${depthRadius}))); + int depthEnd = int(min(float(${this.depth}), + float(d + ${depthRadius} + 1))); + + const int MIN_DEPTH_BEGIN = 0; + const int MAX_DEPTH_END = ${this.depth}; + + float norm = 0.0; + for (int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k) { + if (k < depthBegin){ + continue; + } + else if (k >= depthBegin && k < depthEnd) { + norm += getInputImage(b, r, c, k) * getInputImage(b, r, c, k); + } + else { + break; + } + } + + norm = float(${alpha}) * norm + float(${bias}); + + for(int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k){ + if (k < depthBegin){ + continue; + } + else if (k >= depthBegin && k < depthEnd){ + float dyi = -2.0 * float(${alpha}) + * float(${beta}) + * getInputImage(b, r, c, k) * getOutputImage(b, r, c, d) + / norm; + if (k == d) { + dyi += pow(norm, -1.0 * ${beta}); + } + if (k == coords[3]) { + dyi *= getDy(b, r, c, d); + result += dyi; + } + } + else { + break; + } + } + } + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const lrnGrad = (args) => { + const { inputs, backend, attrs } = args; + const { x, y, dy } = inputs; + const { depthRadius, bias, alpha, beta } = attrs; + const program = new LRNGradProgram(x.shape, depthRadius, bias, alpha, beta); + return backend.runWebGLProgram(program, [x, y, dy], x.dtype); + }; + // tslint:disable-next-line: variable-name + const LRNGradConfig = { + kernelName: LRNGrad, + backendName: 'webgl', + kernelFunc: lrnGrad + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxImpl(x, reduceShape, outShape, backend) { + const inSize = sizeFromShape(reduceShape); + const xSize = sizeFromShape(x.shape); + const batchSize = xSize / inSize; + const reshapedInput = reshape({ inputs: { x }, attrs: { shape: [batchSize, inSize] }, backend }); + const reduced = reduce(reshapedInput, x.dtype, 'max', backend); + const reshapedOutput = reshape({ inputs: { x: reduced }, attrs: { shape: outShape }, backend }); + backend.disposeIntermediateTensorInfo(reshapedInput); + backend.disposeIntermediateTensorInfo(reduced); + return reshapedOutput; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function max(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { reductionIndices, keepDims } = attrs; + const xRank = x.shape.length; + const origAxes = parseAxisParam(reductionIndices, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, xRank); + const maxInputIsTransposed = permutedAxes != null; + const shouldExecuteOnCPU = backend.shouldExecuteOnCPU([x]); + let maxInput = x; + if (maxInputIsTransposed) { + if (shouldExecuteOnCPU) { + const xTexData = backend.texData.get(maxInput.dataId); + const values = xTexData.values; + const newShape = new Array(xRank); + for (let i = 0; i < newShape.length; i++) { + newShape[i] = x.shape[permutedAxes[i]]; + } + const maxInputValues = transposeImplCPU(values, x.shape, x.dtype, permutedAxes, newShape); + maxInput = backend.makeTensorInfo(newShape, x.dtype); + const maxInputData = backend.texData.get(maxInput.dataId); + maxInputData.values = maxInputValues; + } + else { + maxInput = transposeImpl(x, permutedAxes, backend); + } + axes = getInnerMostAxes(axes.length, xRank); + } + assertAxesAreInnerMostDims('max', axes, xRank); + const [maxOutShape, reduceShape] = computeOutAndReduceShapes(maxInput.shape, axes); + let outShape = maxOutShape; + if (keepDims) { + // rather than reshape at the end, set the target shape here. + outShape = expandShapeToKeepDim(maxOutShape, origAxes); + } + let out; + if (shouldExecuteOnCPU) { + const xTexData = backend.texData.get(maxInput.dataId); + const values = xTexData.values; + const outValues = maxImplCPU(values, sizeFromShape(reduceShape), outShape, x.dtype); + out = backend.makeTensorInfo(outShape, x.dtype); + const outData = backend.texData.get(out.dataId); + outData.values = outValues; + } + else { + out = maxImpl(maxInput, reduceShape, outShape, backend); + } + if (maxInputIsTransposed) { + backend.disposeIntermediateTensorInfo(maxInput); + } + return out; + } + const maxConfig = { + kernelName: Max, + backendName: 'webgl', + kernelFunc: max + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const MAXIMUM = CHECK_NAN_SNIPPET + ` + return max(a, b); +`; + const MAXIMUM_PACKED = ` + vec4 result = vec4(max(a, b)); + bvec4 isNaNA = isnan(a); + bvec4 isNaNB = isnan(b); + bvec4 isNaN = bvec4(isNaNA.x || isNaNB.x, isNaNA.y || isNaNB.y, isNaNA.z || isNaNB.z, isNaNA.w || isNaNB.w); + ` + + CHECK_NAN_SNIPPET_PACKED + ` + return result; +`; + const maximum = binaryKernelFunc({ + opSnippet: MAXIMUM, + packedOpSnippet: MAXIMUM_PACKED, + cpuKernelImpl: maximumImplCPU + }); + const maximumConfig = { + kernelName: Maximum$1, + backendName: 'webgl', + kernelFunc: maximum + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPool(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + assertNotComplex(x, 'maxPool'); + const { filterSize, strides, pad, dimRoundingMode } = attrs; + const dilations = 1; + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in maxPool: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + const convInfo = computePool2DInfo(x.shape, filterSize, strides, dilations, pad, dimRoundingMode); + if (convInfo.filterWidth === 1 && convInfo.filterHeight === 1 && + arraysEqual(convInfo.inShape, convInfo.outShape)) { + return identity({ inputs: { x }, backend }); + } + const maxPoolProgram = new Pool2DProgram(convInfo, 'max', false); + return backend.runWebGLProgram(maxPoolProgram, [x], x.dtype); + } + const maxPoolConfig = { + kernelName: MaxPool, + backendName: 'webgl', + kernelFunc: maxPool + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPool3d(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { filterSize, strides, pad, dataFormat, dimRoundingMode } = attrs; + const dilations = [1, 1, 1]; + const convInfo = computePool3DInfo(x.shape, filterSize, strides, dilations, pad, dimRoundingMode, dataFormat); + const maxPoolProgram = new Pool3DProgram(convInfo, 'max', false); + return backend.runWebGLProgram(maxPoolProgram, [x], x.dtype); + } + const maxPool3DConfig = { + kernelName: MaxPool3D, + backendName: 'webgl', + kernelFunc: maxPool3d + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class MaxPool2DBackpropProgram { + constructor(convInfo) { + this.variableNames = ['dy', 'maxPos']; + this.outputShape = convInfo.inShape; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationHeight = convInfo.dilationHeight; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padTop = effectiveFilterHeight - 1 - convInfo.padInfo.top; + const padLeft = effectiveFilterWidth - 1 - convInfo.padInfo.left; + const lastIndex = effectiveFilterHeight * effectiveFilterWidth - 1; + this.userCode = ` + const ivec2 pads = ivec2(${padTop}, ${padLeft}); + + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int d = coords[3]; + + ivec2 dyRCCorner = coords.yz - pads; + int dyRCorner = dyRCCorner.x; + int dyCCorner = dyRCCorner.y; + + // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d). + // ? = to be determined. : = across all values in that axis. + float dotProd = 0.0; + for (int wR = 0; wR < ${effectiveFilterHeight}; + wR += ${dilationHeight}) { + float dyR = float(dyRCorner + wR) / ${strideHeight}.0; + + if (dyR < 0.0 || dyR >= ${convInfo.outHeight}.0 || fract(dyR) > 0.0) { + continue; + } + int idyR = int(dyR); + + for (int wC = 0; wC < ${effectiveFilterWidth}; wC++) { + float dyC = float(dyCCorner + wC) / ${strideWidth}.0; + + if (dyC < 0.0 || dyC >= ${convInfo.outWidth}.0 || + fract(dyC) > 0.0) { + continue; + } + int idyC = int(dyC); + + float dyValue = getDy(b, idyR, idyC, d); + int maxPosValue = ${lastIndex} - int(getMaxPos(b, idyR, idyC, d)); + + // Get the current value, check it against the value from the + // position matrix. + int curPosValue = wR * ${effectiveFilterWidth} + wC; + float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0); + + dotProd += dyValue * mask; + } + } + setOutput(dotProd); + } + `; + } + } + class MaxPool3DBackpropProgram { + constructor(convInfo) { + this.variableNames = ['dy', 'maxPos']; + this.outputShape = convInfo.inShape; + const strideDepth = convInfo.strideDepth; + const strideHeight = convInfo.strideHeight; + const strideWidth = convInfo.strideWidth; + const dilationDepth = convInfo.dilationDepth; + const dilationHeight = convInfo.dilationHeight; + const dilationWidth = convInfo.dilationWidth; + const effectiveFilterDepth = convInfo.effectiveFilterDepth; + const effectiveFilterHeight = convInfo.effectiveFilterHeight; + const effectiveFilterWidth = convInfo.effectiveFilterWidth; + const padFront = effectiveFilterDepth - 1 - convInfo.padInfo.front; + const padTop = effectiveFilterHeight - 1 - convInfo.padInfo.top; + const padLeft = effectiveFilterWidth - 1 - convInfo.padInfo.left; + const lastIndex = effectiveFilterDepth * effectiveFilterHeight * effectiveFilterWidth - 1; + this.userCode = ` + const ivec3 pads = ivec3(${padFront}, ${padTop}, ${padLeft}); + + void main() { + ivec5 coords = getOutputCoords(); + int batch = coords.x; + int ch = coords.u; + + ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads; + int dyDCorner = dyCorner.x; + int dyRCorner = dyCorner.y; + int dyCCorner = dyCorner.z; + + // Convolve dy(?, ?, ?, ch) with pos mask(:, :, :, d) to get + // dx(xD, xR, xC, ch). + // ? = to be determined. : = across all values in that axis. + float dotProd = 0.0; + + for (int wD = 0; wD < ${effectiveFilterDepth}; + wD += ${dilationDepth}) { + float dyD = float(dyDCorner + wD) / ${strideDepth}.0; + + if (dyD < 0.0 || dyD >= ${convInfo.outDepth}.0 || fract(dyD) > 0.0) { + continue; + } + int idyD = int(dyD); + + for (int wR = 0; wR < ${effectiveFilterHeight}; + wR += ${dilationHeight}) { + float dyR = float(dyRCorner + wR) / ${strideHeight}.0; + + if (dyR < 0.0 || dyR >= ${convInfo.outHeight}.0 || + fract(dyR) > 0.0) { + continue; + } + int idyR = int(dyR); + + for (int wC = 0; wC < ${effectiveFilterWidth}; + wC += ${dilationWidth}) { + float dyC = float(dyCCorner + wC) / ${strideWidth}.0; + + if (dyC < 0.0 || dyC >= ${convInfo.outWidth}.0 || + fract(dyC) > 0.0) { + continue; + } + int idyC = int(dyC); + + float dyValue = getDy(batch, idyD, idyR, idyC, ch); + int maxPosValue = ${lastIndex} - + int(getMaxPos(batch, idyD, idyR, idyC, ch)); + + // Get the current value, check it against the value from the + // position matrix. + int curPosValue = + wD * ${effectiveFilterHeight} * ${effectiveFilterWidth} + + wR * ${effectiveFilterWidth} + wC; + float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0); + + dotProd += dyValue * mask; + } + } + } + setOutput(dotProd); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPool3DGrad(args) { + const { inputs, backend, attrs } = args; + const { dy, input } = inputs; + const x = input; + const { filterSize, strides, pad, dimRoundingMode } = attrs; + const dilations = [1, 1, 1]; + const convInfo = computePool3DInfo(x.shape, filterSize, strides, dilations, pad, dimRoundingMode); + const maxPool3dPositionsProgram = new Pool3DProgram(convInfo, 'max', true /* get positions */); + const maxPool3dPositions = backend.runWebGLProgram(maxPool3dPositionsProgram, [x], x.dtype); + const maxPoolBackpropProgram = new MaxPool3DBackpropProgram(convInfo); + const result = backend.runWebGLProgram(maxPoolBackpropProgram, [dy, maxPool3dPositions], x.dtype); + backend.disposeIntermediateTensorInfo(maxPool3dPositions); + return result; + } + const maxPool3DGradConfig = { + kernelName: MaxPool3DGrad, + backendName: 'webgl', + kernelFunc: maxPool3DGrad + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPoolGrad(args) { + const { inputs, backend, attrs } = args; + const { dy, input, output } = inputs; + const x = input; + assertNotComplex([input, output], 'maxPoolGrad'); + const { filterSize, strides, pad, dimRoundingMode } = attrs; + const convInfo = computePool2DInfo(x.shape, filterSize, strides, 1 /* dilations */, pad, dimRoundingMode); + const getPositions = true; + const maxPoolPositionsProgram = new Pool2DProgram(convInfo, 'max', getPositions); + const maxPoolPositions = backend.runWebGLProgram(maxPoolPositionsProgram, [x], x.dtype); + const maxPoolBackPropProgram = new MaxPool2DBackpropProgram(convInfo); + const result = backend.runWebGLProgram(maxPoolBackPropProgram, [dy, maxPoolPositions], x.dtype); + backend.disposeIntermediateTensorInfo(maxPoolPositions); + return result; + } + const maxPoolGradConfig = { + kernelName: MaxPoolGrad, + backendName: 'webgl', + kernelFunc: maxPoolGrad + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function maxPoolWithArgmaxImpl(x, includeBatchInIndex, convInfo, backend) { + let program = new Pool2DProgram(convInfo, 'max', false); + const poolOutput = backend.runWebGLProgram(program, [x], 'float32'); + program = new Pool2DProgram(convInfo, 'max', true, true, includeBatchInIndex); + const indexOutput = backend.runWebGLProgram(program, [x], 'float32'); + return [poolOutput, indexOutput]; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const maxPoolWithArgmaxConfig = { + kernelName: MaxPoolWithArgmax, + backendName: 'webgl', + kernelFunc: ({ inputs, attrs, backend }) => { + const { x } = inputs; + const { filterSize, strides, pad, includeBatchInIndex } = attrs; + const webglBackend = backend; + assert$1(x.shape.length === 4, () => `Error in maxPool: input must be rank 4 but got rank ${x.shape.length}.`); + const dilations = [1, 1]; + assert$1(eitherStridesOrDilationsAreOne(strides, dilations), () => 'Error in maxPool: Either strides or dilations must be 1. ' + + `Got strides ${strides} and dilations '${dilations}'`); + const convInfo = computePool2DInfo(x.shape, filterSize, strides, dilations, pad); + const [result, indexes] = maxPoolWithArgmaxImpl(x, includeBatchInIndex, convInfo, webglBackend); + return [result, indexes]; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function meanImpl(x, reduceShape, outShape, backend) { + const inSize = sizeFromShape(reduceShape); + const xSize = sizeFromShape(x.shape); + const batchSize = xSize / inSize; + const reshapedInput = reshape({ inputs: { x }, attrs: { shape: [batchSize, inSize] }, backend }); + const reduced = reduce(reshapedInput, 'float32', 'mean', backend); + const reshapedOutput = reshape({ inputs: { x: reduced }, attrs: { shape: outShape }, backend }); + backend.disposeIntermediateTensorInfo(reshapedInput); + backend.disposeIntermediateTensorInfo(reduced); + return reshapedOutput; + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const meanConfig = { + kernelName: Mean, + backendName: 'webgl', + kernelFunc: ({ inputs, attrs, backend }) => { + const { x } = inputs; + const { keepDims, axis } = attrs; + const webglBackend = backend; + const xRank = x.shape.length; + const origAxes = parseAxisParam(axis, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, xRank); + const meanInputIsTransposed = permutedAxes != null; + const shouldExecuteOnCPU = webglBackend.shouldExecuteOnCPU([x]); + const intermediates = []; + let meanInput = x; + if (meanInputIsTransposed) { + if (shouldExecuteOnCPU) { + const xTexData = webglBackend.texData.get(meanInput.dataId); + const values = xTexData.values; + const newShape = new Array(xRank); + for (let i = 0; i < newShape.length; i++) { + newShape[i] = x.shape[permutedAxes[i]]; + } + const meanInputValues = transposeImplCPU(values, x.shape, x.dtype, permutedAxes, newShape); + meanInput = webglBackend.makeTensorInfo(newShape, x.dtype); + const meanInputData = webglBackend.texData.get(meanInput.dataId); + meanInputData.values = meanInputValues; + } + else { + meanInput = transposeImpl(x, permutedAxes, webglBackend); + } + intermediates.push(meanInput); + axes = getInnerMostAxes(axes.length, xRank); + } + assertAxesAreInnerMostDims('sum', axes, xRank); + const [meanOutShape, reduceShape] = computeOutAndReduceShapes(meanInput.shape, axes); + let outShape = meanOutShape; + if (keepDims) { + // rather than reshape at the end, set the target shape here. + outShape = expandShapeToKeepDim(meanOutShape, origAxes); + } + const out = meanImpl(meanInput, reduceShape, outShape, webglBackend); + for (const i of intermediates) { + webglBackend.disposeIntermediateTensorInfo(i); + } + return out; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function min(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + const xRank = x.shape.length; + const origAxes = parseAxisParam(axis, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, xRank); + let permutedX = x; + if (permutedAxes != null) { + permutedX = transpose({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + axes = getInnerMostAxes(axes.length, x.shape.length); + } + assertAxesAreInnerMostDims('min', axes, xRank); + const [outShape, reduceShape] = computeOutAndReduceShapes(permutedX.shape, axes); + const inSize = sizeFromShape(reduceShape); + const a2D = reshape({ inputs: { x: permutedX }, backend, attrs: { shape: [-1, inSize] } }); + const reduced = reduce(a2D, a2D.dtype, 'min', backend); + let res; + if (keepDims) { + const newShape = expandShapeToKeepDim(outShape, origAxes); + res = reshape({ inputs: { x: reduced }, backend, attrs: { shape: newShape } }); + } + else { + res = reshape({ inputs: { x: reduced }, backend, attrs: { shape: outShape } }); + } + backend.disposeIntermediateTensorInfo(a2D); + backend.disposeIntermediateTensorInfo(reduced); + if (permutedAxes != null) { + backend.disposeIntermediateTensorInfo(permutedX); + } + return res; + } + const minConfig = { + kernelName: Min, + backendName: 'webgl', + kernelFunc: min + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const MINIMUM = CHECK_NAN_SNIPPET + ` + return min(a, b); +`; + const MINIMUM_PACKED = ` + vec4 result = vec4(min(a, b)); + bvec4 isNaNA = isnan(a); + bvec4 isNaNB = isnan(b); + bvec4 isNaN = bvec4(isNaNA.x || isNaNB.x, isNaNA.y || isNaNB.y, isNaNA.z || isNaNB.z, isNaNA.w || isNaNB.w); + ` + + CHECK_NAN_SNIPPET_PACKED + ` + return result; +`; + const minimum = binaryKernelFunc({ + opSnippet: MINIMUM, + packedOpSnippet: MINIMUM_PACKED, + cpuKernelImpl: minimumImplCPU + }); + const minimumConfig = { + kernelName: Minimum$1, + backendName: 'webgl', + kernelFunc: minimum + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class MirrorPadProgram { + constructor(xShape, paddings, mode) { + this.variableNames = ['x']; + this.outputShape = paddings.map((p, i) => p[0] /* beforePad */ + xShape[i] + p[1] /* afterPad */); + const rank = xShape.length; + const dtype = getCoordsDataType(rank); + const start = paddings.map(p => p[0]).join(','); + const end = paddings.map((p, i) => p[0] + xShape[i]).join(','); + const unpackedCoords = ['coords[0]', 'coords[1]', 'coords[2]', 'coords[3]'].slice(0, rank); + const offset = mode === 'reflect' ? 0 : 1; + if (rank === 1) { + this.userCode = ` + int start = ${start}; + int end = ${end}; + + void main() { + int outC = getOutputCoords(); + if (outC < start) { + outC = start * 2 - outC - ${offset}; + } else if(outC >= end) { + outC = (end - 1) * 2 - outC + ${offset}; + } + setOutput(getX(outC - start)); + } + `; + return; + } + this.userCode = ` + ${dtype} start = ${dtype}(${start}); + ${dtype} end = ${dtype}(${end}); + + void main() { + ${dtype} outC = getOutputCoords(); + for (int i = 0; i < ${rank}; i++) { + if (outC[i] < start[i]) { + outC[i] = start[i] * 2 - outC[i] - ${offset}; + } else if(outC[i] >= end[i]) { + outC[i] = (end[i] - 1) * 2 - outC[i] + ${offset}; + } + } + ${dtype} coords = outC - start; + setOutput(getX(${unpackedCoords})); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + /** + * Example shader code for + * `mirrorPad(tf.tensor1d([1, 2, 3], 'int32'), [[2, 2]], 'reflect')` + * ``` + * const int start = int(2); + * const int end = int(5); + * + * void main() { + * int outputLoc = getOutputCoords(); + * vec4 result = vec4(0.); + * + * int rc = outputLoc; + * + * int source = rc; + * if (source < start) { + * source = start * 2 - source - 0; + * } else if (source >= end) { + * source = (end - 1) * 2 - source + 0; + * } + * source -= start; + * + * result[0] = getChannel(getX(source), source); + * rc += 1; + * if(rc < 6) { + * int source = rc; + * if (source < start) { + * source = start * 2 - source - 0; + * } else if (source >= end) { + * source = (end - 1) * 2 - source + 0; + * } + * source -= start; + * + * result[1] = getChannel(getX(source), source); + * } + * + * setOutput(result); + * } + * ``` + */ + class MirrorPadPackedProgram { + constructor(xShape, paddings, mode) { + this.variableNames = ['x']; + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = paddings.map((p, i) => p[0] /* beforePad */ + xShape[i] + p[1] /* afterPad */); + const rank = xShape.length; + const dtype = getCoordsDataType(rank); + const start = paddings.map(p => p[0]).join(','); + const end = paddings.map((p, i) => p[0] + xShape[i]).join(','); + const coords = getChannels('rc', rank); + const source = getChannels('source', rank); + const cLimit = `${coords[rank - 1]} < ${this.outputShape[rank - 1]}`; + const innerDims = rank === 1 ? 'source' : `vec2(${source.slice(-2).join()})`; + const offset = mode === 'reflect' ? 0 : 1; + let mainLoop = ''; + if (rank === 1) { + const padSetup = ` + ${dtype} source = rc; + if (source < start) { + source = start * 2 - source - ${offset}; + } else if (source >= end) { + source = (end - 1) * 2 - source + ${offset}; + } + source -= start; + `; + mainLoop = ` + ${dtype} rc = outputLoc; + ${padSetup} + result[0] = getChannel(getX(${source.join()}), ${innerDims}); + ${coords[rank - 1]} += 1; + if(${cLimit}) { + ${padSetup} + result[1] = getChannel(getX(${source.join()}), ${innerDims}); + } + `; + } + else { + const padSetup = ` + ${dtype} source = rc; + ${dtype} lt = ${dtype}(lessThan(source, start)); + ${dtype} gte = ${dtype}(greaterThanEqual(source, end)); + ${dtype} orig = 1 - (lt + gte); + source = orig * source + + lt * (start * 2 - source - ${offset}) + + gte * ((end - 1) * 2 - source + ${offset}); + source -= start; + `; + mainLoop = ` + ${dtype} rc = outputLoc; + ${padSetup} + result[0] = getChannel(getX(${source.join()}), ${innerDims}); + ${coords[rank - 1]} += 1; + if(${cLimit}) { + ${padSetup} + result[1] = getChannel(getX(${source.join()}), ${innerDims}); + } + rc = outputLoc; + ${coords[rank - 2]} += 1; + if(${coords[rank - 2]} < ${this.outputShape[rank - 2]}) { + ${padSetup} + result[2] = getChannel(getX(${source.join()}), ${innerDims}); + ${coords[rank - 1]} += 1; + if(${cLimit}) { + ${padSetup} + result[3] = getChannel(getX(${source.join()}), ${innerDims}); + } + } + `; + } + this.userCode = ` + const ${dtype} start = ${dtype}(${start}); + const ${dtype} end = ${dtype}(${end}); + + void main() { + ${dtype} outputLoc = getOutputCoords(); + vec4 result = vec4(0.); + ${mainLoop} + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const mirrorPadKernelFunc = ({ inputs, backend, attrs }) => { + const { x } = inputs; + const { paddings, mode } = attrs; + const program = env().getBool('WEBGL_PACK_ARRAY_OPERATIONS') ? + new MirrorPadPackedProgram(x.shape, paddings, mode) : + new MirrorPadProgram(x.shape, paddings, mode); + const output = backend.runWebGLProgram(program, [x], x.dtype); + return output; + }; + const mirrorPadConfig = { + kernelName: MirrorPad, + backendName: 'webgl', + kernelFunc: mirrorPadKernelFunc, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const MOD = `if (b == 0.0) return NAN; + return mod(a, b);`; + const MOD_PACKED = ` + vec4 result = mod(a, b); + bvec4 isNaN = equal(b, vec4(0.0)); + ` + + CHECK_NAN_SNIPPET_PACKED + ` + return result; +`; + const mod = binaryKernelFunc({ + opSnippet: MOD, + packedOpSnippet: MOD_PACKED, + }); + const modConfig = { + kernelName: Mod, + backendName: 'webgl', + kernelFunc: mod + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class MultinomialProgram { + constructor(batchSize, numOutcomes, numSamples) { + this.variableNames = ['probs']; + this.customUniforms = [{ name: 'seed', type: 'float' }]; + this.outputShape = [batchSize, numSamples]; + this.userCode = ` + void main() { + ivec2 coords = getOutputCoords(); + int batch = coords[0]; + + float r = random(seed); + float cdf = 0.0; + + for (int i = 0; i < ${numOutcomes - 1}; i++) { + cdf += getProbs(batch, i); + + if (r < cdf) { + setOutput(float(i)); + return; + } + } + + // If no other event happened, last event happened. + setOutput(float(${numOutcomes - 1})); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Without the equality check div produces 0.9999 for a = b, which when + // floored can cause errors. + const DIV = ` +if (a == b) { + return 1.0; +}; +return a / b;`; + // We do the same as in ./binaryop_gpu, with vec4 and ivec4. + // On Linux, the vectorized implementation produces NaNs when a and b are 0. + const DIV_PACKED = ` + // vec4 one = vec4(equal(a, b)); + // return one + (vec4(1.0) - one) * a / b; + vec4 result = a / b; + if(a.x == b.x) { + result.x = 1.; + } + if(a.y == b.y) { + result.y = 1.; + } + if(a.z == b.z) { + result.z = 1.; + } + if(a.w == b.w) { + result.w = 1.; + } + + return result; +`; + const realDiv = binaryKernelFunc({ opSnippet: DIV, packedOpSnippet: DIV_PACKED, checkOutOfBounds: true }); + const realDivConfig = { + kernelName: RealDiv, + backendName: 'webgl', + kernelFunc: realDiv, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SUB = 'return a - b;'; + const sub = binaryKernelFunc({ + opSnippet: SUB, + packedOpSnippet: SUB, + supportsComplex: true, + cpuKernelImpl: subImplCPU + }); + const subConfig = { + kernelName: Sub, + backendName: 'webgl', + kernelFunc: sub + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function softmax(args) { + const { inputs, backend, attrs } = args; + const { logits } = inputs; + const { dim } = attrs; + const axes = parseAxisParam([dim], logits.shape); + const maxLogit = max({ + inputs: { x: logits }, + backend, + attrs: { reductionIndices: axes, keepDims: false } + }); + const expandedShape = expandShapeToKeepDim(maxLogit.shape, axes); + const maxLogitsReshaped = reshape({ inputs: { x: maxLogit }, backend, attrs: { shape: expandedShape } }); + const a = sub({ inputs: { a: logits, b: maxLogitsReshaped }, backend }); + const b = exp({ inputs: { x: a }, backend }); + const sumExp = sum({ inputs: { x: b }, backend, attrs: { axis: axes, keepDims: false } }); + const sumExpReshaped = reshape({ inputs: { x: sumExp }, backend, attrs: { shape: expandedShape } }); + const res = realDiv({ inputs: { a: b, b: sumExpReshaped }, backend }); + backend.disposeIntermediateTensorInfo(maxLogit); + backend.disposeIntermediateTensorInfo(maxLogitsReshaped); + backend.disposeIntermediateTensorInfo(a); + backend.disposeIntermediateTensorInfo(b); + backend.disposeIntermediateTensorInfo(sumExp); + backend.disposeIntermediateTensorInfo(sumExpReshaped); + return res; + } + const softmaxConfig = { + kernelName: Softmax$2, + backendName: 'webgl', + kernelFunc: softmax + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function multinomial(args) { + const { inputs, backend, attrs } = args; + const { logits } = inputs; + const { numSamples, seed, normalized } = attrs; + const probs = normalized ? + logits : + softmax({ inputs: { logits }, backend, attrs: { dim: logits.shape.length - 1 } }); + const batchSize = probs.shape[0]; + const numOutcomes = probs.shape[1]; + const program = new MultinomialProgram(batchSize, numOutcomes, numSamples); + const customValues = [[seed]]; + const res = backend.runWebGLProgram(program, [probs], 'int32', customValues); + if (!normalized) { + backend.disposeIntermediateTensorInfo(probs); + } + return res; + } + const multinomialConfig = { + kernelName: Multinomial, + backendName: 'webgl', + kernelFunc: multinomial + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const NEG = CHECK_NAN_SNIPPET$1 + ` + return -x; +`; + const NEG_PACKED = ` + vec4 result = -x; + bvec4 isNaN = isnan(x); + + result.r = isNaN.r ? x.r : result.r; + result.g = isNaN.g ? x.g : result.g; + result.b = isNaN.b ? x.b : result.b; + result.a = isNaN.a ? x.a : result.a; + + return result; +`; + // This doesn't use unaryKernelFunc because negImplCPU is not of type + // SimpleUnaryKernelImplCPU. + function neg(args) { + const { inputs, backend } = args; + const { x } = inputs; + if (backend.shouldExecuteOnCPU([x])) { + const xData = backend.texData.get(x.dataId); + const [outValues, newShape] = negImplCPU(xData.values, x.shape, x.dtype); + return backend.makeTensorInfo(newShape, x.dtype, outValues); + } + let program; + if (env().getBool('WEBGL_PACK_UNARY_OPERATIONS')) { + program = new UnaryOpPackedProgram(x.shape, NEG_PACKED); + } + else { + program = new UnaryOpProgram(x.shape, NEG); + } + return backend.runWebGLProgram(program, [x], x.dtype); + } + const negConfig = { + kernelName: Neg, + backendName: 'webgl', + kernelFunc: neg + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const nonMaxSuppressionV3Impl = nonMaxSuppressionV3Impl$2; + function nonMaxSuppressionV3(args) { + warn('tf.nonMaxSuppression() in webgl locks the UI thread. ' + + 'Call tf.nonMaxSuppressionAsync() instead'); + const { inputs, backend, attrs } = args; + const { boxes, scores } = inputs; + const { maxOutputSize, iouThreshold, scoreThreshold } = attrs; + const boxesVals = backend.readSync(boxes.dataId); + const scoresVals = backend.readSync(scores.dataId); + const { selectedIndices } = nonMaxSuppressionV3Impl(boxesVals, scoresVals, maxOutputSize, iouThreshold, scoreThreshold); + return backend.makeTensorInfo([selectedIndices.length], 'int32', new Int32Array(selectedIndices)); + } + const nonMaxSuppressionV3Config = { + kernelName: NonMaxSuppressionV3, + backendName: 'webgl', + kernelFunc: nonMaxSuppressionV3 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const nonMaxSuppressionV4Impl = nonMaxSuppressionV4Impl$2; + function nonMaxSuppressionV4(args) { + warn('tf.nonMaxSuppression() in webgl locks the UI thread. ' + + 'Call tf.nonMaxSuppressionAsync() instead'); + const { inputs, backend, attrs } = args; + const { boxes, scores } = inputs; + const { maxOutputSize, iouThreshold, scoreThreshold, padToMaxOutputSize } = attrs; + const boxesVals = backend.readSync(boxes.dataId); + const scoresVals = backend.readSync(scores.dataId); + const { selectedIndices, validOutputs } = nonMaxSuppressionV4Impl(boxesVals, scoresVals, maxOutputSize, iouThreshold, scoreThreshold, padToMaxOutputSize); + return [ + backend.makeTensorInfo([selectedIndices.length], 'int32', new Int32Array(selectedIndices)), + backend.makeTensorInfo([], 'int32', new Int32Array([validOutputs])) + ]; + } + const nonMaxSuppressionV4Config = { + kernelName: NonMaxSuppressionV4, + backendName: 'webgl', + kernelFunc: nonMaxSuppressionV4 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const nonMaxSuppressionV5Impl = nonMaxSuppressionV5Impl$2; + function nonMaxSuppressionV5(args) { + warn('tf.nonMaxSuppression() in webgl locks the UI thread. ' + + 'Call tf.nonMaxSuppressionAsync() instead'); + const { inputs, backend, attrs } = args; + const { boxes, scores } = inputs; + const { maxOutputSize, iouThreshold, scoreThreshold, softNmsSigma } = attrs; + const boxesVals = backend.readSync(boxes.dataId); + const scoresVals = backend.readSync(scores.dataId); + const maxOutputSizeVal = maxOutputSize; + const iouThresholdVal = iouThreshold; + const scoreThresholdVal = scoreThreshold; + const softNmsSigmaVal = softNmsSigma; + const { selectedIndices, selectedScores } = nonMaxSuppressionV5Impl(boxesVals, scoresVals, maxOutputSizeVal, iouThresholdVal, scoreThresholdVal, softNmsSigmaVal); + return [ + backend.makeTensorInfo([selectedIndices.length], 'int32', new Int32Array(selectedIndices)), + backend.makeTensorInfo([selectedScores.length], 'float32', new Float32Array(selectedScores)) + ]; + } + const nonMaxSuppressionV5Config = { + kernelName: NonMaxSuppressionV5, + backendName: 'webgl', + kernelFunc: nonMaxSuppressionV5 + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class OneHotProgram { + constructor(numIndices, depth, onValue, offValue) { + this.variableNames = ['indices']; + this.outputShape = [numIndices, depth]; + this.userCode = ` + void main() { + ivec2 coords = getOutputCoords(); + int index = round(getIndices(coords.x)); + setOutput(mix(float(${offValue}), float(${onValue}), + float(index == coords.y))); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const oneHot = (args) => { + const { inputs, backend, attrs } = args; + const { indices } = inputs; + const { dtype, depth, onValue, offValue } = attrs; + const indicesSize = sizeFromShape(indices.shape); + const program = new OneHotProgram(indicesSize, depth, onValue, offValue); + const reshaped = reshape({ inputs: { x: indices }, backend, attrs: { shape: [indicesSize] } }); + const result = backend.runWebGLProgram(program, [reshaped], dtype); + backend.disposeIntermediateTensorInfo(reshaped); + const outShape = [...indices.shape, depth]; + const out = reshape({ inputs: { x: result }, backend, attrs: { shape: outShape } }); + backend.disposeIntermediateTensorInfo(result); + return out; + }; + const oneHotConfig = { + kernelName: OneHot, + backendName: 'webgl', + kernelFunc: oneHot + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function zerosLike(args) { + const { inputs, backend } = args; + const { x } = inputs; + if (x.dtype === 'complex64') { + const realPart = real({ inputs: { input: x }, backend }); + const r = zerosLike({ inputs: { x: realPart }, backend }); + const imagPart = imag({ inputs: { input: x }, backend }); + const i = zerosLike({ inputs: { x: imagPart }, backend }); + const result = complex({ inputs: { real: r, imag: i }, backend }); + backend.disposeIntermediateTensorInfo(realPart); + backend.disposeIntermediateTensorInfo(r); + backend.disposeIntermediateTensorInfo(imagPart); + backend.disposeIntermediateTensorInfo(i); + return result; + } + else { + return fill({ + attrs: { + shape: x.shape, + dtype: x.dtype, + value: x.dtype === 'string' ? '' : 0 + }, + backend + }); + } + } + const zerosLikeConfig = { + kernelName: ZerosLike, + backendName: 'webgl', + kernelFunc: zerosLike + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function onesLike(args) { + const { inputs, backend } = args; + const { x } = inputs; + if (x.dtype === 'string') { + throw new Error('onesLike is not supported under string dtype'); + } + else if (x.dtype === 'complex64') { + const realPart = real({ inputs: { input: x }, backend }); + const r = onesLike({ inputs: { x: realPart }, backend }); + const imagPart = imag({ inputs: { input: x }, backend }); + const i = zerosLike({ inputs: { x: imagPart }, backend }); + const result = complex({ inputs: { real: r, imag: i }, backend }); + backend.disposeIntermediateTensorInfo(realPart); + backend.disposeIntermediateTensorInfo(r); + backend.disposeIntermediateTensorInfo(imagPart); + backend.disposeIntermediateTensorInfo(i); + return result; + } + else { + // TODO(cais, smilkov): Add WebGL shader for onesLike: + // https://github.com/tensorflow/tfjs/issues/1293 + return fill({ attrs: { shape: x.shape, dtype: x.dtype, value: 1 }, backend }); + } + } + const onesLikeConfig = { + kernelName: OnesLike, + backendName: 'webgl', + kernelFunc: onesLike + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function pack(args) { + const { inputs, backend, attrs } = args; + const { axis } = attrs; + if (inputs.length === 1) { + return expandDims({ inputs: { input: inputs[0] }, backend, attrs: { dim: axis } }); + } + const shape = inputs[0].shape; + const dtype = inputs[0].dtype; + inputs.forEach(t => { + assertShapesMatch(shape, t.shape, 'All tensors passed to stack must have matching shapes'); + assert$1(dtype === t.dtype, () => 'All tensors passed to stack must have matching dtypes'); + }); + const intermediateTensorInfos = []; + const expandedTensors = inputs.map(t => { + const expandedT = expandDims({ inputs: { input: t }, backend, attrs: { dim: axis } }); + intermediateTensorInfos.push(expandedT); + return expandedT; + }); + const result = concat({ inputs: expandedTensors, backend, attrs: { axis } }); + intermediateTensorInfos.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return result; + } + const packConfig = { + kernelName: Pack, + backendName: 'webgl', + kernelFunc: pack + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class PadProgram { + constructor(xShape, paddings, constantValue) { + this.variableNames = ['x']; + this.customUniforms = [{ name: 'value', type: 'float' }]; + this.outputShape = paddings.map((p, i) => p[0] /* beforePad */ + xShape[i] + p[1] /* afterPad */); + const rank = xShape.length; + const type = getCoordsDataType(rank); + const start = paddings.map(p => p[0]).join(','); + const end = paddings.map((p, i) => p[0] + xShape[i]).join(','); + const unpackedCoords = ['coords[0]', 'coords[1]', 'coords[2]', 'coords[3]'].slice(0, rank); + if (rank === 1) { + this.userCode = ` + int start = ${start}; + int end = ${end}; + + void main() { + int outC = getOutputCoords(); + if (outC < start || outC >= end) { + setOutput(value); + } else { + setOutput(getX(outC - start)); + } + } + `; + return; + } + this.userCode = ` + ${type} start = ${type}(${start}); + ${type} end = ${type}(${end}); + + void main() { + ${type} outC = getOutputCoords(); + if (any(lessThan(outC, start)) || any(greaterThanEqual(outC, end))) { + setOutput(value); + } else { + ${type} coords = outC - start; + setOutput(getX(${unpackedCoords})); + } + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class PadPackedProgram { + constructor(xShape, paddings, constantValue) { + this.variableNames = ['x']; + this.packedInputs = true; + this.packedOutput = true; + this.customUniforms = [{ name: 'value', type: 'float' }]; + this.outputShape = paddings.map((p, i) => p[0] /* beforePad */ + xShape[i] + p[1] /* afterPad */); + const rank = xShape.length; + const dtype = getCoordsDataType(rank); + const start = paddings.map(p => p[0]).join(','); + const end = paddings.map((p, i) => p[0] + xShape[i]).join(','); + const coords = getChannels('rc', rank); + const source = getChannels('source', rank); + const cLimit = `${coords[rank - 1]} < ${this.outputShape[rank - 1]}`; + const innerDims = rank === 1 ? 'source' : `vec2(${source.slice(-2).join()})`; + const componentSetup = [ + `${dtype} rc = outputLoc;`, `${coords[rank - 1]} += 1; + if(${cLimit}) { + `, + rank === 1 ? '' : `} + rc = outputLoc; + ${coords[rank - 2]} += 1; + if(${coords[rank - 2]} < ${this.outputShape[rank - 2]}) {`, + rank === 1 ? '' : ` ${coords[rank - 1]} += 1; + if(${cLimit}) {` + ]; + const paddingArea = rank === 1 ? + 'rc < start || rc >= end' : + 'any(lessThan(rc, start)) || any(greaterThanEqual(rc, end))'; + let mainLoop = ''; + for (let i = 0, j = rank === 1 ? 2 : 4; i < j; i++) { + mainLoop += ` + ${componentSetup[i]} + if (${paddingArea}) { + result[${i}] = float(value); + } else { + ${dtype} source = rc - start; + result[${i}] = getChannel(getX(${source.join()}), ${innerDims}); + } + `; + } + mainLoop += (rank === 1 ? `} ` : `}}`); + this.userCode = ` + const ${dtype} start = ${dtype}(${start}); + const ${dtype} end = ${dtype}(${end}); + + void main() { + ${dtype} outputLoc = getOutputCoords(); + vec4 result = vec4(0.); + ${mainLoop} + setOutput(result); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const padV2 = (args) => { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { paddings, constantValue } = attrs; + if (sizeFromShape(x.shape) === 0) { + // Short-circuit the computation, since x doesn't have value, only + // the shape is used to compute output shape to pad. + const outputShape = paddings.map((p, i) => p[0] /* beforePad */ + x.shape[i] + p[1] /* afterPad */); + return fill({ + backend, + attrs: { shape: outputShape, value: constantValue, dtype: x.dtype } + }); + } + const program = env().getBool('WEBGL_PACK_ARRAY_OPERATIONS') ? + new PadPackedProgram(x.shape, paddings, constantValue) : + new PadProgram(x.shape, paddings, constantValue); + const customValues = [[constantValue]]; + return backend.runWebGLProgram(program, [x], x.dtype, customValues); + }; + const padV2Config = { + kernelName: PadV2, + backendName: 'webgl', + kernelFunc: padV2 + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const POW = ` + if(a < 0.0 && floor(b) < b){ + return NAN; + } + if (b == 0.0) { + return 1.0; + } + return (round(mod(b, 2.0)) != 1) ? + pow(abs(a), b) : sign(a) * pow(abs(a), b); +`; + const POW_PACKED = ` + // isModRound1 has 1 for components with round(mod(b, 2.0)) == 1, 0 otherwise. + vec4 isModRound1 = vec4(equal(round(mod(b, 2.0)), ivec4(1))); + vec4 multiplier = sign(a) * isModRound1 + (vec4(1.0) - isModRound1); + vec4 result = multiplier * pow(abs(a), b); + + // Ensure that a^0 = 1, including 0^0 = 1 as this correspond to TF and JS + bvec4 isExpZero = equal(b, vec4(0.0)); + result.r = isExpZero.r ? 1.0 : result.r; + result.g = isExpZero.g ? 1.0 : result.g; + result.b = isExpZero.b ? 1.0 : result.b; + result.a = isExpZero.a ? 1.0 : result.a; + + bvec4 isNaN1 = lessThan(a, vec4(0.0)); + bvec4 isNaN2 = lessThan(floor(b), b); + bvec4 isNaN = bvec4(isNaN1.x && isNaN2.x, isNaN1.y && isNaN2.y, isNaN1.z && isNaN2.z, isNaN1.w && isNaN2.w); + ` + + CHECK_NAN_SNIPPET_PACKED + ` + return result; +`; + const pow = binaryKernelFunc({ opSnippet: POW, packedOpSnippet: POW_PACKED }); + const powConfig = { + kernelName: Pow, + backendName: 'webgl', + kernelFunc: pow + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function prod(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { axis, keepDims } = attrs; + const xRank = x.shape.length; + const toDispose = []; + const origAxes = parseAxisParam(axis, x.shape); + let axes = origAxes; + const permutedAxes = getAxesPermutation(axes, xRank); + let permutedX = x; + if (permutedAxes != null) { + permutedX = transpose({ inputs: { x }, backend, attrs: { perm: permutedAxes } }); + axes = getInnerMostAxes(axes.length, xRank); + toDispose.push(permutedX); + } + assertAxesAreInnerMostDims('prod', axes, xRank); + let res; + if (backend.shouldExecuteOnCPU([permutedX])) { + const xVals = backend.texData.get(permutedX.dataId).values; + const { outVals, outShape, outDtype } = prodImplCPU(permutedX.shape, permutedX.dtype, xVals, axes); + res = backend.makeTensorInfo(outShape, outDtype, outVals); + } + else { + const [outShape, reduceShape] = computeOutAndReduceShapes(permutedX.shape, axes); + const inSize = sizeFromShape(reduceShape); + const a2D = reshape({ inputs: { x: permutedX }, backend, attrs: { shape: [-1, inSize] } }); + const outputDType = sumOutType(x.dtype); + const reduced = reduce(a2D, outputDType, 'prod', backend); + res = reshape({ inputs: { x: reduced }, backend, attrs: { shape: outShape } }); + toDispose.push(a2D); + toDispose.push(reduced); + } + if (keepDims) { + toDispose.push(res); + const newShape = expandShapeToKeepDim(res.shape, origAxes); + res = reshape({ inputs: { x: res }, backend, attrs: { shape: newShape } }); + } + toDispose.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return res; + } + const prodConfig = { + kernelName: Prod, + backendName: 'webgl', + kernelFunc: prod + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function raggedGather(args) { + const { inputs, backend, attrs } = args; + const { paramsNestedSplits, paramsDenseValues, indices } = inputs; + const { outputRaggedRank } = attrs; + const $paramsNestedSplits = paramsNestedSplits.map(t => backend.readSync(t.dataId)); + const $paramsNestedSplitsShapes = paramsNestedSplits.map(t => t.shape); + const $paramsDenseValues = backend.readSync(paramsDenseValues.dataId); + const $indices = backend.readSync(indices.dataId); + const [outputNestedSplits, outputDenseValues, outputDenseValuesShape] = raggedGatherImplCPU($paramsNestedSplits, $paramsNestedSplitsShapes, $paramsDenseValues, paramsDenseValues.shape, paramsDenseValues.dtype, $indices, indices.shape, outputRaggedRank); + const outputNestedSplitsTensors = outputNestedSplits.map((splits) => backend.makeTensorInfo([splits.length], 'int32', splits)); + const outputDenseValuesTensor = backend.makeTensorInfo(outputDenseValuesShape, paramsDenseValues.dtype, outputDenseValues); + return outputNestedSplitsTensors.concat([outputDenseValuesTensor]); + } + const raggedGatherConfig = { + kernelName: RaggedGather, + backendName: 'webgl', + kernelFunc: raggedGather, + }; + + /** + * @license + * Copyright 2022 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function raggedRange(args) { + const { inputs, backend } = args; + const { starts, limits, deltas } = inputs; + const $starts = backend.readSync(starts.dataId); + const $limits = backend.readSync(limits.dataId); + const $deltas = backend.readSync(deltas.dataId); + const [rtNestedSplitsData, rtDenseValuesData] = raggedRangeImplCPU($starts, starts.shape, starts.dtype, $limits, limits.shape, $deltas, deltas.shape); + const rtNestedSplits = backend.makeTensorInfo([rtNestedSplitsData.length], 'int32', rtNestedSplitsData); + const rtDenseValues = backend.makeTensorInfo([rtDenseValuesData.length], starts.dtype, rtDenseValuesData); + return [rtNestedSplits, rtDenseValues]; + } + const raggedRangeConfig = { + kernelName: RaggedRange, + backendName: 'webgl', + kernelFunc: raggedRange, + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function raggedTensorToTensor(args) { + const { inputs, backend, attrs } = args; + const { shape, values, defaultValue, rowPartitionTensors } = inputs; + const { rowPartitionTypes } = attrs; + const $shape = backend.readSync(shape.dataId); + const $values = backend.readSync(values.dataId); + const $defaultValue = backend.readSync(defaultValue.dataId); + const $rowPartitionValues = rowPartitionTensors.map(t => backend.readSync(t.dataId)); + const rowPartitionValuesShapes = rowPartitionTensors.map(t => t.shape); + const [outputShape, output] = raggedTensorToTensorImplCPU($shape, shape.shape, $values, values.shape, values.dtype, $defaultValue, defaultValue.shape, $rowPartitionValues, rowPartitionValuesShapes, rowPartitionTypes); + return backend.makeTensorInfo(outputShape, values.dtype, output); + } + const raggedTensorToTensorConfig = { + kernelName: RaggedTensorToTensor, + backendName: 'webgl', + kernelFunc: raggedTensorToTensor, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const range = (args) => { + const { backend, attrs } = args; + const { start, stop, step, dtype } = attrs; + const values = rangeImplCPU(start, stop, step, dtype); + return backend.makeTensorInfo([values.length], dtype, values); + }; + const rangeConfig = { + kernelName: Range, + backendName: 'webgl', + kernelFunc: range + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const RECIPROCAL = `return 1.0 / x;`; + const reciprocal = unaryKernelFunc({ opSnippet: RECIPROCAL }); + const reciprocalConfig = { + kernelName: Reciprocal, + backendName: 'webgl', + kernelFunc: reciprocal, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const RELU = CHECK_NAN_SNIPPET$1 + ` + return (x < 0.0) ? 0.0 : x; +`; + const RELU_PACKED = ` + vec4 result = x * vec4(greaterThanEqual(x, vec4(0.0))); + bvec4 isNaN = isnan(x); + + result.r = isNaN.r ? x.r : result.r; + result.g = isNaN.g ? x.g : result.g; + result.b = isNaN.b ? x.b : result.b; + result.a = isNaN.a ? x.a : result.a; + + return result; +`; + const relu = unaryKernelFunc({ opSnippet: RELU, packedOpSnippet: RELU_PACKED }); + const reluConfig = { + kernelName: Relu$1, + backendName: 'webgl', + kernelFunc: relu + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const RELU6 = CHECK_NAN_SNIPPET$1 + ` + return (x < 0.0) ? 0.0 : min(6.0, x); +`; + const RELU6_PACKED = ` + vec4 result = min(x, vec4(6.)) * vec4(greaterThanEqual(x, vec4(0.0))); + bvec4 isNaN = isnan(x); + + result.r = isNaN.r ? x.r : result.r; + result.g = isNaN.g ? x.g : result.g; + result.b = isNaN.b ? x.b : result.b; + result.a = isNaN.a ? x.a : result.a; + + return result; +`; + const relu6 = unaryKernelFunc({ opSnippet: RELU6, packedOpSnippet: RELU6_PACKED }); + const relu6Config = { + kernelName: Relu6$1, + backendName: 'webgl', + kernelFunc: relu6 + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ResizeBilinearProgram { + constructor(inputShape, newHeight, newWidth, alignCorners, halfPixelCenters) { + this.variableNames = ['A']; + this.outputShape = []; + const [batch, oldHeight, oldWidth, depth] = inputShape; + this.outputShape = [batch, newHeight, newWidth, depth]; + const effectiveInSize = [ + (alignCorners && newHeight > 1) ? oldHeight - 1 : oldHeight, + (alignCorners && newWidth > 1) ? oldWidth - 1 : oldWidth + ]; + const effectiveOutSize = [ + (alignCorners && newHeight > 1) ? newHeight - 1 : newHeight, + (alignCorners && newWidth > 1) ? newWidth - 1 : newWidth + ]; + let sourceFracIndexRC; + if (halfPixelCenters) { + sourceFracIndexRC = + `(vec2(yRC) + vec2(0.5)) * effectiveInputOverOutputRatioRC` + + ` - vec2(0.5)`; + } + else { + sourceFracIndexRC = `vec2(yRC) * effectiveInputOverOutputRatioRC`; + } + this.userCode = ` + const vec2 effectiveInputOverOutputRatioRC = vec2( + ${effectiveInSize[0] / effectiveOutSize[0]}, + ${effectiveInSize[1] / effectiveOutSize[1]}); + const vec2 inputShapeRC = vec2(${oldHeight}.0, ${oldWidth}.0); + + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int d = coords[3]; + ivec2 yRC = coords.yz; + + // Fractional source index. + vec2 sourceFracIndexRC = ${sourceFracIndexRC}; + + // Compute the four integer indices. + ivec2 sourceFloorRC = ivec2(max(sourceFracIndexRC, vec2(0.0))); + ivec2 sourceCeilRC = ivec2( + min(inputShapeRC - 1.0, ceil(sourceFracIndexRC))); + + float topLeft = getA(b, sourceFloorRC.x, sourceFloorRC.y, d); + float bottomLeft = getA(b, sourceCeilRC.x, sourceFloorRC.y, d); + float topRight = getA(b, sourceFloorRC.x, sourceCeilRC.y, d); + float bottomRight = getA(b, sourceCeilRC.x, sourceCeilRC.y, d); + + vec2 fracRC = sourceFracIndexRC - vec2(sourceFloorRC); + + float top = topLeft + (topRight - topLeft) * fracRC.y; + float bottom = bottomLeft + (bottomRight - bottomLeft) * fracRC.y; + float newValue = top + (bottom - top) * fracRC.x; + + setOutput(newValue); + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ResizeBilinearPackedProgram { + constructor(inputShape, newHeight, newWidth, alignCorners, halfPixelCenters) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = []; + const [batch, oldHeight, oldWidth, depth] = inputShape; + this.outputShape = [batch, newHeight, newWidth, depth]; + const effectiveInSize = [ + (alignCorners && newHeight > 1) ? oldHeight - 1 : oldHeight, + (alignCorners && newWidth > 1) ? oldWidth - 1 : oldWidth + ]; + const effectiveOutSize = [ + (alignCorners && newHeight > 1) ? newHeight - 1 : newHeight, + (alignCorners && newWidth > 1) ? newWidth - 1 : newWidth + ]; + let sourceFracIndexRC; + if (halfPixelCenters) { + sourceFracIndexRC = `(vec3(yRC) + vec3(0.5)) * ` + + `effectiveInputOverOutputRatioRC - vec3(0.5)`; + } + else { + sourceFracIndexRC = `vec3(yRC) * effectiveInputOverOutputRatioRC`; + } + this.userCode = ` + const vec3 effectiveInputOverOutputRatioRC = vec3( + ${effectiveInSize[0] / effectiveOutSize[0]}, + ${effectiveInSize[1] / effectiveOutSize[1]}, + ${effectiveInSize[1] / effectiveOutSize[1]}); + const vec3 inputShapeRC = vec3(${oldHeight}.0, ${oldWidth}.0, + ${oldWidth}.0); + + float getAValue(int b, int r, int c, int d) { + return getChannel(getA(b, r, c, d), vec2(c, d)); + } + + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int d = coords[3]; + // Calculate values for next column in yRC.z. + ivec3 yRC = coords.yzz + ivec3(0, 0, 1); + + // Fractional source index. + vec3 sourceFracIndexRC = ${sourceFracIndexRC}; + + // Compute the four integer indices. + ivec3 sourceFloorRC = ivec3(max(sourceFracIndexRC, vec3(0.0))); + ivec3 sourceCeilRC = ivec3( + min(inputShapeRC - 1.0, ceil(sourceFracIndexRC))); + + // Should we calculate next column and row elements in 2x2 packed cell. + bool hasNextCol = d < ${depth - 1}; + bool hasNextRow = coords.z < ${newWidth - 1}; + + // In parallel, construct four corners for all four components in + // packed 2x2 cell. + vec4 topLeft = vec4( + getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d), + hasNextCol ? getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d + 1) + : 0.0, + hasNextRow ? getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d) + : 0.0, + (hasNextRow && hasNextCol) ? + getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d + 1) : 0.0); + + vec4 bottomLeft = vec4( + getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d), + hasNextCol ? getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d + 1) + : 0.0, + hasNextRow ? getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d) + : 0.0, + (hasNextRow && hasNextCol) ? + getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d + 1) : 0.0); + + vec4 topRight = vec4( + getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d), + hasNextCol ? getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d + 1) + : 0.0, + hasNextRow ? getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d) + : 0.0, + (hasNextRow && hasNextCol) ? + getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d + 1) : 0.0); + + vec4 bottomRight = vec4( + getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d), + hasNextCol ? getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d + 1) + : 0.0, + hasNextRow ? getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d) + : 0.0, + (hasNextRow && hasNextCol) ? + getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d + 1) : 0.0); + + vec3 fracRC = sourceFracIndexRC - vec3(sourceFloorRC); + + vec4 top = mix(topLeft, topRight, fracRC.yyzz); + vec4 bottom = mix(bottomLeft, bottomRight, fracRC.yyzz); + vec4 newValue = mix(top, bottom, fracRC.x); + + setOutput(newValue); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function resizeBilinear(args) { + const { inputs, backend, attrs } = args; + const { images } = inputs; + const { alignCorners, halfPixelCenters, size } = attrs; + const [newHeight, newWidth] = size; + const program = env().getBool('WEBGL_PACK_IMAGE_OPERATIONS') ? + new ResizeBilinearPackedProgram(images.shape, newHeight, newWidth, alignCorners, halfPixelCenters) : + new ResizeBilinearProgram(images.shape, newHeight, newWidth, alignCorners, halfPixelCenters); + return backend.runWebGLProgram(program, [images], 'float32'); + } + const resizeBilinearConfig = { + kernelName: ResizeBilinear, + backendName: 'webgl', + kernelFunc: resizeBilinear + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ResizeBilinearBackpropProgram { + constructor(dyShape, inputShape, alignCorners) { + this.variableNames = ['dy']; + this.outputShape = []; + this.outputShape = inputShape; + const [, xHeight, xWidth,] = inputShape; + const [, yHeight, yWidth] = dyShape; + // In the backwards pass, we want to find the pixels that were generated for + // each pixel in the input image the forward pass and add the corresponding + // coefficient from dy to the gradient (with some interpolation). + const effectiveXSize = [ + (alignCorners && yHeight > 1) ? xHeight - 1 : xHeight, + (alignCorners && yWidth > 1) ? xWidth - 1 : xWidth + ]; + const effectiveYSize = [ + (alignCorners && yHeight > 1) ? yHeight - 1 : yHeight, + (alignCorners && yWidth > 1) ? yWidth - 1 : yWidth + ]; + const heightScale = effectiveXSize[0] / effectiveYSize[0]; + const widthScale = effectiveXSize[1] / effectiveYSize[1]; + const invHeightScale = 1 / heightScale; + const invWidthScale = 1 / widthScale; + // This defines the size of the window of values around a particular + // index in dy that we want to search for contributions to dx. + const winHeight = (Math.ceil(invHeightScale) * 2) + 2; + const winWidth = (Math.ceil(invWidthScale) * 2) + 2; + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int d = coords[3]; + int r = coords[1]; + int c = coords[2]; + + float accumulator = 0.0; + + const float heightScale = float(${heightScale}); + const float widthScale = float(${widthScale}); + + const float invHeightScale = float(${invHeightScale}); + const float invWidthScale = float(${invWidthScale}); + + const int winHeight = int(${winHeight}); + const int winWidth = int(${winWidth}); + + // Compute bounds for where in dy we will look + float startRLerp = floor(float(r) * invHeightScale); + int startDyR = int(startRLerp - float(winHeight / 2)); + + float startCLerp = floor(float(c) * invWidthScale); + int startDyC = int(startCLerp - float(winWidth / 2)); + + // Loop over dy + for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) { + int dyR = dyROffset + startDyR; + + // Guard against the window exceeding the bounds of dy + if (dyR < 0 || dyR >= ${yHeight}) { + continue; + } + + for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) { + int dyC = dyCOffset + startDyC; + + // Guard against the window exceeding the bounds of dy + if (dyC < 0 || dyC >= ${yWidth}) { + continue; + } + + float dxR = float(dyR) * heightScale; + int topDxRIndex = int(floor(dxR)); + int bottomDxRIndex = int(min(ceil(dxR), ${xHeight - 1}.0)); + float dxRLerp = dxR - float(topDxRIndex); + float inverseDxRLerp = 1.0 - dxRLerp; + + float dxC = float(dyC) * widthScale; + int leftDxCIndex = int(floor(dxC)); + int rightDxCIndex = int(min(ceil(dxC), ${xWidth - 1}.0)); + float dxCLerp = dxC - float(leftDxCIndex); + float inverseDxCLerp = 1.0 - dxCLerp; + + if (r == topDxRIndex && c == leftDxCIndex) { + // topLeft + accumulator += + getDy(b, dyR, dyC, d) * inverseDxRLerp * inverseDxCLerp; + } + + if (r == topDxRIndex && c == rightDxCIndex) { + // topRight + accumulator += getDy(b, dyR, dyC, d) * inverseDxRLerp * dxCLerp; + } + + if (r == bottomDxRIndex && c == leftDxCIndex) { + // bottomLeft + accumulator += getDy(b, dyR, dyC, d) * dxRLerp * inverseDxCLerp; + } + + if (r == bottomDxRIndex && c == rightDxCIndex) { + // bottomRight + accumulator += getDy(b, dyR, dyC, d) * dxRLerp * dxCLerp; + } + } + } + // End loop over dy + + setOutput(accumulator); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function resizeBilinearGrad(args) { + const { inputs, backend, attrs } = args; + const { images, dy } = inputs; + const { alignCorners } = attrs; + const program = new ResizeBilinearBackpropProgram(dy.shape, images.shape, alignCorners); + return backend.runWebGLProgram(program, [dy], dy.dtype); + } + const resizeBilinearGradConfig = { + kernelName: ResizeBilinearGrad, + backendName: 'webgl', + kernelFunc: resizeBilinearGrad + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ResizeNearestNeighborProgram { + constructor(inputShape, newHeight, newWidth, alignCorners, halfPixelCenters) { + this.variableNames = ['A']; + this.outputShape = []; + const [batch, oldHeight, oldWidth, depth] = inputShape; + this.outputShape = [batch, newHeight, newWidth, depth]; + const effectiveInSize = [ + (alignCorners && newHeight > 1) ? oldHeight - 1 : oldHeight, + (alignCorners && newWidth > 1) ? oldWidth - 1 : oldWidth + ]; + const effectiveOutSize = [ + (alignCorners && newHeight > 1) ? newHeight - 1 : newHeight, + (alignCorners && newWidth > 1) ? newWidth - 1 : newWidth + ]; + // When align corners is false, we rounds the value with floor. + const roundBase = alignCorners ? '0.5' : '0.0'; + let sourceFracIndexRC; + if (halfPixelCenters) { + sourceFracIndexRC = + `max((vec2(yRC) + vec2(0.5)) * effectiveInputOverOutputRatioRC` + + `, vec2(0.0))`; + } + else { + sourceFracIndexRC = `vec2(yRC) * effectiveInputOverOutputRatioRC`; + } + this.userCode = ` + const vec2 effectiveInputOverOutputRatioRC = vec2( + ${effectiveInSize[0] / effectiveOutSize[0]}, + ${effectiveInSize[1] / effectiveOutSize[1]}); + const vec2 inputShapeRC = vec2(${oldHeight}.0, ${oldWidth}.0); + + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int d = coords[3]; + ivec2 yRC = coords.yz; + + // Fractional source index. + vec2 sourceFracIndexRC = ${sourceFracIndexRC}; + + // Compute the coordinators of nearest neighbor point. + ivec2 sourceNearestRC = ivec2( + min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${roundBase}))); + float newValue = getA(b, sourceNearestRC.x, sourceNearestRC.y, d); + + setOutput(newValue); + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ResizeNearestNeighborPackedProgram { + constructor(inputShape, newHeight, newWidth, alignCorners, halfPixelCenters) { + this.variableNames = ['A']; + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = []; + const [batch, oldHeight, oldWidth, depth] = inputShape; + this.outputShape = [batch, newHeight, newWidth, depth]; + const effectiveInSize = [ + (alignCorners && newHeight > 1) ? oldHeight - 1 : oldHeight, + (alignCorners && newWidth > 1) ? oldWidth - 1 : oldWidth + ]; + const effectiveOutSize = [ + (alignCorners && newHeight > 1) ? newHeight - 1 : newHeight, + (alignCorners && newWidth > 1) ? newWidth - 1 : newWidth + ]; + // When align corners is false, we rounds the value with floor. + const roundBase = alignCorners ? '0.5' : '0.0'; + let sourceFracIndexRC; + if (halfPixelCenters) { + sourceFracIndexRC = `max((vec3(yRC) + vec3(0.5)) * ` + + `effectiveInputOverOutputRatioRC, vec3(0.0))`; + } + else { + sourceFracIndexRC = `vec3(yRC) * effectiveInputOverOutputRatioRC`; + } + this.userCode = ` + const vec3 effectiveInputOverOutputRatioRC = vec3( + ${effectiveInSize[0] / effectiveOutSize[0]}, + ${effectiveInSize[1] / effectiveOutSize[1]}, + ${effectiveInSize[1] / effectiveOutSize[1]}); + const vec3 inputShapeRC = vec3(${oldHeight}.0, ${oldWidth}.0, + ${oldWidth}.0); + + float getAValue(int b, int r, int c, int d) { + return getChannel(getA(b, r, c, d), vec2(c, d)); + } + + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int d = coords[3]; + // Calculate values for next column in yRC.z. + ivec3 yRC = coords.yzz + ivec3(0, 0, 1); + + // Fractional source index. + vec3 sourceFracIndexRC = ${sourceFracIndexRC}; + + // Compute the coordinators of nearest neighbor point. + ivec3 sourceNearestRC = ivec3( + min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${roundBase}))); + + // Should we calculate next column and row elements in 2x2 packed cell. + bool hasNextCol = d < ${depth - 1}; + bool hasNextRow = coords.z < ${newWidth - 1}; + + vec4 newValue = vec4( + getAValue(b, sourceNearestRC.x, sourceNearestRC.y, d), + hasNextCol ? getAValue(b, sourceNearestRC.x, sourceNearestRC.y, d + 1) + : 0.0, + hasNextRow ? getAValue(b, sourceNearestRC.x, sourceNearestRC.z, d) + : 0.0, + (hasNextRow && hasNextCol) ? + getAValue(b, sourceNearestRC.x, sourceNearestRC.z, d + 1) : 0.0); + + setOutput(newValue); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function resizeNearestNeighbor(args) { + const { inputs, backend, attrs } = args; + const { images } = inputs; + const { alignCorners, halfPixelCenters, size } = attrs; + const [newHeight, newWidth] = size; + const program = env().getBool('WEBGL_PACK_IMAGE_OPERATIONS') ? + new ResizeNearestNeighborPackedProgram(images.shape, newHeight, newWidth, alignCorners, halfPixelCenters) : + new ResizeNearestNeighborProgram(images.shape, newHeight, newWidth, alignCorners, halfPixelCenters); + return backend.runWebGLProgram(program, [images], images.dtype); + } + const resizeNearestNeighborConfig = { + kernelName: ResizeNearestNeighbor, + backendName: 'webgl', + kernelFunc: resizeNearestNeighbor + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ResizeNearestNeigborBackpropProgram { + constructor(dyShape, inputShape, alignCorners) { + this.variableNames = ['dy']; + this.outputShape = []; + this.outputShape = inputShape; + const [, xHeight, xWidth,] = inputShape; + const [, yHeight, yWidth] = dyShape; + // In the backwards pass, we want to find the pixels that were generated for + // each pixel in the input image the forward pass and add the corresponding + // coefficient from dy to the gradient (with some interpolation). + const effectiveXSize = [ + (alignCorners && yHeight > 1) ? xHeight - 1 : xHeight, + (alignCorners && yWidth > 1) ? xWidth - 1 : xWidth + ]; + const effectiveYSize = [ + (alignCorners && yHeight > 1) ? yHeight - 1 : yHeight, + (alignCorners && yWidth > 1) ? yWidth - 1 : yWidth + ]; + const heightScale = effectiveXSize[0] / effectiveYSize[0]; + const widthScale = effectiveXSize[1] / effectiveYSize[1]; + const invHeightScale = 1 / heightScale; + const invWidthScale = 1 / widthScale; + // This defines the size of the window of values around a particular + // index in dy that we want to search for contributions to dx. + const winHeight = (Math.ceil(invHeightScale) * 2) + 2; + const winWidth = (Math.ceil(invWidthScale) * 2) + 2; + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int b = coords[0]; + int d = coords[3]; + int r = coords[1]; + int c = coords[2]; + + float accumulator = 0.0; + + const float heightScale = float(${heightScale}); + const float widthScale = float(${widthScale}); + + const float invHeightScale = float(${invHeightScale}); + const float invWidthScale = float(${invWidthScale}); + + const int winHeight = int(${winHeight}); + const int winWidth = int(${winWidth}); + + // Compute bounds for where in dy we will look + float startRLerp = floor(float(r) * invHeightScale); + int startDyR = int(floor(startRLerp - float(winHeight / 2))); + + float startCLerp = floor(float(c) * invWidthScale); + int startDyC = int(floor(startCLerp - float(winWidth / 2))); + + // Loop over dy + for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) { + int dyR = dyROffset + startDyR; + + // Guard against the window exceeding the bounds of dy + if (dyR < 0 || dyR >= ${yHeight}) { + continue; + } + + for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) { + int dyC = dyCOffset + startDyC; + + // Guard against the window exceeding the bounds of dy + if (dyC < 0 || dyC >= ${yWidth}) { + continue; + } + + float sourceFracRow = + float(${effectiveXSize[0]}) * + (float(dyR) / float(${effectiveYSize[0]})); + + float sourceFracCol = + float(${effectiveXSize[1]}) * + (float(dyC) / float(${effectiveYSize[1]})); + + int sourceNearestRow = int(min( + float(int(${xHeight}) - 1), + ${alignCorners} ? float(round(sourceFracRow)) : + float(floor(sourceFracRow)))); + + int sourceNearestCol = int(min( + float(int(${xWidth}) - 1), + ${alignCorners} ? float(round(sourceFracCol)) : + float(floor(sourceFracCol)))); + + if (r == sourceNearestRow && c == sourceNearestCol) { + accumulator += getDy(b, dyR, dyC, d); + } + } + } + // End loop over dy + + setOutput(accumulator); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function resizeNearestNeighborGrad(args) { + const { inputs, backend, attrs } = args; + const { images, dy } = inputs; + const { alignCorners } = attrs; + const program = new ResizeNearestNeigborBackpropProgram(dy.shape, images.shape, alignCorners); + return backend.runWebGLProgram(program, [dy], dy.dtype); + } + const resizeNearestNeighborGradConfig = { + kernelName: ResizeNearestNeighborGrad, + backendName: 'webgl', + kernelFunc: resizeNearestNeighborGrad + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ReverseProgram { + constructor(xShape, axis) { + this.variableNames = ['x']; + const rank = xShape.length; + if (rank > 4) { + throw new Error(`WebGL backend: Reverse of rank-${rank} tensor is not yet supported`); + } + this.outputShape = xShape; + if (rank === 1) { + this.userCode = ` + void main() { + int coord = getOutputCoords(); + setOutput(getX(${xShape[0]} - coord - 1)); + } + `; + return; + } + const getInCoord = (i) => { + if (axis.indexOf(i) !== -1 && xShape[i] !== 1) { + return `${xShape[i]} - coords[${i}] - 1`; + } + return `coords[${i}]`; + }; + const inCoords = xShape.map((_, i) => getInCoord(i)).join(','); + const type = getCoordsDataType(rank); + this.userCode = ` + void main() { + ${type} coords = getOutputCoords(); + setOutput(getX(${inCoords})); + } + `; + } + } + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ReversePackedProgram { + constructor(xShape, axis) { + this.variableNames = ['x']; + this.packedInputs = true; + this.packedOutput = true; + const rank = xShape.length; + if (rank > 4) { + throw new Error(`WebGL backend: Reverse of rank-${rank} tensor is not yet supported`); + } + this.outputShape = xShape; + const channels = getChannels('rc', rank); + const nextColumn = `${channels[rank - 1]} + 1 < ${this.outputShape[rank - 1]}`; + const nextRow = `${channels[rank - 2]} + 1 < ${this.outputShape[rank - 2]}`; + const type = getCoordsDataType(rank); + if (rank === 1) { + this.userCode = ` + void main(){ + int rc = getOutputCoords(); + vec4 result = vec4(0.); + result.r = getChannel(getX(${xShape[0]} - rc - 1), + ${xShape[0]} - rc - 1); + if(${nextColumn}){ + result.g = getChannel(getX(${xShape[0]} - (rc + 1) - 1), + ${xShape[0]} - (rc + 1) - 1); + } + setOutput(result); + } + `; + } + else { + this.userCode = ` + void main() { + ${type} rc = getOutputCoords(); + vec4 result = vec4(0.); + result.r = ${getR(channels.slice())}; + if(${nextColumn}){ + result.g = ${getG(channels.slice())}; + } + if(${nextRow}) { + result.b = ${getB(channels.slice())}; + if(${nextColumn}) { + result.a = ${getA(channels.slice())}; + } + } + setOutput(result); + } + `; + } + function getR(channels) { + return getChannel(channels); + } + function getG(channels) { + channels[rank - 1] = '(' + channels[rank - 1] + ` + 1)`; + return getChannel(channels); + } + function getB(channels) { + channels[rank - 2] = '(' + channels[rank - 2] + ` + 1)`; + return getChannel(channels); + } + function getA(channels) { + channels[rank - 1] = '(' + channels[rank - 1] + ` + 1)`; + channels[rank - 2] = '(' + channels[rank - 2] + ` + 1)`; + return getChannel(channels); + } + function getChannel(channels) { + const inCoordsArray = xShape.map((_, i) => getInCoord(i, channels)); + const inCoords = inCoordsArray.join(','); + const innerDims = inCoordsArray.slice(-2).join(','); + return `getChannel(getX(${inCoords}), vec2(${innerDims}))`; + } + function getInCoord(i, channels1) { + if (axis.indexOf(i) !== -1 && xShape[i] !== 1) { + return `${xShape[i]} - ${channels1[i]} - 1`; + } + else { + return `${channels1[i]}`; + } + } + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function reverse(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { dims } = attrs; + const xRank = x.shape.length; + const $dims = parseAxisParam(dims, x.shape); + if (xRank === 0) { + return identity({ inputs: { x }, backend }); + } + const program = env().getBool('WEBGL_PACK_ARRAY_OPERATIONS') ? + new ReversePackedProgram(x.shape, $dims) : + new ReverseProgram(x.shape, $dims); + return backend.runWebGLProgram(program, [x], x.dtype); + } + const reverseConfig = { + kernelName: Reverse, + backendName: 'webgl', + kernelFunc: reverse + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class RotateProgram { + constructor(imageShape, fillValue) { + this.variableNames = ['Image']; + this.outputShape = []; + this.customUniforms = [{ name: 'params', type: 'vec4' }]; + const imageHeight = imageShape[1]; + const imageWidth = imageShape[2]; + this.outputShape = imageShape; + let fillSnippet = ''; + if (typeof fillValue === 'number') { + fillSnippet = `float outputValue = ${fillValue.toFixed(2)};`; + } + else { + fillSnippet = ` + vec3 fill = vec3(${fillValue.join(',')}); + float outputValue = fill[coords[3]];`; + } + this.userCode = ` + void main() { + ivec4 coords = getOutputCoords(); + int x = coords[2]; + int y = coords[1]; + float coordXFloat = (float(x) - params[0]) * params[3] - + (float(y) - params[1]) * params[2]; + float coordYFloat = (float(x) - params[0]) * params[2] + + (float(y) - params[1]) * params[3]; + int coordX = int(round(coordXFloat + params[0])); + int coordY = int(round(coordYFloat + params[1])); + ${fillSnippet} + if(coordX >= 0 && coordX < ${imageWidth} && coordY >= 0 && coordY < ${imageHeight}) { + outputValue = getImage(coords[0], coordY, coordX, coords[3]); + } + setOutput(outputValue); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const rotateWithOffsetConfig = { + kernelName: RotateWithOffset, + backendName: 'webgl', + kernelFunc: ({ inputs, attrs, backend }) => { + const { image } = inputs; + const { radians, fillValue, center } = attrs; + const webglBackend = backend; + const program = new RotateProgram(image.shape, fillValue); + const [centerX, centerY] = getImageCenter(center, image.shape[1], image.shape[2]); + const customValues = [[centerX, centerY, Math.sin(radians), Math.cos(radians)]]; + const output = webglBackend.runWebGLProgram(program, [image], image.dtype, customValues); + return output; + } + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const ROUND = ` + // OpenGL ES does not support round function. + // The algorithm is based on banker's rounding. + float base = floor(x); + if ((x - base) < 0.5) { + return floor(x); + } else if ((x - base) > 0.5) { + return ceil(x); + } else { + if (mod(base, 2.0) == 0.0) { + return base; + } else { + return base + 1.0; + } + } +`; + const round = unaryKernelFunc({ opSnippet: ROUND }); + const roundConfig = { + kernelName: Round, + backendName: 'webgl', + kernelFunc: round, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const RSQRT = `return inversesqrt(x);`; + const rsqrt = unaryKernelFunc({ opSnippet: RSQRT, cpuKernelImpl: rsqrtImplCPU }); + const rsqrtConfig = { + kernelName: Rsqrt, + backendName: 'webgl', + kernelFunc: rsqrt + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ScatterProgram { + constructor(updateSize, sliceDim, indicesRank, updatesRank, strides, shape, summingDupeIndex = true, defaultIsTensor = false) { + this.variableNames = ['updates', 'indices', 'defaultValue']; + this.outputShape = shape; + const stridesType = getCoordsDataType(strides.length); + const dtype = getCoordsDataType(shape.length); + let indicesString = ''; + if (indicesRank === 1) { + indicesString = 'i'; + } + else if (indicesRank === 2) { + indicesString = 'i, j'; + } + const indicesSnippet = `getIndices(${indicesString})`; + let updatesString = ''; + if (updatesRank === 1) { + updatesString = 'i'; + } + else if (updatesRank === 2) { + updatesString = 'i, coords[1]'; + } + const updatesSnippet = `getUpdates(${updatesString})`; + let defaultValuesString = ''; + if (defaultIsTensor) { + defaultValuesString = 'coords[0], coords[1]'; + } + const defaultValueSnippet = `getDefaultValue(${defaultValuesString})`; + const strideString = sliceDim > 1 ? 'strides[j]' : 'strides'; + this.userCode = ` + ${stridesType} strides = ${stridesType}(${strides}); + + void main() { + ${dtype} coords = getOutputCoords(); + float sum = 0.0; + bool found = false; + for (int i = 0; i < ${updateSize}; i++) { + int flattenedIndex = 0; + for (int j = 0; j < ${sliceDim}; j++) { + int index = round(${indicesSnippet}); + flattenedIndex += index * ${strideString}; + } + if (flattenedIndex == coords[0]) { + sum += ${updatesSnippet}; + found = true; + } + } + setOutput(mix(${defaultValueSnippet}, sum, float(found))); + } + `; + } + } + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class ScatterPackedProgram { + constructor(updateSize, sliceDim, indicesRank, updatesRank, strides, shape, summingDupeIndex = true, defaultIsTensor = false) { + this.variableNames = ['updates', 'indices', 'defaultValue']; + this.packedInputs = true; + this.packedOutput = true; + this.outputShape = shape; + const stridesType = getCoordsDataType(strides.length); + const dtype = getCoordsDataType(shape.length); + let indicesString = ''; + if (indicesRank === 1) { + indicesString = 'i'; + } + else if (indicesRank === 2) { + indicesString = 'i, j'; + } + const indicesSnippet = `getIndices(${indicesString})`; + let updatesString = ''; + if (updatesRank === 1) { + updatesString = 'i'; + } + else if (updatesRank === 2) { + updatesString = 'i, coords[1]'; + } + const updatesSnippet = `getUpdates(${updatesString})`; + let defaultValuesString = ''; + if (defaultIsTensor) { + defaultValuesString = 'coords[0], coords[1]'; + } + const defaultValueSnippet = `getDefaultValue(${defaultValuesString})`; + const strideString = sliceDim > 1 ? 'strides[j]' : 'strides'; + const strideString2 = sliceDim > 1 ? 'strides[j + 1]' : 'strides'; + this.userCode = ` + ${stridesType} strides = ${stridesType}(${strides}); + + void main() { + ${dtype} coords = getOutputCoords(); + vec4 sum = vec4(0.); + vec4 found = vec4(0.); + for (int i = 0; i < ${updateSize}; i+=2) { + ivec2 flattenedIndex = ivec2(0); + for (int j = 0; j < ${sliceDim}; j+=2) { + ivec4 index = round(${indicesSnippet}); + flattenedIndex += index.xz * ${strideString}; + if (j + 1 < ${sliceDim}) { + flattenedIndex += index.yw * ${strideString2}; + } + } + if (flattenedIndex[0] == coords[0] || flattenedIndex[1] == coords[0] || + flattenedIndex[0] == coords[0] + 1 || flattenedIndex[1] == coords[0] + 1) { + vec4 updVals = ${updatesSnippet}; + if (flattenedIndex[0] == coords[0]) { + sum.xy += updVals.xy; + found.xy = vec2(1.); + } else if (flattenedIndex[0] == coords[0] + 1) { + sum.zw += updVals.xy; + found.zw = vec2(1.); + } + if (flattenedIndex[1] == coords[0]) { + sum.xy += updVals.zw; + found.xy = vec2(1.); + } else if (flattenedIndex[1] == coords[0] + 1) { + sum.zw += updVals.zw; + found.zw = vec2(1.); + } + } + } + setOutput(mix(${defaultValueSnippet}, sum, found)); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function scatterNd(args) { + const { inputs, backend, attrs } = args; + const { indices, updates } = inputs; + const { shape } = attrs; + const { sliceRank, numUpdates, sliceSize, strides, outputSize } = calculateShapes(updates, indices, shape); + const flattenShape = [outputSize / sliceSize, sliceSize]; + if (outputSize === 0) { + return backend.makeTensorInfo(shape, indices.dtype); + } + const flattenIndices = reshape({ inputs: { x: indices }, backend, attrs: { shape: [numUpdates, sliceRank] } }); + const flattenX = reshape({ inputs: { x: updates }, backend, attrs: { shape: [numUpdates, sliceSize] } }); + const defaultValue = backend.makeTensorInfo([], 'float32', new Float32Array([0])); // scalar(0) + let program; + if (env().getBool('WEBGL_PACK')) { + program = new ScatterPackedProgram(numUpdates, sliceRank, flattenIndices.shape.length, flattenX.shape.length, strides, flattenShape); + } + else { + program = new ScatterProgram(numUpdates, sliceRank, flattenIndices.shape.length, flattenX.shape.length, strides, flattenShape); + } + const res = backend.runWebGLProgram(program, [flattenX, flattenIndices, defaultValue], flattenX.dtype); + const reshaped = reshape({ inputs: { x: res }, backend, attrs: { shape } }); + backend.disposeIntermediateTensorInfo(flattenIndices); + backend.disposeIntermediateTensorInfo(flattenX); + backend.disposeIntermediateTensorInfo(res); + backend.disposeIntermediateTensorInfo(defaultValue); + return reshaped; + } + const scatterNdConfig = { + kernelName: ScatterNd, + backendName: 'webgl', + kernelFunc: scatterNd + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class SearchSortedProgram { + constructor(batchSize, numInputs, numValues, side) { + this.variableNames = ['sortedSequence', 'values']; + this.customUniforms = [{ name: 'numInputs', type: 'int' }]; + this.outputShape = [batchSize, numValues]; + const webGL2LoopHead = 'while (left < right) {'; + // WebGL1 doesn't accept non constant loop conditions, so upper bound loop + // iterations. + const webGL1LoopHead = `for (int i = 0; i < ${Math.ceil(Math.log2(numInputs + 1))}; ++i) { if (left >= right) break;`; + const loopHead = env().getNumber('WEBGL_VERSION') === 2 ? webGL2LoopHead : + webGL1LoopHead; + // left corresponds to lower bound and right to upper bound. + const boundComparator = side === 'left' ? '<' : '<='; + this.userCode = ` + int findBound(int batch, float value) { + int left = 0; + int right = numInputs; + int mid; + ${loopHead} + mid = (left + right) / 2; + if (getSortedSequence(batch, mid) ${boundComparator} value) { + left = mid + 1; + } else { + right = mid; + } + } + return right; + } + + void main() { + ivec2 coords = getOutputCoords(); + int batch = coords[0]; + int valueIndex = coords[1]; + + float value = getValues(batch, valueIndex); + + setOutput(float(findBound(batch, value))); + } + `; + } + } + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function searchSorted(args) { + const { inputs, backend, attrs } = args; + const { sortedSequence, values } = inputs; + const { side } = attrs; + const program = new SearchSortedProgram(sortedSequence.shape[0], sortedSequence.shape[1], values.shape[1], side); + const customValues = [[sortedSequence.shape[1]]]; + return backend.runWebGLProgram(program, [sortedSequence, values], 'int32', customValues); + } + const searchSortedConfig = { + kernelName: SearchSorted, + backendName: 'webgl', + kernelFunc: searchSorted, + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class SelectProgram { + constructor(cRank, shape, rank) { + this.variableNames = ['c', 'a', 'b']; + this.outputShape = shape; + let cCoords; + let abCoords; + if (rank > 4) { + throw Error(`Where for rank ${rank} is not yet supported`); + } + if (rank === 1) { + abCoords = `resRC`; + cCoords = `resRC`; + } + else { + const currentCoords = ['resRC.x', 'resRC.y', 'resRC.z', 'resRC.w']; + const cCoordVars = []; + const abCoordVars = []; + for (let i = 0; i < shape.length; i++) { + abCoordVars.push(`${currentCoords[i]}`); + if (i < cRank) { + cCoordVars.push(`${currentCoords[i]}`); + } + } + cCoords = cCoordVars.join(); + abCoords = abCoordVars.join(); + } + const dtype = getCoordsDataType(rank); + this.userCode = ` + void main() { + ${dtype} resRC = getOutputCoords(); + float cVal = getC(${cCoords}); + if (cVal >= 1.0) { + setOutput(getA(${abCoords})); + } else { + setOutput(getB(${abCoords})); + } + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function select(args) { + const { inputs, backend } = args; + const { condition, t, e } = inputs; + const program = new SelectProgram(condition.shape.length, t.shape, t.shape.length); + return backend.runWebGLProgram(program, [condition, t, e], upcastType(t.dtype, e.dtype)); + } + const selectConfig = { + kernelName: Select, + backendName: 'webgl', + kernelFunc: select + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SELU = ` + // Stable and Attracting Fixed Point (0, 1) for Normalized Weights. + // see: https://arxiv.org/abs/1706.02515 + float scaleAlpha = ${SELU_SCALEALPHA}; + float scale = ${SELU_SCALE}; + return (x >= 0.0) ? scale * x : scaleAlpha * (exp(x) - 1.0); +`; + const selu = unaryKernelFunc({ opSnippet: SELU }); + const seluConfig = { + kernelName: Selu$1, + backendName: 'webgl', + kernelFunc: selu, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SIGMOID = CHECK_NAN_SNIPPET_UNARY + ` + return 1.0 / (1.0 + exp(-1.0 * x)); +`; + const SIGMOID_PACKED = ` + vec4 result = 1.0 / (1.0 + exp(-1.0 * x)); + bvec4 isNaN = isnan(x); + + result.r = isNaN.r ? x.r : result.r; + result.g = isNaN.g ? x.g : result.g; + result.b = isNaN.b ? x.b : result.b; + result.a = isNaN.a ? x.a : result.a; + + return result; +`; + const sigmoid = unaryKernelFunc({ + opSnippet: SIGMOID, + packedOpSnippet: SIGMOID_PACKED, + cpuKernelImpl: sigmoidImplCPU + }); + const sigmoidConfig = { + kernelName: Sigmoid$1, + backendName: 'webgl', + kernelFunc: sigmoid, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // Sign does not propagate NANs. + const SIGN = ` + if (isnan(x)) { return 0.0; } + return sign(x); +`; + const sign = unaryKernelFunc({ opSnippet: SIGN }); + const signConfig = { + kernelName: Sign, + backendName: 'webgl', + kernelFunc: sign, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SIN = CHECK_NAN_SNIPPET_UNARY + ` + return sin(x); +`; + const SIN_PACKED = ` + vec4 result = sin(x); + bvec4 isNaN = isnan(x); + ${CHECK_NAN_SNIPPET_PACKED} + return result; +`; + const sin = unaryKernelFunc({ opSnippet: SIN, packedOpSnippet: SIN_PACKED }); + const sinConfig = { + kernelName: Sin, + backendName: 'webgl', + kernelFunc: sin, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SINH = ` + float e2x = exp(x); + return (e2x - 1.0 / e2x) / 2.0; +`; + const sinh = unaryKernelFunc({ opSnippet: SINH }); + const sinhConfig = { + kernelName: Sinh, + backendName: 'webgl', + kernelFunc: sinh, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SOFTPLUS = ` + float epsilon = 1.1920928955078125e-7; + float threshold = log(epsilon) + 2.0; + + bool too_large = x > -threshold; + bool too_small = x < threshold; + + float result; + float exp_x = exp(x); + + if (too_large){ + result = x; + } + else if (too_small){ + result = exp_x; + } + else{ + result = log(exp_x + 1.0); + } + return result; +`; + const softplus = unaryKernelFunc({ opSnippet: SOFTPLUS }); + const softplusConfig = { + kernelName: Softplus$1, + backendName: 'webgl', + kernelFunc: softplus, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const spaceToBatchND = (args) => { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { blockShape, paddings } = attrs; + assert$1(x.shape.length <= 4, () => 'spaceToBatchND for rank > 4 with a WebGL backend not ' + + 'implemented yet'); + const prod = blockShape.reduce((a, b) => a * b); + const completePaddings = [[0, 0]]; + completePaddings.push(...paddings); + for (let i = 1 + blockShape.length; i < x.shape.length; ++i) { + completePaddings.push([0, 0]); + } + const toDispose = []; + const paddedX = padV2({ + inputs: { x }, + backend, + attrs: { paddings: completePaddings, constantValue: 0 } + }); + const reshapedPaddedShape = getReshaped(paddedX.shape, blockShape, prod, false); + const permutedReshapedPaddedPermutation = getPermuted(reshapedPaddedShape.length, blockShape.length, false); + const flattenShape = getReshapedPermuted(paddedX.shape, blockShape, prod, false); + const reshapedPaddedX = reshape({ inputs: { x: paddedX }, backend, attrs: { shape: reshapedPaddedShape } }); + const paddedXT = transpose({ + inputs: { x: reshapedPaddedX }, + backend, + attrs: { perm: permutedReshapedPaddedPermutation } + }); + const result = reshape({ inputs: { x: paddedXT }, backend, attrs: { shape: flattenShape } }); + toDispose.push(paddedX); + toDispose.push(reshapedPaddedX); + toDispose.push(paddedXT); + toDispose.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return result; + }; + const spaceToBatchNDConfig = { + kernelName: SpaceToBatchND, + backendName: 'webgl', + kernelFunc: spaceToBatchND + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseFillEmptyRows(args) { + const { inputs, backend } = args; + const { indices, values, denseShape, defaultValue } = inputs; + if (denseShape.shape.length !== 1) { + throw new Error(`Dense shape must be a vector, saw: + ${denseShape.shape}`); + } + if (indices.shape.length !== 2) { + throw new Error(`Indices must be a matrix, saw: + ${indices.shape}`); + } + if (values.shape.length !== 1) { + throw new Error(`Values must be a vector, saw: + ${values.shape}`); + } + if (defaultValue.shape.length !== 0) { + throw new Error(`Default value must be a scalar, saw: + ${defaultValue.shape}`); + } + const $indices = backend.readSync(indices.dataId); + const $values = backend.readSync(values.dataId); + const $denseShape = backend.readSync(denseShape.dataId); + const $defaultValue = backend.readSync(defaultValue.dataId)[0]; + const [outputIndices, outputIndicesShape, outputValues, emptyRowIndicator, reverseIndexMap] = sparseFillEmptyRowsImplCPU($indices, indices.shape, indices.dtype, $values, values.dtype, $denseShape, $defaultValue); + return [ + backend.makeTensorInfo(outputIndicesShape, indices.dtype, outputIndices), + backend.makeTensorInfo([outputIndicesShape[0]], values.dtype, outputValues), + backend.makeTensorInfo([emptyRowIndicator.length], 'bool', new Uint8Array(emptyRowIndicator.map((value) => Number(value)))), + backend.makeTensorInfo([reverseIndexMap.length], indices.dtype, new Int32Array(reverseIndexMap)), + ]; + } + const sparseFillEmptyRowsConfig = { + kernelName: SparseFillEmptyRows, + backendName: 'webgl', + kernelFunc: sparseFillEmptyRows, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseReshape(args) { + const { inputs, backend } = args; + const { inputIndices, inputShape, newShape } = inputs; + if (inputIndices.shape.length !== 2) { + throw new Error(`Input indices should be a matrix but received shape ${inputIndices.shape}`); + } + if (inputShape.shape.length !== 1) { + throw new Error(`Input shape should be a vector but received shape ${inputShape.shape}`); + } + if (newShape.shape.length !== 1) { + throw new Error(`Target shape should be a vector but received shape ${newShape.shape}`); + } + const $inputShape = Array.from(backend.readSync(inputShape.dataId)); + const $inputIndices = backend.readSync(inputIndices.dataId); + const targetShape = Array.from(backend.readSync(newShape.dataId)); + const [newIndices, indicesShape, outputShape] = sparseReshapeImplCPU($inputIndices, inputIndices.shape, inputIndices.dtype, $inputShape, targetShape); + return [ + backend.makeTensorInfo(indicesShape, inputIndices.dtype, newIndices), + backend.makeTensorInfo([outputShape.length], newShape.dtype, new Int32Array(outputShape)), + ]; + } + const sparseReshapeConfig = { + kernelName: SparseReshape, + backendName: 'webgl', + kernelFunc: sparseReshape, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseSegmentMean(args) { + const { inputs, backend } = args; + const { data, indices, segmentIds } = inputs; + if (data.shape.length < 1) { + throw new Error(`Data should be at least 1 dimensional but received scalar`); + } + if (indices.shape.length !== 1) { + throw new Error(`Indices should be a vector but received shape + ${indices.shape}`); + } + if (segmentIds.shape.length !== 1) { + throw new Error(`Segment ids should be a vector but received shape + ${segmentIds.shape}`); + } + const $data = backend.readSync(data.dataId); + const $indices = backend.readSync(indices.dataId); + const $segmentIds = backend.readSync(segmentIds.dataId); + const [outputData, outputDataShape] = sparseSegmentReductionImplCPU($data, data.shape, data.dtype, $indices, $segmentIds, true); + return backend.makeTensorInfo(outputDataShape, data.dtype, outputData); + } + const sparseSegmentMeanConfig = { + kernelName: SparseSegmentMean, + backendName: 'webgl', + kernelFunc: sparseSegmentMean, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseSegmentSum(args) { + const { inputs, backend } = args; + const { data, indices, segmentIds } = inputs; + if (data.shape.length < 1) { + throw new Error(`Data should be at least 1 dimensional but received scalar`); + } + if (indices.shape.length !== 1) { + throw new Error(`Indices should be a vector but received shape + ${indices.shape}`); + } + if (segmentIds.shape.length !== 1) { + throw new Error(`Segment ids should be a vector but received shape + ${segmentIds.shape}`); + } + const $data = backend.readSync(data.dataId); + const $indices = backend.readSync(indices.dataId); + const $segmentIds = backend.readSync(segmentIds.dataId); + const [outputData, outputDataShape] = sparseSegmentReductionImplCPU($data, data.shape, data.dtype, $indices, $segmentIds); + return backend.makeTensorInfo(outputDataShape, data.dtype, outputData); + } + const sparseSegmentSumConfig = { + kernelName: SparseSegmentSum, + backendName: 'webgl', + kernelFunc: sparseSegmentSum, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function sparseToDense(args) { + const { inputs, backend, attrs } = args; + const { sparseIndices, sparseValues, defaultValue } = inputs; + const { outputShape } = attrs; + const { sliceRank, numUpdates, sliceSize, strides, outputSize } = calculateShapes(sparseValues, sparseIndices, outputShape); + const sumDupeIndices = false; + if (sparseValues.dtype === 'string') { + const indicesBuf = backend.bufferSync(sparseIndices); + const updatesBuf = backend.bufferSync(sparseValues); + const $defaultValue = decodeString(backend.readSync(defaultValue.dataId)[0]); + const outBuf = scatterImplCPU(indicesBuf, updatesBuf, outputShape, outputSize, sliceSize, numUpdates, sliceRank, strides, $defaultValue, sumDupeIndices); + return backend.makeTensorInfo(outputShape, outBuf.dtype, outBuf.values); + } + const program = new ScatterProgram(numUpdates, sliceRank, sparseIndices.shape.length, sparseValues.shape.length, strides, [outputSize, 1], sumDupeIndices); + const res = backend.runWebGLProgram(program, [sparseValues, sparseIndices, defaultValue], sparseValues.dtype); + const reshaped = reshape({ inputs: { x: res }, backend, attrs: { shape: outputShape } }); + backend.disposeIntermediateTensorInfo(res); + return reshaped; + } + const sparseToDenseConfig = { + kernelName: SparseToDense, + backendName: 'webgl', + kernelFunc: sparseToDense + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function splitV(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { numOrSizeSplits, axis } = attrs; + const $axis = parseAxisParam(axis, x.shape)[0]; + const splitSizes = prepareSplitSize(x, numOrSizeSplits, $axis); + const xRank = x.shape.length; + const begin = new Array(xRank).fill(0); + const size = x.shape.slice(); + return splitSizes.map(s => { + const sliceSize = [...size]; + sliceSize[$axis] = s; + const sliceT = slice({ inputs: { x }, backend, attrs: { begin, size: sliceSize } }); + begin[$axis] += s; + return sliceT; + }); + } + const splitVConfig = { + kernelName: SplitV, + backendName: 'webgl', + kernelFunc: splitV + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SQRT = `return sqrt(x);`; + const sqrt = unaryKernelFunc({ opSnippet: SQRT, packedOpSnippet: SQRT, cpuKernelImpl: sqrtImplCPU }); + const sqrtConfig = { + kernelName: Sqrt, + backendName: 'webgl', + kernelFunc: sqrt + }; + + /** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SQUARE = `return x * x;`; + const square = unaryKernelFunc({ opSnippet: SQUARE }); + const squareConfig = { + kernelName: Square, + backendName: 'webgl', + kernelFunc: square, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const SQUARED_DIFFERENCE = 'return (a - b) * (a - b);'; + const squaredDifference = binaryKernelFunc({ opSnippet: SQUARED_DIFFERENCE, packedOpSnippet: SQUARED_DIFFERENCE }); + const squaredDifferenceConfig = { + kernelName: SquaredDifference, + backendName: 'webgl', + kernelFunc: squaredDifference, + }; + + /** + * @license + * Copyright 2023 Google LLC. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function staticRegexReplace(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + if (x.dtype !== 'string') { + throw new Error('Input must be of datatype string'); + } + const $x = backend.readSync(x.dataId); + const stringInput = fromUint8ToStringArray($x); + const output = staticRegexReplaceImplCPU(stringInput, 'string', attrs); + return backend.makeTensorInfo(x.shape, 'string', output); + } + const staticRegexReplaceConfig = { + kernelName: StaticRegexReplace, + backendName: 'webgl', + kernelFunc: staticRegexReplace, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function step({ inputs, attrs, backend }) { + const { x } = inputs; + const opSnippet = CHECK_NAN_SNIPPET$1 + ` + return x > 0.0 ? 1.0 : float(${attrs.alpha}); + `; + const program = new UnaryOpProgram(x.shape, opSnippet); + return backend.runWebGLProgram(program, [x], x.dtype); + } + const stepConfig = { + kernelName: Step, + backendName: 'webgl', + kernelFunc: step, + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class StridedSliceProgram { + constructor(begin, strides, size) { + this.variableNames = ['x']; + this.outputShape = size; + const rank = size.length; + const inputDtype = getCoordsDataType(size.length); + const dtype = getCoordsDataType(size.length); + let newCoords = ''; + if (rank === 1) { + newCoords = 'coords * strides + begin'; + } + else { + let outputAxis = 0; + newCoords = + size.map((_, i) => { + outputAxis++; + return size.length === 1 ? + `coords * strides[${i}] + begin[${i}]` : + `coords[${outputAxis - 1}] * strides[${i}] + begin[${i}]`; + }) + .join(','); + } + this.userCode = ` + ${inputDtype} begin = ${inputDtype}(${begin}); + ${inputDtype} strides = ${inputDtype}(${strides}); + + void main() { + ${dtype} coords = getOutputCoords(); + setOutput(getX(${newCoords})); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stridedSlice(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask } = attrs; + const { finalShapeSparse, finalShape, isIdentity, sliceDim0, isSimpleSlice, begin: $begin, end: $end, strides: $strides } = sliceInfo(x.shape, begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask); + let result; + if (isIdentity) { + // Optimization #1, slice is a no-op plus reshape + result = reshape({ inputs: { x }, backend, attrs: { shape: finalShape } }); + } + else if (sliceDim0 || isSimpleSlice) { + // Optimization #2, slice is memory contiguous (only occurs in dim 0) + assert$1(x.shape.length >= 1, () => `Input must have rank at least 1, got: ${x.shape.length}`); + const size = computeOutShape$2($begin, $end, $strides); + // To tolerate begin[0] > end[0] (a 0-output slice), we min(begin, end). + const sliced = slice({ inputs: { x }, backend, attrs: { begin: $begin, size } }); + result = + reshape({ inputs: { x: sliced }, backend, attrs: { shape: finalShape } }); + backend.disposeIntermediateTensorInfo(sliced); + } + else { + const shouldExecuteOnCPU = backend.shouldExecuteOnCPU([x]); + if (shouldExecuteOnCPU) { + // tslint:disable-next-line: no-unnecessary-type-assertion + const values = backend.readSync(x.dataId); + // tslint:disable-next-line: no-unnecessary-type-assertion + const xBuf = buffer(x.shape, x.dtype, values); + const resultValues = stridedSliceImplCPU(finalShapeSparse, xBuf, $strides, $begin); + result = backend.makeTensorInfo(finalShape, x.dtype, resultValues.values); + } + else { + const program = new StridedSliceProgram($begin, $strides, finalShapeSparse); + result = backend.runWebGLProgram(program, [x], x.dtype); + } + } + const resultReshaped = reshape({ inputs: { x: result }, backend, attrs: { shape: finalShape } }); + backend.disposeIntermediateTensorInfo(result); + return resultReshaped; + } + const stridedSliceConfig = { + kernelName: StridedSlice, + backendName: 'webgl', + kernelFunc: stridedSlice + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stringNGrams(args) { + const { inputs, backend, attrs } = args; + const { separator, nGramWidths, leftPad, rightPad, padWidth, preserveShortSequences } = attrs; + const { data, dataSplits } = inputs; + const $data = backend.readSync(data.dataId); + const $dataSplits = backend.readSync(dataSplits.dataId); + const [nGrams, nGramsSplits] = stringNGramsImplCPU($data, $dataSplits, separator, nGramWidths, leftPad, rightPad, padWidth, preserveShortSequences); + return [ + backend.makeTensorInfo([nGrams.length], 'string', nGrams), + backend.makeTensorInfo(dataSplits.shape, 'int32', nGramsSplits), + ]; + } + const stringNGramsConfig = { + kernelName: StringNGrams, + backendName: 'webgl', + kernelFunc: stringNGrams, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stringSplit(args) { + const { inputs, backend, attrs } = args; + const { skipEmpty } = attrs; + const { input, delimiter } = inputs; + if (input.dtype !== 'string') { + throw new Error('Input must be of datatype string'); + } + if (input.shape.length !== 1) { + throw new Error(`Input must be a vector, got shape: ${input.shape}`); + } + if (delimiter.shape.length !== 0) { + throw new Error(`Delimiter must be a scalar, got shape: ${delimiter.shape}`); + } + const $input = backend.readSync(input.dataId); + const $delimiter = backend.readSync(delimiter.dataId)[0]; + const [indices, values, shape] = stringSplitImplCPU($input, $delimiter, skipEmpty); + const outputSize = values.length; + return [ + backend.makeTensorInfo([outputSize, 2], 'int32', indices), + backend.makeTensorInfo([outputSize], 'string', values), + backend.makeTensorInfo([2], 'int32', new Int32Array(shape)) + ]; + } + const stringSplitConfig = { + kernelName: StringSplit, + backendName: 'webgl', + kernelFunc: stringSplit, + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function stringToHashBucketFast(args) { + const { inputs, backend, attrs } = args; + const { numBuckets } = attrs; + const { input } = inputs; + if (input.dtype !== 'string') { + throw new Error('Input must be of datatype string'); + } + if (numBuckets <= 0) { + throw new Error(`Number of buckets must be at least 1`); + } + const $input = backend.readSync(input.dataId); + const output = stringToHashBucketFastImplCPU($input, numBuckets); + return backend.makeTensorInfo(input.shape, 'int32', output); + } + const stringToHashBucketFastConfig = { + kernelName: StringToHashBucketFast, + backendName: 'webgl', + kernelFunc: stringToHashBucketFast, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const TAN = `return tan(x);`; + const tan = unaryKernelFunc({ opSnippet: TAN }); + const tanConfig = { + kernelName: Tan, + backendName: 'webgl', + kernelFunc: tan, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const TANH = ` + float e2x = exp(-2.0 * abs(x)); + return sign(x) * (1.0 - e2x) / (1.0 + e2x); +`; + const tanh = unaryKernelFunc({ opSnippet: TANH }); + const tanhConfig = { + kernelName: Tanh$1, + backendName: 'webgl', + kernelFunc: tanh, + }; + + /** + * @license + * Copyright 2022 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function tensorScatterUpdate(args) { + const { inputs, backend, attrs } = args; + const { tensor, indices, updates } = inputs; + const {} = attrs; + const { sliceRank, numUpdates, sliceSize, strides, outputSize } = calculateShapes(updates, indices, tensor.shape); + const flattenShape = [outputSize / sliceSize, sliceSize]; + if (outputSize === 0) { + return backend.makeTensorInfo(tensor.shape, indices.dtype); + } + const flattenIndices = reshape({ inputs: { x: indices }, backend, attrs: { shape: [numUpdates, sliceRank] } }); + const flattenX = reshape({ inputs: { x: updates }, backend, attrs: { shape: [numUpdates, sliceSize] } }); + const flattenTensor = reshape({ inputs: { x: tensor }, backend, attrs: { shape: flattenShape } }); + const program = new ScatterProgram(numUpdates, sliceRank, flattenIndices.shape.length, flattenX.shape.length, strides, flattenShape, false, true); + const res = backend.runWebGLProgram(program, [flattenX, flattenIndices, flattenTensor], flattenTensor.dtype); + const reshaped = reshape({ inputs: { x: res }, backend, attrs: { shape: tensor.shape } }); + backend.disposeIntermediateTensorInfo(flattenIndices); + backend.disposeIntermediateTensorInfo(flattenX); + backend.disposeIntermediateTensorInfo(flattenTensor); + backend.disposeIntermediateTensorInfo(res); + return reshaped; + } + const tensorScatterUpdateConfig = { + kernelName: TensorScatterUpdate, + backendName: 'webgl', + kernelFunc: tensorScatterUpdate + }; + + /** + * @license + * Copyright 2017 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class TileProgram { + constructor(aShape, reps) { + this.variableNames = ['A']; + const outputShape = new Array(aShape.length); + for (let i = 0; i < outputShape.length; i++) { + outputShape[i] = aShape[i] * reps[i]; + } + this.outputShape = outputShape; + this.rank = outputShape.length; + const dtype = getCoordsDataType(this.rank); + const sourceCoords = getSourceCoords(aShape); + this.userCode = ` + void main() { + ${dtype} resRC = getOutputCoords(); + setOutput(getA(${sourceCoords})); + } + `; + } + } + function getSourceCoords(aShape) { + const rank = aShape.length; + if (rank > 5) { + throw Error(`Tile for rank ${rank} is not yet supported`); + } + if (rank === 1) { + return `imod(resRC, ${aShape[0]})`; + } + const currentCoords = ['resRC.x', 'resRC.y', 'resRC.z', 'resRC.w', 'resRC.u']; + const sourceCoords = []; + for (let i = 0; i < aShape.length; i++) { + sourceCoords.push(`imod(${currentCoords[i]}, ${aShape[i]})`); + } + return sourceCoords.join(); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function tile(params) { + const { inputs, backend, attrs } = params; + const { x } = inputs; + const { reps } = attrs; + // tile gpu program cannot handle rank > 5 case. + if (x.dtype === 'string' || x.shape.length > 5) { + // Even thought string tensor is always on CPU, just to be consistent on how + // to access tensor data. + const data = backend.readSync(x.dataId); + const value = x.dtype === 'string' ? + data.map(d => decodeString(d)) : + data; + const buf = buffer(x.shape, x.dtype, value); + const outBuf = tileImplCPU(buf, reps); + return backend.makeTensorInfo(outBuf.shape, outBuf.dtype, outBuf.values); + } + const program = new TileProgram(x.shape, reps); + const output = backend.runWebGLProgram(program, [x], x.dtype); + return output; + } + const tileConfig = { + kernelName: Tile, + backendName: 'webgl', + kernelFunc: tile, + }; + + // Based on Algorithm 2 of Bitonic Top K, ref: + // https://anilshanbhag.in/static/papers/gputopk_sigmod18.pdf + // The original algorithm is based on computing the top K only, however + // since for TFJS we require the indices of the top K values as well then the + // algorithm found here is a bit modified. Rather than producing the values + // at each step, the indices containing the top K are generated instead. + // The output values are not generated to reduce the number of outputs in the + // GPU, the values can easily be retrieved from the indices using a gather + // op. + class SwapProgram { + /** + * @param shape desired output shape (can be larger than input shape, output + * will be padded with -Infinity) + */ + constructor(shape) { + this.variableNames = ['x', 'indices']; + // |n| Size of the original input of TopK. + // |firstPass|indicates if this is the first time swap is being used which + // means no indices input containing the top K is present yet. + // |inc| Swaps pairs of indices (0, inc), (1, inc + 1), (2, inc + 2) ... + this.customUniforms = [ + { name: 'n', type: 'int' }, + { name: 'firstPass', type: 'int' }, + { name: 'negativeInf', type: 'float' }, + { name: 'dir', type: 'int' }, + { name: 'inc', type: 'int' } + ]; + this.outputShape = shape; + this.userCode = ` + void main() { + ivec2 coords = getOutputCoords(); + int batch = coords[0]; + int elemIdx = coords[1]; + + // We compare elements pair-wise within a group of size 2 * inc. + // The comparing rule for each group alternates between ascending + // and descending. Within each group, we compare each pair at + // positions i and i+inc. To decide whether an element at position i + // is x0 or x1, we mod it by 2 * inc, if the result is smaller than + // inc, it is in the first half of the group, we denote it as x0, + // otherwise we denote it as x1. + // For example, as shown in the Bitonic top K paper referenced above, + // Figure5(a) shows that element[1] is in the + // second half of the group when group size is 2, but it is in the + // first half of the group when group size is 4. + + bool isFirstInPair = imod(elemIdx, 2 * inc) < inc; + int i = isFirstInPair ? elemIdx : elemIdx - inc; + + int i0 = firstPass == 1 ? i : int(getIndices(batch, i)); + int i1 = firstPass == 1 ? i + inc : int(getIndices(batch, i + inc)); + float x0 = i0 < n ? getX(batch, i0) : negativeInf; + float x1 = i1 < n ? getX(batch, i1) : negativeInf; + + // Denotes which direction indices are in (ascending or descending). + bool reverse = imod(elemIdx, 2 * dir) >= dir; + bool isGreater = x0 > x1 || (x0 == x1 && i1 > i0); + if (reverse == isGreater) { // Elements in opposite order of direction + int iTemp = i0; + i0 = i1; + i1 = iTemp; + } + if (isFirstInPair) { + setOutput(float(i0)); + } else { + setOutput(float(i1)); + } + } + `; + } + } + class MergeProgram { + /** + * @param shape desired output shape (must be half of the input size) + */ + constructor(shape) { + this.variableNames = ['x', 'indices']; + // |n| Size of the original input of TopK + // |firstPass| indicates if this is the first time swap is being used which + // means no indices input containing the top K is present yet. + // |k| Top k elements desired + this.customUniforms = [ + { name: 'n', type: 'int' }, + { name: 'firstPass', type: 'int' }, + { name: 'k', type: 'int' } + ]; + this.outputShape = shape; + this.userCode = ` + void main() { + // Takes max of indices (0, k), (1, k + 1), (2, k + 2) ... + ivec2 coords = getOutputCoords(); + int batch = coords[0]; + int elemIdx = coords[1]; + + // The output size is half of the previous size. + // If the previous sequence is | | | | _ _ _ _ | | | | _ _ _ _ (k=4), + // we only need to output the indices at positions |, the indices at + // positions _ can be thrown away, see Figure5(b) After Phase 2 + // (Merge phase) in the Bitonic Top K paper referenced above. + // For example, the paper shows we only need to output the orange bars. + // The output sequence should look like this | | | | | | | |. + // Because the sequence is halved, to map the output index back + // to the previous sequence to find the corresponding value, + // we need to double the index. When we double the index, + // we basically interpolate a position, so 2i looks like + // | _ | _ | _ | _ | _ | _ | _. We move the | to the first k position + // of each 2k positions by - elemIdx % k. E.g. for output at + // index 4,5,6,7, we want to get the corresponding element at + // original index 8,9,10,11, for output at index 8,9,10,11, + // we want to get the corresponding element at original index + // 16,17,18,19, so on and so forth. + + int i = elemIdx < k ? elemIdx : (elemIdx * 2 - imod(elemIdx, k)); + int i0 = firstPass == 1 ? i : int(getIndices(batch, i)); + int i1 = firstPass == 1 ? i + k : int(getIndices(batch, i + k)); + + float x0 = getX(batch, i0); + float x1 = i1 < n ? getX(batch, i1) : x0; + + setOutput(x0 >= x1 ? float(i0) : float(i1)); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function disposeIntermediateTensorInfoOrNull(backend, tensorInfo) { + if (tensorInfo !== null) { + backend.disposeIntermediateTensorInfo(tensorInfo); + } + } + function roundUpToPow2(num) { + let pow2 = 1; + while (pow2 < num) { + pow2 *= 2; + } + return pow2; + } + // Based on Algorithm 2 of Bitonic Top K, ref: + // https://anilshanbhag.in/static/papers/gputopk_sigmod18.pdf + function topK(args) { + const { inputs, backend, attrs } = args; + const { x } = inputs; + const { k, sorted } = attrs; + // Empirically determined constant used to determine last dim threshold for + // handing off execution to the CPU. + const TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD = env().getNumber('TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD'); + // Empirically determined constant used to determine k threshold for handing + // off execution to the CPU. + const TOPK_K_CPU_HANDOFF_THRESHOLD = env().getNumber('TOPK_K_CPU_HANDOFF_THRESHOLD'); + const xShape = x.shape; + const lastDim = xShape[xShape.length - 1]; + if (backend.shouldExecuteOnCPU([x]) || + lastDim < TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD || + k > TOPK_K_CPU_HANDOFF_THRESHOLD) { + const xVals = backend.readSync(x.dataId); + const [allTopKVals, allTopKIndices] = topKImplCPU(xVals, xShape, x.dtype, k, sorted); + return [ + backend.makeTensorInfo(allTopKVals.shape, allTopKVals.dtype, allTopKVals.values), + backend.makeTensorInfo(allTopKIndices.shape, allTopKIndices.dtype, allTopKIndices.values) + ]; + } + if (k === 0) { + xShape[xShape.length - 1] = 0; + return [ + backend.makeTensorInfo(xShape, x.dtype, []), + backend.makeTensorInfo(xShape, 'int32', []) + ]; + } + if (lastDim === 1 /* firstPass */) { + return [ + x, fill({ attrs: { shape: xShape, dtype: 'int32', value: 0 }, backend }) + ]; + } + // Eagerly unpack x input since it is passed in to all the shaders which + // require unpacked inputs. + const xtexData = backend.texData.get(x.dataId); + const xIsPacked = xtexData !== null && xtexData.isPacked; + const xUnPacked = xIsPacked ? backend.unpackTensor(x) : x; + // Reshape into a 2d tensor [batch, lastDim] and compute topk along lastDim. + const xSize = sizeFromShape(xShape); + const batch = xSize / lastDim; + const x2D = reshape({ inputs: { x: xUnPacked }, attrs: { shape: [batch, lastDim] }, backend }); + if (xIsPacked) { + disposeIntermediateTensorInfoOrNull(backend, xUnPacked); + } + const kPow2 = roundUpToPow2(k); + const lastDimPow2 = roundUpToPow2(lastDim); + // Only the indices containing the top K are kept at every step to reduce + // number of outputs in the GPU algorithms, so once the final set of indices + // is computed then gather is used to grab the corresponding values + // from the original input. + let indices = null; + // GPU algorithm always takes in an indices input but this input is not used + // on the first run of a GPU algorithm, therefore if indices is null we simply + // pass in x2D instead of it but the value will not actually be used + const getInputs = () => indices === null ? [x2D, x2D] : [x2D, indices]; + const runSwap = (dir, inc, shape) => { + const inputs = getInputs(); + const program = new SwapProgram(shape); + const fistPass = indices === null ? 1 : 0; + const customValues = [[lastDim], [fistPass], [Number.NEGATIVE_INFINITY], [dir], [inc]]; + const prevIndices = indices; + indices = backend.runWebGLProgram(program, inputs, 'int32', customValues); + disposeIntermediateTensorInfoOrNull(backend, prevIndices); + }; + // Step 1: local sort + for (let len = 1; len < kPow2; len *= 2) { + const dir = len * 2; + for (let inc = len; inc >= 1; inc /= 2) { + runSwap(dir, inc, [batch, lastDimPow2]); + } + } + // Step 2: merge + for (let indicesSize = lastDimPow2; indicesSize > kPow2; indicesSize /= 2) { + const inputs = getInputs(); + const mergeProgram = new MergeProgram([batch, indicesSize / 2]); + const firstPass = indices === null ? 1 : 0; + const customValues = [[lastDim], [firstPass], [kPow2]]; + const prevIndices = indices; + indices = + backend.runWebGLProgram(mergeProgram, inputs, 'int32', customValues); + disposeIntermediateTensorInfoOrNull(backend, prevIndices); + // Step 3: rebuild + const len = kPow2 / 2; + const dir = len * 2; + for (let inc = len; inc >= 1; inc /= 2) { + runSwap(dir, inc, indices.shape); + } + } + // Keep only the requested top K results instead of kPow2 + let prevIndices = indices; + indices = slice({ inputs: { x: indices }, backend, attrs: { begin: 0, size: [batch, k] } }); + disposeIntermediateTensorInfoOrNull(backend, prevIndices); + // Gather values on last dimension + let values = gatherV2({ inputs: { x: x2D, indices }, backend, attrs: { axis: 1, batchDims: 1 } }); + disposeIntermediateTensorInfoOrNull(backend, x2D); + // Reshape back to the original input shape, except that the last + // dimension is k. + const newShape = xShape.slice(0, -1); + newShape.push(k); + prevIndices = indices; + indices = reshape({ inputs: { x: indices }, attrs: { shape: newShape }, backend }); + disposeIntermediateTensorInfoOrNull(backend, prevIndices); + const prevValues = values; + values = reshape({ inputs: { x: values }, attrs: { shape: newShape }, backend }); + disposeIntermediateTensorInfoOrNull(backend, prevValues); + return [values, indices]; + } + const topKConfig = { + kernelName: TopK, + backendName: 'webgl', + kernelFunc: topK + }; + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class TransformProgram { + constructor(imageHeight, imageWidth, interpolation, fillMode, fillValue, outShape) { + this.variableNames = ['Image', 'Transforms']; + this.outputShape = outShape; + const interpolationModeId = interpolation === 'nearest' ? 1 : 2; + let fillModeId; + switch (fillMode) { + case 'constant': + fillModeId = 1; + break; + case 'reflect': + fillModeId = 2; + break; + case 'wrap': + fillModeId = 3; + break; + case 'nearest': + fillModeId = 4; + break; + default: + fillModeId = 1; + break; + } + this.userCode = ` + float mapCoord(float outCoord, float len) { + float inCoord = outCoord; + if(${fillModeId} == 2) { + if (inCoord < 0.0) { + if (len <= 1.0) { + inCoord = 0.0; + } else { + float sz2 = 2.0 * len; + if (inCoord < sz2) { + inCoord = sz2 * float(int(float(-inCoord / sz2))) + + inCoord; + } + inCoord = inCoord < -len ? inCoord + sz2 : -inCoord - 1.0; + } + } else if (inCoord > len - 1.0) { + if (len <= 1.0) { + inCoord = 0.0; + } else { + float sz2 = 2.0 * len; + inCoord -= sz2 * float(int(float(inCoord / sz2))); + if (inCoord >= len) { + inCoord = sz2 - inCoord - 1.0; + } + } + } + return clamp(inCoord, 0.0, len - 1.0); + } else if (${fillModeId} == 3) { + if (inCoord < 0.0) { + if (len <= 1.0) { + inCoord = 0.0; + } else { + float sz = len - 1.0; + inCoord += len * (float(int(float(-inCoord / sz))) + 1.0); + } + } else if (inCoord > len - 1.0) { + if (len <= 1.0) { + inCoord = 0.0; + } else { + float sz = len - 1.0; + inCoord -= len * float(int(float(inCoord / sz))); + } + } + return clamp(inCoord, 0.0, len - 1.0); + } else if (${fillModeId} == 4) { + return clamp(outCoord, 0.0, len - 1.0); + } else { + return outCoord; + } + } + + float readWithFillValue(int batch, int coordY, int coordX, + int channel) { + float outputValue; + if (0 <= coordY && coordY < ${imageHeight} && 0 <= coordX && coordX < ${imageWidth}) { + outputValue = getImage(batch, coordY, coordX, channel); + } else { + outputValue = float(${fillValue}); + } + return outputValue; + } + + void main() { + ivec4 coords = getOutputCoords(); + float outputValue; + int batch = coords[0]; + int x = coords[2]; + int y = coords[1]; + int channel = coords[3]; + float xf = float(x); + float yf = float(y); + float a1 = getTransforms(batch, 0); + float a2 = getTransforms(batch, 1); + float a3 = getTransforms(batch, 2); + float b1 = getTransforms(batch, 3); + float b2 = getTransforms(batch, 4); + float b3 = getTransforms(batch, 5); + float c1 = getTransforms(batch, 6); + float c2 = getTransforms(batch, 7); + float projection = c1 * xf + c2 * yf + 1.0; + if (projection == 0.0) { + outputValue = float(${fillValue}); + } else { + float inX = (a1 * xf + a2 * yf + a3) / projection; + float inY = (b1 * xf + b2 * yf + b3) / projection; + float mapX = mapCoord(inX, float(${imageWidth})); + float mapY = mapCoord(inY, float(${imageHeight})); + + if (${interpolationModeId} == 1) { + int coordY = int(round(mapY)); + int coordX = int(round(mapX)); + outputValue = readWithFillValue(batch, coordY, coordX, + channel); + } else { + float yFloor = floor(mapY); + float xFloor = floor(mapX); + float yCeil = yFloor + 1.0; + float xCeil = xFloor + 1.0; + float valueYFloor = (xCeil - mapX) * + readWithFillValue(batch, int(yFloor), int(xFloor), channel) + + (mapX - xFloor) * + readWithFillValue(batch, int(yFloor), int(xCeil), channel); + float valueYCeil = (xCeil - mapX) * + readWithFillValue(batch, int(yCeil), int(xFloor), channel) + + (mapX - xFloor) * + readWithFillValue(batch, int(yCeil), int(xCeil), channel); + outputValue = (yCeil - mapY) * valueYFloor + + (mapY - yFloor) * valueYCeil; + } + } + setOutput(outputValue); + } + `; + } + } + + /** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function transform(args) { + const { inputs, backend, attrs } = args; + const { image, transforms } = inputs; + const { interpolation, fillMode, fillValue, outputShape } = attrs; + const [batch, imageHeight, imageWidth, numChannels] = image.shape; + const [outHeight, outWidth] = outputShape != null ? outputShape : [imageHeight, imageWidth]; + const outShape = [batch, outHeight, outWidth, + numChannels]; + const program = new TransformProgram(imageHeight, imageWidth, interpolation, fillMode, fillValue, outShape); + return backend.runWebGLProgram(program, [image, transforms], 'float32'); + } + const transformConfig = { + kernelName: Transform, + backendName: 'webgl', + kernelFunc: transform + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function unique(args) { + const { inputs, attrs, backend } = args; + const { axis } = attrs; + const { x } = inputs; + assertNotComplex(x, 'unique'); + // For now, always forward calculation to the CPU backend. + console.warn('WARNING: ', 'UI might be locked temporarily as data is being downloaded'); + const values = backend.readSync(x.dataId); + const { outputValues, outputShape, indices } = uniqueImplCPU(values, axis, x.shape, x.dtype); + return [ + backend.makeTensorInfo(outputShape, x.dtype, outputValues), + backend.makeTensorInfo([indices.length], 'int32', indices), + ]; + } + const uniqueConfig = { + kernelName: Unique, + backendName: 'webgl', + kernelFunc: unique, + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function unpack(args) { + const { inputs, backend, attrs } = args; + const { value } = inputs; + let { axis } = attrs; + if (axis < 0) { + axis += value.shape.length; + } + const x = value; + const xRank = x.shape.length; + const num = value.shape[axis]; + const outShape = new Array(xRank - 1); + let outIndex = 0; + for (let i = 0; i < xRank; i++) { + if (i !== axis) { + outShape[outIndex++] = x.shape[i]; + } + } + const toDispose = []; + const begin = new Array(xRank).fill(0); + const size = x.shape.slice(); + size[axis] = 1; + const res = new Array(num); + for (let i = 0; i < res.length; i++) { + begin[axis] = i; + const sliced = slice({ inputs: { x }, backend, attrs: { begin, size } }); + const reshaped = reshape({ inputs: { x: sliced }, backend, attrs: { shape: outShape } }); + res[i] = reshaped; + toDispose.push(sliced); + } + toDispose.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return res; + } + const unpackConfig = { + kernelName: Unpack, + backendName: 'webgl', + kernelFunc: unpack + }; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + class SegmentOpProgram { + constructor(segOpInfo, segOpType) { + this.variableNames = ['x', 'segmentIds']; + const windowSize = segOpInfo.windowSize; + const batchSize = segOpInfo.batchSize; + const inSize = segOpInfo.inSize; + const numSegments = segOpInfo.numSegments; + const outSize = numSegments * Math.ceil(inSize / windowSize); + this.outputShape = [batchSize, outSize]; + const initializationValue = '0.0'; + const returnValue = `sumValue`; + const windowSizeNearestVec4 = Math.floor(windowSize / 4) * 4; + const windowSizeVec4Remainder = windowSize % 4; + const updateSnippet = ` + sumValue += dot(values, segFilter); + `; + let checkValueOutOfBounds = ''; + if (inSize % windowSize > 0) { + checkValueOutOfBounds = ` + if (inIdx < 0 || inIdx >= ${inSize}) { + return initializationValue; + } + `; + } + let checkSegmentIdOutOfBounds = ''; + if (inSize % windowSize > 0) { + checkSegmentIdOutOfBounds = ` + if (inIdx < 0 || inIdx >= ${inSize}) { + return -1.0; + } + `; + } + this.userCode = ` + const float initializationValue = ${initializationValue}; + + float getValue(int batch, int inIdx) { + ${checkValueOutOfBounds} + return getX(batch, inIdx); + } + + float getSegmentIdAtIndex(int inIdx) { + ${checkSegmentIdOutOfBounds} + return getSegmentIds(inIdx); + } + + void main() { + ivec2 coords = getOutputCoords(); + int batch = coords[0]; + int outIdx = coords[1]; + int inOffset = int(floor(float(outIdx) / float( + ${numSegments})) * float(${windowSize})); + int currentSeg = int(mod(float(outIdx), float(${numSegments}))); + + float sumValue = 0.0; + + for (int i = 0; i < ${windowSizeNearestVec4}; i += 4) { + int inIdx = inOffset + i; + vec4 values = vec4( + getValue(batch, inIdx), + getValue(batch, inIdx + 1), + getValue(batch, inIdx + 2), + getValue(batch, inIdx + 3) + ); + + vec4 segFilter = vec4( + int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0, + int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0, + int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0, + int(getSegmentIdAtIndex(inIdx + 3)) == currentSeg ? 1 : 0 + ); + + ${updateSnippet} + } + + int inIdx = inOffset + ${windowSizeNearestVec4}; + if (${windowSizeVec4Remainder === 1}) { + vec4 values = vec4( + getValue(batch, inIdx), + initializationValue, + initializationValue, + initializationValue + ); + + int inIdxSeg = int(getSegmentIdAtIndex(inIdx)); + + vec4 segFilter = vec4( + int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0, + 0, + 0, + 0 + ); + + ${updateSnippet} + } else if (${windowSizeVec4Remainder === 2}) { + vec4 values = vec4( + getValue(batch, inIdx), + getValue(batch, inIdx + 1), + initializationValue, + initializationValue + ); + + vec4 segFilter = vec4( + int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0, + int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0, + 0, + 0 + ); + + ${updateSnippet} + } else if (${windowSizeVec4Remainder === 3}) { + vec4 values = vec4( + getValue(batch, inIdx), + getValue(batch, inIdx + 1), + getValue(batch, inIdx + 2), + initializationValue + ); + + vec4 segFilter = vec4( + int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0, + int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0, + int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0, + 0 + ); + + ${updateSnippet} + } + setOutput(${returnValue}); + } + `; + } + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + function unsortedSegmentSum(args) { + const { inputs, backend, attrs } = args; + const { x, segmentIds } = inputs; + const { numSegments } = attrs; + const xRank = x.shape.length; + const toDispose = []; + let axis = 0; + const permutation = getAxesPermutation([axis], xRank); + let permutedX = x; + if (permutation != null) { + permutedX = transpose({ inputs: { x }, backend, attrs: { perm: permutation } }); + toDispose.push(permutedX); + axis = getInnerMostAxes(1, xRank)[0]; + } + const outShape = computeOutShape(permutedX.shape, axis, numSegments); + const inSize = sizeFromShape([permutedX.shape[axis]]); + const a2D = reshape({ inputs: { x: permutedX }, backend, attrs: { shape: [-1, inSize] } }); + toDispose.push(a2D); + const outputDType = sumOutType(x.dtype); + const segOpCompute = (x, segOpType, segmentIds, dtype, numSegments) => { + const batchSize = x.shape[0]; + const inSize = x.shape[1]; + const windowSize = segOpComputeOptimalWindowSize(inSize, numSegments); + const segOpInfo = { windowSize, inSize, batchSize, numSegments }; + const program = new SegmentOpProgram(segOpInfo, segOpType); + const output = backend.compileAndRun(program, [x, segmentIds], dtype); + toDispose.push(output); + // No need to run another GPGPU program. + if (output.shape[1] === numSegments) { + return output; + } + const rangeInfo = range({ + backend, + attrs: { start: 0, stop: numSegments, step: 1, dtype: 'float32' } + }); + const tileInfo = tile({ + inputs: { x: rangeInfo }, + backend, + attrs: { reps: [inSize / windowSize] } + }); + toDispose.push(rangeInfo); + toDispose.push(tileInfo); + const result = segOpCompute(output, segOpType, tileInfo, dtype, numSegments); + return result; + }; + const segOpResult = segOpCompute(a2D, 'unsortedSegmentSum', segmentIds, outputDType, numSegments); + const reshaped = reshape({ inputs: { x: segOpResult }, backend, attrs: { shape: outShape } }); + let result = reshaped; + if (permutation != null) { + toDispose.push(reshaped); + const perm = getUndoAxesPermutation(permutation); + result = transpose({ inputs: { x: result }, backend, attrs: { perm } }); + } + toDispose.forEach(t => backend.disposeIntermediateTensorInfo(t)); + return result; + } + const unsortedSegmentSumConfig = { + kernelName: UnsortedSegmentSum, + backendName: 'webgl', + kernelFunc: unsortedSegmentSum + }; + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + // List all kernel configs here + const kernelConfigs = [ + _fusedMatMulConfig, + absConfig, + acosConfig, + acoshConfig, + addConfig, + addNConfig, + allConfig, + anyConfig, + argMaxConfig, + argMinConfig, + asinConfig, + asinhConfig, + atanConfig, + atan2Config, + atanhConfig, + avgPoolConfig, + avgPool3DConfig, + avgPool3DGradConfig, + avgPoolGradConfig, + batchMatMulConfig, + batchNormConfig, + batchToSpaceNDConfig, + bincountConfig, + bitwiseAndConfig, + broadcastArgsConfig, + castConfig, + ceilConfig, + clipByValueConfig, + complexConfig, + complexAbsConfig, + concatConfig, + conv2DConfig, + conv2DBackpropFilterConfig, + conv2DBackpropInputConfig, + conv3DConfig, + conv3DBackpropFilterV2Config, + conv3DBackpropInputConfig, + cosConfig, + coshConfig, + cropAndResizeConfig, + cumprodConfig, + cumsumConfig, + denseBincountConfig, + depthToSpaceConfig, + depthwiseConv2dNativeConfig, + depthwiseConv2dNativeBackpropFilterConfig, + depthwiseConv2dNativeBackpropInputConfig, + diagConfig, + dilation2DConfig, + einsumConfig, + eluConfig, + eluGradConfig, + equalConfig, + erfConfig, + expConfig, + expandDimsConfig, + expm1Config, + fftConfig, + fillConfig, + flipLeftRightConfig, + floorConfig, + floorDivConfig, + fromPixelsConfig, + fusedConv2DConfig, + fusedDepthwiseConv2DConfig, + gatherNdConfig, + gatherV2Config, + greaterConfig, + greaterEqualConfig, + identityConfig, + ifftConfig, + imagConfig, + isFiniteConfig, + isInfConfig, + isNaNConfig, + leakyReluConfig, + lessConfig, + lessEqualConfig, + linSpaceConfig, + logConfig, + log1pConfig, + logicalAndConfig, + logicalNotConfig, + logicalOrConfig, + LRNConfig, + LRNGradConfig, + maxConfig, + maximumConfig, + maxPoolConfig, + maxPool3DConfig, + maxPool3DGradConfig, + maxPoolGradConfig, + maxPoolWithArgmaxConfig, + meanConfig, + minConfig, + minimumConfig, + mirrorPadConfig, + modConfig, + multinomialConfig, + multiplyConfig, + negConfig, + nonMaxSuppressionV3Config, + nonMaxSuppressionV4Config, + nonMaxSuppressionV5Config, + notEqualConfig, + oneHotConfig, + onesLikeConfig, + packConfig, + padV2Config, + powConfig, + preluConfig, + prodConfig, + raggedGatherConfig, + raggedRangeConfig, + raggedTensorToTensorConfig, + rangeConfig, + realConfig, + realDivConfig, + reciprocalConfig, + reluConfig, + relu6Config, + reshapeConfig, + resizeBilinearConfig, + resizeBilinearGradConfig, + resizeNearestNeighborConfig, + resizeNearestNeighborGradConfig, + reverseConfig, + rotateWithOffsetConfig, + roundConfig, + rsqrtConfig, + scatterNdConfig, + searchSortedConfig, + selectConfig, + seluConfig, + sigmoidConfig, + signConfig, + sinConfig, + sinhConfig, + sliceConfig, + softmaxConfig, + softplusConfig, + spaceToBatchNDConfig, + sparseFillEmptyRowsConfig, + sparseReshapeConfig, + sparseSegmentMeanConfig, + sparseSegmentSumConfig, + sparseToDenseConfig, + splitVConfig, + sqrtConfig, + squareConfig, + squaredDifferenceConfig, + staticRegexReplaceConfig, + stepConfig, + stridedSliceConfig, + stringNGramsConfig, + stringSplitConfig, + stringToHashBucketFastConfig, + subConfig, + sumConfig, + tanConfig, + tanhConfig, + tensorScatterUpdateConfig, + tileConfig, + topKConfig, + transformConfig, + transposeConfig, + uniqueConfig, + unpackConfig, + unsortedSegmentSumConfig, + zerosLikeConfig + ]; + for (const kernelConfig of kernelConfigs) { + registerKernel(kernelConfig); + } + + /** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + + /** @license See the LICENSE file. */ + // This code is auto-generated, do not modify this file! + const version$1 = '4.22.0'; + + /** + * @license + * Copyright 2018 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + const version = { + 'tfjs-core': version$7, + 'tfjs-backend-cpu': version$3, + 'tfjs-backend-webgl': version$2, + 'tfjs-data': version$4, + 'tfjs-layers': version$6, + 'tfjs-converter': version$5, + 'tfjs': version$1 + }; + + exports.Abs = Abs; + exports.Acos = Acos; + exports.Acosh = Acosh; + exports.AdadeltaOptimizer = AdadeltaOptimizer; + exports.AdagradOptimizer = AdagradOptimizer; + exports.AdamOptimizer = AdamOptimizer; + exports.AdamaxOptimizer = AdamaxOptimizer; + exports.Add = Add$1; + exports.AddN = AddN; + exports.All = All; + exports.Any = Any; + exports.ArgMax = ArgMax; + exports.ArgMin = ArgMin; + exports.Asin = Asin; + exports.Asinh = Asinh; + exports.Atan = Atan; + exports.Atan2 = Atan2; + exports.Atanh = Atanh; + exports.AvgPool = AvgPool; + exports.AvgPool3D = AvgPool3D; + exports.AvgPool3DGrad = AvgPool3DGrad; + exports.AvgPoolGrad = AvgPoolGrad; + exports.BatchMatMul = BatchMatMul; + exports.BatchToSpaceND = BatchToSpaceND; + exports.Bincount = Bincount; + exports.BitwiseAnd = BitwiseAnd; + exports.BroadcastArgs = BroadcastArgs; + exports.BroadcastTo = BroadcastTo; + exports.Callback = Callback; + exports.CallbackList = CallbackList; + exports.Cast = Cast; + exports.Ceil = Ceil; + exports.ClipByValue = ClipByValue; + exports.Complex = Complex; + exports.ComplexAbs = ComplexAbs; + exports.Concat = Concat; + exports.Conv2D = Conv2D$1; + exports.Conv2DBackpropFilter = Conv2DBackpropFilter; + exports.Conv2DBackpropInput = Conv2DBackpropInput; + exports.Conv3D = Conv3D$1; + exports.Conv3DBackpropFilterV2 = Conv3DBackpropFilterV2; + exports.Conv3DBackpropInputV2 = Conv3DBackpropInputV2; + exports.Cos = Cos; + exports.Cosh = Cosh; + exports.CropAndResize = CropAndResize; + exports.Cumprod = Cumprod; + exports.Cumsum = Cumsum; + exports.CustomCallback = CustomCallback; + exports.DataStorage = DataStorage; + exports.DenseBincount = DenseBincount; + exports.DepthToSpace = DepthToSpace; + exports.DepthwiseConv2dNative = DepthwiseConv2dNative; + exports.DepthwiseConv2dNativeBackpropFilter = DepthwiseConv2dNativeBackpropFilter; + exports.DepthwiseConv2dNativeBackpropInput = DepthwiseConv2dNativeBackpropInput; + exports.Diag = Diag; + exports.Dilation2D = Dilation2D; + exports.Dilation2DBackpropFilter = Dilation2DBackpropFilter; + exports.Dilation2DBackpropInput = Dilation2DBackpropInput; + exports.Draw = Draw; + exports.EarlyStopping = EarlyStopping; + exports.Einsum = Einsum; + exports.Elu = Elu$1; + exports.EluGrad = EluGrad; + exports.Environment = Environment; + exports.Equal = Equal; + exports.Erf = Erf; + exports.Exp = Exp; + exports.ExpandDims = ExpandDims; + exports.Expm1 = Expm1; + exports.FFT = FFT; + exports.Fill = Fill; + exports.FlipLeftRight = FlipLeftRight; + exports.Floor = Floor; + exports.FloorDiv = FloorDiv; + exports.FromPixels = FromPixels; + exports.FusedBatchNorm = FusedBatchNorm; + exports.FusedConv2D = FusedConv2D; + exports.FusedDepthwiseConv2D = FusedDepthwiseConv2D; + exports.GPGPUContext = GPGPUContext; + exports.GatherNd = GatherNd; + exports.GatherV2 = GatherV2; + exports.GraphModel = GraphModel; + exports.Greater = Greater; + exports.GreaterEqual = GreaterEqual; + exports.History = History; + exports.IFFT = IFFT; + exports.Identity = Identity$1; + exports.Imag = Imag; + exports.InputSpec = InputSpec; + exports.IsFinite = IsFinite; + exports.IsInf = IsInf; + exports.IsNan = IsNan; + exports.KernelBackend = KernelBackend; + exports.LRN = LRN; + exports.LRNGrad = LRNGrad; + exports.LayerVariable = LayerVariable; + exports.LayersModel = LayersModel; + exports.LeakyRelu = LeakyRelu; + exports.Less = Less; + exports.LessEqual = LessEqual; + exports.LinSpace = LinSpace; + exports.Log = Log; + exports.Log1p = Log1p; + exports.LogSoftmax = LogSoftmax$1; + exports.LogicalAnd = LogicalAnd; + exports.LogicalNot = LogicalNot; + exports.LogicalOr = LogicalOr; + exports.LogicalXor = LogicalXor; + exports.LowerBound = LowerBound; + exports.MathBackendCPU = MathBackendCPU; + exports.MathBackendWebGL = MathBackendWebGL; + exports.MatrixBandPart = MatrixBandPart; + exports.Max = Max; + exports.MaxPool = MaxPool; + exports.MaxPool3D = MaxPool3D; + exports.MaxPool3DGrad = MaxPool3DGrad; + exports.MaxPoolGrad = MaxPoolGrad; + exports.MaxPoolWithArgmax = MaxPoolWithArgmax; + exports.Maximum = Maximum$1; + exports.Mean = Mean; + exports.Min = Min; + exports.Minimum = Minimum$1; + exports.MirrorPad = MirrorPad; + exports.Mod = Mod; + exports.MomentumOptimizer = MomentumOptimizer; + exports.Multinomial = Multinomial; + exports.Multiply = Multiply$1; + exports.Neg = Neg; + exports.NonMaxSuppressionV3 = NonMaxSuppressionV3; + exports.NonMaxSuppressionV4 = NonMaxSuppressionV4; + exports.NonMaxSuppressionV5 = NonMaxSuppressionV5; + exports.NotEqual = NotEqual; + exports.OP_SCOPE_SUFFIX = OP_SCOPE_SUFFIX; + exports.OneHot = OneHot; + exports.OnesLike = OnesLike; + exports.Optimizer = Optimizer; + exports.OptimizerConstructors = OptimizerConstructors; + exports.Pack = Pack; + exports.PadV2 = PadV2; + exports.Pool = Pool; + exports.Pow = Pow; + exports.Prelu = Prelu; + exports.Prod = Prod; + exports.RMSPropOptimizer = RMSPropOptimizer; + exports.RNN = RNN; + exports.RaggedGather = RaggedGather; + exports.RaggedRange = RaggedRange; + exports.RaggedTensorToTensor = RaggedTensorToTensor; + exports.Range = Range; + exports.Real = Real; + exports.RealDiv = RealDiv; + exports.Reciprocal = Reciprocal; + exports.Relu = Relu$1; + exports.Relu6 = Relu6$1; + exports.Reshape = Reshape$1; + exports.ResizeBilinear = ResizeBilinear; + exports.ResizeBilinearGrad = ResizeBilinearGrad; + exports.ResizeNearestNeighbor = ResizeNearestNeighbor; + exports.ResizeNearestNeighborGrad = ResizeNearestNeighborGrad; + exports.Reverse = Reverse; + exports.RotateWithOffset = RotateWithOffset; + exports.Round = Round; + exports.Rsqrt = Rsqrt; + exports.SGDOptimizer = SGDOptimizer; + exports.ScatterNd = ScatterNd; + exports.SearchSorted = SearchSorted; + exports.Select = Select; + exports.Selu = Selu$1; + exports.Sequential = Sequential; + exports.Sigmoid = Sigmoid$1; + exports.Sign = Sign; + exports.Sin = Sin; + exports.Sinh = Sinh; + exports.Slice = Slice; + exports.Softmax = Softmax$2; + exports.Softplus = Softplus$1; + exports.SpaceToBatchND = SpaceToBatchND; + exports.SparseFillEmptyRows = SparseFillEmptyRows; + exports.SparseReshape = SparseReshape; + exports.SparseSegmentMean = SparseSegmentMean; + exports.SparseSegmentSum = SparseSegmentSum; + exports.SparseToDense = SparseToDense; + exports.SplitV = SplitV; + exports.Sqrt = Sqrt; + exports.Square = Square; + exports.SquaredDifference = SquaredDifference; + exports.StaticRegexReplace = StaticRegexReplace; + exports.Step = Step; + exports.StridedSlice = StridedSlice; + exports.StringNGrams = StringNGrams; + exports.StringSplit = StringSplit; + exports.StringToHashBucketFast = StringToHashBucketFast; + exports.Sub = Sub; + exports.Sum = Sum; + exports.SymbolicTensor = SymbolicTensor; + exports.Tan = Tan; + exports.Tanh = Tanh$1; + exports.Tensor = Tensor; + exports.TensorBuffer = TensorBuffer; + exports.TensorScatterUpdate = TensorScatterUpdate; + exports.Tile = Tile; + exports.TopK = TopK; + exports.Transform = Transform; + exports.Transpose = Transpose; + exports.Unique = Unique; + exports.Unpack = Unpack; + exports.UnsortedSegmentSum = UnsortedSegmentSum; + exports.UpperBound = UpperBound; + exports.Variable = Variable; + exports.ZerosLike = ZerosLike; + exports._FusedMatMul = _FusedMatMul; + exports.abs = abs$2; + exports.acos = acos$2; + exports.acosh = acosh$2; + exports.add = add$3; + exports.addN = addN$2; + exports.all = all$2; + exports.any = any$2; + exports.argMax = argMax$2; + exports.argMin = argMin$2; + exports.asin = asin$2; + exports.asinh = asinh$2; + exports.atan = atan$2; + exports.atan2 = atan2$2; + exports.atanh = atanh$2; + exports.avgPool = avgPool$2; + exports.avgPool3d = avgPool3d$1; + exports.backend = backend$1; + exports.backend_util = backend_util; + exports.basicLSTMCell = basicLSTMCell; + exports.batchNorm = batchNorm$2; + exports.batchNorm2d = batchNorm2d; + exports.batchNorm3d = batchNorm3d; + exports.batchNorm4d = batchNorm4d; + exports.batchToSpaceND = batchToSpaceND$2; + exports.bincount = bincount$2; + exports.bitwiseAnd = bitwiseAnd$2; + exports.booleanMaskAsync = booleanMaskAsync; + exports.broadcastArgs = broadcastArgs$2; + exports.broadcastTo = broadcastTo; + exports.broadcast_util = broadcast_util; + exports.browser = browser; + exports.buffer = buffer; + exports.callbacks = callbacks; + exports.cast = cast$3; + exports.ceil = ceil$2; + exports.clipByValue = clipByValue$2; + exports.clone = clone; + exports.complex = complex$2; + exports.concat = concat$2; + exports.concat1d = concat1d; + exports.concat2d = concat2d; + exports.concat3d = concat3d; + exports.concat4d = concat4d; + exports.constraints = exports_constraints; + exports.conv1d = conv1d$2; + exports.conv2d = conv2d$4; + exports.conv2dTranspose = conv2dTranspose$1; + exports.conv3d = conv3d$2; + exports.conv3dTranspose = conv3dTranspose$1; + exports.copyRegisteredKernels = copyRegisteredKernels; + exports.cos = cos$2; + exports.cosh = cosh$2; + exports.cosineWindow = cosineWindow; + exports.cumprod = cumprod$2; + exports.cumsum = cumsum$2; + exports.customGrad = customGrad; + exports.data = index; + exports.denseBincount = denseBincount$2; + exports.deprecationWarn = deprecationWarn; + exports.depthToSpace = depthToSpace$2; + exports.depthwiseConv2d = depthwiseConv2d$3; + exports.deregisterOp = deregisterOp; + exports.device_util = device_util; + exports.diag = diag$2; + exports.dilation2d = dilation2d; + exports.disableDeprecationWarnings = disableDeprecationWarnings; + exports.dispose = dispose; + exports.disposeVariables = disposeVariables; + exports.div = div$1; + exports.divNoNan = divNoNan; + exports.dot = dot$2; + exports.dropout = dropout$2; + exports.einsum = einsum$2; + exports.elu = elu$4; + exports.enableDebugMode = enableDebugMode; + exports.enableProdMode = enableProdMode; + exports.enclosingPowerOfTwo = enclosingPowerOfTwo; + exports.engine = engine; + exports.ensureShape = ensureShape; + exports.env = env; + exports.equal = equal$2; + exports.erf = erf$2; + exports.euclideanNorm = euclideanNorm; + exports.exp = exp$2; + exports.expandDims = expandDims$3; + exports.expm1 = expm1$2; + exports.eye = eye; + exports.fft = fft$2; + exports.fill = fill$2; + exports.findBackend = findBackend; + exports.findBackendFactory = findBackendFactory; + exports.floor = floor$2; + exports.floorDiv = floorDiv$2; + exports.forceHalfFloat = forceHalfFloat; + exports.fused = fused_ops; + exports.gather = gather$1; + exports.gatherND = gatherND; + exports.gather_util = gather_nd_util; + exports.getBackend = getBackend$1; + exports.getGradient = getGradient; + exports.getKernel = getKernel; + exports.getKernelsForBackend = getKernelsForBackend; + exports.gpgpu_util = gpgpu_util; + exports.grad = grad; + exports.grads = grads; + exports.greater = greater$3; + exports.greaterEqual = greaterEqual$2; + exports.ifft = ifft$2; + exports.imag = imag$2; + exports.image = image$1; + exports.inTopKAsync = inTopKAsync; + exports.initializers = exports_initializers; + exports.input = input; + exports.io = io; + exports.irfft = irfft; + exports.isFinite = isFinite$3; + exports.isInf = isInf$2; + exports.isNaN = isNaN$3; + exports.keep = keep; + exports.kernel_impls = kernel_impls; + exports.layers = exports_layers; + exports.leakyRelu = leakyRelu$2; + exports.less = less$3; + exports.lessEqual = lessEqual$2; + exports.linalg = linalg; + exports.linspace = linspace; + exports.loadGraphModel = loadGraphModel; + exports.loadGraphModelSync = loadGraphModelSync; + exports.loadLayersModel = loadLayersModel; + exports.localResponseNormalization = localResponseNormalization; + exports.log = log$2; + exports.log1p = log1p$2; + exports.logSigmoid = logSigmoid; + exports.logSoftmax = logSoftmax; + exports.logSumExp = logSumExp; + exports.logicalAnd = logicalAnd$2; + exports.logicalNot = logicalNot$2; + exports.logicalOr = logicalOr$2; + exports.logicalXor = logicalXor; + exports.losses = losses; + exports.lowerBound = lowerBound$1; + exports.matMul = matMul$1; + exports.math = math; + exports.max = max$3; + exports.maxPool = maxPool$2; + exports.maxPool3d = maxPool3d$1; + exports.maxPoolWithArgmax = maxPoolWithArgmax; + exports.maximum = maximum$4; + exports.mean = mean$3; + exports.memory = memory; + exports.meshgrid = meshgrid; + exports.metrics = exports_metrics; + exports.min = min$3; + exports.minimum = minimum$4; + exports.mirrorPad = mirrorPad$1; + exports.mod = mod$2; + exports.model = model; + exports.models = exports_models; + exports.moments = moments; + exports.movingAverage = movingAverage; + exports.mul = mul; + exports.multiRNNCell = multiRNNCell; + exports.multinomial = multinomial$2; + exports.neg = neg$2; + exports.nextFrame = nextFrame; + exports.norm = norm; + exports.notEqual = notEqual$2; + exports.oneHot = oneHot$3; + exports.ones = ones$1; + exports.onesLike = onesLike$3; + exports.op = op; + exports.outerProduct = outerProduct; + exports.pad = pad; + exports.pad1d = pad1d; + exports.pad2d = pad2d; + exports.pad3d = pad3d; + exports.pad4d = pad4d; + exports.pool = pool$1; + exports.pow = pow$3; + exports.prelu = prelu$3; + exports.print = print; + exports.prod = prod$2; + exports.profile = profile; + exports.raggedGather = raggedGather$2; + exports.raggedRange = raggedRange$2; + exports.raggedTensorToTensor = raggedTensorToTensor$2; + exports.rand = rand; + exports.randomGamma = randomGamma; + exports.randomNormal = randomNormal$2; + exports.randomStandardNormal = randomStandardNormal; + exports.randomUniform = randomUniform$1; + exports.randomUniformInt = randomUniformInt; + exports.range = range$3; + exports.ready = ready; + exports.real = real$2; + exports.reciprocal = reciprocal$2; + exports.registerBackend = registerBackend; + exports.registerCallbackConstructor = registerCallbackConstructor; + exports.registerGradient = registerGradient; + exports.registerKernel = registerKernel; + exports.registerOp = registerOp; + exports.regularizers = exports_regularizers; + exports.relu = relu$2; + exports.relu6 = relu6$2; + exports.removeBackend = removeBackend; + exports.reshape = reshape$3; + exports.reverse = reverse$2; + exports.reverse1d = reverse1d; + exports.reverse2d = reverse2d; + exports.reverse3d = reverse3d; + exports.reverse4d = reverse4d; + exports.rfft = rfft; + exports.round = round$2; + exports.rsqrt = rsqrt$2; + exports.scalar = scalar; + exports.scatterND = scatterND; + exports.scatter_util = scatter_nd_util; + exports.searchSorted = searchSorted$2; + exports.selu = selu$2; + exports.separableConv2d = separableConv2d$1; + exports.sequential = sequential; + exports.serialization = serialization; + exports.setBackend = setBackend$1; + exports.setPlatform = setPlatform; + exports.setWebGLContext = setWebGLContext; + exports.setdiff1dAsync = setdiff1dAsync; + exports.shared = shared; + exports.sigmoid = sigmoid$2; + exports.sign = sign$3; + exports.signal = signal; + exports.sin = sin$2; + exports.sinh = sinh$2; + exports.slice = slice$2; + exports.slice1d = slice1d; + exports.slice2d = slice2d; + exports.slice3d = slice3d; + exports.slice4d = slice4d; + exports.slice_util = slice_util; + exports.softmax = softmax$3; + exports.softplus = softplus$2; + exports.spaceToBatchND = spaceToBatchND$2; + exports.sparse = sparse$1; + exports.sparseToDense = sparseToDense$2; + exports.spectral = spectral$1; + exports.split = split$3; + exports.sqrt = sqrt$2; + exports.square = square$2; + exports.squaredDifference = squaredDifference$2; + exports.squeeze = squeeze; + exports.stack = stack; + exports.step = step$2; + exports.stridedSlice = stridedSlice$2; + exports.string = string$1; + exports.sub = sub$2; + exports.sum = sum$3; + exports.sumOutType = sumOutType; + exports.tan = tan$2; + exports.tanh = tanh$2; + exports.tensor = tensor; + exports.tensor1d = tensor1d; + exports.tensor2d = tensor2d; + exports.tensor3d = tensor3d; + exports.tensor4d = tensor4d; + exports.tensor5d = tensor5d; + exports.tensor6d = tensor6d; + exports.tensorScatterUpdate = tensorScatterUpdate$2; + exports.tensor_util = tensor_util; + exports.test_util = test_util; + exports.tidy = tidy; + exports.tile = tile$3; + exports.time = time; + exports.topk = topk; + exports.train = train; + exports.transpose = transpose$2; + exports.truncatedNormal = truncatedNormal$1; + exports.unique = unique$3; + exports.unregisterGradient = unregisterGradient; + exports.unregisterKernel = unregisterKernel; + exports.unsortedSegmentSum = unsortedSegmentSum$2; + exports.unstack = unstack; + exports.upcastType = upcastType; + exports.upperBound = upperBound$1; + exports.util = util; + exports.valueAndGrad = valueAndGrad; + exports.valueAndGrads = valueAndGrads; + exports.variable = variable$1; + exports.variableGrads = variableGrads; + exports.version = version; + exports.version_converter = version$5; + exports.version_core = version$7; + exports.version_cpu = version$3; + exports.version_layers = version$6; + exports.version_webgl = version$2; + exports.webgl = webgl; + exports.webgl_util = webgl_util; + exports.where = where; + exports.whereAsync = whereAsync; + exports.zeros = zeros$2; + exports.zerosLike = zerosLike$3; + +})); +//# sourceMappingURL=tf.es2017.js.map diff --git a/graalwasm/graalwasm-tensorflow/src/main/resources/tfjs-backend-wasm-simd.wasm b/graalwasm/graalwasm-tensorflow/src/main/resources/tfjs-backend-wasm-simd.wasm new file mode 100755 index 0000000000000000000000000000000000000000..b515dee98b4614a42f1e44b6080fc0654cfea876 GIT binary patch literal 311123 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

L=749qpwp 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Ɋ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 jh^=7@8_?Jmh8=+d5&VMDB&^|( Date: Fri, 13 Jun 2025 10:57:02 +0100 Subject: [PATCH 2/2] updated readme file --- graalwasm/graalwasm-tensorflow/README.md | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/graalwasm/graalwasm-tensorflow/README.md b/graalwasm/graalwasm-tensorflow/README.md index e9c63711..aa6434b7 100644 --- a/graalwasm/graalwasm-tensorflow/README.md +++ b/graalwasm/graalwasm-tensorflow/README.md @@ -1,24 +1,15 @@ -# 🏠 House Price Prediction Demo (Spring Boot + Thymeleaf + GraalVM JS WASM) +# Tensorflow with GraalWasm Spring-boot Demo This is a simple Spring Boot application that predicts house prices using a JavaScript function executed via GraalVM, with a web frontend built using Thymeleaf. +This demo illustrates how GraalWasm can be used to embed tensorflow-wasm . The demo also uses GraalJS to access the Tensorflow module through the WebAssembly JavaScript API. -## 📦 Prerequisites +## Run the Application -- Java 21+ (GraalVM recommended) -- Maven 3.x -- GraalVM setup (with JavaScript support) -- Internet browser +To start the demo, simply run: -## 🚀 How to Run - -### 1. Build the project -```bash -mvn clean package -``` -### 2. Run the Spring Boot application ```bash mvn spring-boot:run ``` -### 3. Open your browser +When the demo runs, open the following URLs in a browser: Go to: http://localhost:8080 \ No newline at end of file

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]QjcBCk8TM^eF-ix;gj;+@yVt=gs;MHsya*g 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

Lo4*liDe2x8-_QdN0=^^; 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 z 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 t*IWde&erZQSXhrUYh8ou1wX3 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

wSYWEk#vi;}YiEO3uFw0!#4tiIDof-)rie(2t(b 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