Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert MLOperand methods into readonly attributes #293

Merged
merged 2 commits into from
Oct 30, 2024
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
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