@tensorflow/tfjs-backend-wasm
Version:
This package adds a WebAssembly backend to TensorFlow.js. It currently supports the following models from our [models](https://github.com/tensorflow/tfjs-models) repo: - BlazeFace - BodyPix - CocoSSD - Face landmarks detection - HandPose - KNN classifier
85 lines • 14.4 kB
JavaScript
/**
* @license
* Copyright 2020 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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, Conv2DBackpropInput, util } from '@tensorflow/tfjs-core';
let wasmConv2DBackpropInput;
function setup(backend) {
wasmConv2DBackpropInput = backend.wasm.cwrap(Conv2DBackpropInput, null, [
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number',
'number', // outId
]);
}
function conv2DBackpropInput(args) {
const { backend, inputs, attrs } = args;
const { dy, filter } = inputs;
const { strides, pad, dataFormat, dimRoundingMode, inputShape } = attrs;
const dilations = 1;
const $dataFormat = backend_util.convertConv2DDataFormat(dataFormat);
const convInfo = backend_util.computeConv2DInfo(inputShape, filter.shape, strides, dilations, pad, dimRoundingMode, false /* depthwise */, $dataFormat);
const { batchSize, filterHeight, filterWidth, inChannels, inHeight, inWidth, outChannels, outHeight, outWidth, strideHeight, strideWidth } = convInfo;
const topPad = filterHeight - 1 - convInfo.padInfo.top;
const leftPad = filterWidth - 1 - convInfo.padInfo.left;
const isChannelsLast = convInfo.dataFormat === 'channelsLast';
const dxStrides = util.computeStrides(convInfo.inShape);
const dyStrides = util.computeStrides(dy.shape);
const [fltS0, fltS1, fltS2] = util.computeStrides(filter.shape);
const xBatchStride = dxStrides[0];
const xRowStride = isChannelsLast ? dxStrides[1] : dxStrides[2];
const xColStride = isChannelsLast ? dxStrides[2] : 1;
const xChannelStride = isChannelsLast ? 1 : dxStrides[1];
const yBatchStride = dyStrides[0];
const yRowStride = isChannelsLast ? dyStrides[1] : dyStrides[2];
const yColStride = isChannelsLast ? dyStrides[2] : 1;
const yChannelStride = isChannelsLast ? 1 : dyStrides[1];
const out = backend.makeOutput(convInfo.inShape, 'float32');
const outId = backend.dataIdMap.get(out.dataId).id;
const dyId = backend.dataIdMap.get(dy.dataId).id;
const filterId = backend.dataIdMap.get(filter.dataId).id;
wasmConv2DBackpropInput(dyId, filterId, batchSize, filterHeight, filterWidth, inHeight, inWidth, inChannels, outHeight, outWidth, outChannels, strideHeight, strideWidth, topPad, leftPad, fltS0, fltS1, fltS2, xBatchStride, xRowStride, xColStride, xChannelStride, yBatchStride, yRowStride, yColStride, yChannelStride, outId);
return out;
}
export const conv2DBackpropInputConfig = {
kernelName: Conv2DBackpropInput,
backendName: 'wasm',
setupFunc: setup,
kernelFunc: conv2DBackpropInput
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29udjJEQmFja3Byb3BJbnB1dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3RmanMtYmFja2VuZC13YXNtL3NyYy9rZXJuZWxzL0NvbnYyREJhY2twcm9wSW5wdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFDLFlBQVksRUFBRSxtQkFBbUIsRUFBNkYsSUFBSSxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFJekssSUFBSSx1QkFROEMsQ0FBQztBQUVuRCxTQUFTLEtBQUssQ0FBQyxPQUFvQjtJQUNqQyx1QkFBdUIsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLEVBQUU7UUFDdEUsUUFBUTtRQUNSLFFBQVE7UUFDUixRQUFRO1FBQ1IsUUFBUTtRQUNSLFFBQVE7UUFDUixRQUFRO1FBQ1IsUUFBUTtRQUNSLFFBQVE7UUFDUixRQUFRO1FBQ1IsUUFBUTtRQUNSLFFBQVE7UUFDUixRQUFRO1FBQ1IsUUFBUTtRQUNSLFFBQVE7UUFDUixRQUFRO1FBQ1IsUUFBUTtRQUNSLFFBQVE7UUFDUixRQUFRO1FBQ1IsUUFBUTtRQUNSLFFBQVE7UUFDUixRQUFRO1FBQ1IsUUFBUTtRQUNSLFFBQVE7UUFDUixRQUFRO1FBQ1IsUUFBUTtRQUNSLFFBQVE7UUFDUixRQUFRLEVBQUcsUUFBUTtLQUNwQixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxJQUk1QjtJQUNDLE1BQU0sRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBQyxHQUFHLElBQUksQ0FBQztJQUN0QyxNQUFNLEVBQUMsRUFBRSxFQUFFLE1BQU0sRUFBQyxHQUFHLE1BQU0sQ0FBQztJQUM1QixNQUFNLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBQyxHQUFHLEtBQUss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SSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUN2RSxVQUFVLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFDdkUsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUM5RCxVQUFVLEVBQUUsY0FBYyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUNoRSxjQUFjLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDM0IsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQWlCO0lBQ3JELFVBQVUsRUFBRSxtQkFBbUI7SUFDL0IsV0FBVyxFQUFFLE1BQU07SUFDbkIsU0FBUyxFQUFFLEtBQUs7SUFDaEIsVUFBVSxFQUFFLG1CQUE0QztDQUN6RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQge2JhY2tlbmRfdXRpbCwgQ29udjJEQmFja3Byb3BJbnB1dCwgQ29udjJEQmFja3Byb3BJbnB1dEF0dHJzLCBDb252MkRCYWNrcHJvcElucHV0SW5wdXRzLCBLZXJuZWxDb25maWcsIEtlcm5lbEZ1bmMsIFRlbnNvckluZm8sIHV0aWx9IGZyb20gJ0B0ZW5zb3JmbG93L3RmanMtY29yZSc7XG5cbmltcG9ydCB7QmFja2VuZFdhc219IGZyb20gJy4uL2JhY2tlbmRfd2FzbSc7XG5cbmxldCB3YXNtQ29udjJEQmFja3Byb3BJbnB1dDogKFxuICAgIGR5SWQ6IG51bWJlciwgZmlsdGVySWQ6IG51bWJlciwgYmF0Y2hTaXplOiBudW1iZXIsIGZpbHRlckhlaWdodDogbnVtYmVyLFxuICAgIGZpbHRlcldpZHRoOiBudW1iZXIsIGluSGVpZ2h0OiBudW1iZXIsIGluV2lkdGg6IG51bWJlciwgaW5DaGFubmVsczogbnVtYmVyLFxuICAgIG91dEhlaWdodDogbnVtYmVyLCBvdXRXaWR0aDogbnVtYmVyLCBvdXRDaGFubmVsczogbnVtYmVyLFxuICAgIHN0cmlkZUhlaWdodDogbnVtYmVyLCBzdHJpZGVXaWR0aDogbnVtYmVyLCB0b3BQYWQ6IG51bWJlciwgbGVmdFBhZDogbnVtYmVyLFxuICAgIGZsdFMwOiBudW1iZXIsIGZsdFMxOiBudW1iZXIsIGZsdFMyOiBudW1iZXIsIHhCYXRjaFN0cmlkZTogbnVtYmVyLFxuICAgIHhSb3dTdHJpZGU6IG51bWJlciwgeENvbFN0cmlkZTogbnVtYmVyLCB4Q2hhbm5lbFN0cmlkZTogbnVtYmVyLFxuICAgIHlCYXRjaFN0cmlkZTogbnVtYmVyLCB5Um93U3RyaWRlOiBudW1iZXIsIHlDb2xTdHJpZGU6IG51bWJlcixcbiAgICB5Q2hhbm5lbFN0cmlkZTogbnVtYmVyLCBvdXRJZDogbnVtYmVyKSA9PiB2b2lkO1xuXG5mdW5jdGlvbiBzZXR1cChiYWNrZW5kOiBCYWNrZW5kV2FzbSk6IHZvaWQge1xuICB3YXNtQ29udjJEQmFja3Byb3BJbnB1dCA9IGJhY2tlbmQud2FzbS5jd3JhcChDb252MkRCYWNrcHJvcElucHV0LCBudWxsLCBbXG4gICAgJ251bWJlcicsICAvLyBkeUlkXG4gICAgJ251bWJlcicsICAvLyBmaWx0ZXJJZFxuICAgICdudW1iZXInLCAgLy8gYmF0Y2hTaXplXG4gICAgJ251bWJlcicsICAvLyBmaWx0ZXJIZWlnaHRcbiAgICAnbnVtYmVyJywgIC8vIGZpbHRlcldpZHRoXG4gICAgJ251bWJlcicsICAvLyBpbkhlaWdodFxuICAgICdudW1iZXInLCAgLy8gaW5XaWR0aFxuICAgICdudW1iZXInLCAgLy8gaW5DaGFubmVsc1xuICAgICdudW1iZXInLCAgLy8gb3V0SGVpZ2h0XG4gICAgJ251bWJlcicsICAvLyBvdXRXaWR0aFxuICAgICdudW1iZXInLCAgLy8gb3V0Q2hhbm5lbHNcbiAgICAnbnVtYmVyJywgIC8vIHN0cmlkZUhlaWdodFxuICAgICdudW1iZXInLCAgLy8gc3RyaWRlV2lkdGhcbiAgICAnbnVtYmVyJywgIC8vIHRvcFBhZFxuICAgICdudW1iZXInLCAgLy8gbGVmdFBhZFxuICAgICdudW1iZXInLCAgLy8gZmx0UzBcbiAgICAnbnVtYmVyJywgIC8vIGZsdFMxXG4gICAgJ251bWJlcicsICAvLyBmbHRTMlxuICAgICdudW1iZXInLCAgLy8geEJhdGNoU3RyaWRlXG4gICAgJ251bWJlcicsICAvLyB4Um93U3RyaWRlXG4gICAgJ251bWJlcicsICAvLyB4Q29sU3RyaWRlXG4gICAgJ251bWJlcicsICAvLyB4Q2hhbm5lbFN0cmlkZVxuICAgICdudW1iZXInLCAgLy8geUJhdGNoU3RyaWRlXG4gICAgJ251bWJlcicsICAvLyB5Um93U3RyaWRlXG4gICAgJ251bWJlcicsICAvLyB5Q29sU3RyaWRlXG4gICAgJ251bWJlcicsICAvLyB5Q2hhbm5lbFN0cmlkZVxuICAgICdudW1iZXInLCAgLy8gb3V0SWRcbiAgXSk7XG59XG5cbmZ1bmN0aW9uIGNvbnYyREJhY2twcm9wSW5wdXQoYXJnczoge1xuICBiYWNrZW5kOiBCYWNrZW5kV2FzbSxcbiAgaW5wdXRzOiBDb252MkRCYWNrcHJvcElucHV0SW5wdXRzLFxuICBhdHRyczogQ29udjJEQmFja3Byb3BJbnB1dEF0dHJzXG59KTogVGVuc29ySW5mbyB7XG4gIGNvbnN0IHtiYWNrZW5kLCBpbnB1dHMsIGF0dHJzfSA9IGFyZ3M7XG4gIGNvbnN0IHtkeSwgZmlsdGVyfSA9IGlucHV0cztcbiAgY29uc3Qge3N0cmlkZXMsIHBhZCwgZGF0YUZvcm1hdCwgZGltUm91bmRpbmdNb2RlLCBpbnB1dFNoYXBlfSA9IGF0dHJzO1xuXG4gIGNvbnN0IGRpbGF0aW9ucyA9IDE7XG5cbiAgY29uc3QgJGRhdGFGb3JtYXQgPSBiYWNrZW5kX3V0aWwuY29udmVydENvbnYyRERhdGFGb3JtYXQoZGF0YUZvcm1hdCk7XG4gIGNvbnN0IGNvbnZJbmZvID0gYmFja2VuZF91dGlsLmNvbXB1dGVDb252MkRJbmZvKFxuICAgICAgaW5wdXRTaGFwZSwgZmlsdGVyLnNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLCBzdHJpZGVzLFxuICAgICAgZGlsYXRpb25zLCBwYWQsIGRpbVJvdW5kaW5nTW9kZSwgZmFsc2UgLyogZGVwdGh3aXNlICovLCAkZGF0YUZvcm1hdCk7XG4gIGNvbnN0IHtcbiAgICBiYXRjaFNpemUsXG4gICAgZmlsdGVySGVpZ2h0LFxuICAgIGZpbHRlcldpZHRoLFxuICAgIGluQ2hhbm5lbHMsXG4gICAgaW5IZWlnaHQsXG4gICAgaW5XaWR0aCxcbiAgICBvdXRDaGFubmVscyxcbiAgICBvdXRIZWlnaHQsXG4gICAgb3V0V2lkdGgsXG4gICAgc3RyaWRlSGVpZ2h0LFxuICAgIHN0cmlkZVdpZHRoXG4gIH0gPSBjb252SW5mbztcblxuICBjb25zdCB0b3BQYWQgPSBmaWx0ZXJIZWlnaHQgLSAxIC0gY29udkluZm8ucGFkSW5mby50b3A7XG4gIGNvbnN0IGxlZnRQYWQgPSBmaWx0ZXJXaWR0aCAtIDEgLSBjb252SW5mby5wYWRJbmZvLmxlZnQ7XG5cbiAgY29uc3QgaXNDaGFubmVsc0xhc3QgPSBjb252SW5mby5kYXRhRm9ybWF0ID09PSAnY2hhbm5lbHNMYXN0JztcbiAgY29uc3QgZHhTdHJpZGVzID0gdXRpbC5jb21wdXRlU3RyaWRlcyhjb252SW5mby5pblNoYXBlKTtcbiAgY29uc3QgZHlTdHJpZGVzID0gdXRpbC5jb21wdXRlU3RyaWRlcyhkeS5zaGFwZSk7XG4gIGNvbnN0IFtmbHRTMCwgZmx0UzEsIGZsdFMyXSA9IHV0aWwuY29tcHV0ZVN0cmlkZXMoZmlsdGVyLnNoYXBlKTtcbiAgY29uc3QgeEJhdGNoU3RyaWRlID0gZHhTdHJpZGVzWzBdO1xuICBjb25zdCB4Um93U3RyaWRlID0gaXNDaGFubmVsc0xhc3QgPyBkeFN0cmlkZXNbMV0gOiBkeFN0cmlkZXNbMl07XG4gIGNvbnN0IHhDb2xTdHJpZGUgPSBpc0NoYW5uZWxzTGFzdCA/IGR4U3RyaWRlc1syXSA6IDE7XG4gIGNvbnN0IHhDaGFubmVsU3RyaWRlID0gaXNDaGFubmVsc0xhc3QgPyAxIDogZHhTdHJpZGVzWzFdO1xuICBjb25zdCB5QmF0Y2hTdHJpZGUgPSBkeVN0cmlkZXNbMF07XG4gIGNvbnN0IHlSb3dTdHJpZGUgPSBpc0NoYW5uZWxzTGFzdCA/IGR5U3RyaWRlc1sxXSA6IGR5U3RyaWRlc1syXTtcbiAgY29uc3QgeUNvbFN0cmlkZSA9IGlzQ2hhbm5lbHNMYXN0ID8gZHlTdHJpZGVzWzJdIDogMTtcbiAgY29uc3QgeUNoYW5uZWxTdHJpZGUgPSBpc0NoYW5uZWxzTGFzdCA/IDEgOiBkeVN0cmlkZXNbMV07XG5cbiAgY29uc3Qgb3V0ID0gYmFja2VuZC5tYWtlT3V0cHV0KGNvbnZJbmZvLmluU2hhcGUsICdmbG9hdDMyJyk7XG4gIGNvbnN0IG91dElkID0gYmFja2VuZC5kYXRhSWRNYXAuZ2V0KG91dC5kYXRhSWQpLmlkO1xuICBjb25zdCBkeUlkID0gYmFja2VuZC5kYXRhSWRNYXAuZ2V0KGR5LmRhdGFJZCkuaWQ7XG4gIGNvbnN0IGZpbHRlcklkID0gYmFja2VuZC5kYXRhSWRNYXAuZ2V0KGZpbHRlci5kYXRhSWQpLmlkO1xuXG4gIHdhc21Db252MkRCYWNrcHJvcElucHV0KFxuICAgICAgZHlJZCwgZmlsdGVySWQsIGJhdGNoU2l6ZSwgZmlsdGVySGVpZ2h0LCBmaWx0ZXJXaWR0aCwgaW5IZWlnaHQsIGluV2lkdGgsXG4gICAgICBpbkNoYW5uZWxzLCBvdXRIZWlnaHQsIG91dFdpZHRoLCBvdXRDaGFubmVscywgc3RyaWRlSGVpZ2h0LCBzdHJpZGVXaWR0aCxcbiAgICAgIHRvcFBhZCwgbGVmdFBhZCwgZmx0UzAsIGZsdFMxLCBmbHRTMiwgeEJhdGNoU3RyaWRlLCB4Um93U3RyaWRlLFxuICAgICAgeENvbFN0cmlkZSwgeENoYW5uZWxTdHJpZGUsIHlCYXRjaFN0cmlkZSwgeVJvd1N0cmlkZSwgeUNvbFN0cmlkZSxcbiAgICAgIHlDaGFubmVsU3RyaWRlLCBvdXRJZCk7XG4gIHJldHVybiBvdXQ7XG59XG5cbmV4cG9ydCBjb25zdCBjb252MkRCYWNrcHJvcElucHV0Q29uZmlnOiBLZXJuZWxDb25maWcgPSB7XG4gIGtlcm5lbE5hbWU6IENvbnYyREJhY2twcm9wSW5wdXQsXG4gIGJhY2tlbmROYW1lOiAnd2FzbScsXG4gIHNldHVwRnVuYzogc2V0dXAsXG4gIGtlcm5lbEZ1bmM6IGNvbnYyREJhY2twcm9wSW5wdXQgYXMgdW5rbm93biBhcyBLZXJuZWxGdW5jXG59O1xuIl19