function binaryKernelFunc({ opSnippet, packedOpSnippet, checkOutOfBounds = false, supportsComplex = false, cpuKernelImpl, dtype }) {
    return ({ inputs, backend }) => {
        const { a, b } = inputs;
        const webglBackend = backend;
        if (supportsComplex && a.dtype === 'complex64') {
            const aData = webglBackend.texData.get(a.dataId);
            const bData = webglBackend.texData.get(b.dataId);
            const [real, imag] = [
                [aData.complexTensorInfos.real, bData.complexTensorInfos.real],
                [aData.complexTensorInfos.imag, bData.complexTensorInfos.imag]
            ].map(complexParts => {
                const [aPart, bPart] = complexParts;
                const aHandle = {
                    dataId: aPart.dataId,
                    dtype: aPart.dtype,
                    shape: a.shape
                };
                const bHandle = {
                    dataId: bPart.dataId,
                    dtype: bPart.dtype,
                    shape: b.shape
                };
                const program = new BinaryOpProgram(opSnippet, a.shape, b.shape);
                return webglBackend.runWebGLProgram(program, [aHandle, bHandle], upcastType(aPart.dtype, bPart.dtype));
            });
            const complexOutput = complex({ inputs: { real, imag }, backend: webglBackend });
            webglBackend.disposeIntermediateTensorInfo(real);
            webglBackend.disposeIntermediateTensorInfo(imag);
            // TODO(annxingyuan): Implement CPU forwarding for complex inputs.
            return complexOutput;
        }
        const $dtype = dtype || upcastType(a.dtype, b.dtype);
        if (webglBackend.shouldExecuteOnCPU([a, b]) && cpuKernelImpl != null) {
            const aData = webglBackend.texData.get(a.dataId);
            const bData = webglBackend.texData.get(b.dataId);
            const [outValues, outShape] = cpuKernelImpl(a.shape, b.shape, aData.values, bData.values, $dtype);
            const out = webglBackend.makeTensorInfo(outShape, $dtype);
            const outData = webglBackend.texData.get(out.dataId);
            outData.values = outValues;
            return out;
        }
        const shouldUsePackedProgram = env().getBool('WEBGL_PACK_BINARY_OPERATIONS') &&
            packedOpSnippet != null;
        let program;
        if (shouldUsePackedProgram) {
            program = new BinaryOpPackedProgram(packedOpSnippet, a.shape, b.shape, checkOutOfBounds);
        }
        else {
            program = new BinaryOpProgram(opSnippet, a.shape, b.shape);
        }
        return webglBackend.runWebGLProgram(program, [a, b], $dtype);
    };
}
/**
 * Template that creates a `KernelFunc` for binary ops.
 * @param opSnippet Op snippet to create `BinaryOpProgram`.
 * @param packedOpSnippet Op snippet to create `BinaryOpPackedProgram`.
 * @param checkOutOfBoundsForPackedProgram Whether to set checkOutOfBounds=true
 *     when creating BinaryOpPackedProgram.
 * @param dtype Optional. If set, the result has this dtype. Otherwise, the
 *     result has the same dtype as the first input. This is mainly used in
 *     comparison kernels, such as Equal, Less, Greater, etc.
 */
