From b3c08d83adabd6179a36c3a891474546de2d7804 Mon Sep 17 00:00:00 2001 From: Wanming Lin Date: Wed, 24 Sep 2025 15:46:50 +0800 Subject: [PATCH] Use preferredInputLayout to select model for different backends --- common/utils.js | 11 ++++------- face_recognition/main.js | 7 +++---- facial_landmark_detection/main.js | 5 ++--- image_classification/main.js | 9 ++++----- object_detection/main.js | 9 ++++----- semantic_segmentation/main.js | 5 ++--- 6 files changed, 19 insertions(+), 27 deletions(-) diff --git a/common/utils.js b/common/utils.js index 31761337..46e097c2 100644 --- a/common/utils.js +++ b/common/utils.js @@ -432,13 +432,10 @@ export function permuteData(array, dims, axes) { return [permutedData, shape]; } -export function getDefaultLayout(deviceType) { - if (deviceType.indexOf('cpu') != -1) { - return 'nhwc'; - } else if (deviceType.indexOf('gpu') != -1 || - deviceType.indexOf('npu') != -1) { - return 'nchw'; - } +export async function getDefaultLayout(deviceType) { + const context = await navigator.ml.createContext({deviceType}); + const limits = context.opSupportLimits(); + return limits.preferredInputLayout ?? 'nchw'; } /** diff --git a/face_recognition/main.js b/face_recognition/main.js index 68bc5bbd..79994374 100644 --- a/face_recognition/main.js +++ b/face_recognition/main.js @@ -54,7 +54,8 @@ $('#backendBtns .btn').on('change', async (e) => { if (inputType === 'camera') { await stopCamRender(); } - layout = utils.getDefaultLayout($(e.target).attr('id')); + [backend, deviceType] = $(e.target).attr('id').split('_'); + layout = await utils.getDefaultLayout(deviceType); await main(); }); @@ -296,8 +297,6 @@ function constructNetObject(type) { async function main() { try { if (fdModelName === '') return; - [backend, deviceType] = - $('input[name="backend"]:checked').attr('id').split('_'); ui.handleClick(disabledSelectors, true); if (isFirstTimeLoad) $('#hint').hide(); const [numRuns, powerPreference] = utils.getUrlParams(); @@ -359,7 +358,7 @@ async function main() { utils.sizeOfShape(frInputOptions.inputShape))); for (let i = 0; i < numRuns; i++) { if (numRuns > 1) { - // clear all predicted embeddings for benckmarking + // clear all predicted embeddings for benchmarking targetEmbeddings = null; searchEmbeddings = null; } diff --git a/facial_landmark_detection/main.js b/facial_landmark_detection/main.js index f295acb1..fa6ab2a8 100644 --- a/facial_landmark_detection/main.js +++ b/facial_landmark_detection/main.js @@ -50,7 +50,8 @@ $('#backendBtns .btn').on('change', async (e) => { if (inputType === 'camera') { await stopCamRender(); } - layout = utils.getDefaultLayout($(e.target).attr('id')); + [backend, deviceType] = $(e.target).attr('id').split('_'); + layout = await utils.getDefaultLayout(deviceType); await main(); }); @@ -232,8 +233,6 @@ function constructNetObject(type) { async function main() { try { if (fdModelName === '') return; - [backend, deviceType] = - $('input[name="backend"]:checked').attr('id').split('_'); ui.handleClick(disabledSelectors, true); if (isFirstTimeLoad) $('#hint').hide(); const [numRuns, powerPreference] = utils.getUrlParams(); diff --git a/image_classification/main.js b/image_classification/main.js index 9fe42c86..29767894 100644 --- a/image_classification/main.js +++ b/image_classification/main.js @@ -98,18 +98,17 @@ $('#backendBtns .btn').on('change', async (e) => { if (inputType === 'camera') { await stopCamRender(); } - const backendId = $(e.target).attr('id'); - layout = utils.getDefaultLayout(backendId); - [backend, deviceType] = backendId.split('_'); + [backend, deviceType] = $(e.target).attr('id').split('_'); + layout = await utils.getDefaultLayout(deviceType); // Only show the supported models for each deviceType. Now fp16 nchw models // are only supported on gpu/npu. - if (backendId == 'webnn_gpu') { + if (deviceType == 'gpu') { ui.handleBtnUI('#float16Label', false); ui.handleBtnUI('#float32Label', false); ui.handleBtnUI('#uint8Label', true); $('#float32').click(); utils.displayAvailableModels(modelList, modelIds, deviceType, dataType); - } else if (backendId == 'webnn_npu') { + } else if (deviceType == 'npu') { ui.handleBtnUI('#float16Label', false); ui.handleBtnUI('#float32Label', true); ui.handleBtnUI('#uint8Label', true); diff --git a/object_detection/main.js b/object_detection/main.js index f866b321..8365bc64 100644 --- a/object_detection/main.js +++ b/object_detection/main.js @@ -68,16 +68,15 @@ $('#backendBtns .btn').on('change', async (e) => { if (inputType === 'camera') { await stopCamRender(); } - const backendId = $(e.target).attr('id'); - layout = utils.getDefaultLayout(backendId); - [backend, deviceType] = backendId.split('_'); + [backend, deviceType] = $(e.target).attr('id').split('_'); + layout = await utils.getDefaultLayout(deviceType); // Only show the supported models for each deviceType. Now fp16 nchw models // are only supported on gpu/npu. - if (backendId == 'webnn_gpu') { + if (deviceType == 'gpu') { ui.handleBtnUI('#float16Label', false); ui.handleBtnUI('#float32Label', false); utils.displayAvailableModels(modelList, modelIds, deviceType, dataType); - } else if (backendId == 'webnn_npu') { + } else if (deviceType == 'npu') { ui.handleBtnUI('#float16Label', false); ui.handleBtnUI('#float32Label', true); $('#float16').click(); diff --git a/semantic_segmentation/main.js b/semantic_segmentation/main.js index 032eef7d..270b9629 100644 --- a/semantic_segmentation/main.js +++ b/semantic_segmentation/main.js @@ -53,7 +53,8 @@ $('#backendBtns .btn').on('change', async (e) => { if (inputType === 'camera') { await stopCamRender(); } - layout = utils.getDefaultLayout($(e.target).attr('id')); + [backend, deviceType] = $(e.target).attr('id').split('_'); + layout = await utils.getDefaultLayout(deviceType); await main(); }); @@ -326,8 +327,6 @@ function constructNetObject(type) { export async function main() { try { if (modelName === '') return; - [backend, deviceType] = - $('input[name="backend"]:checked').attr('id').split('_'); ui.handleClick(disabledSelectors, true); if (isFirstTimeLoad) $('#hint').hide(); let start;