Skip to content

Commit

Permalink
Merge pull request #293 from Honry/mloperand-method
Browse files Browse the repository at this point in the history
Convert MLOperand methods into readonly attributes
  • Loading branch information
huningxin authored Oct 30, 2024
2 parents 41ca020 + bb45b24 commit 77a98b9
Show file tree
Hide file tree
Showing 15 changed files with 96 additions and 42 deletions.
11 changes: 7 additions & 4 deletions face_recognition/facenet_nchw.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ export class FaceNetNchw {
}

input = await input;

const isShapeMethod = typeof input.shape === 'function';
const inputShape = isShapeMethod ? input.shape() : input.shape;
const weightsShape = isShapeMethod ? weights.shape() : weights.shape;
// WebNN spec drops autoPad support, compute the explicit padding instead.
if (options.autoPad == 'same-upper') {
options.padding =
computePadding2DForAutoPad(
/* nchw */[input.shape()[2], input.shape()[3]],
/* oihw */[weights.shape()[2], weights.shape()[3]],
/* nchw */[inputShape[2], inputShape[3]],
/* oihw */[weightsShape[2], weightsShape[3]],
options.strides, options.dilations, options.autoPad);
}
const conv2d = this.builder_.conv2d(input, weights, options);
Expand Down Expand Up @@ -266,7 +268,8 @@ export class FaceNetNchw {

const averagePool = this.builder_.averagePool2d(await block8_6);
// Use reshape to implement squeeze(averagePool, {axes: [2, 3]});
const squeezed_shape = averagePool.shape();
const squeezed_shape = typeof averagePool.shape === 'function' ?
averagePool.shape() : averagePool.shape;
squeezed_shape.splice(2, 2);
const squeeze = this.builder_.reshape(averagePool, squeezed_shape);
const gemm = await this.buildGemm_(squeeze);
Expand Down
8 changes: 5 additions & 3 deletions face_recognition/facenet_nhwc.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ export class FaceNetNhwc {
}

input = await input;

const isShapeMethod = typeof input.shape === 'function';
const inputShape = isShapeMethod ? input.shape() : input.shape;
const weightsShape = isShapeMethod ? weights.shape() : weights.shape;
// WebNN spec drops autoPad support, compute the explicit padding instead.
if (options.autoPad == 'same-upper') {
options.padding =
computePadding2DForAutoPad(
/* nwhc */[input.shape()[1], input.shape()[2]],
/* ohwi */[weights.shape()[1], weights.shape()[2]],
/* nwhc */[inputShape[1], inputShape[2]],
/* ohwi */[weightsShape[1], weightsShape[2]],
options.strides, options.dilations, options.autoPad);
}
const conv2d = this.builder_.conv2d(input, weights, options);
Expand Down
8 changes: 6 additions & 2 deletions facial_landmark_detection/ssd_mobilenetv2_face_nchw.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,12 @@ ${nameArray[1]}`;
const weights = buildConstantByNpy(this.builder_, weightsName);
const biasName = prefix + biasSuffix;
const bias = buildConstantByNpy(this.builder_, biasName);
const inputShape = (await input).shape();
const weightsShape = (await weights).shape();

const isShapeMethod = typeof (await input).shape === 'function';
const inputShape = isShapeMethod ? (await input).shape() :
(await input).shape;
const weightsShape = isShapeMethod ? (await weights).shape() :
(await weights).shape;
options.padding = computePadding2DForAutoPad(
/* nchw */[inputShape[2], inputShape[3]],
/* oihw */[weightsShape[2], weightsShape[3]],
Expand Down
7 changes: 5 additions & 2 deletions facial_landmark_detection/ssd_mobilenetv2_face_nhwc.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,11 @@ ${nameArray[1]}`;
options.filterLayout = 'ihwo';
}
options.bias = await bias;
const inputShape = (await input).shape();
const weightsShape = (await weights).shape();
const isShapeMethod = typeof (await input).shape === 'function';
const inputShape = isShapeMethod ? (await input).shape() :
(await input).shape;
const weightsShape = isShapeMethod ? (await weights).shape() :
(await weights).shape;
options.padding = computePadding2DForAutoPad(
/* nhwc */[inputShape[1], inputShape[2]],
/* ohwi or ihwo */[weightsShape[1], weightsShape[2]],
Expand Down
7 changes: 5 additions & 2 deletions image_classification/mobilenet_nhwc.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ export class MobileNetV2Nhwc {
options.bias = await bias;
// WebNN spec drops autoPad support, compute the explicit padding instead.
if (options.autoPad == 'same-upper') {
const isShapeMethod = typeof weights.shape === 'function';
const inputShape = isShapeMethod ? (await input).shape() : (await input).shape;
const weightsShape = isShapeMethod ? weights.shape() : weights.shape;
options.padding =
computePadding2DForAutoPad(
/* nwhc */[await input.shape()[1], await input.shape()[2]],
/* ohwi or ihwo */[weights.shape()[1], weights.shape()[2]],
/* nwhc */[inputShape[1], inputShape[2]],
/* ohwi or ihwo */[weightsShape[1], weightsShape[2]],
options.strides, options.dilations, options.autoPad);
}
const conv2d = this.builder_.conv2d(await input, weights, options);
Expand Down
12 changes: 9 additions & 3 deletions image_classification/resnet50v2_nhwc.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,14 @@ export class ResNet50V2Nhwc {
options.bias = await bias;
// WebNN spec drops autoPad support, compute the explicit padding instead.
if (options.autoPad == 'same-upper') {
const isShapeMethod = typeof weights.shape === 'function';
const inputShape = isShapeMethod ? (await input).shape() :
(await input).shape;
const weightsShape = isShapeMethod ? weights.shape() : weights.shape;
options.padding =
computePadding2DForAutoPad(
/* nwhc */[await input.shape()[1], await input.shape()[2]],
/* ohwi */[weights.shape()[1], weights.shape()[2]],
/* nwhc */[inputShape[1], inputShape[2]],
/* ohwi */[weightsShape[1], weightsShape[2]],
options.strides, options.dilations, options.autoPad);
}
const conv2d = this.builder_.conv2d(await input, weights, options);
Expand Down Expand Up @@ -141,10 +145,12 @@ export class ResNet50V2Nhwc {
const conv1 = await this.buildConv_(
input, ['', '', '1'], {strides, padding: [3, 3, 3, 3]}, false);
const windowDimensions = [3, 3];
const conv1Shape = typeof conv1.shape === 'function' ?
conv1.shape() : conv1.shape;
const pool = this.builder_.maxPool2d(
conv1, {windowDimensions, strides, layout,
padding: computePadding2DForAutoPad(
/* nhwc */ [conv1.shape()[1], conv1.shape()[2]],
/* nhwc */ [conv1Shape[1], conv1Shape[2]],
windowDimensions, strides, /* dilations */ undefined,
'same-upper')});
// Block 1
Expand Down
8 changes: 6 additions & 2 deletions image_classification/squeezenet_nhwc.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ export class SqueezeNetNhwc {
options.bias = await bias;
// WebNN spec drops autoPad support, compute the explicit padding instead.
if (options.autoPad == 'same-upper') {
const isShapeMethod = typeof weights.shape === 'function';
const inputShape = isShapeMethod ? (await input).shape() :
(await input).shape;
const weightsShape = isShapeMethod ? weights.shape() : weights.shape;
options.padding =
computePadding2DForAutoPad(
/* nwhc */[await input.shape()[1], await input.shape()[2]],
/* ohwi */[weights.shape()[1], weights.shape()[2]],
/* nwhc */[inputShape[1], inputShape[2]],
/* ohwi */[weightsShape[1], weightsShape[2]],
options.strides, options.dilations, options.autoPad);
}
const conv2d = this.builder_.conv2d(await input, weights, options);
Expand Down
22 changes: 14 additions & 8 deletions nnotepad/js/nnotepad.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,21 @@ const kArgTypeOperand = 3;

class WebNNUtil {
static bufferForOperand(operand) {
const size = [...operand.shape()].reduce((a, b) => a * b, 1);
const ctor = WebNNUtil.dataTypeToBufferType(operand.dataType());
const isShapeMethod = typeof operand.shape === 'function';
const operandShape = isShapeMethod ? operand.shape() : operand.shape;
const operandDataType = isShapeMethod ? operand.dataType() :
operand.dataType;
const size = [...operandShape].reduce((a, b) => a * b, 1);
const ctor = WebNNUtil.dataTypeToBufferType(operandDataType);
return Reflect.construct(ctor, [size]);
}

static async tensorForOperand(operand, context) {
const isShapeMethod = typeof operand.shape === 'function';
const desc = {
dataType: operand.dataType(),
dimensions: operand.shape(),
shape: operand.shape(),
dataType: isShapeMethod ? operand.dataType() : operand.dataType,
dimensions: isShapeMethod ? operand.shape() : operand.shape,
shape: isShapeMethod ? operand.shape() : operand.shape,
usage: MLTensorUsage.READ,
readable: true,
};
Expand Down Expand Up @@ -613,9 +618,10 @@ export class NNotepad {

return outputOperands.map(
(op, index) => ({
dataType: op.dataType(),
dimensions: op.shape(),
shape: op.shape(),
dataType: typeof op.shape === 'function' ? op.dataType() :
op.dataType,
dimensions: typeof op.shape === 'function' ? op.shape() : op.shape,
shape: typeof op.shape === 'function' ? op.shape() : op.shape,
buffer: maybeProxyForFloat16Array(outputBuffers[`output-${index}`]),
}));
}
Expand Down
5 changes: 3 additions & 2 deletions nsnet2/nsnet2.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export class NSNet2 {
const [gru94, gru93] = this.builder_.gru(transpose31, weight192, recurrentWeight193, frames, this.hiddenSize,
{bias: bias194, recurrentBias: recurrentBias194, initialHiddenState: initialState92, returnSequence: true});
// Use reshape to implement squeeze(gru93, {axes: [1]});
const squeeze95Shape = gru93.shape();
const isShapeMethod = typeof gru93.shape === 'function';
const squeeze95Shape = isShapeMethod ? gru93.shape() : gru93.shape;
squeeze95Shape.splice(1, 1);
const squeeze95 = this.builder_.reshape(gru93, squeeze95Shape);
const initialState155 = this.builder_.input('initialState155', initialStateDesc);
Expand Down Expand Up @@ -89,7 +90,7 @@ export class NSNet2 {
const [gru157, gru156] = this.builder_.gru(squeeze95, weight212, recurrentWeight213, frames, this.hiddenSize,
{bias: bias214, recurrentBias: recurrentBias214, initialHiddenState: initialState155, returnSequence: true});
// Use reshape to implement squeeze(gru156, {axes: [1]});
const squeeze158Shape = gru156.shape();
const squeeze158Shape = isShapeMethod ? gru156.shape() : gru156.shape;
squeeze158Shape.splice(1, 1);
const squeeze158 = this.builder_.reshape(gru156, squeeze158Shape);
const transpose159 = this.builder_.transpose(squeeze158, {permutation: [1, 0, 2]});
Expand Down
7 changes: 5 additions & 2 deletions object_detection/ssd_mobilenetv1_nchw.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,12 @@ ${nameArray[1]}_BatchNorm_batchnorm`;
const biasName = this.biasUrl_ + prefix + biasSuffix;
const bias = await buildConstantByNpy(
this.builder_, biasName, this.targetDataType_);
const isShapeMethod = typeof input.shape === 'function';
const inputShape = isShapeMethod ? input.shape() : input.shape;
const weightsShape = isShapeMethod ? weights.shape() : weights.shape;
options.padding = computePadding2DForAutoPad(
/* nchw */[input.shape()[2], input.shape()[3]],
/* oihw */[weights.shape()[2], weights.shape()[3]],
/* nchw */[inputShape[2], inputShape[3]],
/* oihw */[weightsShape[2], weightsShape[3]],
options.strides, options.dilations, 'same-upper');
options.bias = bias;
const conv2d = this.builder_.conv2d(input, weights, options);
Expand Down
7 changes: 5 additions & 2 deletions object_detection/ssd_mobilenetv1_nhwc.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,12 @@ ${nameArray[1]}_BatchNorm_batchnorm`;
options.filterLayout = 'ihwo';
}
options.bias = bias;
const isShapeMethod = typeof input.shape === 'function';
const inputShape = isShapeMethod ? input.shape() : input.shape;
const weightsShape = isShapeMethod ? weights.shape() : weights.shape;
options.padding = computePadding2DForAutoPad(
/* nhwc */[input.shape()[1], input.shape()[2]],
/* ohwi or ihwo */[weights.shape()[1], weights.shape()[2]],
/* nhwc */[inputShape[1], inputShape[2]],
/* ohwi or ihwo */[weightsShape[1], weightsShape[2]],
options.strides, options.dilations, 'same-upper');
const conv2d = this.builder_.conv2d(input, weights, options);
if (relu6) {
Expand Down
11 changes: 8 additions & 3 deletions object_detection/tiny_yolov2_nchw.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ export class TinyYoloV2Nchw {
const weight = await buildConstantByNpy(
this.builder_, weightName, this.targetDataType_);
const options = {autoPad: 'same-upper'};
const isShapeMethod = typeof input.shape === 'function';
const inputShape = isShapeMethod ? input.shape() : input.shape;
const weightShape = isShapeMethod ? weight.shape() : weight.shape;
options.padding = computePadding2DForAutoPad(
/* nchw */[input.shape()[2], input.shape()[3]],
/* oihw */[weight.shape()[2], weight.shape()[3]],
/* nchw */[inputShape[2], inputShape[3]],
/* oihw */[weightShape[2], weightShape[3]],
options.strides, options.dilations, 'same-upper');
options.bias = await buildConstantByNpy(
this.builder_, biasName, this.targetDataType_);
Expand All @@ -52,8 +55,10 @@ export class TinyYoloV2Nchw {
}

buildMaxPool2d_(input, options) {
const isShapeMethod = typeof input.shape === 'function';
const inputShape = isShapeMethod ? input.shape() : input.shape;
options.padding = computePadding2DForAutoPad(
/* nchw */[input.shape()[2], input.shape()[3]],
/* nchw */[inputShape[2], inputShape[3]],
options.windowDimensions,
options.strides, options.dilations, 'same-upper');
return this.builder_.maxPool2d(input, options);
Expand Down
11 changes: 8 additions & 3 deletions object_detection/tiny_yolov2_nhwc.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@ export class TinyYoloV2Nhwc {
filterLayout: 'ohwi',
};
options.bias = bias;
const isShapeMethod = typeof input.shape === 'function';
const inputShape = isShapeMethod ? input.shape() : input.shape;
const weightsShape = isShapeMethod ? weights.shape() : weights.shape;
options.padding = computePadding2DForAutoPad(
/* nhwc */[input.shape()[1], input.shape()[2]],
/* ohwi */[weights.shape()[1], weights.shape()[2]],
/* nhwc */[inputShape[1], inputShape[2]],
/* ohwi */[weightsShape[1], weightsShape[2]],
options.strides, options.dilations, 'same-upper');
let conv = this.builder_.conv2d(input, weights, options);
if (leakyRelu) {
Expand All @@ -47,8 +50,10 @@ export class TinyYoloV2Nhwc {
}

buildMaxPool2d_(input, options) {
const isShapeMethod = typeof input.shape === 'function';
const inputShape = isShapeMethod ? input.shape() : input.shape;
options.padding = computePadding2DForAutoPad(
/* nhwc */[input.shape()[1], input.shape()[2]],
/* nhwc */[inputShape[1], inputShape[2]],
options.windowDimensions,
options.strides, options.dilations, 'same-upper');
return this.builder_.maxPool2d(input, options);
Expand Down
7 changes: 5 additions & 2 deletions semantic_segmentation/deeplabv3_mnv2_nhwc.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ export class DeepLabV3MNV2Nhwc {
} else {
options.filterLayout = 'ohwi';
}
const isShapeMethod = typeof input.shape === 'function';
const inputShape = isShapeMethod ? input.shape() : input.shape;
const weightsShape = isShapeMethod ? weights.shape() : weights.shape;
options.padding = computePadding2DForAutoPad(
/* nhwc */[input.shape()[1], input.shape()[2]],
/* ohwi or ihwo */[weights.shape()[1], weights.shape()[2]],
/* nhwc */[inputShape[1], inputShape[2]],
/* ohwi or ihwo */[weightsShape[1], weightsShape[2]],
options.strides, options.dilations, 'same-upper');
options.bias = bias;
const conv2d = this.builder_.conv2d(input, weights, options);
Expand Down
7 changes: 5 additions & 2 deletions style_transfer/fast_style_transfer_net.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ export class FastStyleTransferNet {

buildInstanceNormalization_(conv2D, variableMul, variableAdd) {
if ('instanceNormalization' in this.builder_) {
const isShapeMethod = typeof variableMul.shape === 'function';
const variableMulShape = isShapeMethod ? variableMul.shape() : variableMul.shape;
const variableAddShape = isShapeMethod ? variableAdd.shape() : variableAdd.shape;
// Use reshape to implement squeeze(variableMul); and squeeze(variableAdd);
const mulShape = variableMul.shape().filter((dim) => dim !==1);
const addShape = variableAdd.shape().filter((dim) => dim !==1);
const mulShape = variableMulShape.filter((dim) => dim !==1);
const addShape = variableAddShape.filter((dim) => dim !==1);
const mulSqueeze = this.builder_.reshape(variableMul, mulShape);
const addSqueeze = this.builder_.reshape(variableAdd, addShape);
return this.builder_.instanceNormalization(conv2D, {scale: mulSqueeze, bias: addSqueeze});
Expand Down

0 comments on commit 77a98b9

Please sign in to comment.