Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ describe('basic math', () => {
node.op = 'Prod';
node.inputParams['axes'] = createNumericArrayAttrFromIndex(1);
node.inputNames = ['input1', 'input2'];
const input2 = [tfc.scalar(2)];
const input2 = [tfc.tensor1d([2])];
executeOp(node, {input1, input2}, context);

expect(tfc.prod).toHaveBeenCalledWith(input1[0], [2]);
Expand Down
10 changes: 5 additions & 5 deletions tfjs-converter/src/operations/executors/convolution_executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {NamedTensorsMap} from '../../data/types';
import {ExecutionContext} from '../../executor/execution_context';
import {InternalOpExecutor, Node} from '../types';

import {getParamValue} from './utils';
import {getPadding, getParamValue} from './utils';

export const executeOp: InternalOpExecutor = (node: Node,
tensorMap: NamedTensorsMap,
Expand All @@ -46,7 +46,7 @@ export const executeOp: InternalOpExecutor = (node: Node,
case 'Conv2D': {
const stride =
getParamValue('strides', node, tensorMap, context) as number[];
const pad = getParamValue('pad', node, tensorMap, context);
const pad = getPadding(node, tensorMap, context);
const dataFormat =
(getParamValue('dataFormat', node, tensorMap, context) as string)
.toUpperCase();
Expand Down Expand Up @@ -88,7 +88,7 @@ export const executeOp: InternalOpExecutor = (node: Node,
}
const stride =
getParamValue('strides', node, tensorMap, context) as number[];
const pad = getParamValue('pad', node, tensorMap, context);
const pad = getPadding(node, tensorMap, context);
const dataFormat =
(getParamValue('dataFormat', node, tensorMap, context) as string)
.toUpperCase();
Expand Down Expand Up @@ -121,7 +121,7 @@ export const executeOp: InternalOpExecutor = (node: Node,
[number, number, number, number];
const stride =
getParamValue('strides', node, tensorMap, context) as number[];
const pad = getParamValue('pad', node, tensorMap, context);
const pad = getPadding(node, tensorMap, context);
return [tfc.conv2dTranspose(
getParamValue('x', node, tensorMap, context) as tfc.Tensor3D |
tfc.Tensor4D,
Expand All @@ -132,7 +132,7 @@ export const executeOp: InternalOpExecutor = (node: Node,
case 'DepthwiseConv2d': {
const stride =
getParamValue('strides', node, tensorMap, context) as number[];
const pad = getParamValue('pad', node, tensorMap, context);
const pad = getPadding(node, tensorMap, context);
const dilations =
getParamValue('dilations', node, tensorMap, context) as number[];
const dataFormat =
Expand Down
134 changes: 133 additions & 1 deletion tfjs-converter/src/operations/executors/convolution_executor_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@ describe('convolution', () => {
.toHaveBeenCalledWith(
input1[0], input2[0], [2, 2], 'same', 'NHWC', [2, 2]);
});
it('should support explicit padding', () => {
spyOn(tfc, 'conv2d');
node.op = 'Conv2D';
node.inputParams['filter'] = createTensorAttr(1);
node.attrParams['strides'] = createNumericArrayAttr([1, 2, 2, 1]);
node.attrParams['pad'] = createStrAttr('explicit');
node.attrParams['explicitPaddings'] =
createNumericArrayAttr([0, 0, 1, 1, 2, 2, 0, 0]);
node.attrParams['dataFormat'] = createStrAttr('NHWC');
node.attrParams['dilations'] = createNumericArrayAttr([1, 2, 2, 1]);

const input1 = [tfc.scalar(1.0)];
const input2 = [tfc.scalar(1.0)];
node.inputNames = ['input1', 'input2'];

executeOp(node, {input1, input2}, context);

expect(tfc.conv2d)
.toHaveBeenCalledWith(
input1[0], input2[0], [2, 2], [[0, 0], [1, 1], [2, 2], [0, 0]],
'NHWC', [2, 2]);
});
});
describe('Conv2DBackpropInput', () => {
it('should call tfc.conv2dTranspose', () => {
Expand All @@ -111,6 +133,31 @@ describe('convolution', () => {
.toHaveBeenCalledWith(
input1[0], input2[0], [1, 2, 2, 2], [2, 2], 'same');
});
it('should support explicit padding', () => {
spyOn(tfc, 'conv2dTranspose');
node.op = 'Conv2DBackpropInput';
node.attrParams['outputShape'] = createNumericArrayAttr([1, 2, 2, 2]);
node.inputParams['filter'] = createTensorAttr(1);
node.attrParams['strides'] = createNumericArrayAttr([1, 2, 2, 1]);
node.attrParams['pad'] = createStrAttr('explicit');
node.attrParams['explicitPaddings'] =
createNumericArrayAttr([0, 0, 1, 1, 2, 2, 0, 0]);

const input1 = [tfc.scalar(1.0)];
const input2 = [tfc.scalar(1.0)];
node.inputNames = ['input1', 'input2'];

executeOp(node, {input1, input2}, context);

expect(tfc.conv2dTranspose)
.toHaveBeenCalledWith(
input1[0],
input2[0],
[1, 2, 2, 2],
[2, 2],
[[0, 0], [1, 1], [2, 2], [0, 0]],
);
});
});
describe('Conv1D', () => {
it('should call tfc.conv1d', () => {
Expand Down Expand Up @@ -155,6 +202,29 @@ describe('convolution', () => {
.toHaveBeenCalledWith(
input1[0], input2[0], [2, 2], 'same', 'NHWC', [2, 2]);
});
it('support explicit padding', () => {
spyOn(tfc, 'depthwiseConv2d');
node.op = 'DepthwiseConv2d';
node.category = 'convolution';
node.inputParams['input'] = createTensorAttr(0);
node.inputParams['filter'] = createTensorAttr(1);
node.attrParams['strides'] = createNumericArrayAttr([1, 2, 2, 1]);
node.attrParams['pad'] = createStrAttr('explicit');
node.attrParams['explicitPaddings'] =
createNumericArrayAttr([0, 0, 1, 1, 2, 2, 0, 0]);
node.attrParams['dataFormat'] = createStrAttr('NHWC');
node.attrParams['dilations'] = createNumericArrayAttr([1, 2, 2, 1]);
const input1 = [tfc.scalar(1.0)];
const input2 = [tfc.scalar(1.0)];
node.inputNames = ['input1', 'input2'];

executeOp(node, {input1, input2}, context);

expect(tfc.depthwiseConv2d)
.toHaveBeenCalledWith(
input1[0], input2[0], [2, 2], [[0, 0], [1, 1], [2, 2], [0, 0]],
'NHWC', [2, 2]);
});
});

describe('Conv3d', () => {
Expand Down Expand Up @@ -257,7 +327,38 @@ describe('convolution', () => {
preluActivationWeights: undefined
});
});
it('should support explicit padding', () => {
spyOn(tfc.fused, 'conv2d');
node.op = '_FusedConv2D';
node.inputParams['filter'] = createTensorAttr(1);
node.inputParams['args'] = createTensorsAttr(2, 0);
node.attrParams['fusedOps'] = createStrArrayAttr(['biasadd', 'relu']);
node.attrParams['strides'] = createNumericArrayAttr([1, 2, 2, 1]);
node.attrParams['pad'] = createStrAttr('explicit');
node.attrParams['explicitPaddings'] =
createNumericArrayAttr([0, 0, 1, 1, 2, 2, 0, 0]);
node.attrParams['dataFormat'] = createStrAttr('NHWC');
node.attrParams['dilations'] = createNumericArrayAttr([1, 2, 2, 1]);
node.attrParams['numArgs'] = createNumberAttr(1);
const input1 = [tfc.scalar(1.0)];
const input2 = [tfc.scalar(2.0)];
const input3 = [tfc.scalar(3.0)];

node.inputNames = ['input1', 'input2', 'input3'];
executeOp(node, {input1, input2, input3}, context);

expect(tfc.fused.conv2d).toHaveBeenCalledWith({
x: input1[0],
filter: input2[0],
strides: [2, 2],
pad: [[0, 0], [1, 1], [2, 2], [0, 0]],
dataFormat: 'NHWC',
dilations: [2, 2],
bias: input3[0],
activation: 'relu',
preluActivationWeights: undefined
});
});
it('with bias and prelu activation func', () => {
spyOn(tfc.fused, 'conv2d');
node.op = '_FusedConv2D';
Expand Down Expand Up @@ -341,6 +442,38 @@ describe('convolution', () => {
});
});
describe('FusedDepthwiseConv2d', () => {
it('support explicit padding', () => {
spyOn(tfc.fused, 'depthwiseConv2d');
node.op = 'FusedDepthwiseConv2dNative';
node.inputParams['filter'] = createTensorAttr(1);
node.inputParams['args'] = createTensorsAttr(2, 0);
node.attrParams['fusedOps'] = createStrArrayAttr(['biasadd', 'relu']);
node.attrParams['strides'] = createNumericArrayAttr([1, 2, 2, 1]);
node.attrParams['pad'] = createStrAttr('explicit');
node.attrParams['explicitPaddings'] =
createNumericArrayAttr([0, 0, 1, 1, 2, 2, 0, 0]);
node.attrParams['dataFormat'] = createStrAttr('NHWC');
node.attrParams['dilations'] = createNumericArrayAttr([1, 2, 2, 1]);
node.attrParams['numArgs'] = createNumberAttr(1);
const input1 = [tfc.scalar(1.0)];
const input2 = [tfc.scalar(2.0)];
const input3 = [tfc.scalar(3.0)];

node.inputNames = ['input1', 'input2', 'input3'];
executeOp(node, {input1, input2, input3}, context);

expect(tfc.fused.depthwiseConv2d).toHaveBeenCalledWith({
x: input1[0],
filter: input2[0],
strides: [2, 2],
pad: [[0, 0], [1, 1], [2, 2], [0, 0]],
dataFormat: 'NHWC',
dilations: [2, 2],
bias: input3[0],
activation: 'relu',
preluActivationWeights: undefined
});
});
it('with bias and activation func', () => {
spyOn(tfc.fused, 'depthwiseConv2d');
node.op = 'FusedDepthwiseConv2dNative';
Expand Down Expand Up @@ -371,7 +504,6 @@ describe('convolution', () => {
preluActivationWeights: undefined
});
});

it('with bias and prelu activation func', () => {
spyOn(tfc.fused, 'depthwiseConv2d');
node.op = 'FusedDepthwiseConv2dNative';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ describe('normalization', () => {
node.inputParams.sparseValues = createTensorAttr(2);
node.inputParams.defaultValue = createTensorAttr(3);
node.inputNames = ['input1', 'input2', 'input3', 'input4'];
const input2 = [tfc.scalar(1)];
const input2 = [tfc.tensor1d([1], 'int32')];
const input3 = [tfc.scalar(2)];
const input4 = [tfc.scalar(3)];
executeOp(node, {input1, input2, input3, input4}, context);
Expand Down
35 changes: 19 additions & 16 deletions tfjs-converter/src/operations/executors/slice_join_executor_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,10 @@ describe('slice join', () => {
spyOn(tfc, 'reverse');
node.op = 'Reverse';
node.inputParams.axis = createNumericArrayAttrFromIndex(1);
node.inputNames = ['input1', 'input2'];
executeOp(node, {input1, input2}, context);
node.inputNames = ['input1', 'input4'];
executeOp(node, {input1, input4}, context);

expect(tfc.reverse).toHaveBeenCalledWith(input1[0], [2]);
expect(tfc.reverse).toHaveBeenCalledWith(input1[0], [3]);
});
it('should match json def for reverse', () => {
node.op = 'Reverse';
Expand All @@ -196,10 +196,10 @@ describe('slice join', () => {
spyOn(tfc, 'reverse');
node.op = 'ReverseV2';
node.inputParams.axis = createNumericArrayAttrFromIndex(1);
node.inputNames = ['input1', 'input2'];
executeOp(node, {input1, input2}, context);
node.inputNames = ['input1', 'input4'];
executeOp(node, {input1, input4}, context);

expect(tfc.reverse).toHaveBeenCalledWith(input1[0], [2]);
expect(tfc.reverse).toHaveBeenCalledWith(input1[0], [3]);
});
it('should match json def for reverse', () => {
node.op = 'ReverseV2';
Expand All @@ -211,10 +211,10 @@ describe('slice join', () => {
spyOn(tfc, 'tile');
node.op = 'Tile';
node.inputParams.reps = createNumericArrayAttrFromIndex(1);
node.inputNames = ['input1', 'input2'];
executeOp(node, {input1, input2}, context);
node.inputNames = ['input1', 'input4'];
executeOp(node, {input1, input4}, context);

expect(tfc.tile).toHaveBeenCalledWith(input1[0], [2]);
expect(tfc.tile).toHaveBeenCalledWith(input1[0], [3]);
});
it('should match json def for tile', () => {
node.op = 'Tile';
Expand All @@ -227,9 +227,10 @@ describe('slice join', () => {
node.op = 'Slice';
node.inputParams.begin = createNumericArrayAttrFromIndex(1);
node.inputParams.size = createNumericArrayAttrFromIndex(2);
node.inputNames = ['input1', 'input2', 'input3'];
const input6 = [tfc.tensor1d([2], 'int32')];
node.inputNames = ['input1', 'input6', 'input4'];

executeOp(node, {input1, input2, input3}, context);
executeOp(node, {input1, input6, input4}, context);

expect(tfc.slice).toHaveBeenCalledWith(input1[0], [2], [3]);
});
Expand All @@ -251,8 +252,10 @@ describe('slice join', () => {
node.attrParams.ellipsisMask = createNumberAttr(1);
node.attrParams.newAxisMask = createNumberAttr(2);
node.attrParams.shrinkAxisMask = createNumberAttr(3);
node.inputNames = ['input1', 'input2', 'input3', 'input4'];
executeOp(node, {input1, input2, input3, input4}, context);
node.inputNames = ['input1', 'input6', 'input7', 'input4'];
const input6 = [tfc.tensor1d([2], 'int32')];
const input7 = [tfc.tensor1d([3], 'int32')];
executeOp(node, {input1, input6, input7, input4}, context);

expect(tfc.stridedSlice)
.toHaveBeenCalledWith(input1[0], [2], [3], [3], 4, 5, 1, 2, 3);
Expand Down Expand Up @@ -367,7 +370,7 @@ describe('slice join', () => {
node.inputNames = ['input1', 'input2', 'input3'];
executeOp(node, {input1, input2, input3}, context);

expect(tfc.split).toHaveBeenCalledWith(input1[0], [2], 3);
expect(tfc.split).toHaveBeenCalledWith(input1[0], 2, 3);
});
it('should match json def for split', () => {
node.op = 'SplitV';
Expand All @@ -383,8 +386,8 @@ describe('slice join', () => {
node.inputParams.indices = createTensorAttr(0);
node.inputParams.values = createTensorAttr(1);
node.inputParams.shape = createNumericArrayAttrFromIndex(2);
node.inputNames = ['input1', 'input2', 'input3'];
executeOp(node, {input1, input2, input3}, context);
node.inputNames = ['input1', 'input2', 'input4'];
executeOp(node, {input1, input2, input4}, context);

expect(tfc.scatterND).toHaveBeenCalledWith(input1[0], input2[0], [3]);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {NamedTensorsMap} from '../../data/types';
import {ExecutionContext} from '../../executor/execution_context';
import {InternalOpExecutor, Node} from '../types';

import {getParamValue, split} from './utils';
import {getParamValue} from './utils';

export const executeOp: InternalOpExecutor = (node: Node,
tensorMap: NamedTensorsMap,
Expand Down Expand Up @@ -54,25 +54,24 @@ export const executeOp: InternalOpExecutor = (node: Node,
case 'Pad': {
return [tfc.pad(
getParamValue('x', node, tensorMap, context) as tfc.Tensor,
split(
getParamValue('padding', node, tensorMap, context) as number[],
2) as Array<[number, number]>,
getParamValue('padding', node, tensorMap, context) as
Array<[number, number]>,
getParamValue('constantValue', node, tensorMap, context) as number)];
}
case 'SpaceToBatchND': {
const blockShape =
getParamValue('blockShape', node, tensorMap, context) as number[];
const paddings = split(
getParamValue('paddings', node, tensorMap, context) as number[], 2);
const paddings =
getParamValue('paddings', node, tensorMap, context) as number[][];
return [tfc.spaceToBatchND(
getParamValue('x', node, tensorMap, context) as tfc.Tensor,
blockShape, paddings)];
}
case 'BatchToSpaceND': {
const blockShape =
getParamValue('blockShape', node, tensorMap, context) as number[];
const crops = split(
getParamValue('crops', node, tensorMap, context) as number[], 2);
const crops =
getParamValue('crops', node, tensorMap, context) as number[][];
return [tfc.batchToSpaceND(
getParamValue('x', node, tensorMap, context) as tfc.Tensor,
blockShape, crops)];
Expand Down
Loading