JavaScript CPU backend implementation for TensorFlow.js enabling machine learning operations in vanilla JavaScript
—
The shared module provides 50+ optimized kernel implementations that can be reused across different TensorFlow.js backends. These implementations handle the core mathematical operations, array manipulations, and specialized computations with broadcasting support and performance optimizations.
import { shared } from '@tensorflow/tfjs-backend-cpu/base';
// Access individual implementations
const { addImpl, multiplyImpl, expImpl } = shared;// Basic binary operation signature
type SimpleBinaryOperation = (a: number | string, b: number | string) => number;
// Binary kernel implementation with broadcasting
type SimpleBinaryKernelImpl = (
aShape: number[],
bShape: number[],
aVals: TypedArray | string[],
bVals: TypedArray | string[],
dtype: DataType
) => [TypedArray, number[]];
// Complex number binary operations
type ComplexBinaryOperation = (
aReal: number,
aImag: number,
bReal: number,
bImag: number
) => { real: number, imag: number };
// Complex binary kernel implementation
type ComplexBinaryKernelImpl = (
aShape: number[],
bShape: number[],
aRealVals: Float32Array,
aImagVals: Float32Array,
bRealVals: Float32Array,
bImagVals: Float32Array
) => [TypedArray, TypedArray, number[]];// Common typed arrays used in implementations
type TypedArray =
| Float32Array
| Int32Array
| Uint8Array
| Uint16Array
| Uint32Array
| Int16Array
| Int8Array;
// Return type for most operations
type OperationResult = [TypedArray, number[]]; // [values, outputShape]
// Utility types for complex operations
interface ComplexResult {
real: TypedArray;
imag: TypedArray;
outputShape: number[];
}function addImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray | string[],
bVals: TypedArray | string[],
dtype: DataType
): [TypedArray, number[]]Element-wise addition with automatic broadcasting support.
Parameters:
aShape: number[] - Shape of first tensorbShape: number[] - Shape of second tensoraVals: TypedArray | string[] - Values of first tensorbVals: TypedArray | string[] - Values of second tensordtype: DataType - Output data typeReturns: [TypedArray, number[]] - Result values and output shape
Example:
import { shared } from '@tensorflow/tfjs-backend-cpu/base';
// Element-wise addition
const [result, shape] = shared.addImpl(
[2, 2], // aShape
[2, 2], // bShape
new Float32Array([1, 2, 3, 4]), // aVals
new Float32Array([5, 6, 7, 8]), // bVals
'float32' // dtype
);
console.log(result); // Float32Array([6, 8, 10, 12])
console.log(shape); // [2, 2]
// Broadcasting example
const [broadcastResult, broadcastShape] = shared.addImpl(
[3, 1], // aShape
[1, 4], // bShape (broadcasts to [3, 4])
new Float32Array([1, 2, 3]), // aVals
new Float32Array([10, 20, 30, 40]), // bVals
'float32'
);
console.log(broadcastShape); // [3, 4] - broadcasted output shapefunction multiplyImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [TypedArray, number[]]Element-wise multiplication with broadcasting.
Example:
const [result, shape] = shared.multiplyImpl(
[2, 3], // aShape
[2, 3], // bShape
new Float32Array([1, 2, 3, 4, 5, 6]), // aVals
new Float32Array([2, 2, 2, 2, 2, 2]), // bVals
'float32'
);
console.log(result); // Float32Array([2, 4, 6, 8, 10, 12])function subImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [TypedArray, number[]]Element-wise subtraction with broadcasting.
Example:
const [result, shape] = shared.subImpl(
[3], // aShape
[3], // bShape
new Float32Array([5, 7, 9]), // aVals
new Float32Array([1, 2, 3]), // bVals
'float32'
);
console.log(result); // Float32Array([4, 5, 6])function simpleAbsImpl(vals: TypedArray): Float32ArrayComputes absolute values element-wise.
Parameters:
vals: TypedArray - Input valuesReturns: Float32Array - Absolute values
Example:
const result = shared.simpleAbsImpl(new Float32Array([-2, -1, 0, 1, 2]));
console.log(result); // Float32Array([2, 1, 0, 1, 2])function expImpl(vals: TypedArray): Float32ArrayComputes exponential (e^x) element-wise.
Example:
const result = shared.expImpl(new Float32Array([0, 1, 2]));
console.log(result); // Float32Array([1, 2.718..., 7.389...])function logImpl(vals: TypedArray): Float32ArrayComputes natural logarithm element-wise.
Example:
const result = shared.logImpl(new Float32Array([1, Math.E, Math.E * Math.E]));
console.log(result); // Float32Array([0, 1, 2])function sqrtImpl(vals: TypedArray): Float32ArrayComputes square root element-wise.
Example:
const result = shared.sqrtImpl(new Float32Array([1, 4, 9, 16]));
console.log(result); // Float32Array([1, 2, 3, 4])function rsqrtImpl(vals: TypedArray): Float32ArrayComputes reciprocal square root (1/sqrt(x)) element-wise.
Example:
const result = shared.rsqrtImpl(new Float32Array([1, 4, 9, 16]));
console.log(result); // Float32Array([1, 0.5, 0.333..., 0.25])function negImpl(vals: TypedArray, dtype: DataType): TypedArrayComputes negation (-x) element-wise.
Example:
const result = shared.negImpl(new Float32Array([1, -2, 3, -4]), 'float32');
console.log(result); // Float32Array([-1, 2, -3, 4])function sigmoidImpl(vals: TypedArray): Float32ArrayComputes sigmoid activation function: 1 / (1 + e^(-x)).
Example:
const result = shared.sigmoidImpl(new Float32Array([-2, -1, 0, 1, 2]));
console.log(result); // Float32Array([0.119, 0.269, 0.5, 0.731, 0.881])function expm1Impl(vals: TypedArray): Float32ArrayComputes e^x - 1, more accurate for small values than exp(x) - 1.
Example:
const result = shared.expm1Impl(new Float32Array([0, 0.001, 1]));
console.log(result); // More accurate than exp() - 1 for small valuesfunction ceilImpl(vals: TypedArray): Float32ArrayComputes ceiling function element-wise.
Example:
const result = shared.ceilImpl(new Float32Array([1.1, 2.8, -1.2, -0.5]));
console.log(result); // Float32Array([2, 3, -1, 0])function floorImpl(vals: TypedArray): Float32ArrayComputes floor function element-wise.
Example:
const result = shared.floorImpl(new Float32Array([1.8, 2.1, -1.2, -0.5]));
console.log(result); // Float32Array([1, 2, -2, -1])function equalImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [Uint8Array, number[]]Element-wise equality comparison with broadcasting.
Returns: [Uint8Array, number[]] - Boolean results as Uint8Array (1 for true, 0 for false)
Example:
const [result, shape] = shared.equalImpl(
[3], // aShape
[3], // bShape
new Float32Array([1, 2, 3]), // aVals
new Float32Array([1, 4, 3]), // bVals
'float32'
);
console.log(result); // Uint8Array([1, 0, 1]) - true, false, truefunction greaterImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [Uint8Array, number[]]Element-wise greater-than comparison.
Example:
const [result, shape] = shared.greaterImpl(
[3], // aShape
[3], // bShape
new Float32Array([3, 2, 1]), // aVals
new Float32Array([1, 2, 3]), // bVals
'float32'
);
console.log(result); // Uint8Array([1, 0, 0]) - true, false, falsefunction lessImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [Uint8Array, number[]]Element-wise less-than comparison.
Example:
const [result, shape] = shared.lessImpl(
[2, 2], // aShape
[2, 2], // bShape
new Float32Array([1, 5, 3, 2]), // aVals
new Float32Array([2, 4, 3, 1]), // bVals
'float32'
);
console.log(result); // Uint8Array([1, 0, 0, 0])function greaterEqualImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [Uint8Array, number[]]Element-wise greater-than-or-equal comparison.
function lessEqualImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [Uint8Array, number[]]Element-wise less-than-or-equal comparison.
function notEqualImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [Uint8Array, number[]]Element-wise not-equal comparison.
function floorDivImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [TypedArray, number[]]Element-wise floor division with broadcasting.
Example:
const [result, shape] = shared.floorDivImpl(
[3], // aShape
[3], // bShape
new Float32Array([7, 8, 9]), // aVals
new Float32Array([2, 3, 4]), // bVals
'float32'
);
console.log(result); // Float32Array([3, 2, 2]) - floor(7/2), floor(8/3), floor(9/4)function maximumImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [TypedArray, number[]]Element-wise maximum with broadcasting.
Example:
const [result, shape] = shared.maximumImpl(
[3], // aShape
[3], // bShape
new Float32Array([1, 5, 3]), // aVals
new Float32Array([4, 2, 6]), // bVals
'float32'
);
console.log(result); // Float32Array([4, 5, 6])function minimumImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [TypedArray, number[]]Element-wise minimum with broadcasting.
Example:
const [result, shape] = shared.minimumImpl(
[3], // aShape
[3], // bShape
new Float32Array([1, 5, 3]), // aVals
new Float32Array([4, 2, 6]), // bVals
'float32'
);
console.log(result); // Float32Array([1, 2, 3])function squaredDifferenceImpl(
aShape: number[],
bShape: number[],
aVals: TypedArray,
bVals: TypedArray,
dtype: DataType
): [TypedArray, number[]]Element-wise squared difference: (a - b)^2.
Example:
const [result, shape] = shared.squaredDifferenceImpl(
[3], // aShape
[3], // bShape
new Float32Array([4, 6, 8]), // aVals
new Float32Array([2, 4, 6]), // bVals
'float32'
);
console.log(result); // Float32Array([4, 4, 4]) - (4-2)^2, (6-4)^2, (8-6)^2function concatImpl(
tensors: TypedArray[],
outShape: number[],
dtype: DataType,
axis: number
): TypedArrayConcatenates multiple tensors along specified axis.
Parameters:
tensors: TypedArray[] - Array of tensor values to concatenateoutShape: number[] - Output shape after concatenationdtype: DataType - Output data typeaxis: number - Axis along which to concatenateExample:
const result = shared.concatImpl(
[
new Float32Array([1, 2]), // First tensor
new Float32Array([3, 4]), // Second tensor
new Float32Array([5, 6]) // Third tensor
],
[6], // Output shape: [6] (concatenating 3 tensors of shape [2])
'float32', // Data type
0 // Axis 0
);
console.log(result); // Float32Array([1, 2, 3, 4, 5, 6])
// 2D concatenation example
const result2d = shared.concatImpl(
[
new Float32Array([1, 2, 3, 4]), // Shape [2, 2]
new Float32Array([5, 6, 7, 8]) // Shape [2, 2]
],
[4, 2], // Output shape after concat along axis 0
'float32',
0 // Concatenate along rows
);function sliceImpl(
vals: TypedArray,
begin: number[],
size: number[],
shape: number[],
dtype: DataType
): [TypedArray, number[]]Extracts a slice from a tensor.
Parameters:
vals: TypedArray - Input tensor valuesbegin: number[] - Starting indices for each dimensionsize: number[] - Size of slice in each dimensionshape: number[] - Input tensor shapedtype: DataType - Data typeExample:
const [result, outShape] = shared.sliceImpl(
new Float32Array([1, 2, 3, 4, 5, 6]), // Input: [[1,2,3], [4,5,6]]
[0, 1], // Begin at [row=0, col=1]
[2, 2], // Take 2 rows, 2 columns
[2, 3], // Input shape [2, 3]
'float32'
);
console.log(result); // Float32Array([2, 3, 5, 6])
console.log(outShape); // [2, 2]function stridedSliceImpl(
vals: TypedArray,
begin: number[],
end: number[],
strides: number[],
beginMask: number,
endMask: number,
ellipsisMask: number,
newAxisMask: number,
shrinkAxisMask: number,
shape: number[],
dtype: DataType
): [TypedArray, number[]]Advanced slicing with strides and masking options.
Example:
const [result, outShape] = shared.stridedSliceImpl(
new Float32Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), // Input [10]
[1], // begin
[8], // end
[2], // strides (every 2nd element)
0, 0, 0, 0, 0, // masks
[10], // input shape
'float32'
);
console.log(result); // Float32Array([1, 3, 5, 7])function tileImpl(
vals: TypedArray,
shape: number[],
dtype: DataType,
reps: number[]
): TypedArrayTiles (repeats) a tensor according to repetition counts.
Parameters:
vals: TypedArray - Input tensor valuesshape: number[] - Input tensor shapedtype: DataType - Data typereps: number[] - Repetition count for each dimensionExample:
const result = shared.tileImpl(
new Float32Array([1, 2]), // Input: [1, 2]
[2], // Input shape: [2]
'float32',
[3] // Repeat 3 times
);
console.log(result); // Float32Array([1, 2, 1, 2, 1, 2])
// 2D tiling
const result2d = shared.tileImpl(
new Float32Array([1, 2, 3, 4]), // Input: [[1,2], [3,4]]
[2, 2], // Input shape: [2, 2]
'float32',
[2, 3] // Repeat 2x vertically, 3x horizontally
);
// Result shape: [4, 6]function transposeImpl(
vals: TypedArray,
shape: number[],
dtype: DataType,
perm: number[]
): TypedArrayTransposes tensor dimensions according to permutation.
Parameters:
vals: TypedArray - Input tensor valuesshape: number[] - Input tensor shapedtype: DataType - Data typeperm: number[] - Permutation of dimensionsExample:
const result = shared.transposeImpl(
new Float32Array([1, 2, 3, 4, 5, 6]), // Input: [[1,2,3], [4,5,6]]
[2, 3], // Input shape [2 rows, 3 cols]
'float32',
[1, 0] // Permutation: swap dimensions [rows, cols] -> [cols, rows]
);
console.log(result); // Float32Array([1, 4, 2, 5, 3, 6])
// Result represents [[1,4], [2,5], [3,6]] - shape [3, 2]function gatherV2Impl(
xVals: TypedArray,
xShape: number[],
xDtype: DataType,
indices: TypedArray,
indicesShape: number[],
axis: number
): [TypedArray, number[]]Gathers values from tensor at specified indices along an axis.
Example:
const [result, outShape] = shared.gatherV2Impl(
new Float32Array([10, 20, 30, 40, 50, 60]), // Input: [[10,20,30], [40,50,60]]
[2, 3], // Input shape
'float32',
new Int32Array([2, 0, 1]), // Indices to gather
[3], // Indices shape
1 // Axis 1 (columns)
);
console.log(result); // Gathers columns 2, 0, 1function gatherNdImpl(
indicesData: TypedArray,
indicesShape: number[],
paramsData: TypedArray,
paramsShape: number[],
dtype: DataType
): [TypedArray, number[]]N-dimensional gather operation using multi-dimensional indices.
Example:
const [result, outShape] = shared.gatherNdImpl(
new Int32Array([0, 1, 1, 0]), // Indices: [[0,1], [1,0]]
[2, 2], // Indices shape
new Float32Array([1, 2, 3, 4]), // Params: [[1,2], [3,4]]
[2, 2], // Params shape
'float32'
);
console.log(result); // Float32Array([2, 3]) - values at [0,1] and [1,0]function scatterImpl(
indices: TypedArray,
updates: TypedArray,
shape: number[],
outputSize: number,
sliceSize: number,
numUpdates: number,
sliceRank: number,
strides: number[],
defaultValue: number,
sumDupeIndices: boolean
): TypedArrayScatters updates into output tensor at specified indices.
Example:
const result = shared.scatterImpl(
new Int32Array([1, 3]), // Indices where to scatter
new Float32Array([10, 20]), // Values to scatter
[5], // Output shape
5, // Output size
1, // Slice size
2, // Number of updates
0, // Slice rank
[1], // Strides
0, // Default value
false // Don't sum duplicate indices
);
console.log(result); // Float32Array([0, 10, 0, 20, 0])function topKImpl(
xVals: TypedArray,
xShape: number[],
xDtype: DataType,
k: number,
sorted: boolean
): [TypedArray, Int32Array, number[]]Finds top-k largest values and their indices.
Returns: [values, indices, outputShape]
Example:
const [values, indices, shape] = shared.topKImpl(
new Float32Array([3, 1, 4, 1, 5, 9, 2, 6]), // Input values
[8], // Input shape
'float32',
3, // k=3 (top 3)
true // sorted=true
);
console.log(values); // Float32Array([9, 6, 5]) - top 3 values
console.log(indices); // Int32Array([5, 7, 4]) - their indicesfunction uniqueImpl(
values: TypedArray,
axis: number,
shape: number[],
dtype: DataType
): { outputValues: TypedArray, outputShape: number[], indices: Int32Array }Finds unique values in tensor.
Example:
const result = shared.uniqueImpl(
new Float32Array([1, 2, 1, 3, 2, 4]), // Input with duplicates
0, // Axis
[6], // Shape
'float32'
);
console.log(result.outputValues); // Float32Array([1, 2, 3, 4])
console.log(result.indices); // Int32Array mapping original to unique indicesfunction rangeImpl(
start: number,
stop: number,
step: number,
dtype: 'float32' | 'int32'
): TypedArrayGenerates a sequence of numbers.
Example:
const result = shared.rangeImpl(0, 10, 2, 'float32');
console.log(result); // Float32Array([0, 2, 4, 6, 8])
const negativeStep = shared.rangeImpl(10, 0, -1.5, 'float32');
console.log(negativeStep); // Float32Array([10, 8.5, 7, 5.5, 4, 2.5, 1])function linSpaceImpl(
start: number,
stop: number,
num: number
): Float32ArrayGenerates linearly spaced values between start and stop.
Example:
const result = shared.linSpaceImpl(0, 1, 5);
console.log(result); // Float32Array([0, 0.25, 0.5, 0.75, 1])
const reverse = shared.linSpaceImpl(10, 0, 6);
console.log(reverse); // Float32Array([10, 8, 6, 4, 2, 0])function stringNGramsImpl(
data: Uint8Array[],
dataSplits: TypedArray,
separator: string,
nGramWidths: number[],
leftPad: string,
rightPad: string,
padWidth: number,
preserveShortSequences: boolean
): [Uint8Array[], Int32Array]Generates N-grams from string sequences.
Example:
// Convert strings to Uint8Array format expected by implementation
const textEncoder = new TextEncoder();
const data = [
textEncoder.encode('hello'),
textEncoder.encode('world')
];
const splits = new Int32Array([0, 1, 2]); // Split positions
const [ngrams, ngramSplits] = shared.stringNGramsImpl(
data,
splits,
' ', // separator
[2, 3], // Generate 2-grams and 3-grams
'<s>', // left padding
'</s>', // right padding
1, // pad width
true // preserve short sequences
);function stringSplitImpl(
input: Uint8Array[],
delimiter: Uint8Array,
skipEmpty: boolean,
result: Uint8Array[],
resultSplits: TypedArray,
maxSplit?: number
): voidSplits strings by delimiter.
function staticRegexReplaceImpl(
input: Uint8Array[],
pattern: string,
rewrite: string,
global: boolean
): Uint8Array[]Performs regex replacement on strings.
function stringToHashBucketFastImpl(
input: Uint8Array[],
numBuckets: number
): Int32ArrayHashes strings to bucket indices.
Example:
const textEncoder = new TextEncoder();
const strings = [
textEncoder.encode('apple'),
textEncoder.encode('banana'),
textEncoder.encode('cherry')
];
const buckets = shared.stringToHashBucketFastImpl(strings, 10);
console.log(buckets); // Int32Array with bucket indices [0-9]function sparseFillEmptyRowsImpl(
indices: TypedArray,
indicesShape: number[],
values: TypedArray,
denseShape: TypedArray,
defaultValue: number | string
): [TypedArray, TypedArray, Uint8Array, TypedArray]Fills empty rows in sparse matrix representation.
function sparseReshapeImpl(
inputIndices: TypedArray,
inputIndicesShape: number[],
inputShape: number[],
targetShape: number[]
): [TypedArray, number[]]Reshapes sparse tensor representation.
function sparseSegmentReductionImpl(
input: TypedArray,
inputShape: number[],
inputDType: DataType,
indices: TypedArray,
segmentIds: TypedArray,
isMean: boolean = false,
defaultValue: number = 0
): [TypedArray, number[]]Performs segment reduction on sparse data.
function raggedGatherImpl(
paramsNestedSplits: TypedArray[],
paramsNestedSplitsShapes: number[][],
paramsDenseValues: TypedArray,
paramsDenseValuesShape: number[],
paramsDenseValuesDType: DataType,
indices: TypedArray,
indicesShape: number[],
outputRaggedRank: number
): [TypedArray[], number[][], TypedArray, number[]]Gathers from ragged tensors using nested indices.
function raggedRangeImpl(
starts: TypedArray,
startsShape: number[],
limits: TypedArray,
limitsShape: number[],
deltas: TypedArray
): [TypedArray, Int32Array]Generates ragged ranges with different limits per row.
function raggedTensorToTensorImpl(
shape: number[],
shapesShape: number[],
values: TypedArray,
valuesShape: number[],
valuesDType: DataType,
defaultValue: TypedArray,
defaultValueShape: number[],
rowPartitionValues: TypedArray[],
rowPartitionValuesShapes: number[][],
rowPartitionTypes: string[]
): TypedArrayConverts ragged tensor to dense tensor representation.
function castImpl(
values: TypedArray,
shape: number[],
inputDType: DataType,
outputDType: DataType
): [TypedArray, number[]]Casts tensor values between data types.
Example:
const [result, shape] = shared.castImpl(
new Float32Array([1.7, 2.3, 3.9]), // Input float values
[3], // Shape
'float32', // Input dtype
'int32' // Output dtype
);
console.log(result); // Int32Array([1, 2, 3]) - truncated to integersfunction prodImpl(
xVals: TypedArray,
reduceSize: number,
outShape: number[],
dtype: DataType
): TypedArrayComputes product reduction.
Example:
const result = shared.prodImpl(
new Float32Array([2, 3, 4, 5]), // Input values
4, // Reduce all 4 elements
[], // Output shape (scalar)
'float32'
);
console.log(result); // Float32Array([120]) - 2*3*4*5 = 120function maxImpl(
aVals: TypedArray,
reduceSize: number,
outShape: number[],
dtype: DataType
): TypedArrayComputes maximum reduction.
Example:
const result = shared.maxImpl(
new Float32Array([3, 1, 4, 1, 5, 9, 2, 6]), // Input values
8, // Reduce all elements
[], // Scalar output
'float32'
);
console.log(result); // Float32Array([9]) - maximum valuefunction bincountImpl(
xVals: Int32Array,
weightsVals: TypedArray,
weightsDtype: DataType,
weightsShape: number[],
size: number
): TypedArrayCounts occurrences in bins with optional weights.
Example:
const result = shared.bincountImpl(
new Int32Array([1, 1, 2, 2, 2, 3]), // Values to bin
new Float32Array([1, 1, 1, 1, 1, 1]), // Weights (all 1s = simple count)
'float32', // Weights dtype
[6], // Weights shape
4 // Number of bins
);
console.log(result); // Float32Array([0, 2, 3, 1]) - counts per binfunction bitwiseAndImpl(
aShape: number[],
bShape: number[],
aVals: Int32Array,
bVals: Int32Array,
dtype: DataType
): [Int32Array, number[]]Element-wise bitwise AND operation.
Example:
const [result, shape] = shared.bitwiseAndImpl(
[3], // aShape
[3], // bShape
new Int32Array([5, 3, 7]), // aVals (binary: 101, 011, 111)
new Int32Array([3, 5, 1]), // bVals (binary: 011, 101, 001)
'int32'
);
console.log(result); // Int32Array([1, 1, 1]) - bitwise AND resultsAll shared implementations are optimized for performance:
import { shared } from '@tensorflow/tfjs-backend-cpu/base';
class CustomBackend extends KernelBackend {
customAddOperation(a: TensorInfo, b: TensorInfo): TensorInfo {
const aVals = this.readSync(a.dataId) as Float32Array;
const bVals = this.readSync(b.dataId) as Float32Array;
// Leverage optimized CPU implementation
const [resultVals, resultShape] = shared.addImpl(
a.shape,
b.shape,
aVals,
bVals,
a.dtype
);
return this.makeOutput(resultVals, resultShape, a.dtype);
}
// Custom implementation using multiple shared ops
customComplexOp(input: TensorInfo): TensorInfo {
const inputVals = this.readSync(input.dataId) as Float32Array;
// Chain multiple shared implementations
const expResult = shared.expImpl(inputVals);
const sqrtResult = shared.sqrtImpl(expResult);
const absResult = shared.simpleAbsImpl(sqrtResult);
return this.makeOutput(absResult, input.shape, input.dtype);
}
}// Efficient use of shared implementations
function efficientBatchProcessing(backend: MathBackendCPU, inputs: TensorInfo[]): TensorInfo[] {
const results: TensorInfo[] = [];
for (const input of inputs) {
const vals = backend.readSync(input.dataId) as Float32Array;
// Process using shared implementation
const processedVals = shared.sigmoidImpl(vals);
const result = backend.makeOutput(processedVals, input.shape, input.dtype);
results.push(result);
// Clean up intermediate if not needed
backend.disposeIntermediateTensorInfo(input);
}
return results;
}Install with Tessl CLI
npx tessl i tessl/npm-tensorflow--tfjs-backend-cpu