diff --git a/tfjs-converter/docs/supported_ops.md b/tfjs-converter/docs/supported_ops.md index acf066705d8..d414ee13c69 100644 --- a/tfjs-converter/docs/supported_ops.md +++ b/tfjs-converter/docs/supported_ops.md @@ -232,6 +232,7 @@ |Any|any| |ArgMax|argMax| |ArgMin|argMin| +|Cumsum|cumsum| |Max|max| |Mean|mean| |Min|min| @@ -273,6 +274,7 @@ |Tensorflow Op Name|Tensorflow.js Op Name| |---|---| |BatchToSpaceND|batchToSpaceND| +|BroadcstTo|broadcastTo| |Cast|cast| |DepthToSpace|depthToSpace| |ExpandDims|expandDims| diff --git a/tfjs-converter/python/tensorflowjs/op_list/convolution.json b/tfjs-converter/python/tensorflowjs/op_list/convolution.json index 10d4f8b1e19..e6bfe28c238 100644 --- a/tfjs-converter/python/tensorflowjs/op_list/convolution.json +++ b/tfjs-converter/python/tensorflowjs/op_list/convolution.json @@ -287,6 +287,12 @@ "type": "string", "defaultValue": "NHWC" }, + { + "tfName": "explicit_paddings", + "name": "explicitPaddings", + "type": "number[]", + "defaultValue": [] + }, { "tfName": "dilations", "name": "dilations", @@ -416,6 +422,12 @@ "name": "dataFormat", "type": "string", "notSupported": true + }, + { + "tfName": "explicit_paddings", + "name": "explicitPaddings", + "type": "number[]", + "defaultValue": [] } ] }, @@ -451,6 +463,12 @@ "type": "string", "defaultValue": "NHWC" }, + { + "tfName": "explicit_paddings", + "name": "explicitPaddings", + "type": "number[]", + "defaultValue": [] + }, { "tfName": "dilations", "name": "dilations", @@ -490,6 +508,12 @@ "type": "string", "defaultValue": "NHWC" }, + { + "tfName": "explicit_paddings", + "name": "explicitPaddings", + "type": "number[]", + "defaultValue": [] + }, { "tfName": "dilations", "name": "dilations", diff --git a/tfjs-converter/python/tensorflowjs/op_list/reduction.json b/tfjs-converter/python/tensorflowjs/op_list/reduction.json index bad0d2e7cfd..af1486d4c90 100644 --- a/tfjs-converter/python/tensorflowjs/op_list/reduction.json +++ b/tfjs-converter/python/tensorflowjs/op_list/reduction.json @@ -191,5 +191,33 @@ "type": "bool" } ] + }, + { + "tfOpName": "Cumsum", + "category": "reduction", + "inputs": [ + { + "start": 0, + "name": "x", + "type": "tensor" + }, + { + "start": 1, + "name": "axis", + "type": "number" + } + ], + "attrs": [ + { + "tfName": "exclusive", + "name": "exclusive", + "type": "bool" + }, + { + "tfName": "reverse", + "name": "reverse", + "type": "bool" + } + ] } ] \ No newline at end of file diff --git a/tfjs-converter/python/tensorflowjs/op_list/transformation.json b/tfjs-converter/python/tensorflowjs/op_list/transformation.json index 5fd9292913e..8d270e071bc 100644 --- a/tfjs-converter/python/tensorflowjs/op_list/transformation.json +++ b/tfjs-converter/python/tensorflowjs/op_list/transformation.json @@ -184,5 +184,22 @@ "type": "string" } ] + }, + { + "tfOpName": "BroadcastTo", + "category": "transformation", + "inputs": [ + { + "start": 0, + "name": "x", + "type": "tensor" + }, + { + "start": 1, + "name": "shape", + "type": "number[]" + } + ], + "attrs": [] } ] \ No newline at end of file diff --git a/tfjs-converter/src/operations/executors/reduction_executor.ts b/tfjs-converter/src/operations/executors/reduction_executor.ts index 945b09f46c1..46511b77f20 100644 --- a/tfjs-converter/src/operations/executors/reduction_executor.ts +++ b/tfjs-converter/src/operations/executors/reduction_executor.ts @@ -24,9 +24,9 @@ import {InternalOpExecutor, Node} from '../types'; import {getParamValue} from './utils'; export const executeOp: InternalOpExecutor = (node: Node, - tensorMap: NamedTensorsMap, - context: ExecutionContext): - tfc.Tensor[] => { + tensorMap: NamedTensorsMap, + context: ExecutionContext): + tfc.Tensor[] => { switch (node.op) { case 'Max': { const axis = getParamValue('axis', node, tensorMap, context) as number[]; @@ -94,6 +94,16 @@ export const executeOp: InternalOpExecutor = (node: Node, getParamValue('x', node, tensorMap, context) as tfc.Tensor, axis, keepDims)]; } + case 'Cumsum': { + const axis = getParamValue('axis', node, tensorMap, context) as number; + const exclusive = + getParamValue('exclusive', node, tensorMap, context) as boolean; + const reverse = + getParamValue('reverse', node, tensorMap, context) as boolean; + return [tfc.cumsum( + getParamValue('x', node, tensorMap, context) as tfc.Tensor, axis, + exclusive, reverse)]; + } default: throw TypeError(`Node type ${node.op} is not implemented`); } diff --git a/tfjs-converter/src/operations/executors/reduction_executor_test.ts b/tfjs-converter/src/operations/executors/reduction_executor_test.ts index 2afe346e1a4..e4ec83fb98b 100644 --- a/tfjs-converter/src/operations/executors/reduction_executor_test.ts +++ b/tfjs-converter/src/operations/executors/reduction_executor_test.ts @@ -20,7 +20,7 @@ import {ExecutionContext} from '../../executor/execution_context'; import {Node} from '../types'; import {executeOp} from './reduction_executor'; -import {createBoolAttr, createNumberAttr, createTensorAttr} from './test_helper'; +import {createBoolAttr, createNumberAttr, createNumberAttrFromIndex, createTensorAttr} from './test_helper'; describe('reduction', () => { let node: Node; @@ -68,6 +68,20 @@ describe('reduction', () => { expect(tfc.argMin).toHaveBeenCalledWith(input1[0], 1); }); + describe('Cumsum', () => { + it('should call tfc.cumsum', () => { + spyOn(tfc, 'cumsum'); + node.op = 'Cumsum'; + node.attrParams.exclusive = createBoolAttr(true); + node.attrParams.reverse = createBoolAttr(false); + node.inputNames = ['input1', 'input2']; + node.inputParams.axis = createNumberAttrFromIndex(1); + const input2 = [tfc.scalar(2)]; + executeOp(node, {input1, input2}, context); + + expect(tfc.cumsum).toHaveBeenCalledWith(input1[0], 2, true, false); + }); + }); }); }); }); diff --git a/tfjs-converter/src/operations/executors/transformation_executor.ts b/tfjs-converter/src/operations/executors/transformation_executor.ts index 62fba5759d8..96339c1562b 100644 --- a/tfjs-converter/src/operations/executors/transformation_executor.ts +++ b/tfjs-converter/src/operations/executors/transformation_executor.ts @@ -24,9 +24,9 @@ import {InternalOpExecutor, Node} from '../types'; import {getParamValue, split} from './utils'; export const executeOp: InternalOpExecutor = (node: Node, - tensorMap: NamedTensorsMap, - context: ExecutionContext): - tfc.Tensor[] => { + tensorMap: NamedTensorsMap, + context: ExecutionContext): + tfc.Tensor[] => { switch (node.op) { case 'Cast': { return [tfc.cast( @@ -88,6 +88,11 @@ export const executeOp: InternalOpExecutor = (node: Node, getParamValue('x', node, tensorMap, context) as tfc.Tensor4D, blockSize, dataFormat)]; } + case 'BroadcastTo': { + return [tfc.broadcastTo( + getParamValue('x', node, tensorMap, context) as tfc.Tensor, + getParamValue('shape', node, tensorMap, context) as number[])]; + } default: throw TypeError(`Node type ${node.op} is not implemented`); } diff --git a/tfjs-converter/src/operations/executors/transformation_executor_test.ts b/tfjs-converter/src/operations/executors/transformation_executor_test.ts index b199c727e27..acb068d5539 100644 --- a/tfjs-converter/src/operations/executors/transformation_executor_test.ts +++ b/tfjs-converter/src/operations/executors/transformation_executor_test.ts @@ -153,5 +153,17 @@ describe('transformation', () => { expect(tfc.depthToSpace).toHaveBeenCalledWith(input1[0], 1, 'NHWC'); }); }); + describe('BroadcastTo', () => { + it('should call tfc.broadcastTo', () => { + spyOn(tfc, 'broadcastTo'); + node.op = 'BroadcastTo'; + node.inputParams.shape = createNumericArrayAttrFromIndex(1); + node.inputNames = ['input1', 'input2']; + + executeOp(node, {input1, input2}, context); + + expect(tfc.broadcastTo).toHaveBeenCalledWith(input1[0], [1, 1]); + }); + }); }); }); diff --git a/tfjs-converter/src/operations/op_list/convolution.ts b/tfjs-converter/src/operations/op_list/convolution.ts index 6d1c76e6252..9665afa7a30 100644 --- a/tfjs-converter/src/operations/op_list/convolution.ts +++ b/tfjs-converter/src/operations/op_list/convolution.ts @@ -147,6 +147,12 @@ export const json: OpMapper[] = [ 'type': 'string', 'defaultValue': 'NHWC' }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + }, {'tfName': 'dilations', 'name': 'dilations', 'type': 'number[]'} ] }, @@ -211,12 +217,19 @@ export const json: OpMapper[] = [ ], 'attrs': [ {'tfName': 'strides', 'name': 'strides', 'type': 'number[]'}, - {'tfName': 'padding', 'name': 'pad', 'type': 'string'}, { + {'tfName': 'padding', 'name': 'pad', 'type': 'string'}, + { 'tfName': 'data_format', 'name': 'dataFormat', 'type': 'string', 'notSupported': true - } + }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + }, ] }, { @@ -234,6 +247,12 @@ export const json: OpMapper[] = [ 'type': 'string', 'defaultValue': 'NHWC' }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + }, {'tfName': 'dilations', 'name': 'dilations', 'type': 'number[]'} ] }, @@ -252,6 +271,12 @@ export const json: OpMapper[] = [ 'type': 'string', 'defaultValue': 'NHWC' }, + { + 'tfName': 'explicit_paddings', + 'name': 'explicitPaddings', + 'type': 'number[]', + 'defaultValue': [] + }, {'tfName': 'dilations', 'name': 'dilations', 'type': 'number[]'} ] }, diff --git a/tfjs-converter/src/operations/op_list/reduction.ts b/tfjs-converter/src/operations/op_list/reduction.ts index fb6c5853ddf..124f208b679 100644 --- a/tfjs-converter/src/operations/op_list/reduction.ts +++ b/tfjs-converter/src/operations/op_list/reduction.ts @@ -96,5 +96,17 @@ export const json: OpMapper[] = [ {'start': 1, 'name': 'axis', 'type': 'number[]'}, ], 'attrs': [{'tfName': 'keep_dims', 'name': 'keepDims', 'type': 'bool'}] + }, + { + 'tfOpName': 'Cumsum', + 'category': 'reduction', + 'inputs': [ + {'start': 0, 'name': 'x', 'type': 'tensor'}, + {'start': 1, 'name': 'axis', 'type': 'number'}, + ], + 'attrs': [ + {'tfName': 'exclusive', 'name': 'exclusive', 'type': 'bool'}, + {'tfName': 'reverse', 'name': 'reverse', 'type': 'bool'} + ] } ]; diff --git a/tfjs-converter/src/operations/op_list/transformation.ts b/tfjs-converter/src/operations/op_list/transformation.ts index d729ec94e7f..f8ca864789a 100644 --- a/tfjs-converter/src/operations/op_list/transformation.ts +++ b/tfjs-converter/src/operations/op_list/transformation.ts @@ -118,5 +118,14 @@ export const json: OpMapper[] = [ {'tfName': 'block_size', 'name': 'blockSize', 'type': 'number'}, {'tfName': 'data_format', 'name': 'dataFormat', 'type': 'string'} ] + }, + { + 'tfOpName': 'BroadcastTo', + 'category': 'transformation', + 'inputs': [ + {'start': 0, 'name': 'x', 'type': 'tensor'}, + {'start': 1, 'name': 'shape', 'type': 'number[]'}, + ], + 'attrs': [] } ];