diff --git a/js/web/karma.conf.js b/js/web/karma.conf.js index 49553088bd2d8..f3947b080d019 100644 --- a/js/web/karma.conf.js +++ b/js/web/karma.conf.js @@ -6,6 +6,7 @@ const bundleMode = require('minimist')(process.argv)['bundle-mode'] || 'dev'; // 'dev'|'perf'|undefined; const karmaPlugins = require('minimist')(process.argv)['karma-plugins'] || undefined; const timeoutMocha = require('minimist')(process.argv)['timeout-mocha'] || 60000; +const forceLocalHost = !!require('minimist')(process.argv)['force-localhost']; const commonFile = bundleMode === 'dev' ? '../common/dist/ort-common.js' : '../common/dist/ort-common.min.js' const mainFile = bundleMode === 'dev' ? 'test/ort.dev.js' : 'test/ort.perf.js'; @@ -16,18 +17,20 @@ const mainFile = bundleMode === 'dev' ? 'test/ort.dev.js' : 'test/ort.perf.js'; // https://stackoverflow.com/a/8440736 // function getMachineIpAddress() { - var os = require('os'); - var ifaces = os.networkInterfaces(); + if (!forceLocalHost) { + var os = require('os'); + var ifaces = os.networkInterfaces(); - for (const ifname in ifaces) { - for (const iface of ifaces[ifname]) { - if ('IPv4' !== iface.family || iface.internal !== false) { - // skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses - continue; - } + for (const ifname in ifaces) { + for (const iface of ifaces[ifname]) { + if ('IPv4' !== iface.family || iface.internal !== false) { + // skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses + continue; + } - // returns the first available IP address - return iface.address; + // returns the first available IP address + return iface.address; + } } } @@ -80,6 +83,9 @@ module.exports = function (config) { ChromeTest: { base: 'ChromeHeadless', flags: ['--enable-features=SharedArrayBuffer'] }, ChromePerf: { base: 'Chrome', flags: ['--window-size=1,1', '--enable-features=SharedArrayBuffer'] }, ChromeDebug: { debug: true, base: 'Chrome', flags: ['--remote-debugging-port=9333', '--enable-features=SharedArrayBuffer'] }, + ChromeCanaryTest: { base: 'ChromeCanaryHeadless', flags: ['--enable-features=SharedArrayBuffer', '--enable-unsafe-webgpu'] }, + ChromeCanaryPerf: { base: 'ChromeCanary', flags: ['--window-size=1,1', '--enable-features=SharedArrayBuffer', '--enable-unsafe-webgpu'] }, + ChromeCanaryDebug: { debug: true, base: 'ChromeCanary', flags: ['--remote-debugging-port=9333', '--enable-features=SharedArrayBuffer', '--enable-unsafe-webgpu'] }, // // ==== BrowserStack browsers ==== diff --git a/js/web/lib/onnxjs/backends/backend-webgpu.ts b/js/web/lib/onnxjs/backends/backend-webgpu.ts index 6919571e83b5a..653e7f4f4d1c4 100644 --- a/js/web/lib/onnxjs/backends/backend-webgpu.ts +++ b/js/web/lib/onnxjs/backends/backend-webgpu.ts @@ -9,11 +9,23 @@ import {Session} from '../session'; import {WebGpuSessionHandler} from './webgpu/session-handler'; export class WebGpuBackend implements Backend { - initialize(): boolean { + device: GPUDevice; + async initialize(): Promise { try { - // STEP.1 TODO: set up context (one time initialization) + if (!navigator.gpu) { + // WebGPU is not available. + Logger.warning('WebGpuBackend', 'WebGPU is not available.'); + return false; + } - // STEP.2 TODO: set up flags + const adapter = await navigator.gpu.requestAdapter(); + if (!adapter) { + Logger.warning('WebGpuBackend', 'Failed to get GPU adapter.'); + return false; + } + this.device = await adapter.requestDevice(); + + // TODO: set up flags Logger.setWithEnv(env); diff --git a/js/web/script/test-runner-cli.ts b/js/web/script/test-runner-cli.ts index f4d2d0a90b4fd..de842a18f5592 100644 --- a/js/web/script/test-runner-cli.ts +++ b/js/web/script/test-runner-cli.ts @@ -50,7 +50,7 @@ if (shouldLoadSuiteTestData) { // The default backends and opset version lists. Those will be used in suite tests. const DEFAULT_BACKENDS: readonly TestRunnerCliArgs.Backend[] = - args.env === 'node' ? ['cpu', 'wasm'] : ['wasm', 'webgl']; + args.env === 'node' ? ['cpu', 'wasm'] : ['wasm', 'webgl', 'webgpu']; const DEFAULT_OPSET_VERSIONS: readonly number[] = [13, 12, 11, 10, 9, 8, 7]; const FILE_CACHE_ENABLED = args.fileCache; // whether to enable file cache @@ -454,11 +454,13 @@ function run(config: Test.Config) { // STEP 5. use Karma to run test npmlog.info('TestRunnerCli.Run', '(5/5) Running karma to start test runner...'); const karmaCommand = path.join(npmBin, 'karma'); + const webgpu = args.backends.indexOf('webgpu') > -1; const browser = getBrowserNameFromEnv( args.env, args.bundleMode === 'perf' ? 'perf' : args.debug ? 'debug' : - 'test'); + 'test', + webgpu); const karmaArgs = ['start', `--browsers ${browser}`]; if (args.debug) { karmaArgs.push('--log-level info --timeout-mocha 9999999'); @@ -468,6 +470,9 @@ function run(config: Test.Config) { if (args.noSandbox) { karmaArgs.push('--no-sandbox'); } + if (webgpu) { + karmaArgs.push('--force-localhost'); + } karmaArgs.push(`--bundle-mode=${args.bundleMode}`); if (browser === 'Edge') { // There are currently 2 Edge browser launchers: @@ -559,10 +564,11 @@ function saveConfig(config: Test.Config) { fs.writeJSONSync(path.join(TEST_ROOT, './testdata-config.json'), config); } -function getBrowserNameFromEnv(env: TestRunnerCliArgs['env'], mode: 'debug'|'perf'|'test') { + +function getBrowserNameFromEnv(env: TestRunnerCliArgs['env'], mode: 'debug'|'perf'|'test', webgpu: boolean) { switch (env) { case 'chrome': - return selectChromeBrowser(mode); + return selectChromeBrowser(mode, webgpu); case 'edge': return 'Edge'; case 'firefox': @@ -578,13 +584,18 @@ function getBrowserNameFromEnv(env: TestRunnerCliArgs['env'], mode: 'debug'|'per } } -function selectChromeBrowser(mode: 'debug'|'perf'|'test') { +function selectChromeBrowser(mode: 'debug'|'perf'|'test', webgpu: boolean) { + let browserName = 'Chrome'; + if (webgpu) { + browserName += 'Canary'; + } + switch (mode) { case 'debug': - return 'ChromeDebug'; + return browserName + 'Debug'; case 'perf': - return 'ChromePerf'; + return browserName + 'Perf'; default: - return 'ChromeTest'; + return browserName + 'Test'; } }