From 2a56c703635a5cad5706cb658bd9992eec0fe364 Mon Sep 17 00:00:00 2001 From: Jing Jin <8752427+jinjingforever@users.noreply.github.com> Date: Fri, 18 Sep 2020 11:23:05 -0700 Subject: [PATCH 1/6] save --- tfjs-backend-cpu/src/backend_cpu.ts | 465 +------------------ tfjs-backend-cpu/src/kernels/Abs.ts | 29 ++ tfjs-backend-cpu/src/kernels/Acos.ts | 28 ++ tfjs-backend-cpu/src/kernels/Acosh.ts | 28 ++ tfjs-backend-cpu/src/kernels/Asin.ts | 28 ++ tfjs-backend-cpu/src/kernels/Asinh.ts | 28 ++ tfjs-backend-cpu/src/kernels/Atan.ts | 28 ++ tfjs-backend-cpu/src/kernels/Atanh.ts | 28 ++ tfjs-backend-cpu/src/kernels/Ceil.ts | 28 ++ tfjs-backend-cpu/src/kernels/Clip.ts | 33 ++ tfjs-backend-cpu/src/kernels/Cosh.ts | 28 ++ tfjs-backend-cpu/src/kernels/Elu.ts | 29 ++ tfjs-backend-cpu/src/kernels/Erf.ts | 46 ++ tfjs-backend-cpu/src/kernels/Exp.ts | 28 ++ tfjs-backend-cpu/src/kernels/Expm1.ts | 28 ++ tfjs-backend-cpu/src/kernels/Floor.ts | 28 ++ tfjs-backend-cpu/src/kernels/IsFinite.ts | 29 ++ tfjs-backend-cpu/src/kernels/IsInf.ts | 29 ++ tfjs-backend-cpu/src/kernels/IsNaN.ts | 29 ++ tfjs-backend-cpu/src/kernels/Log.ts | 28 ++ tfjs-backend-cpu/src/kernels/Log1p.ts | 28 ++ tfjs-backend-cpu/src/kernels/LogicalNot.ts | 29 ++ tfjs-backend-cpu/src/kernels/Reciprocal.ts | 28 ++ tfjs-backend-cpu/src/kernels/Round.ts | 42 ++ tfjs-backend-cpu/src/kernels/Rsqrt.ts | 28 ++ tfjs-backend-cpu/src/kernels/Selu.ts | 37 ++ tfjs-backend-cpu/src/kernels/Sigmoid.ts | 29 ++ tfjs-backend-cpu/src/kernels/Sign.ts | 36 ++ tfjs-backend-cpu/src/kernels/Sin.ts | 28 ++ tfjs-backend-cpu/src/kernels/Sinh.ts | 28 ++ tfjs-backend-cpu/src/kernels/Softplus.ts | 56 +++ tfjs-backend-cpu/src/kernels/Sqrt.ts | 28 ++ tfjs-backend-cpu/src/kernels/Step.ts | 35 ++ tfjs-backend-cpu/src/kernels/Tan.ts | 28 ++ tfjs-backend-cpu/src/kernels/Tanh.ts | 28 ++ tfjs-backend-cpu/src/register_all_kernels.ts | 68 +++ tfjs-backend-cpu/src/utils/binary_types.ts | 5 +- tfjs-backend-cpu/src/utils/kernel_utils.ts | 41 +- 38 files changed, 1161 insertions(+), 466 deletions(-) create mode 100644 tfjs-backend-cpu/src/kernels/Abs.ts create mode 100644 tfjs-backend-cpu/src/kernels/Acos.ts create mode 100644 tfjs-backend-cpu/src/kernels/Acosh.ts create mode 100644 tfjs-backend-cpu/src/kernels/Asin.ts create mode 100644 tfjs-backend-cpu/src/kernels/Asinh.ts create mode 100644 tfjs-backend-cpu/src/kernels/Atan.ts create mode 100644 tfjs-backend-cpu/src/kernels/Atanh.ts create mode 100644 tfjs-backend-cpu/src/kernels/Ceil.ts create mode 100644 tfjs-backend-cpu/src/kernels/Clip.ts create mode 100644 tfjs-backend-cpu/src/kernels/Cosh.ts create mode 100644 tfjs-backend-cpu/src/kernels/Elu.ts create mode 100644 tfjs-backend-cpu/src/kernels/Erf.ts create mode 100644 tfjs-backend-cpu/src/kernels/Exp.ts create mode 100644 tfjs-backend-cpu/src/kernels/Expm1.ts create mode 100644 tfjs-backend-cpu/src/kernels/Floor.ts create mode 100644 tfjs-backend-cpu/src/kernels/IsFinite.ts create mode 100644 tfjs-backend-cpu/src/kernels/IsInf.ts create mode 100644 tfjs-backend-cpu/src/kernels/IsNaN.ts create mode 100644 tfjs-backend-cpu/src/kernels/Log.ts create mode 100644 tfjs-backend-cpu/src/kernels/Log1p.ts create mode 100644 tfjs-backend-cpu/src/kernels/LogicalNot.ts create mode 100644 tfjs-backend-cpu/src/kernels/Reciprocal.ts create mode 100644 tfjs-backend-cpu/src/kernels/Round.ts create mode 100644 tfjs-backend-cpu/src/kernels/Rsqrt.ts create mode 100644 tfjs-backend-cpu/src/kernels/Selu.ts create mode 100644 tfjs-backend-cpu/src/kernels/Sigmoid.ts create mode 100644 tfjs-backend-cpu/src/kernels/Sign.ts create mode 100644 tfjs-backend-cpu/src/kernels/Sin.ts create mode 100644 tfjs-backend-cpu/src/kernels/Sinh.ts create mode 100644 tfjs-backend-cpu/src/kernels/Softplus.ts create mode 100644 tfjs-backend-cpu/src/kernels/Sqrt.ts create mode 100644 tfjs-backend-cpu/src/kernels/Step.ts create mode 100644 tfjs-backend-cpu/src/kernels/Tan.ts create mode 100644 tfjs-backend-cpu/src/kernels/Tanh.ts diff --git a/tfjs-backend-cpu/src/backend_cpu.ts b/tfjs-backend-cpu/src/backend_cpu.ts index e0736c021bb..1cf0e70aac2 100644 --- a/tfjs-backend-cpu/src/backend_cpu.ts +++ b/tfjs-backend-cpu/src/backend_cpu.ts @@ -37,7 +37,7 @@ function mapActivation( } else if (activation === 'relu') { return backend.relu(x); } else if (activation === 'elu') { - return backend.elu(x); + return tf.elu(x); } else if (activation === 'relu6') { return backend.relu6(x); } else if (activation === 'prelu') { @@ -318,7 +318,7 @@ export class MathBackendCPU extends KernelBackend { // TODO(lina128): Use sub directly once softmax is modularized. const a = tf.sub(logits, maxLogit.reshape(expandedShape)); - const b = this.exp(a); + const b = tf.exp(a); const sumExp = this.sum(b, axes).reshape(expandedShape); // TODO(annxingyuan): Call divImpl rather than op as part of softmax @@ -615,17 +615,6 @@ export class MathBackendCPU extends KernelBackend { }); } - logicalNot(x: T): T { - assertNotComplex(x, 'logicalNot'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Uint8Array(values.length); - for (let i = 0; i < values.length; ++i) { - newValues[i] = values[i] ? 0 : 1; - } - return this.makeOutput(newValues, x.shape, 'bool'); - } - logicalAnd(a: Tensor, b: Tensor): Tensor { assertNotComplex([a, b], 'logicalAnd'); @@ -789,188 +778,6 @@ export class MathBackendCPU extends KernelBackend { }); } - ceil(x: T): T { - assertNotComplex(x, 'ceil'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - newValues[i] = Math.ceil(values[i]); - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - floor(x: T): T { - assertNotComplex(x, 'floor'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - newValues[i] = Math.floor(values[i]); - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - sign(x: T): T { - assertNotComplex(x, 'x'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - if (values[i] < 0) { - newValues[i] = -1; - } else if (values[i] > 0) { - newValues[i] = 1; - } else { - newValues[i] = 0; - } - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - isNaN(x: T): T { - assertNotComplex(x, 'x'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Uint8Array(values.length); - for (let i = 0; i < values.length; ++i) { - if (Number.isNaN(values[i])) { - newValues[i] = 1; - } - } - return this.makeOutput(newValues, x.shape, 'bool'); - } - - isInf(x: T): T { - assertNotComplex(x, 'x'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Uint8Array(values.length); - for (let i = 0; i < values.length; ++i) { - if (Math.abs(values[i]) === Infinity) { - newValues[i] = 1; - } - } - return this.makeOutput(newValues, x.shape, 'bool'); - } - - isFinite(x: T): T { - assertNotComplex(x, 'x'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Uint8Array(values.length); - for (let i = 0; i < values.length; ++i) { - if (Number.isFinite(values[i])) { - newValues[i] = 1; - } - } - return this.makeOutput(newValues, x.shape, 'bool'); - } - - round(x: T): T { - assertNotComplex(x, 'round'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - // The algorithm is based on banker's rounding. - const base = Math.floor(values[i]); - if (values[i] - base < 0.5) { - newValues[i] = Math.floor(values[i]); - } else if (values[i] - base > 0.5) { - newValues[i] = Math.ceil(values[i]); - } else { - if (base % 2.0 === 0.0) { - newValues[i] = base; - } else { - newValues[i] = base + 1.0; - } - } - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - exp(x: T): T { - assertNotComplex(x, 'exp'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - newValues[i] = Math.exp(values[i]); - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - expm1(x: T): T { - assertNotComplex(x, 'expm1'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - newValues[i] = Math.expm1(values[i]); - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - log(x: T): T { - assertNotComplex(x, 'log'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - const value = values[i]; - newValues[i] = Math.log(value); - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - log1p(x: T): T { - assertNotComplex(x, 'log1p'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - const value = values[i]; - newValues[i] = Math.log1p(value); - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - sqrt(x: T): T { - assertNotComplex(x, 'sqrt'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - const value = values[i]; - newValues[i] = Math.sqrt(value); - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - rsqrt(x: T): T { - assertNotComplex(x, 'rsqrt'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - const value = values[i]; - newValues[i] = 1 / Math.sqrt(value); - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - - reciprocal(x: T): T { - assertNotComplex(x, 'reciprocal'); - - const values = this.readSync(x.dataId) as TypedArray; - const newValues = new Float32Array(values.length); - for (let i = 0; i < values.length; ++i) { - newValues[i] = 1 / values[i]; - } - return this.makeOutput(newValues, x.shape, 'float32'); - } - linear(x: T): T { return x; } @@ -1007,22 +814,6 @@ export class MathBackendCPU extends KernelBackend { (xValue, aValue) => xValue < 0 ? aValue * xValue : xValue) as T; } - elu(x: T): T { - assertNotComplex(x, 'elu'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - const v = values[i]; - if (v >= 0) { - resultValues[i] = v; - } else { - resultValues[i] = (Math.exp(v) - 1); - } - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - eluDer(dy: T, y: T): T { assertNotComplex([dy, y], 'eluDer'); @@ -1040,49 +831,6 @@ export class MathBackendCPU extends KernelBackend { return this.makeOutput(resultValues, y.shape, 'float32'); } - selu(x: T): T { - assertNotComplex(x, 'selu'); - - // Stable and Attracting Fixed Point (0, 1) for Normalized Weights. - // see: https://arxiv.org/abs/1706.02515 - const scaleAlpha = backend_util.SELU_SCALEALPHA; - const scale = backend_util.SELU_SCALE; - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - const v = values[i]; - if (v >= 0) { - resultValues[i] = scale * v; - } else { - resultValues[i] = scaleAlpha * (Math.exp(v) - 1); - } - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - clip(x: T, min: number, max: number): T { - assertNotComplex(x, 'clip'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - const v = values[i]; - resultValues[i] = v > max ? max : (v < min ? min : v); - } - return this.makeOutput(resultValues, x.shape, x.dtype); - } - - abs(x: T): T { - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.abs(values[i]); - } - - return this.makeOutput(resultValues, x.shape, 'float32'); - } - complexAbs(x: T): T { const resultValues = new Float32Array(x.size); const values = this.readSync(x.dataId) as TypedArray; @@ -1095,110 +843,6 @@ export class MathBackendCPU extends KernelBackend { return this.makeOutput(resultValues, x.shape, 'float32'); } - sigmoid(x: T): T { - assertNotComplex(x, 'sigmoid'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = 1 / (1 + Math.exp(-values[i])); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - softplus(x: T): T { - assertNotComplex(x, 'softplus'); - - // 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 resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - - for (let i = 0; i < values.length; ++i) { - // Value above which exp(x) may overflow, but softplus(x) == x - // is within machine epsilon. - const tooLarge = values[i] > -threshold; - - // Value below which exp(x) may underflow, but softplus(x) == exp(x) - // is within machine epsilon. - const tooSmall = values[i] < threshold; - - const expX = Math.exp(values[i]); - let result; - - if (tooSmall) { - result = expX; - } else if (tooLarge) { - result = values[i]; - } else { - result = Math.log(1.0 + expX); - } - resultValues[i] = result; - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - sin(x: T): T { - assertNotComplex(x, 'sin'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.sin(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - tan(x: T): T { - assertNotComplex(x, 'tan'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.tan(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - asin(x: T): T { - assertNotComplex(x, 'asin'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.asin(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - acos(x: T): T { - assertNotComplex(x, 'acos'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.acos(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - atan(x: T): T { - assertNotComplex(x, 'atan'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.atan(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - atan2(a: T, b: T): T { assertNotComplex([a, b], 'atan2'); @@ -1207,111 +851,6 @@ export class MathBackendCPU extends KernelBackend { T; } - sinh(x: T): T { - assertNotComplex(x, 'sinh'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.sinh(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - cosh(x: T): T { - assertNotComplex(x, 'cosh'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.cosh(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - tanh(x: T): T { - assertNotComplex(x, 'tanh'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = util.tanh(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - asinh(x: T): T { - assertNotComplex(x, 'asinh'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.asinh(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - acosh(x: T): T { - assertNotComplex(x, 'acosh'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.acosh(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - atanh(x: T): T { - assertNotComplex(x, 'atanh'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - resultValues[i] = Math.atanh(values[i]); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - erf(x: T): T { - assertNotComplex(x, 'erf'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - const p = backend_util.ERF_P; - const a1 = backend_util.ERF_A1; - const a2 = backend_util.ERF_A2; - const a3 = backend_util.ERF_A3; - const a4 = backend_util.ERF_A4; - const a5 = backend_util.ERF_A5; - for (let i = 0; i < values.length; ++i) { - const sign = Math.sign(values[i]); - const v = Math.abs(values[i]); - const t = 1.0 / (1.0 + p * v); - resultValues[i] = sign * - (1.0 - - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * - Math.exp(-v * v)); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - - step(x: T, alpha = 0): T { - assertNotComplex(x, 'step'); - - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - for (let i = 0; i < values.length; ++i) { - const value = values[i]; - if (isNaN(value)) { - resultValues[i] = NaN; - } else { - resultValues[i] = value > 0 ? 1 : alpha; - } - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - fusedConv2d( {input, filter, convInfo, bias, activation, preluActivationWeights}: backend_util.FusedConv2DConfig): Tensor4D { diff --git a/tfjs-backend-cpu/src/kernels/Abs.ts b/tfjs-backend-cpu/src/kernels/Abs.ts new file mode 100644 index 00000000000..cf2574041f9 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Abs.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Abs, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const absKernelFunc = unaryKernelFunc( + Abs, (x) => Math.abs(x), 'float32', (real, imag) => Math.hypot(real, imag)); + +export const absConfig: KernelConfig = { + kernelName: Abs, + backendName: 'cpu', + kernelFunc: absKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Acos.ts b/tfjs-backend-cpu/src/kernels/Acos.ts new file mode 100644 index 00000000000..72911130411 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Acos.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Acos, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const acosKernelFunc = unaryKernelFunc(Acos, (x) => Math.acos(x)); + +export const acosConfig: KernelConfig = { + kernelName: Acos, + backendName: 'cpu', + kernelFunc: acosKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Acosh.ts b/tfjs-backend-cpu/src/kernels/Acosh.ts new file mode 100644 index 00000000000..56c709caf19 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Acosh.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Acosh, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const acoshKernelFunc = unaryKernelFunc(Acosh, (x) => Math.acosh(x)); + +export const acoshConfig: KernelConfig = { + kernelName: Acosh, + backendName: 'cpu', + kernelFunc: acoshKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Asin.ts b/tfjs-backend-cpu/src/kernels/Asin.ts new file mode 100644 index 00000000000..c64563f4ab5 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Asin.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Asin, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const asinKernelFunc = unaryKernelFunc(Asin, (x) => Math.asin(x)); + +export const asinConfig: KernelConfig = { + kernelName: Asin, + backendName: 'cpu', + kernelFunc: asinKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Asinh.ts b/tfjs-backend-cpu/src/kernels/Asinh.ts new file mode 100644 index 00000000000..d2b69eda37e --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Asinh.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Asinh, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const asinhKernelFunc = unaryKernelFunc(Asinh, (x) => Math.asinh(x)); + +export const asinhConfig: KernelConfig = { + kernelName: Asinh, + backendName: 'cpu', + kernelFunc: asinhKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Atan.ts b/tfjs-backend-cpu/src/kernels/Atan.ts new file mode 100644 index 00000000000..8f19548f37e --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Atan.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Atan, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const atanKernelFunc = unaryKernelFunc(Atan, (x) => Math.atan(x)); + +export const atanConfig: KernelConfig = { + kernelName: Atan, + backendName: 'cpu', + kernelFunc: atanKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Atanh.ts b/tfjs-backend-cpu/src/kernels/Atanh.ts new file mode 100644 index 00000000000..b8b39e16042 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Atanh.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Atanh, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const atanhKernelFunc = unaryKernelFunc(Atanh, (x) => Math.atanh(x)); + +export const atanhConfig: KernelConfig = { + kernelName: Atanh, + backendName: 'cpu', + kernelFunc: atanhKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Ceil.ts b/tfjs-backend-cpu/src/kernels/Ceil.ts new file mode 100644 index 00000000000..18d94006e9f --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Ceil.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Ceil, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const ceilKernelFunc = unaryKernelFunc(Ceil, (x) => Math.ceil(x)); + +export const ceilConfig: KernelConfig = { + kernelName: Ceil, + backendName: 'cpu', + kernelFunc: ceilKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Clip.ts b/tfjs-backend-cpu/src/kernels/Clip.ts new file mode 100644 index 00000000000..2b76c9c85f6 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Clip.ts @@ -0,0 +1,33 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {ClipByValue, ClipByValueAttrs, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const clipKernelFunc = unaryKernelFunc(ClipByValue, (x, attrs) => { + const clipAttrs = attrs as {} as ClipByValueAttrs; + return x > clipAttrs.clipValueMax ? + clipAttrs.clipValueMax : + (x < clipAttrs.clipValueMin ? clipAttrs.clipValueMin : x); +}); + +export const clipConfig: KernelConfig = { + kernelName: ClipByValue, + backendName: 'cpu', + kernelFunc: clipKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Cosh.ts b/tfjs-backend-cpu/src/kernels/Cosh.ts new file mode 100644 index 00000000000..95200be0d79 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Cosh.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Cosh, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const coshKernelFunc = unaryKernelFunc(Cosh, (x) => Math.cosh(x)); + +export const coshConfig: KernelConfig = { + kernelName: Cosh, + backendName: 'cpu', + kernelFunc: coshKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Elu.ts b/tfjs-backend-cpu/src/kernels/Elu.ts new file mode 100644 index 00000000000..364b87deccd --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Elu.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Elu, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const eluKernelFunc = + unaryKernelFunc(Elu, (x) => x >= 0 ? x : (Math.exp(x) - 1)); + +export const eluConfig: KernelConfig = { + kernelName: Elu, + backendName: 'cpu', + kernelFunc: eluKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Erf.ts b/tfjs-backend-cpu/src/kernels/Erf.ts new file mode 100644 index 00000000000..77be4df1488 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Erf.ts @@ -0,0 +1,46 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {backend_util, Erf, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +const p = backend_util.ERF_P; +const a1 = backend_util.ERF_A1; +const a2 = backend_util.ERF_A2; +const a3 = backend_util.ERF_A3; +const a4 = backend_util.ERF_A4; +const a5 = backend_util.ERF_A5; + +export const erfKernelFunc = unaryKernelFunc( + Erf, + (x) => { + const sign = Math.sign(x); + const v = Math.abs(x); + 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)); + }, +); + +export const erfConfig: KernelConfig = { + kernelName: Erf, + backendName: 'cpu', + kernelFunc: erfKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Exp.ts b/tfjs-backend-cpu/src/kernels/Exp.ts new file mode 100644 index 00000000000..e49e34a6f7c --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Exp.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Exp, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const expKernelFunc = unaryKernelFunc(Exp, (x) => Math.exp(x)); + +export const expConfig: KernelConfig = { + kernelName: Exp, + backendName: 'cpu', + kernelFunc: expKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Expm1.ts b/tfjs-backend-cpu/src/kernels/Expm1.ts new file mode 100644 index 00000000000..c20f84d4950 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Expm1.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Expm1, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const expm1KernelFunc = unaryKernelFunc(Expm1, (x) => Math.expm1(x)); + +export const expm1Config: KernelConfig = { + kernelName: Expm1, + backendName: 'cpu', + kernelFunc: expm1KernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Floor.ts b/tfjs-backend-cpu/src/kernels/Floor.ts new file mode 100644 index 00000000000..9d48d8451f7 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Floor.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {Floor, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const floorKernelFunc = unaryKernelFunc(Floor, (x) => Math.floor(x)); + +export const floorConfig: KernelConfig = { + kernelName: Floor, + backendName: 'cpu', + kernelFunc: floorKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/IsFinite.ts b/tfjs-backend-cpu/src/kernels/IsFinite.ts new file mode 100644 index 00000000000..c5df7c3ab7b --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/IsFinite.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {IsFinite, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const isFiniteKernelFunc = + unaryKernelFunc(IsFinite, (x) => Number.isFinite(x) ? 1 : 0, 'bool'); + +export const isFiniteConfig: KernelConfig = { + kernelName: IsFinite, + backendName: 'cpu', + kernelFunc: isFiniteKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/IsInf.ts b/tfjs-backend-cpu/src/kernels/IsInf.ts new file mode 100644 index 00000000000..d19154faedd --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/IsInf.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {IsInf, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const isInfKernelFunc = + unaryKernelFunc(IsInf, (x) => Math.abs(x) === Infinity ? 1 : 0, 'bool'); + +export const isInfConfig: KernelConfig = { + kernelName: IsInf, + backendName: 'cpu', + kernelFunc: isInfKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/IsNaN.ts b/tfjs-backend-cpu/src/kernels/IsNaN.ts new file mode 100644 index 00000000000..dc84c0e2569 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/IsNaN.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {IsNan, KernelConfig} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const isNaNKernelFunc = + unaryKernelFunc(IsNan, (x) => Number.isNaN(x) ? 1 : 0, 'bool'); + +export const isNaNConfig: KernelConfig = { + kernelName: IsNan, + backendName: 'cpu', + kernelFunc: isNaNKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Log.ts b/tfjs-backend-cpu/src/kernels/Log.ts new file mode 100644 index 00000000000..45bd0d9cc6a --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Log.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Log} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const logKernelFunc = unaryKernelFunc(Log, (x) => Math.log(x)); + +export const logConfig: KernelConfig = { + kernelName: Log, + backendName: 'cpu', + kernelFunc: logKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Log1p.ts b/tfjs-backend-cpu/src/kernels/Log1p.ts new file mode 100644 index 00000000000..e17e5ae3224 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Log1p.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Log1p} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const log1pKernelFunc = unaryKernelFunc(Log1p, (x) => Math.log1p(x)); + +export const log1pConfig: KernelConfig = { + kernelName: Log1p, + backendName: 'cpu', + kernelFunc: log1pKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/LogicalNot.ts b/tfjs-backend-cpu/src/kernels/LogicalNot.ts new file mode 100644 index 00000000000..890b226cfc3 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/LogicalNot.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, LogicalNot} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const logicalNotKernelFunc = + unaryKernelFunc(LogicalNot, (x) => x ? 0 : 1, 'bool'); + +export const logicalNotConfig: KernelConfig = { + kernelName: LogicalNot, + backendName: 'cpu', + kernelFunc: logicalNotKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Reciprocal.ts b/tfjs-backend-cpu/src/kernels/Reciprocal.ts new file mode 100644 index 00000000000..65817724754 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Reciprocal.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Reciprocal} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const reciprocalKernelFunc = unaryKernelFunc(Reciprocal, (x) => 1 / x); + +export const reciprocalConfig: KernelConfig = { + kernelName: Reciprocal, + backendName: 'cpu', + kernelFunc: reciprocalKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Round.ts b/tfjs-backend-cpu/src/kernels/Round.ts new file mode 100644 index 00000000000..a3dc07f39f6 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Round.ts @@ -0,0 +1,42 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Round} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const roundKernelFunc = unaryKernelFunc(Round, (x) => { + // The algorithm is based on banker's rounding. + const base = Math.floor(x); + if (x - base < 0.5) { + return Math.floor(x); + } else if (x - base > 0.5) { + return Math.ceil(x); + } else { + if (base % 2.0 === 0.0) { + return base; + } else { + return base + 1.0; + } + } +}); + +export const roundConfig: KernelConfig = { + kernelName: Round, + backendName: 'cpu', + kernelFunc: roundKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Rsqrt.ts b/tfjs-backend-cpu/src/kernels/Rsqrt.ts new file mode 100644 index 00000000000..72837f927b9 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Rsqrt.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Rsqrt} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const rsqrtKernelFunc = unaryKernelFunc(Rsqrt, (x) => 1 / Math.sqrt(x)); + +export const rsqrtConfig: KernelConfig = { + kernelName: Rsqrt, + backendName: 'cpu', + kernelFunc: rsqrtKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Selu.ts b/tfjs-backend-cpu/src/kernels/Selu.ts new file mode 100644 index 00000000000..d41b90d5a49 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Selu.ts @@ -0,0 +1,37 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {backend_util, KernelConfig, Selu} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +const scaleAlpha = backend_util.SELU_SCALEALPHA; +const scale = backend_util.SELU_SCALE; + +export const seluKernelFunc = unaryKernelFunc(Selu, (x) => { + if (x >= 0) { + return scale * x; + } else { + return scaleAlpha * (Math.exp(x) - 1); + } +}); + +export const seluConfig: KernelConfig = { + kernelName: Selu, + backendName: 'cpu', + kernelFunc: seluKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Sigmoid.ts b/tfjs-backend-cpu/src/kernels/Sigmoid.ts new file mode 100644 index 00000000000..569545bcfca --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Sigmoid.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Sigmoid} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const sigmoidKernelFunc = + unaryKernelFunc(Sigmoid, (x) => 1 / (1 + Math.exp(-x))); + +export const sigmoidConfig: KernelConfig = { + kernelName: Sigmoid, + backendName: 'cpu', + kernelFunc: sigmoidKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Sign.ts b/tfjs-backend-cpu/src/kernels/Sign.ts new file mode 100644 index 00000000000..f8adba453da --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Sign.ts @@ -0,0 +1,36 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Sign} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const signKernelFunc = unaryKernelFunc(Sign, (x) => { + if (x < 0) { + return -1; + } else if (x > 0) { + return 1; + } else { + return 0; + } +}); + +export const signConfig: KernelConfig = { + kernelName: Sign, + backendName: 'cpu', + kernelFunc: signKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Sin.ts b/tfjs-backend-cpu/src/kernels/Sin.ts new file mode 100644 index 00000000000..7ec83b7cda7 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Sin.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Sin} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const sinKernelFunc = unaryKernelFunc(Sin, (x) => Math.sin(x)); + +export const sinConfig: KernelConfig = { + kernelName: Sin, + backendName: 'cpu', + kernelFunc: sinKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Sinh.ts b/tfjs-backend-cpu/src/kernels/Sinh.ts new file mode 100644 index 00000000000..4cbfbeee6a9 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Sinh.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Sinh} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const sinhKernelFunc = unaryKernelFunc(Sinh, (x) => Math.sinh(x)); + +export const sinhConfig: KernelConfig = { + kernelName: Sinh, + backendName: 'cpu', + kernelFunc: sinhKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Softplus.ts b/tfjs-backend-cpu/src/kernels/Softplus.ts new file mode 100644 index 00000000000..104132ffe73 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Softplus.ts @@ -0,0 +1,56 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Softplus} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +// 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; + +export const softplusKernelFunc = unaryKernelFunc(Softplus, (x) => { + // Value above which exp(x) may overflow, but softplus(x) == x + // is within machine epsilon. + const tooLarge = x > -threshold; + + // Value below which exp(x) may underflow, but softplus(x) == exp(x) + // is within machine epsilon. + const tooSmall = x < threshold; + + const expX = Math.exp(x); + let result; + + if (tooSmall) { + result = expX; + } else if (tooLarge) { + result = x; + } else { + result = Math.log(1.0 + expX); + } + return result; +}); + +export const softplusConfig: KernelConfig = { + kernelName: Softplus, + backendName: 'cpu', + kernelFunc: softplusKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Sqrt.ts b/tfjs-backend-cpu/src/kernels/Sqrt.ts new file mode 100644 index 00000000000..cc8f685c67f --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Sqrt.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Sqrt} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const sqrtKernelFunc = unaryKernelFunc(Sqrt, (x) => Math.sqrt(x)); + +export const sqrtConfig: KernelConfig = { + kernelName: Sqrt, + backendName: 'cpu', + kernelFunc: sqrtKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Step.ts b/tfjs-backend-cpu/src/kernels/Step.ts new file mode 100644 index 00000000000..798460b168c --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Step.ts @@ -0,0 +1,35 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Step, StepAttrs} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const stepKernelFunc = unaryKernelFunc(Step, (x, attrs) => { + const stepAttrs = attrs as {} as StepAttrs; + if (isNaN(x)) { + return NaN; + } else { + return x > 0 ? 1 : stepAttrs.alpha; + } +}); + +export const stepConfig: KernelConfig = { + kernelName: Step, + backendName: 'cpu', + kernelFunc: stepKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Tan.ts b/tfjs-backend-cpu/src/kernels/Tan.ts new file mode 100644 index 00000000000..93a1bc2f918 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Tan.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Tan} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const tanKernelFunc = unaryKernelFunc(Tan, (x) => Math.tan(x)); + +export const tanConfig: KernelConfig = { + kernelName: Tan, + backendName: 'cpu', + kernelFunc: tanKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/kernels/Tanh.ts b/tfjs-backend-cpu/src/kernels/Tanh.ts new file mode 100644 index 00000000000..603b48ac6f5 --- /dev/null +++ b/tfjs-backend-cpu/src/kernels/Tanh.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {KernelConfig, Tanh} from '@tensorflow/tfjs-core'; + +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const tanhKernelFunc = unaryKernelFunc(Tanh, (x) => Math.tanh(x)); + +export const tanhConfig: KernelConfig = { + kernelName: Tanh, + backendName: 'cpu', + kernelFunc: tanhKernelFunc, +}; diff --git a/tfjs-backend-cpu/src/register_all_kernels.ts b/tfjs-backend-cpu/src/register_all_kernels.ts index 5051806001c..9403e7754aa 100644 --- a/tfjs-backend-cpu/src/register_all_kernels.ts +++ b/tfjs-backend-cpu/src/register_all_kernels.ts @@ -19,20 +19,41 @@ // the contents of this file and import only the kernels that are needed. import {KernelConfig, registerKernel} from '@tensorflow/tfjs-core'; +import {absConfig} from './kernels/Abs'; +import {acosConfig} from './kernels/Acos'; +import {acoshConfig} from './kernels/Acosh'; import {addConfig} from './kernels/Add'; +import {asinConfig} from './kernels/Asin'; +import {asinhConfig} from './kernels/Asinh'; +import {atanConfig} from './kernels/Atan'; +import {atanhConfig} from './kernels/Atanh'; import {castConfig} from './kernels/Cast'; +import {ceilConfig} from './kernels/Ceil'; +import {clipConfig} from './kernels/Clip'; import {complexConfig} from './kernels/Complex'; import {concatConfig} from './kernels/Concat'; import {cosConfig} from './kernels/Cos'; +import {coshConfig} from './kernels/Cosh'; import {dilation2dConfig} from './kernels/Dilation2D'; import {dilation2dBackpropFilterConfig} from './kernels/Dilation2DBackpropFilter'; import {dilation2dBackpropInputConfig} from './kernels/Dilation2DBackpropInput'; import {divConfig} from './kernels/Div'; +import {eluConfig} from './kernels/Elu'; +import {erfConfig} from './kernels/Erf'; +import {expConfig} from './kernels/Exp'; +import {expm1Config} from './kernels/Expm1'; import {fftConfig} from './kernels/FFT'; import {flipLeftRightConfig} from './kernels/FlipLeftRight'; +import {floorConfig} from './kernels/Floor'; import {identityConfig} from './kernels/Identity'; import {ifftConfig} from './kernels/IFFT'; import {imagConfig} from './kernels/Imag'; +import {isFiniteConfig} from './kernels/IsFinite'; +import {isInfConfig} from './kernels/IsInf'; +import {isNaNConfig} from './kernels/IsNaN'; +import {logConfig} from './kernels/Log'; +import {log1pConfig} from './kernels/Log1p'; +import {logicalNotConfig} from './kernels/LogicalNot'; import {maxConfig} from './kernels/Max'; import {maxPoolWithArgmaxConfig} from './kernels/MaxPoolWithArgmax'; import {multiplyConfig} from './kernels/Multiply'; @@ -41,31 +62,65 @@ import {nonMaxSuppressionV5Config} from './kernels/NonMaxSuppressionV5'; import {notEqualConfig} from './kernels/NotEqual'; import {padV2Config} from './kernels/PadV2'; import {realConfig} from './kernels/Real'; +import {reciprocalConfig} from './kernels/Reciprocal'; import {reshapeConfig} from './kernels/Reshape'; import {rotateWithOffsetConfig} from './kernels/RotateWithOffset'; +import {roundConfig} from './kernels/Round'; +import {rsqrtConfig} from './kernels/Rsqrt'; +import {seluConfig} from './kernels/Selu'; +import {sigmoidConfig} from './kernels/Sigmoid'; +import {signConfig} from './kernels/Sign'; +import {sinConfig} from './kernels/Sin'; +import {sinhConfig} from './kernels/Sinh'; import {sliceConfig} from './kernels/Slice'; +import {softplusConfig} from './kernels/Softplus'; import {spaceToBatchNDConfig} from './kernels/SpaceToBatchND'; +import {sqrtConfig} from './kernels/Sqrt'; import {squareConfig} from './kernels/Square'; import {squaredDifferenceConfig} from './kernels/SquaredDifference'; +import {stepConfig} from './kernels/Step'; import {subConfig} from './kernels/Sub'; +import {tanConfig} from './kernels/Tan'; +import {tanhConfig} from './kernels/Tanh'; import {transposeConfig} from './kernels/Transpose'; // List all kernel configs here const kernelConfigs: KernelConfig[] = [ + absConfig, + acosConfig, + acoshConfig, addConfig, + asinConfig, + asinhConfig, + atanConfig, + atanhConfig, castConfig, + ceilConfig, + clipConfig, complexConfig, concatConfig, cosConfig, + coshConfig, dilation2dConfig, dilation2dBackpropInputConfig, dilation2dBackpropFilterConfig, divConfig, + eluConfig, + erfConfig, + expConfig, + expm1Config, fftConfig, flipLeftRightConfig, + floorConfig, identityConfig, ifftConfig, imagConfig, + isFiniteConfig, + isInfConfig, + isNaNConfig, + logConfig, + log1pConfig, + logicalNotConfig, maxPoolWithArgmaxConfig, maxConfig, multiplyConfig, @@ -74,13 +129,26 @@ const kernelConfigs: KernelConfig[] = [ notEqualConfig, padV2Config, realConfig, + reciprocalConfig, reshapeConfig, rotateWithOffsetConfig, + roundConfig, + rsqrtConfig, + seluConfig, + sigmoidConfig, + signConfig, + sinConfig, + sinhConfig, sliceConfig, + softplusConfig, spaceToBatchNDConfig, + sqrtConfig, squareConfig, squaredDifferenceConfig, + stepConfig, subConfig, + tanConfig, + tanhConfig, transposeConfig ]; diff --git a/tfjs-backend-cpu/src/utils/binary_types.ts b/tfjs-backend-cpu/src/utils/binary_types.ts index ac0b01f2b17..1d34e3a1d46 100644 --- a/tfjs-backend-cpu/src/utils/binary_types.ts +++ b/tfjs-backend-cpu/src/utils/binary_types.ts @@ -15,8 +15,11 @@ * ============================================================================= */ -import {DataType, TypedArray} from '@tensorflow/tfjs-core'; +import {DataType, NamedAttrMap, TypedArray} from '@tensorflow/tfjs-core'; +export type SimpleUnaryOperation = (x: number, attrs?: NamedAttrMap) => number; +export type ComplexUnaryOperation = + (real: number, imag: number, attrs?: NamedAttrMap) => number; export type SimpleBinaryOperation = (a: number, b: number) => number; export type SimpleBinaryKernelImpl = (aShape: number[], bShape: number[], aVals: TypedArray, bVals: TypedArray, diff --git a/tfjs-backend-cpu/src/utils/kernel_utils.ts b/tfjs-backend-cpu/src/utils/kernel_utils.ts index 86d2f36cff1..992fb9f6a12 100644 --- a/tfjs-backend-cpu/src/utils/kernel_utils.ts +++ b/tfjs-backend-cpu/src/utils/kernel_utils.ts @@ -15,7 +15,7 @@ * ============================================================================= */ -import {backend_util, BinaryInputs, DataType, KernelFunc, TypedArray, util} from '@tensorflow/tfjs-core'; +import {backend_util, BinaryInputs, DataType, KernelFunc, TypedArray, UnaryInputs, util} from '@tensorflow/tfjs-core'; import {MathBackendCPU} from '../backend_cpu'; import {assertNotComplex} from '../cpu_util'; @@ -23,7 +23,44 @@ import {cast} from '../kernels/Cast'; import {complex} from '../kernels/Complex'; import {createSimpleBinaryKernelImpl} from './binary_impl'; -import {ComplexBinaryKernelImpl, ComplexBinaryOperation, SimpleBinaryOperation} from './binary_types'; +import {ComplexBinaryKernelImpl, ComplexBinaryOperation, ComplexUnaryOperation, SimpleBinaryOperation, SimpleUnaryOperation} from './binary_types'; + +/** + * 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 first input. This is mainly used in + * certain kernels that return bool type, such as isFinite, isInf, etc. + * @param opComplex A `ComplexUnaryOperation` for the kernel to handle complex64 + * inputs. + */ +export function unaryKernelFunc( + name: string, op: SimpleUnaryOperation, dtype?: DataType, + opComplex?: ComplexUnaryOperation): KernelFunc { + return ({inputs, attrs, backend}) => { + const {x} = inputs as UnaryInputs; + const cpuBackend = backend as MathBackendCPU; + + const values = cpuBackend.readSync(x.dataId) as TypedArray; + const xSize = util.sizeFromShape(x.shape); + const newValues = + dtype === 'bool' ? new Uint8Array(xSize) : new Float32Array(xSize); + if (x.dtype === 'complex64') { + util.assert( + opComplex !== undefined, () => `no complex op defined for ${name}`); + for (let i = 0; i < xSize; ++i) { + newValues[i] = opComplex(values[i * 2], values[i * 2 + 1], attrs); + } + } else { + assertNotComplex(x, name); + for (let i = 0; i < xSize; ++i) { + newValues[i] = op(values[i], attrs); + } + } + return cpuBackend.makeTensorInfo(x.shape, dtype || x.dtype, newValues); + }; +} /** * Template that creates a `KernelFunc` for binary ops. From 5c22c7446822ed574a98be590d6f822a2533fa8a Mon Sep 17 00:00:00 2001 From: Jing Jin <8752427+jinjingforever@users.noreply.github.com> Date: Fri, 18 Sep 2020 11:30:19 -0700 Subject: [PATCH 2/6] forgot to remove complexAbs --- tfjs-backend-cpu/src/backend_cpu.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tfjs-backend-cpu/src/backend_cpu.ts b/tfjs-backend-cpu/src/backend_cpu.ts index 1cf0e70aac2..9c8a40ab602 100644 --- a/tfjs-backend-cpu/src/backend_cpu.ts +++ b/tfjs-backend-cpu/src/backend_cpu.ts @@ -831,18 +831,6 @@ export class MathBackendCPU extends KernelBackend { return this.makeOutput(resultValues, y.shape, 'float32'); } - complexAbs(x: T): T { - const resultValues = new Float32Array(x.size); - const values = this.readSync(x.dataId) as TypedArray; - - for (let i = 0; i < x.size; ++i) { - const real = values[i * 2]; - const imag = values[i * 2 + 1]; - resultValues[i] = Math.hypot(real, imag); - } - return this.makeOutput(resultValues, x.shape, 'float32'); - } - atan2(a: T, b: T): T { assertNotComplex([a, b], 'atan2'); From 157f56a4b1e4c8f9f9b6f21ac4072087f96841c2 Mon Sep 17 00:00:00 2001 From: Jing Jin <8752427+jinjingforever@users.noreply.github.com> Date: Mon, 21 Sep 2020 15:18:48 -0700 Subject: [PATCH 3/6] address comments --- tfjs-backend-cpu/src/backend_cpu.ts | 2 +- tfjs-backend-cpu/src/kernels/Abs.ts | 36 ++++++++++++++++++--- tfjs-backend-cpu/src/kernels/Acos.ts | 2 +- tfjs-backend-cpu/src/kernels/Acosh.ts | 2 +- tfjs-backend-cpu/src/kernels/Asin.ts | 2 +- tfjs-backend-cpu/src/kernels/Asinh.ts | 2 +- tfjs-backend-cpu/src/kernels/Atan.ts | 2 +- tfjs-backend-cpu/src/kernels/Atanh.ts | 2 +- tfjs-backend-cpu/src/kernels/Ceil.ts | 2 +- tfjs-backend-cpu/src/kernels/Clip.ts | 9 +++--- tfjs-backend-cpu/src/kernels/Cosh.ts | 2 +- tfjs-backend-cpu/src/kernels/Elu.ts | 2 +- tfjs-backend-cpu/src/kernels/Erf.ts | 6 ++-- tfjs-backend-cpu/src/kernels/Exp.ts | 2 +- tfjs-backend-cpu/src/kernels/Expm1.ts | 2 +- tfjs-backend-cpu/src/kernels/Floor.ts | 2 +- tfjs-backend-cpu/src/kernels/IsFinite.ts | 2 +- tfjs-backend-cpu/src/kernels/IsInf.ts | 2 +- tfjs-backend-cpu/src/kernels/IsNaN.ts | 2 +- tfjs-backend-cpu/src/kernels/Log.ts | 2 +- tfjs-backend-cpu/src/kernels/Log1p.ts | 2 +- tfjs-backend-cpu/src/kernels/LogicalNot.ts | 2 +- tfjs-backend-cpu/src/kernels/Reciprocal.ts | 2 +- tfjs-backend-cpu/src/kernels/Round.ts | 12 +++---- tfjs-backend-cpu/src/kernels/Rsqrt.ts | 3 +- tfjs-backend-cpu/src/kernels/Selu.ts | 8 ++--- tfjs-backend-cpu/src/kernels/Sigmoid.ts | 2 +- tfjs-backend-cpu/src/kernels/Sign.ts | 6 ++-- tfjs-backend-cpu/src/kernels/Sin.ts | 2 +- tfjs-backend-cpu/src/kernels/Sinh.ts | 2 +- tfjs-backend-cpu/src/kernels/Softplus.ts | 10 +++--- tfjs-backend-cpu/src/kernels/Sqrt.ts | 2 +- tfjs-backend-cpu/src/kernels/Step.ts | 6 ++-- tfjs-backend-cpu/src/kernels/Tan.ts | 2 +- tfjs-backend-cpu/src/kernels/Tanh.ts | 2 +- tfjs-backend-cpu/src/utils/binary_types.ts | 5 +-- tfjs-backend-cpu/src/utils/kernel_utils.ts | 37 ++++++++++------------ tfjs-backend-cpu/src/utils/unary_types.ts | 20 ++++++++++++ 38 files changed, 125 insertions(+), 85 deletions(-) create mode 100644 tfjs-backend-cpu/src/utils/unary_types.ts diff --git a/tfjs-backend-cpu/src/backend_cpu.ts b/tfjs-backend-cpu/src/backend_cpu.ts index 9c8a40ab602..5c4cddec857 100644 --- a/tfjs-backend-cpu/src/backend_cpu.ts +++ b/tfjs-backend-cpu/src/backend_cpu.ts @@ -164,7 +164,7 @@ export class MathBackendCPU extends KernelBackend { return tf.buffer(t.shape, t.dtype, decodedData) as TensorBuffer; } - private makeOutput( + makeOutput( values: backend_util.BackendValues, shape: number[], dtype: DataType): T { const dataId = this.write(values, shape, dtype); return engine().makeTensorFromDataId(dataId, shape, dtype, this) as T; diff --git a/tfjs-backend-cpu/src/kernels/Abs.ts b/tfjs-backend-cpu/src/kernels/Abs.ts index cf2574041f9..63bed370e4e 100644 --- a/tfjs-backend-cpu/src/kernels/Abs.ts +++ b/tfjs-backend-cpu/src/kernels/Abs.ts @@ -15,15 +15,41 @@ * ============================================================================= */ -import {Abs, KernelConfig} from '@tensorflow/tfjs-core'; +import {Abs, AbsInputs, KernelConfig, KernelFunc, TypedArray, util} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {MathBackendCPU} from '../backend_cpu'; -export const absKernelFunc = unaryKernelFunc( - Abs, (x) => Math.abs(x), 'float32', (real, imag) => Math.hypot(real, imag)); +export const absKernelFunc = + (args: {inputs: AbsInputs, backend: MathBackendCPU}) => { + const {x} = args.inputs; + const cpuBackend = args.backend; + const resultValues = new Float32Array(util.sizeFromShape(x.shape)); + if (x.dtype !== 'complex64') { + const values = cpuBackend.data.get(x.dataId).values as TypedArray; + for (let i = 0; i < values.length; ++i) { + resultValues[i] = Math.abs(values[i]); + } + } else { + console.log('!!!!!!!!!!!!!!!'); + const complexVals = cpuBackend.data.get(x.dataId); + console.log(complexVals.complexTensorInfos.real); + const real = complexVals.complexTensorInfos.real; + const imag = complexVals.complexTensorInfos.imag; + const realVals = + cpuBackend.data.get(real.dataId).values as Float32Array; + const imagVals = + cpuBackend.data.get(imag.dataId).values as Float32Array; + 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'); + }; export const absConfig: KernelConfig = { kernelName: Abs, backendName: 'cpu', - kernelFunc: absKernelFunc, + kernelFunc: absKernelFunc as {} as KernelFunc, }; diff --git a/tfjs-backend-cpu/src/kernels/Acos.ts b/tfjs-backend-cpu/src/kernels/Acos.ts index 72911130411..43638efa118 100644 --- a/tfjs-backend-cpu/src/kernels/Acos.ts +++ b/tfjs-backend-cpu/src/kernels/Acos.ts @@ -19,7 +19,7 @@ import {Acos, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const acosKernelFunc = unaryKernelFunc(Acos, (x) => Math.acos(x)); +export const acosKernelFunc = unaryKernelFunc(Acos, (xi) => Math.acos(xi)); export const acosConfig: KernelConfig = { kernelName: Acos, diff --git a/tfjs-backend-cpu/src/kernels/Acosh.ts b/tfjs-backend-cpu/src/kernels/Acosh.ts index 56c709caf19..6ccda023cad 100644 --- a/tfjs-backend-cpu/src/kernels/Acosh.ts +++ b/tfjs-backend-cpu/src/kernels/Acosh.ts @@ -19,7 +19,7 @@ import {Acosh, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const acoshKernelFunc = unaryKernelFunc(Acosh, (x) => Math.acosh(x)); +export const acoshKernelFunc = unaryKernelFunc(Acosh, (xi) => Math.acosh(xi)); export const acoshConfig: KernelConfig = { kernelName: Acosh, diff --git a/tfjs-backend-cpu/src/kernels/Asin.ts b/tfjs-backend-cpu/src/kernels/Asin.ts index c64563f4ab5..662de03be77 100644 --- a/tfjs-backend-cpu/src/kernels/Asin.ts +++ b/tfjs-backend-cpu/src/kernels/Asin.ts @@ -19,7 +19,7 @@ import {Asin, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const asinKernelFunc = unaryKernelFunc(Asin, (x) => Math.asin(x)); +export const asinKernelFunc = unaryKernelFunc(Asin, (xi) => Math.asin(xi)); export const asinConfig: KernelConfig = { kernelName: Asin, diff --git a/tfjs-backend-cpu/src/kernels/Asinh.ts b/tfjs-backend-cpu/src/kernels/Asinh.ts index d2b69eda37e..6cf007fc3ef 100644 --- a/tfjs-backend-cpu/src/kernels/Asinh.ts +++ b/tfjs-backend-cpu/src/kernels/Asinh.ts @@ -19,7 +19,7 @@ import {Asinh, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const asinhKernelFunc = unaryKernelFunc(Asinh, (x) => Math.asinh(x)); +export const asinhKernelFunc = unaryKernelFunc(Asinh, (xi) => Math.asinh(xi)); export const asinhConfig: KernelConfig = { kernelName: Asinh, diff --git a/tfjs-backend-cpu/src/kernels/Atan.ts b/tfjs-backend-cpu/src/kernels/Atan.ts index 8f19548f37e..5da82b4de2c 100644 --- a/tfjs-backend-cpu/src/kernels/Atan.ts +++ b/tfjs-backend-cpu/src/kernels/Atan.ts @@ -19,7 +19,7 @@ import {Atan, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const atanKernelFunc = unaryKernelFunc(Atan, (x) => Math.atan(x)); +export const atanKernelFunc = unaryKernelFunc(Atan, (xi) => Math.atan(xi)); export const atanConfig: KernelConfig = { kernelName: Atan, diff --git a/tfjs-backend-cpu/src/kernels/Atanh.ts b/tfjs-backend-cpu/src/kernels/Atanh.ts index b8b39e16042..05cc4196fa9 100644 --- a/tfjs-backend-cpu/src/kernels/Atanh.ts +++ b/tfjs-backend-cpu/src/kernels/Atanh.ts @@ -19,7 +19,7 @@ import {Atanh, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const atanhKernelFunc = unaryKernelFunc(Atanh, (x) => Math.atanh(x)); +export const atanhKernelFunc = unaryKernelFunc(Atanh, (xi) => Math.atanh(xi)); export const atanhConfig: KernelConfig = { kernelName: Atanh, diff --git a/tfjs-backend-cpu/src/kernels/Ceil.ts b/tfjs-backend-cpu/src/kernels/Ceil.ts index 18d94006e9f..11f254a3080 100644 --- a/tfjs-backend-cpu/src/kernels/Ceil.ts +++ b/tfjs-backend-cpu/src/kernels/Ceil.ts @@ -19,7 +19,7 @@ import {Ceil, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const ceilKernelFunc = unaryKernelFunc(Ceil, (x) => Math.ceil(x)); +export const ceilKernelFunc = unaryKernelFunc(Ceil, (xi) => Math.ceil(xi)); export const ceilConfig: KernelConfig = { kernelName: Ceil, diff --git a/tfjs-backend-cpu/src/kernels/Clip.ts b/tfjs-backend-cpu/src/kernels/Clip.ts index 2b76c9c85f6..4ffadc0d9e3 100644 --- a/tfjs-backend-cpu/src/kernels/Clip.ts +++ b/tfjs-backend-cpu/src/kernels/Clip.ts @@ -19,11 +19,12 @@ import {ClipByValue, ClipByValueAttrs, KernelConfig} from '@tensorflow/tfjs-core import {unaryKernelFunc} from '../utils/kernel_utils'; -export const clipKernelFunc = unaryKernelFunc(ClipByValue, (x, attrs) => { +export const clipKernelFunc = unaryKernelFunc(ClipByValue, (xi, attrs) => { const clipAttrs = attrs as {} as ClipByValueAttrs; - return x > clipAttrs.clipValueMax ? - clipAttrs.clipValueMax : - (x < clipAttrs.clipValueMin ? clipAttrs.clipValueMin : x); + if (xi > clipAttrs.clipValueMax) { + return clipAttrs.clipValueMax; + } + return xi < clipAttrs.clipValueMin ? clipAttrs.clipValueMin : xi; }); export const clipConfig: KernelConfig = { diff --git a/tfjs-backend-cpu/src/kernels/Cosh.ts b/tfjs-backend-cpu/src/kernels/Cosh.ts index 95200be0d79..f6888083548 100644 --- a/tfjs-backend-cpu/src/kernels/Cosh.ts +++ b/tfjs-backend-cpu/src/kernels/Cosh.ts @@ -19,7 +19,7 @@ import {Cosh, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const coshKernelFunc = unaryKernelFunc(Cosh, (x) => Math.cosh(x)); +export const coshKernelFunc = unaryKernelFunc(Cosh, (xi) => Math.cosh(xi)); export const coshConfig: KernelConfig = { kernelName: Cosh, diff --git a/tfjs-backend-cpu/src/kernels/Elu.ts b/tfjs-backend-cpu/src/kernels/Elu.ts index 364b87deccd..230cc5d1658 100644 --- a/tfjs-backend-cpu/src/kernels/Elu.ts +++ b/tfjs-backend-cpu/src/kernels/Elu.ts @@ -20,7 +20,7 @@ import {Elu, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; export const eluKernelFunc = - unaryKernelFunc(Elu, (x) => x >= 0 ? x : (Math.exp(x) - 1)); + unaryKernelFunc(Elu, (xi) => xi >= 0 ? xi : (Math.exp(xi) - 1)); export const eluConfig: KernelConfig = { kernelName: Elu, diff --git a/tfjs-backend-cpu/src/kernels/Erf.ts b/tfjs-backend-cpu/src/kernels/Erf.ts index 77be4df1488..625c7c5ac0c 100644 --- a/tfjs-backend-cpu/src/kernels/Erf.ts +++ b/tfjs-backend-cpu/src/kernels/Erf.ts @@ -28,9 +28,9 @@ const a5 = backend_util.ERF_A5; export const erfKernelFunc = unaryKernelFunc( Erf, - (x) => { - const sign = Math.sign(x); - const v = Math.abs(x); + (xi) => { + const sign = Math.sign(xi); + const v = Math.abs(xi); const t = 1.0 / (1.0 + p * v); return sign * (1.0 - diff --git a/tfjs-backend-cpu/src/kernels/Exp.ts b/tfjs-backend-cpu/src/kernels/Exp.ts index e49e34a6f7c..4d64652fe24 100644 --- a/tfjs-backend-cpu/src/kernels/Exp.ts +++ b/tfjs-backend-cpu/src/kernels/Exp.ts @@ -19,7 +19,7 @@ import {Exp, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const expKernelFunc = unaryKernelFunc(Exp, (x) => Math.exp(x)); +export const expKernelFunc = unaryKernelFunc(Exp, (xi) => Math.exp(xi)); export const expConfig: KernelConfig = { kernelName: Exp, diff --git a/tfjs-backend-cpu/src/kernels/Expm1.ts b/tfjs-backend-cpu/src/kernels/Expm1.ts index c20f84d4950..cd049cc5256 100644 --- a/tfjs-backend-cpu/src/kernels/Expm1.ts +++ b/tfjs-backend-cpu/src/kernels/Expm1.ts @@ -19,7 +19,7 @@ import {Expm1, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const expm1KernelFunc = unaryKernelFunc(Expm1, (x) => Math.expm1(x)); +export const expm1KernelFunc = unaryKernelFunc(Expm1, (xi) => Math.expm1(xi)); export const expm1Config: KernelConfig = { kernelName: Expm1, diff --git a/tfjs-backend-cpu/src/kernels/Floor.ts b/tfjs-backend-cpu/src/kernels/Floor.ts index 9d48d8451f7..cdd715f80c1 100644 --- a/tfjs-backend-cpu/src/kernels/Floor.ts +++ b/tfjs-backend-cpu/src/kernels/Floor.ts @@ -19,7 +19,7 @@ import {Floor, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const floorKernelFunc = unaryKernelFunc(Floor, (x) => Math.floor(x)); +export const floorKernelFunc = unaryKernelFunc(Floor, (xi) => Math.floor(xi)); export const floorConfig: KernelConfig = { kernelName: Floor, diff --git a/tfjs-backend-cpu/src/kernels/IsFinite.ts b/tfjs-backend-cpu/src/kernels/IsFinite.ts index c5df7c3ab7b..6205900cd15 100644 --- a/tfjs-backend-cpu/src/kernels/IsFinite.ts +++ b/tfjs-backend-cpu/src/kernels/IsFinite.ts @@ -20,7 +20,7 @@ import {IsFinite, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; export const isFiniteKernelFunc = - unaryKernelFunc(IsFinite, (x) => Number.isFinite(x) ? 1 : 0, 'bool'); + unaryKernelFunc(IsFinite, (xi) => Number.isFinite(xi) ? 1 : 0, 'bool'); export const isFiniteConfig: KernelConfig = { kernelName: IsFinite, diff --git a/tfjs-backend-cpu/src/kernels/IsInf.ts b/tfjs-backend-cpu/src/kernels/IsInf.ts index d19154faedd..f72224f4e74 100644 --- a/tfjs-backend-cpu/src/kernels/IsInf.ts +++ b/tfjs-backend-cpu/src/kernels/IsInf.ts @@ -20,7 +20,7 @@ import {IsInf, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; export const isInfKernelFunc = - unaryKernelFunc(IsInf, (x) => Math.abs(x) === Infinity ? 1 : 0, 'bool'); + unaryKernelFunc(IsInf, (xi) => Math.abs(xi) === Infinity ? 1 : 0, 'bool'); export const isInfConfig: KernelConfig = { kernelName: IsInf, diff --git a/tfjs-backend-cpu/src/kernels/IsNaN.ts b/tfjs-backend-cpu/src/kernels/IsNaN.ts index dc84c0e2569..eee2b1dadc5 100644 --- a/tfjs-backend-cpu/src/kernels/IsNaN.ts +++ b/tfjs-backend-cpu/src/kernels/IsNaN.ts @@ -20,7 +20,7 @@ import {IsNan, KernelConfig} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; export const isNaNKernelFunc = - unaryKernelFunc(IsNan, (x) => Number.isNaN(x) ? 1 : 0, 'bool'); + unaryKernelFunc(IsNan, (xi) => Number.isNaN(xi) ? 1 : 0, 'bool'); export const isNaNConfig: KernelConfig = { kernelName: IsNan, diff --git a/tfjs-backend-cpu/src/kernels/Log.ts b/tfjs-backend-cpu/src/kernels/Log.ts index 45bd0d9cc6a..a1fe3be7e6f 100644 --- a/tfjs-backend-cpu/src/kernels/Log.ts +++ b/tfjs-backend-cpu/src/kernels/Log.ts @@ -19,7 +19,7 @@ import {KernelConfig, Log} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const logKernelFunc = unaryKernelFunc(Log, (x) => Math.log(x)); +export const logKernelFunc = unaryKernelFunc(Log, (xi) => Math.log(xi)); export const logConfig: KernelConfig = { kernelName: Log, diff --git a/tfjs-backend-cpu/src/kernels/Log1p.ts b/tfjs-backend-cpu/src/kernels/Log1p.ts index e17e5ae3224..453688c70d3 100644 --- a/tfjs-backend-cpu/src/kernels/Log1p.ts +++ b/tfjs-backend-cpu/src/kernels/Log1p.ts @@ -19,7 +19,7 @@ import {KernelConfig, Log1p} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const log1pKernelFunc = unaryKernelFunc(Log1p, (x) => Math.log1p(x)); +export const log1pKernelFunc = unaryKernelFunc(Log1p, (xi) => Math.log1p(xi)); export const log1pConfig: KernelConfig = { kernelName: Log1p, diff --git a/tfjs-backend-cpu/src/kernels/LogicalNot.ts b/tfjs-backend-cpu/src/kernels/LogicalNot.ts index 890b226cfc3..0be980ab3c2 100644 --- a/tfjs-backend-cpu/src/kernels/LogicalNot.ts +++ b/tfjs-backend-cpu/src/kernels/LogicalNot.ts @@ -20,7 +20,7 @@ import {KernelConfig, LogicalNot} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; export const logicalNotKernelFunc = - unaryKernelFunc(LogicalNot, (x) => x ? 0 : 1, 'bool'); + unaryKernelFunc(LogicalNot, (xi) => xi ? 0 : 1, 'bool'); export const logicalNotConfig: KernelConfig = { kernelName: LogicalNot, diff --git a/tfjs-backend-cpu/src/kernels/Reciprocal.ts b/tfjs-backend-cpu/src/kernels/Reciprocal.ts index 65817724754..ed024d460aa 100644 --- a/tfjs-backend-cpu/src/kernels/Reciprocal.ts +++ b/tfjs-backend-cpu/src/kernels/Reciprocal.ts @@ -19,7 +19,7 @@ import {KernelConfig, Reciprocal} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const reciprocalKernelFunc = unaryKernelFunc(Reciprocal, (x) => 1 / x); +export const reciprocalKernelFunc = unaryKernelFunc(Reciprocal, (xi) => 1 / xi); export const reciprocalConfig: KernelConfig = { kernelName: Reciprocal, diff --git a/tfjs-backend-cpu/src/kernels/Round.ts b/tfjs-backend-cpu/src/kernels/Round.ts index a3dc07f39f6..cb7ce746901 100644 --- a/tfjs-backend-cpu/src/kernels/Round.ts +++ b/tfjs-backend-cpu/src/kernels/Round.ts @@ -19,13 +19,13 @@ import {KernelConfig, Round} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const roundKernelFunc = unaryKernelFunc(Round, (x) => { +export const roundKernelFunc = unaryKernelFunc(Round, (xi) => { // The algorithm is based on banker's rounding. - const base = Math.floor(x); - if (x - base < 0.5) { - return Math.floor(x); - } else if (x - base > 0.5) { - return Math.ceil(x); + 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; diff --git a/tfjs-backend-cpu/src/kernels/Rsqrt.ts b/tfjs-backend-cpu/src/kernels/Rsqrt.ts index 72837f927b9..a5718cae8d6 100644 --- a/tfjs-backend-cpu/src/kernels/Rsqrt.ts +++ b/tfjs-backend-cpu/src/kernels/Rsqrt.ts @@ -19,7 +19,8 @@ import {KernelConfig, Rsqrt} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const rsqrtKernelFunc = unaryKernelFunc(Rsqrt, (x) => 1 / Math.sqrt(x)); +export const rsqrtKernelFunc = + unaryKernelFunc(Rsqrt, (xi) => 1 / Math.sqrt(xi)); export const rsqrtConfig: KernelConfig = { kernelName: Rsqrt, diff --git a/tfjs-backend-cpu/src/kernels/Selu.ts b/tfjs-backend-cpu/src/kernels/Selu.ts index d41b90d5a49..f9701692987 100644 --- a/tfjs-backend-cpu/src/kernels/Selu.ts +++ b/tfjs-backend-cpu/src/kernels/Selu.ts @@ -22,11 +22,11 @@ import {unaryKernelFunc} from '../utils/kernel_utils'; const scaleAlpha = backend_util.SELU_SCALEALPHA; const scale = backend_util.SELU_SCALE; -export const seluKernelFunc = unaryKernelFunc(Selu, (x) => { - if (x >= 0) { - return scale * x; +export const seluKernelFunc = unaryKernelFunc(Selu, (xi) => { + if (xi >= 0) { + return scale * xi; } else { - return scaleAlpha * (Math.exp(x) - 1); + return scaleAlpha * (Math.exp(xi) - 1); } }); diff --git a/tfjs-backend-cpu/src/kernels/Sigmoid.ts b/tfjs-backend-cpu/src/kernels/Sigmoid.ts index 569545bcfca..ecebce921c1 100644 --- a/tfjs-backend-cpu/src/kernels/Sigmoid.ts +++ b/tfjs-backend-cpu/src/kernels/Sigmoid.ts @@ -20,7 +20,7 @@ import {KernelConfig, Sigmoid} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; export const sigmoidKernelFunc = - unaryKernelFunc(Sigmoid, (x) => 1 / (1 + Math.exp(-x))); + unaryKernelFunc(Sigmoid, (xi) => 1 / (1 + Math.exp(-xi))); export const sigmoidConfig: KernelConfig = { kernelName: Sigmoid, diff --git a/tfjs-backend-cpu/src/kernels/Sign.ts b/tfjs-backend-cpu/src/kernels/Sign.ts index f8adba453da..ca38397b570 100644 --- a/tfjs-backend-cpu/src/kernels/Sign.ts +++ b/tfjs-backend-cpu/src/kernels/Sign.ts @@ -19,10 +19,10 @@ import {KernelConfig, Sign} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const signKernelFunc = unaryKernelFunc(Sign, (x) => { - if (x < 0) { +export const signKernelFunc = unaryKernelFunc(Sign, (xi) => { + if (xi < 0) { return -1; - } else if (x > 0) { + } else if (xi > 0) { return 1; } else { return 0; diff --git a/tfjs-backend-cpu/src/kernels/Sin.ts b/tfjs-backend-cpu/src/kernels/Sin.ts index 7ec83b7cda7..712a51f01fd 100644 --- a/tfjs-backend-cpu/src/kernels/Sin.ts +++ b/tfjs-backend-cpu/src/kernels/Sin.ts @@ -19,7 +19,7 @@ import {KernelConfig, Sin} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const sinKernelFunc = unaryKernelFunc(Sin, (x) => Math.sin(x)); +export const sinKernelFunc = unaryKernelFunc(Sin, (xi) => Math.sin(xi)); export const sinConfig: KernelConfig = { kernelName: Sin, diff --git a/tfjs-backend-cpu/src/kernels/Sinh.ts b/tfjs-backend-cpu/src/kernels/Sinh.ts index 4cbfbeee6a9..99d4cfdda83 100644 --- a/tfjs-backend-cpu/src/kernels/Sinh.ts +++ b/tfjs-backend-cpu/src/kernels/Sinh.ts @@ -19,7 +19,7 @@ import {KernelConfig, Sinh} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const sinhKernelFunc = unaryKernelFunc(Sinh, (x) => Math.sinh(x)); +export const sinhKernelFunc = unaryKernelFunc(Sinh, (xi) => Math.sinh(xi)); export const sinhConfig: KernelConfig = { kernelName: Sinh, diff --git a/tfjs-backend-cpu/src/kernels/Softplus.ts b/tfjs-backend-cpu/src/kernels/Softplus.ts index 104132ffe73..3b008ff4aea 100644 --- a/tfjs-backend-cpu/src/kernels/Softplus.ts +++ b/tfjs-backend-cpu/src/kernels/Softplus.ts @@ -27,22 +27,22 @@ import {unaryKernelFunc} from '../utils/kernel_utils'; const epsilon = 1.1920928955078125e-7; const threshold = Math.log(epsilon) + 2.0; -export const softplusKernelFunc = unaryKernelFunc(Softplus, (x) => { +export const softplusKernelFunc = unaryKernelFunc(Softplus, (xi) => { // Value above which exp(x) may overflow, but softplus(x) == x // is within machine epsilon. - const tooLarge = x > -threshold; + const tooLarge = xi > -threshold; // Value below which exp(x) may underflow, but softplus(x) == exp(x) // is within machine epsilon. - const tooSmall = x < threshold; + const tooSmall = xi < threshold; - const expX = Math.exp(x); + const expX = Math.exp(xi); let result; if (tooSmall) { result = expX; } else if (tooLarge) { - result = x; + result = xi; } else { result = Math.log(1.0 + expX); } diff --git a/tfjs-backend-cpu/src/kernels/Sqrt.ts b/tfjs-backend-cpu/src/kernels/Sqrt.ts index cc8f685c67f..95f8467582e 100644 --- a/tfjs-backend-cpu/src/kernels/Sqrt.ts +++ b/tfjs-backend-cpu/src/kernels/Sqrt.ts @@ -19,7 +19,7 @@ import {KernelConfig, Sqrt} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const sqrtKernelFunc = unaryKernelFunc(Sqrt, (x) => Math.sqrt(x)); +export const sqrtKernelFunc = unaryKernelFunc(Sqrt, (xi) => Math.sqrt(xi)); export const sqrtConfig: KernelConfig = { kernelName: Sqrt, diff --git a/tfjs-backend-cpu/src/kernels/Step.ts b/tfjs-backend-cpu/src/kernels/Step.ts index 798460b168c..7c4eb061f66 100644 --- a/tfjs-backend-cpu/src/kernels/Step.ts +++ b/tfjs-backend-cpu/src/kernels/Step.ts @@ -19,12 +19,12 @@ import {KernelConfig, Step, StepAttrs} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const stepKernelFunc = unaryKernelFunc(Step, (x, attrs) => { +export const stepKernelFunc = unaryKernelFunc(Step, (xi, attrs) => { const stepAttrs = attrs as {} as StepAttrs; - if (isNaN(x)) { + if (isNaN(xi)) { return NaN; } else { - return x > 0 ? 1 : stepAttrs.alpha; + return xi > 0 ? 1 : stepAttrs.alpha; } }); diff --git a/tfjs-backend-cpu/src/kernels/Tan.ts b/tfjs-backend-cpu/src/kernels/Tan.ts index 93a1bc2f918..9547667c1cc 100644 --- a/tfjs-backend-cpu/src/kernels/Tan.ts +++ b/tfjs-backend-cpu/src/kernels/Tan.ts @@ -19,7 +19,7 @@ import {KernelConfig, Tan} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const tanKernelFunc = unaryKernelFunc(Tan, (x) => Math.tan(x)); +export const tanKernelFunc = unaryKernelFunc(Tan, (xi) => Math.tan(xi)); export const tanConfig: KernelConfig = { kernelName: Tan, diff --git a/tfjs-backend-cpu/src/kernels/Tanh.ts b/tfjs-backend-cpu/src/kernels/Tanh.ts index 603b48ac6f5..cb5bf76e58e 100644 --- a/tfjs-backend-cpu/src/kernels/Tanh.ts +++ b/tfjs-backend-cpu/src/kernels/Tanh.ts @@ -19,7 +19,7 @@ import {KernelConfig, Tanh} from '@tensorflow/tfjs-core'; import {unaryKernelFunc} from '../utils/kernel_utils'; -export const tanhKernelFunc = unaryKernelFunc(Tanh, (x) => Math.tanh(x)); +export const tanhKernelFunc = unaryKernelFunc(Tanh, (xi) => Math.tanh(xi)); export const tanhConfig: KernelConfig = { kernelName: Tanh, diff --git a/tfjs-backend-cpu/src/utils/binary_types.ts b/tfjs-backend-cpu/src/utils/binary_types.ts index 1d34e3a1d46..ac0b01f2b17 100644 --- a/tfjs-backend-cpu/src/utils/binary_types.ts +++ b/tfjs-backend-cpu/src/utils/binary_types.ts @@ -15,11 +15,8 @@ * ============================================================================= */ -import {DataType, NamedAttrMap, TypedArray} from '@tensorflow/tfjs-core'; +import {DataType, TypedArray} from '@tensorflow/tfjs-core'; -export type SimpleUnaryOperation = (x: number, attrs?: NamedAttrMap) => number; -export type ComplexUnaryOperation = - (real: number, imag: number, attrs?: NamedAttrMap) => number; export type SimpleBinaryOperation = (a: number, b: number) => number; export type SimpleBinaryKernelImpl = (aShape: number[], bShape: number[], aVals: TypedArray, bVals: TypedArray, diff --git a/tfjs-backend-cpu/src/utils/kernel_utils.ts b/tfjs-backend-cpu/src/utils/kernel_utils.ts index 992fb9f6a12..eff5df463ec 100644 --- a/tfjs-backend-cpu/src/utils/kernel_utils.ts +++ b/tfjs-backend-cpu/src/utils/kernel_utils.ts @@ -23,42 +23,37 @@ import {cast} from '../kernels/Cast'; import {complex} from '../kernels/Complex'; import {createSimpleBinaryKernelImpl} from './binary_impl'; -import {ComplexBinaryKernelImpl, ComplexBinaryOperation, ComplexUnaryOperation, SimpleBinaryOperation, SimpleUnaryOperation} from './binary_types'; +import {ComplexBinaryKernelImpl, ComplexBinaryOperation, SimpleBinaryOperation} from './binary_types'; +import {SimpleUnaryOperation} from './unary_types'; /** * 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 first input. This is mainly used in - * certain kernels that return bool type, such as isFinite, isInf, etc. + * result has the same dtype as the input. This is mainly used in certain + * kernels that return bool type, such as isFinite, isInf, etc. * @param opComplex A `ComplexUnaryOperation` for the kernel to handle complex64 * inputs. */ export function unaryKernelFunc( - name: string, op: SimpleUnaryOperation, dtype?: DataType, - opComplex?: ComplexUnaryOperation): KernelFunc { + name: string, op: SimpleUnaryOperation, dtype?: DataType): KernelFunc { return ({inputs, attrs, backend}) => { const {x} = inputs as UnaryInputs; - const cpuBackend = backend as MathBackendCPU; + assertNotComplex(x, name); + if (x.dtype === 'string' || dtype === 'string') { + throw new Error('unaryKernelFunc does not support string input/output'); + } - const values = cpuBackend.readSync(x.dataId) as TypedArray; + const cpuBackend = backend as MathBackendCPU; + const values = cpuBackend.data.get(x.dataId).values as TypedArray; const xSize = util.sizeFromShape(x.shape); - const newValues = - dtype === 'bool' ? new Uint8Array(xSize) : new Float32Array(xSize); - if (x.dtype === 'complex64') { - util.assert( - opComplex !== undefined, () => `no complex op defined for ${name}`); - for (let i = 0; i < xSize; ++i) { - newValues[i] = opComplex(values[i * 2], values[i * 2 + 1], attrs); - } - } else { - assertNotComplex(x, name); - for (let i = 0; i < xSize; ++i) { - newValues[i] = op(values[i], attrs); - } + const $dtype = dtype || x.dtype; + const newValues = util.getArrayFromDType($dtype, xSize); + for (let i = 0; i < xSize; ++i) { + newValues[i] = op(values[i], attrs); } - return cpuBackend.makeTensorInfo(x.shape, dtype || x.dtype, newValues); + return cpuBackend.makeTensorInfo(x.shape, $dtype, newValues); }; } diff --git a/tfjs-backend-cpu/src/utils/unary_types.ts b/tfjs-backend-cpu/src/utils/unary_types.ts new file mode 100644 index 00000000000..0c411da817e --- /dev/null +++ b/tfjs-backend-cpu/src/utils/unary_types.ts @@ -0,0 +1,20 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {NamedAttrMap} from '@tensorflow/tfjs-core'; + +export type SimpleUnaryOperation = (x: number, attrs?: NamedAttrMap) => number; From a052543af324b37e506dde21cbb141ed3349543d Mon Sep 17 00:00:00 2001 From: Jing Jin <8752427+jinjingforever@users.noreply.github.com> Date: Mon, 21 Sep 2020 15:19:34 -0700 Subject: [PATCH 4/6] remove console.log --- tfjs-backend-cpu/src/kernels/Abs.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/tfjs-backend-cpu/src/kernels/Abs.ts b/tfjs-backend-cpu/src/kernels/Abs.ts index 63bed370e4e..c8cc06ecb93 100644 --- a/tfjs-backend-cpu/src/kernels/Abs.ts +++ b/tfjs-backend-cpu/src/kernels/Abs.ts @@ -30,9 +30,7 @@ export const absKernelFunc = resultValues[i] = Math.abs(values[i]); } } else { - console.log('!!!!!!!!!!!!!!!'); const complexVals = cpuBackend.data.get(x.dataId); - console.log(complexVals.complexTensorInfos.real); const real = complexVals.complexTensorInfos.real; const imag = complexVals.complexTensorInfos.imag; const realVals = From a6056dcccc8047533c228233a25b6b598891653b Mon Sep 17 00:00:00 2001 From: Jing Jin <8752427+jinjingforever@users.noreply.github.com> Date: Mon, 21 Sep 2020 15:29:04 -0700 Subject: [PATCH 5/6] add cos --- tfjs-backend-cpu/src/kernels/Cos.ts | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/tfjs-backend-cpu/src/kernels/Cos.ts b/tfjs-backend-cpu/src/kernels/Cos.ts index 3e57b5b5d46..2ad84e78e1b 100644 --- a/tfjs-backend-cpu/src/kernels/Cos.ts +++ b/tfjs-backend-cpu/src/kernels/Cos.ts @@ -15,26 +15,14 @@ * ============================================================================= */ -import {Cos, CosInputs, KernelConfig, TypedArray, util} from '@tensorflow/tfjs-core'; +import {Cos, KernelConfig} from '@tensorflow/tfjs-core'; -import {MathBackendCPU} from '../backend_cpu'; -import {assertNotComplex} from '../cpu_util'; +import {unaryKernelFunc} from '../utils/kernel_utils'; + +export const cosKernelFunc = unaryKernelFunc(Cos, (xi) => Math.cos(xi)); export const cosConfig: KernelConfig = { kernelName: Cos, backendName: 'cpu', - kernelFunc: ({inputs, backend}) => { - const {x} = inputs as CosInputs; - const cpuBackend = backend as MathBackendCPU; - assertNotComplex(x, 'cos'); - - const values = cpuBackend.data.get(x.dataId).values as TypedArray; - const xSize = util.sizeFromShape(x.shape); - const newValues = new Float32Array(xSize); - for (let i = 0; i < xSize; ++i) { - newValues[i] = Math.cos(values[i]); - } - const dataId = cpuBackend.write(newValues, x.shape, x.dtype); - return {dataId, shape: x.shape, dtype: x.dtype}; - } + kernelFunc: cosKernelFunc, }; From b85d821e88aa5b00d65ba78246834ab7d0a47dcc Mon Sep 17 00:00:00 2001 From: Jing Jin <8752427+jinjingforever@users.noreply.github.com> Date: Tue, 22 Sep 2020 09:09:47 -0700 Subject: [PATCH 6/6] unary_util --- tfjs-backend-cpu/src/kernels/Acos.ts | 2 +- tfjs-backend-cpu/src/kernels/Acosh.ts | 2 +- tfjs-backend-cpu/src/kernels/Asin.ts | 2 +- tfjs-backend-cpu/src/kernels/Asinh.ts | 2 +- tfjs-backend-cpu/src/kernels/Atan.ts | 2 +- tfjs-backend-cpu/src/kernels/Atanh.ts | 2 +- tfjs-backend-cpu/src/kernels/Ceil.ts | 2 +- tfjs-backend-cpu/src/kernels/Clip.ts | 2 +- tfjs-backend-cpu/src/kernels/Cos.ts | 2 +- tfjs-backend-cpu/src/kernels/Cosh.ts | 2 +- tfjs-backend-cpu/src/kernels/Elu.ts | 2 +- tfjs-backend-cpu/src/kernels/Erf.ts | 2 +- tfjs-backend-cpu/src/kernels/Exp.ts | 2 +- tfjs-backend-cpu/src/kernels/Expm1.ts | 2 +- tfjs-backend-cpu/src/kernels/Floor.ts | 2 +- tfjs-backend-cpu/src/kernels/IsFinite.ts | 2 +- tfjs-backend-cpu/src/kernels/IsInf.ts | 2 +- tfjs-backend-cpu/src/kernels/IsNaN.ts | 2 +- tfjs-backend-cpu/src/kernels/Log.ts | 2 +- tfjs-backend-cpu/src/kernels/Log1p.ts | 2 +- tfjs-backend-cpu/src/kernels/LogicalNot.ts | 2 +- tfjs-backend-cpu/src/kernels/Reciprocal.ts | 2 +- tfjs-backend-cpu/src/kernels/Round.ts | 2 +- tfjs-backend-cpu/src/kernels/Rsqrt.ts | 2 +- tfjs-backend-cpu/src/kernels/Selu.ts | 2 +- tfjs-backend-cpu/src/kernels/Sigmoid.ts | 2 +- tfjs-backend-cpu/src/kernels/Sign.ts | 2 +- tfjs-backend-cpu/src/kernels/Sin.ts | 2 +- tfjs-backend-cpu/src/kernels/Sinh.ts | 2 +- tfjs-backend-cpu/src/kernels/Softplus.ts | 2 +- tfjs-backend-cpu/src/kernels/Sqrt.ts | 2 +- tfjs-backend-cpu/src/kernels/Step.ts | 2 +- tfjs-backend-cpu/src/kernels/Tan.ts | 2 +- tfjs-backend-cpu/src/kernels/Tanh.ts | 2 +- tfjs-backend-cpu/src/utils/kernel_utils.ts | 34 +------------- tfjs-backend-cpu/src/utils/unary_utils.ts | 54 ++++++++++++++++++++++ 36 files changed, 89 insertions(+), 67 deletions(-) create mode 100644 tfjs-backend-cpu/src/utils/unary_utils.ts diff --git a/tfjs-backend-cpu/src/kernels/Acos.ts b/tfjs-backend-cpu/src/kernels/Acos.ts index 43638efa118..8f64f517117 100644 --- a/tfjs-backend-cpu/src/kernels/Acos.ts +++ b/tfjs-backend-cpu/src/kernels/Acos.ts @@ -17,7 +17,7 @@ import {Acos, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const acosKernelFunc = unaryKernelFunc(Acos, (xi) => Math.acos(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Acosh.ts b/tfjs-backend-cpu/src/kernels/Acosh.ts index 6ccda023cad..e3371a18aa1 100644 --- a/tfjs-backend-cpu/src/kernels/Acosh.ts +++ b/tfjs-backend-cpu/src/kernels/Acosh.ts @@ -17,7 +17,7 @@ import {Acosh, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const acoshKernelFunc = unaryKernelFunc(Acosh, (xi) => Math.acosh(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Asin.ts b/tfjs-backend-cpu/src/kernels/Asin.ts index 662de03be77..6db150bf19f 100644 --- a/tfjs-backend-cpu/src/kernels/Asin.ts +++ b/tfjs-backend-cpu/src/kernels/Asin.ts @@ -17,7 +17,7 @@ import {Asin, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const asinKernelFunc = unaryKernelFunc(Asin, (xi) => Math.asin(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Asinh.ts b/tfjs-backend-cpu/src/kernels/Asinh.ts index 6cf007fc3ef..253d1256bcf 100644 --- a/tfjs-backend-cpu/src/kernels/Asinh.ts +++ b/tfjs-backend-cpu/src/kernels/Asinh.ts @@ -17,7 +17,7 @@ import {Asinh, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const asinhKernelFunc = unaryKernelFunc(Asinh, (xi) => Math.asinh(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Atan.ts b/tfjs-backend-cpu/src/kernels/Atan.ts index 5da82b4de2c..37ee01a8fe7 100644 --- a/tfjs-backend-cpu/src/kernels/Atan.ts +++ b/tfjs-backend-cpu/src/kernels/Atan.ts @@ -17,7 +17,7 @@ import {Atan, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const atanKernelFunc = unaryKernelFunc(Atan, (xi) => Math.atan(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Atanh.ts b/tfjs-backend-cpu/src/kernels/Atanh.ts index 05cc4196fa9..f0cd938852c 100644 --- a/tfjs-backend-cpu/src/kernels/Atanh.ts +++ b/tfjs-backend-cpu/src/kernels/Atanh.ts @@ -17,7 +17,7 @@ import {Atanh, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const atanhKernelFunc = unaryKernelFunc(Atanh, (xi) => Math.atanh(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Ceil.ts b/tfjs-backend-cpu/src/kernels/Ceil.ts index 11f254a3080..a714d6fc622 100644 --- a/tfjs-backend-cpu/src/kernels/Ceil.ts +++ b/tfjs-backend-cpu/src/kernels/Ceil.ts @@ -17,7 +17,7 @@ import {Ceil, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const ceilKernelFunc = unaryKernelFunc(Ceil, (xi) => Math.ceil(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Clip.ts b/tfjs-backend-cpu/src/kernels/Clip.ts index 4ffadc0d9e3..ec97f84cff2 100644 --- a/tfjs-backend-cpu/src/kernels/Clip.ts +++ b/tfjs-backend-cpu/src/kernels/Clip.ts @@ -17,7 +17,7 @@ import {ClipByValue, ClipByValueAttrs, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const clipKernelFunc = unaryKernelFunc(ClipByValue, (xi, attrs) => { const clipAttrs = attrs as {} as ClipByValueAttrs; diff --git a/tfjs-backend-cpu/src/kernels/Cos.ts b/tfjs-backend-cpu/src/kernels/Cos.ts index 2ad84e78e1b..2c12eef242c 100644 --- a/tfjs-backend-cpu/src/kernels/Cos.ts +++ b/tfjs-backend-cpu/src/kernels/Cos.ts @@ -17,7 +17,7 @@ import {Cos, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const cosKernelFunc = unaryKernelFunc(Cos, (xi) => Math.cos(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Cosh.ts b/tfjs-backend-cpu/src/kernels/Cosh.ts index f6888083548..572dcbb9ee1 100644 --- a/tfjs-backend-cpu/src/kernels/Cosh.ts +++ b/tfjs-backend-cpu/src/kernels/Cosh.ts @@ -17,7 +17,7 @@ import {Cosh, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const coshKernelFunc = unaryKernelFunc(Cosh, (xi) => Math.cosh(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Elu.ts b/tfjs-backend-cpu/src/kernels/Elu.ts index 230cc5d1658..f93fcd107f3 100644 --- a/tfjs-backend-cpu/src/kernels/Elu.ts +++ b/tfjs-backend-cpu/src/kernels/Elu.ts @@ -17,7 +17,7 @@ import {Elu, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const eluKernelFunc = unaryKernelFunc(Elu, (xi) => xi >= 0 ? xi : (Math.exp(xi) - 1)); diff --git a/tfjs-backend-cpu/src/kernels/Erf.ts b/tfjs-backend-cpu/src/kernels/Erf.ts index 625c7c5ac0c..c3bda037f77 100644 --- a/tfjs-backend-cpu/src/kernels/Erf.ts +++ b/tfjs-backend-cpu/src/kernels/Erf.ts @@ -17,7 +17,7 @@ import {backend_util, Erf, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; const p = backend_util.ERF_P; const a1 = backend_util.ERF_A1; diff --git a/tfjs-backend-cpu/src/kernels/Exp.ts b/tfjs-backend-cpu/src/kernels/Exp.ts index 4d64652fe24..c8e0acfd327 100644 --- a/tfjs-backend-cpu/src/kernels/Exp.ts +++ b/tfjs-backend-cpu/src/kernels/Exp.ts @@ -17,7 +17,7 @@ import {Exp, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const expKernelFunc = unaryKernelFunc(Exp, (xi) => Math.exp(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Expm1.ts b/tfjs-backend-cpu/src/kernels/Expm1.ts index cd049cc5256..0ee7ac706b7 100644 --- a/tfjs-backend-cpu/src/kernels/Expm1.ts +++ b/tfjs-backend-cpu/src/kernels/Expm1.ts @@ -17,7 +17,7 @@ import {Expm1, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const expm1KernelFunc = unaryKernelFunc(Expm1, (xi) => Math.expm1(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Floor.ts b/tfjs-backend-cpu/src/kernels/Floor.ts index cdd715f80c1..6613239cbb5 100644 --- a/tfjs-backend-cpu/src/kernels/Floor.ts +++ b/tfjs-backend-cpu/src/kernels/Floor.ts @@ -17,7 +17,7 @@ import {Floor, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const floorKernelFunc = unaryKernelFunc(Floor, (xi) => Math.floor(xi)); diff --git a/tfjs-backend-cpu/src/kernels/IsFinite.ts b/tfjs-backend-cpu/src/kernels/IsFinite.ts index 6205900cd15..7fd5ef7ecfd 100644 --- a/tfjs-backend-cpu/src/kernels/IsFinite.ts +++ b/tfjs-backend-cpu/src/kernels/IsFinite.ts @@ -17,7 +17,7 @@ import {IsFinite, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const isFiniteKernelFunc = unaryKernelFunc(IsFinite, (xi) => Number.isFinite(xi) ? 1 : 0, 'bool'); diff --git a/tfjs-backend-cpu/src/kernels/IsInf.ts b/tfjs-backend-cpu/src/kernels/IsInf.ts index f72224f4e74..27d86afd9a2 100644 --- a/tfjs-backend-cpu/src/kernels/IsInf.ts +++ b/tfjs-backend-cpu/src/kernels/IsInf.ts @@ -17,7 +17,7 @@ import {IsInf, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const isInfKernelFunc = unaryKernelFunc(IsInf, (xi) => Math.abs(xi) === Infinity ? 1 : 0, 'bool'); diff --git a/tfjs-backend-cpu/src/kernels/IsNaN.ts b/tfjs-backend-cpu/src/kernels/IsNaN.ts index eee2b1dadc5..44ef8d19c8c 100644 --- a/tfjs-backend-cpu/src/kernels/IsNaN.ts +++ b/tfjs-backend-cpu/src/kernels/IsNaN.ts @@ -17,7 +17,7 @@ import {IsNan, KernelConfig} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const isNaNKernelFunc = unaryKernelFunc(IsNan, (xi) => Number.isNaN(xi) ? 1 : 0, 'bool'); diff --git a/tfjs-backend-cpu/src/kernels/Log.ts b/tfjs-backend-cpu/src/kernels/Log.ts index a1fe3be7e6f..a1ced04d4a4 100644 --- a/tfjs-backend-cpu/src/kernels/Log.ts +++ b/tfjs-backend-cpu/src/kernels/Log.ts @@ -17,7 +17,7 @@ import {KernelConfig, Log} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const logKernelFunc = unaryKernelFunc(Log, (xi) => Math.log(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Log1p.ts b/tfjs-backend-cpu/src/kernels/Log1p.ts index 453688c70d3..b5549642a26 100644 --- a/tfjs-backend-cpu/src/kernels/Log1p.ts +++ b/tfjs-backend-cpu/src/kernels/Log1p.ts @@ -17,7 +17,7 @@ import {KernelConfig, Log1p} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const log1pKernelFunc = unaryKernelFunc(Log1p, (xi) => Math.log1p(xi)); diff --git a/tfjs-backend-cpu/src/kernels/LogicalNot.ts b/tfjs-backend-cpu/src/kernels/LogicalNot.ts index 0be980ab3c2..0ef72834323 100644 --- a/tfjs-backend-cpu/src/kernels/LogicalNot.ts +++ b/tfjs-backend-cpu/src/kernels/LogicalNot.ts @@ -17,7 +17,7 @@ import {KernelConfig, LogicalNot} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const logicalNotKernelFunc = unaryKernelFunc(LogicalNot, (xi) => xi ? 0 : 1, 'bool'); diff --git a/tfjs-backend-cpu/src/kernels/Reciprocal.ts b/tfjs-backend-cpu/src/kernels/Reciprocal.ts index ed024d460aa..f33fd23d045 100644 --- a/tfjs-backend-cpu/src/kernels/Reciprocal.ts +++ b/tfjs-backend-cpu/src/kernels/Reciprocal.ts @@ -17,7 +17,7 @@ import {KernelConfig, Reciprocal} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const reciprocalKernelFunc = unaryKernelFunc(Reciprocal, (xi) => 1 / xi); diff --git a/tfjs-backend-cpu/src/kernels/Round.ts b/tfjs-backend-cpu/src/kernels/Round.ts index cb7ce746901..ae93e9644ef 100644 --- a/tfjs-backend-cpu/src/kernels/Round.ts +++ b/tfjs-backend-cpu/src/kernels/Round.ts @@ -17,7 +17,7 @@ import {KernelConfig, Round} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const roundKernelFunc = unaryKernelFunc(Round, (xi) => { // The algorithm is based on banker's rounding. diff --git a/tfjs-backend-cpu/src/kernels/Rsqrt.ts b/tfjs-backend-cpu/src/kernels/Rsqrt.ts index a5718cae8d6..6a54ff4fed5 100644 --- a/tfjs-backend-cpu/src/kernels/Rsqrt.ts +++ b/tfjs-backend-cpu/src/kernels/Rsqrt.ts @@ -17,7 +17,7 @@ import {KernelConfig, Rsqrt} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const rsqrtKernelFunc = unaryKernelFunc(Rsqrt, (xi) => 1 / Math.sqrt(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Selu.ts b/tfjs-backend-cpu/src/kernels/Selu.ts index f9701692987..38133ca6510 100644 --- a/tfjs-backend-cpu/src/kernels/Selu.ts +++ b/tfjs-backend-cpu/src/kernels/Selu.ts @@ -17,7 +17,7 @@ import {backend_util, KernelConfig, Selu} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; const scaleAlpha = backend_util.SELU_SCALEALPHA; const scale = backend_util.SELU_SCALE; diff --git a/tfjs-backend-cpu/src/kernels/Sigmoid.ts b/tfjs-backend-cpu/src/kernels/Sigmoid.ts index ecebce921c1..1d8e0a03eed 100644 --- a/tfjs-backend-cpu/src/kernels/Sigmoid.ts +++ b/tfjs-backend-cpu/src/kernels/Sigmoid.ts @@ -17,7 +17,7 @@ import {KernelConfig, Sigmoid} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const sigmoidKernelFunc = unaryKernelFunc(Sigmoid, (xi) => 1 / (1 + Math.exp(-xi))); diff --git a/tfjs-backend-cpu/src/kernels/Sign.ts b/tfjs-backend-cpu/src/kernels/Sign.ts index ca38397b570..0eec5243291 100644 --- a/tfjs-backend-cpu/src/kernels/Sign.ts +++ b/tfjs-backend-cpu/src/kernels/Sign.ts @@ -17,7 +17,7 @@ import {KernelConfig, Sign} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const signKernelFunc = unaryKernelFunc(Sign, (xi) => { if (xi < 0) { diff --git a/tfjs-backend-cpu/src/kernels/Sin.ts b/tfjs-backend-cpu/src/kernels/Sin.ts index 712a51f01fd..fd07bfaf109 100644 --- a/tfjs-backend-cpu/src/kernels/Sin.ts +++ b/tfjs-backend-cpu/src/kernels/Sin.ts @@ -17,7 +17,7 @@ import {KernelConfig, Sin} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const sinKernelFunc = unaryKernelFunc(Sin, (xi) => Math.sin(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Sinh.ts b/tfjs-backend-cpu/src/kernels/Sinh.ts index 99d4cfdda83..e70a85716ed 100644 --- a/tfjs-backend-cpu/src/kernels/Sinh.ts +++ b/tfjs-backend-cpu/src/kernels/Sinh.ts @@ -17,7 +17,7 @@ import {KernelConfig, Sinh} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const sinhKernelFunc = unaryKernelFunc(Sinh, (xi) => Math.sinh(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Softplus.ts b/tfjs-backend-cpu/src/kernels/Softplus.ts index 3b008ff4aea..bcc94592192 100644 --- a/tfjs-backend-cpu/src/kernels/Softplus.ts +++ b/tfjs-backend-cpu/src/kernels/Softplus.ts @@ -17,7 +17,7 @@ import {KernelConfig, Softplus} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; // mirrors the implementation of tf.nn.softplus: https://goo.gl/vkcvwX diff --git a/tfjs-backend-cpu/src/kernels/Sqrt.ts b/tfjs-backend-cpu/src/kernels/Sqrt.ts index 95f8467582e..f6d50df1bca 100644 --- a/tfjs-backend-cpu/src/kernels/Sqrt.ts +++ b/tfjs-backend-cpu/src/kernels/Sqrt.ts @@ -17,7 +17,7 @@ import {KernelConfig, Sqrt} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const sqrtKernelFunc = unaryKernelFunc(Sqrt, (xi) => Math.sqrt(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Step.ts b/tfjs-backend-cpu/src/kernels/Step.ts index 7c4eb061f66..d4b1a79f23d 100644 --- a/tfjs-backend-cpu/src/kernels/Step.ts +++ b/tfjs-backend-cpu/src/kernels/Step.ts @@ -17,7 +17,7 @@ import {KernelConfig, Step, StepAttrs} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const stepKernelFunc = unaryKernelFunc(Step, (xi, attrs) => { const stepAttrs = attrs as {} as StepAttrs; diff --git a/tfjs-backend-cpu/src/kernels/Tan.ts b/tfjs-backend-cpu/src/kernels/Tan.ts index 9547667c1cc..35a69ff4b25 100644 --- a/tfjs-backend-cpu/src/kernels/Tan.ts +++ b/tfjs-backend-cpu/src/kernels/Tan.ts @@ -17,7 +17,7 @@ import {KernelConfig, Tan} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const tanKernelFunc = unaryKernelFunc(Tan, (xi) => Math.tan(xi)); diff --git a/tfjs-backend-cpu/src/kernels/Tanh.ts b/tfjs-backend-cpu/src/kernels/Tanh.ts index cb5bf76e58e..3311d27b90d 100644 --- a/tfjs-backend-cpu/src/kernels/Tanh.ts +++ b/tfjs-backend-cpu/src/kernels/Tanh.ts @@ -17,7 +17,7 @@ import {KernelConfig, Tanh} from '@tensorflow/tfjs-core'; -import {unaryKernelFunc} from '../utils/kernel_utils'; +import {unaryKernelFunc} from '../utils/unary_utils'; export const tanhKernelFunc = unaryKernelFunc(Tanh, (xi) => Math.tanh(xi)); diff --git a/tfjs-backend-cpu/src/utils/kernel_utils.ts b/tfjs-backend-cpu/src/utils/kernel_utils.ts index eff5df463ec..86d2f36cff1 100644 --- a/tfjs-backend-cpu/src/utils/kernel_utils.ts +++ b/tfjs-backend-cpu/src/utils/kernel_utils.ts @@ -15,7 +15,7 @@ * ============================================================================= */ -import {backend_util, BinaryInputs, DataType, KernelFunc, TypedArray, UnaryInputs, util} from '@tensorflow/tfjs-core'; +import {backend_util, BinaryInputs, DataType, KernelFunc, TypedArray, util} from '@tensorflow/tfjs-core'; import {MathBackendCPU} from '../backend_cpu'; import {assertNotComplex} from '../cpu_util'; @@ -24,38 +24,6 @@ import {complex} from '../kernels/Complex'; import {createSimpleBinaryKernelImpl} from './binary_impl'; import {ComplexBinaryKernelImpl, ComplexBinaryOperation, SimpleBinaryOperation} from './binary_types'; -import {SimpleUnaryOperation} from './unary_types'; - -/** - * 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. - * @param opComplex A `ComplexUnaryOperation` for the kernel to handle complex64 - * inputs. - */ -export function unaryKernelFunc( - name: string, op: SimpleUnaryOperation, dtype?: DataType): KernelFunc { - return ({inputs, attrs, backend}) => { - const {x} = inputs as UnaryInputs; - assertNotComplex(x, name); - if (x.dtype === 'string' || dtype === 'string') { - throw new Error('unaryKernelFunc does not support string input/output'); - } - - const cpuBackend = backend as MathBackendCPU; - const values = cpuBackend.data.get(x.dataId).values as TypedArray; - const xSize = util.sizeFromShape(x.shape); - const $dtype = dtype || x.dtype; - const newValues = util.getArrayFromDType($dtype, xSize); - for (let i = 0; i < xSize; ++i) { - newValues[i] = op(values[i], attrs); - } - return cpuBackend.makeTensorInfo(x.shape, $dtype, newValues); - }; -} /** * Template that creates a `KernelFunc` for binary ops. diff --git a/tfjs-backend-cpu/src/utils/unary_utils.ts b/tfjs-backend-cpu/src/utils/unary_utils.ts new file mode 100644 index 00000000000..df0d76d1149 --- /dev/null +++ b/tfjs-backend-cpu/src/utils/unary_utils.ts @@ -0,0 +1,54 @@ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ + +import {DataType, KernelFunc, TypedArray, UnaryInputs, util} from '@tensorflow/tfjs-core'; + +import {MathBackendCPU} from '../backend_cpu'; +import {assertNotComplex} from '../cpu_util'; + +import {SimpleUnaryOperation} from './unary_types'; + +/** + * 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. + * @param opComplex A `ComplexUnaryOperation` for the kernel to handle complex64 + * inputs. + */ +export function unaryKernelFunc( + name: string, op: SimpleUnaryOperation, dtype?: DataType): KernelFunc { + return ({inputs, attrs, backend}) => { + const {x} = inputs as UnaryInputs; + assertNotComplex(x, name); + if (x.dtype === 'string' || dtype === 'string') { + throw new Error('unaryKernelFunc does not support string input/output'); + } + + const cpuBackend = backend as MathBackendCPU; + const values = cpuBackend.data.get(x.dataId).values as TypedArray; + const xSize = util.sizeFromShape(x.shape); + const $dtype = dtype || x.dtype; + const newValues = util.getArrayFromDType($dtype, xSize); + for (let i = 0; i < xSize; ++i) { + newValues[i] = op(values[i], attrs); + } + return cpuBackend.makeTensorInfo(x.shape, $dtype, newValues); + }; +}