Template that creates a `KernelFunc` for binary ops.
@param opSnippet Op snippet to create `BinaryOpProgram`.
@param packedOpSnippet Op snippet to create `BinaryOpPackedProgram`.
Template that creates a ` KernelFunc ` for binary ops . @param opSnippet Op snippet to create ` BinaryOpProgram ` . @param packedOpSnippet Op snippet to create ` BinaryOpPackedProgram ` .
function binaryKernelFunc({ opSnippet, packedOpSnippet, checkOutOfBounds = false, supportsComplex = false, cpuKernelImpl, dtype }) {
    return ({ inputs, backend }) => {
        const { a, b } = inputs;
        const webglBackend = backend;
        if (supportsComplex && a.dtype === 'complex64') {
            const aData = webglBackend.texData.get(a.dataId);
            const bData = webglBackend.texData.get(b.dataId);
            const [real, imag] = [
                [aData.complexTensorInfos.real, bData.complexTensorInfos.real],
                [aData.complexTensorInfos.imag, bData.complexTensorInfos.imag]
            ].map(complexParts => {
                const [aPart, bPart] = complexParts;
                const aHandle = {
                    dataId: aPart.dataId,
                    dtype: aPart.dtype,
                    shape: a.shape
                };
                const bHandle = {
                    dataId: bPart.dataId,
                    dtype: bPart.dtype,
                    shape: b.shape
                };
                const program = new BinaryOpProgram(opSnippet, a.shape, b.shape);
                return webglBackend.runWebGLProgram(program, [aHandle, bHandle], upcastType(aPart.dtype, bPart.dtype));
            });
            const complexOutput = complex({ inputs: { real, imag }, backend: webglBackend });
            webglBackend.disposeIntermediateTensorInfo(real);
            webglBackend.disposeIntermediateTensorInfo(imag);
            return complexOutput;
        }
        const $dtype = dtype || upcastType(a.dtype, b.dtype);
        if (webglBackend.shouldExecuteOnCPU([a, b]) && cpuKernelImpl != null) {
            const aData = webglBackend.texData.get(a.dataId);
            const bData = webglBackend.texData.get(b.dataId);
            const [outValues, outShape] = cpuKernelImpl(a.shape, b.shape, aData.values, bData.values, $dtype);
            const out = webglBackend.makeTensorInfo(outShape, $dtype);
            const outData = webglBackend.texData.get(out.dataId);
            outData.values = outValues;
            return out;
        }
        const shouldUsePackedProgram = env().getBool('WEBGL_PACK_BINARY_OPERATIONS') &&
            packedOpSnippet != null;
        let program;
        if (shouldUsePackedProgram) {
            program = new BinaryOpPackedProgram(packedOpSnippet, a.shape, b.shape, checkOutOfBounds);
        }
        else {
            program = new BinaryOpProgram(opSnippet, a.shape, b.shape);
        }
        return webglBackend.runWebGLProgram(program, [a, b], $dtype);
    };
}
function binaryKernelFunc ( { opSnippet , packedOpSnippet , checkOutOfBounds = false , supportsComplex = false , cpuKernelImpl , dtype } ) { return ( { inputs , backend } ) => { const { a , b } = inputs ; const webglBackend = backend ; if ( supportsComplex && a . dtype === 'complex64' ) { const aData = webglBackend . texData . get ( a . dataId ) ; const bData = webglBackend . texData . get ( b . dataId ) ; const [ real , imag ] = [ [ aData . complexTensorInfos . real , bData . complexTensorInfos . real ] , [ aData . complexTensorInfos . imag , bData . complexTensorInfos . imag ] ] . map ( complexParts => { const [ aPart , bPart ] = complexParts ; const aHandle = { dataId : aPart . dataId , dtype : aPart . dtype , shape : a . shape } ; const bHandle = { dataId : bPart . dataId , dtype : bPart . dtype , shape : b . shape } ; const program = new BinaryOpProgram ( opSnippet , a . shape , b . shape ) ; return webglBackend . runWebGLProgram ( program , [ aHandle , bHandle ] , upcastType ( aPart . dtype , bPart . dtype ) ) ; } ) ; const complexOutput = complex ( { inputs : { real , imag } , backend : webglBackend } ) ; webglBackend . disposeIntermediateTensorInfo ( real ) ; webglBackend . disposeIntermediateTensorInfo ( imag ) ; return complexOutput ; } const $dtype = dtype || upcastType ( a . dtype , b . dtype ) ; if ( webglBackend . shouldExecuteOnCPU ( [ a , b ] ) && cpuKernelImpl != null ) { const aData = webglBackend . texData . get ( a . dataId ) ; const bData = webglBackend . texData . get ( b . dataId ) ; const [ outValues , outShape ] = cpuKernelImpl ( a . shape , b . shape , aData . values , bData . values , $dtype ) ; const out = webglBackend . makeTensorInfo ( outShape , $dtype ) ; const outData = webglBackend . texData . get ( out . dataId ) ; outData . values = outValues ; return out ; } const shouldUsePackedProgram = env ( ) . getBool ( 'WEBGL_PACK_BINARY_OPERATIONS' ) && packedOpSnippet != null ; let program ; if ( shouldUsePackedProgram ) { program = new BinaryOpPackedProgram ( packedOpSnippet , a . shape , b . shape , checkOutOfBounds ) ; } else { program = new BinaryOpProgram ( opSnippet , a . shape , b . shape ) ; } return webglBackend . runWebGLProgram ( program , [ a , b ] , $dtype ) ; } ; }
Template that creates a `KernelFunc` for binary ops.
Template that creates a ` KernelFunc ` for binary ops .
// TODO(annxingyuan): Implement CPU forwarding for complex inputs.