onnxruntime/js/web/script/build.ts
Changming Sun 6cdf071a94
Cherry-picks to the release branch (#16017)
### Description
Cherry-picks 26 commits to the release branch. 
Most cherry-picks are clean merges. Except:

1. When I got conflicts in cgmanifest.json and download-deps.yml, I
choose to ignore the conflicts and regenerate the two files
2. There were some conflicts in cmake/deps.txt, onnxruntime_c_api.cc


PR list:

[js/webgpu] fix Transpose with non-float tensor (#15819)
[js/web] fix terser reserved symbols for worker (#15864)
[JSEP] fix constructor for OrtDevice (#15805)
Bump engine.io from 6.4.1 to 6.4.2 in /js/web (#15799)
Bump engine.io from 6.4.0 to 6.4.2 in /onnxruntime/test/wasm (#15798)
[wasm] revert emsdk to v3.1.19 (#15793)
[wasm/JSEP] add threaded build to artifacts (#15777)
[js/web] add target ort.webgpu.min.js (#15780)
update ort extensions to 94142d8391c9791ec71c38336436319a2d4ac7a0 (#15688)
fix: setting builder optimization level to TRT 8.6 default (#15897)
Adust GetVersionString() GetBuildInfoString() signatures and move them to OrtApi (#15921)
Fix segfault for multiple GPU run (regression) (#15823)
android package fix (#15999)
[CoreML EP] Minor changes to allow CoreML EP to handle more nodes and models. (#15993)
Adding support for conv fp16 fusion on Resnet50v1 (#15474)
update onnx release 1.14 for docker files (#15680)
Avoid generating training documentation during packaging (#15795)
Update Conv-Add-Relu Fusion Transformation (#15834)
Fix symbolic shape infer empty value_info (#15842)
NhwcFusedConv: Add before Activation (#15837)
use __hmul2 instead of __hmul2_rn (#15852)
change the EP device to default OrtDevice() for memoryType equals CPU Input (#15903)
Fixing NhwcFusedConv fp16 (#15950)
fix topo sort in quantization tool (#16003)
[doc] add LeakyRelu to coreml supported ops (#15944)
[DML EP] Add frequent upload heap flushing (#15960)

Co-authored-by: Yulong Wang 
Co-authored-by: dependabot[bot] 
Co-authored-by: Guenther Schmuelling 
Co-authored-by: Shalva Mist 
Co-authored-by: Maximilian Müller 
Co-authored-by: Dmitri Smirnov 
Co-authored-by: pengwa 
Co-authored-by: Ashwini Khade 
Co-authored-by: Edward Chen 
Co-authored-by: Jian Chen 
Co-authored-by: liqun Fu 
Co-authored-by: Baiju Meswani 
Co-authored-by: Tianlei Wu 
Co-authored-by: Chen Fu 
Co-authored-by: Ye Wang 
Co-authored-by: cao lei 
Co-authored-by: Yufeng Li 
Co-authored-by: Rachel Guo 
Co-authored-by: Patrice Vignola
2023-05-19 14:04:43 -07:00

186 lines
7.4 KiB
TypeScript

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import {spawnSync} from 'child_process';
import * as fs from 'fs-extra';
import minimist from 'minimist';
import npmlog from 'npmlog';
import * as path from 'path';
// CMD args
const args = minimist(process.argv);
// --bundle-mode=prod (default)
// --bundle-mode=dev
// --bundle-mode=perf
// --bundle-mode=node
const MODE = args['bundle-mode'] || 'prod';
if (['prod', 'dev', 'perf', 'node'].indexOf(MODE) === -1) {
throw new Error(`unknown build mode: ${MODE}`);
}
// --wasm (default)
// --no-wasm
const WASM = typeof args.wasm === 'undefined' ? true : !!args.wasm;
// -a; --analyzer
const ANALYZER = !!args.a || !!args.analyzer;
// -f; --filter=<regex>
const FILTER = args.f || args.filter;
// Path variables
const ROOT_FOLDER = path.join(__dirname, '..');
const WASM_BINDING_FOLDER = path.join(ROOT_FOLDER, 'lib', 'wasm', 'binding');
const WASM_BINDING_JS_PATH = path.join(WASM_BINDING_FOLDER, 'ort-wasm.js');
const WASM_BINDING_THREADED_JS_PATH = path.join(WASM_BINDING_FOLDER, 'ort-wasm-threaded.js');
const WASM_BINDING_SIMD_THREADED_JSEP_JS_PATH = path.join(WASM_BINDING_FOLDER, 'ort-wasm-simd-threaded.jsep.js');
const WASM_BINDING_THREADED_WORKER_JS_PATH = path.join(WASM_BINDING_FOLDER, 'ort-wasm-threaded.worker.js');
const WASM_BINDING_THREADED_MIN_JS_PATH = path.join(WASM_BINDING_FOLDER, 'ort-wasm-threaded.min.js');
const WASM_BINDING_SIMD_THREADED_JSEP_MIN_JS_PATH =
path.join(WASM_BINDING_FOLDER, 'ort-wasm-simd-threaded.jsep.min.js');
const WASM_BINDING_THREADED_MIN_WORKER_JS_PATH = path.join(WASM_BINDING_FOLDER, 'ort-wasm-threaded.min.worker.js');
const WASM_DIST_FOLDER = path.join(ROOT_FOLDER, 'dist');
const WASM_WASM_PATH = path.join(WASM_DIST_FOLDER, 'ort-wasm.wasm');
const WASM_THREADED_WASM_PATH = path.join(WASM_DIST_FOLDER, 'ort-wasm-threaded.wasm');
const WASM_SIMD_WASM_PATH = path.join(WASM_DIST_FOLDER, 'ort-wasm-simd.wasm');
const WASM_SIMD_THREADED_WASM_PATH = path.join(WASM_DIST_FOLDER, 'ort-wasm-simd-threaded.wasm');
const WASM_SIMD_JSEP_WASM_PATH = path.join(WASM_DIST_FOLDER, 'ort-wasm-simd.jsep.wasm');
const WASM_SIMD_THREADED_JSEP_WASM_PATH = path.join(WASM_DIST_FOLDER, 'ort-wasm-simd-threaded.jsep.wasm');
const WASM_THREADED_WORKER_JS_PATH = path.join(WASM_DIST_FOLDER, 'ort-wasm-threaded.worker.js');
const WASM_THREADED_JS_PATH = path.join(WASM_DIST_FOLDER, 'ort-wasm-threaded.js');
const WASM_SIMD_THREADED_JSEP_JS_PATH = path.join(WASM_DIST_FOLDER, 'ort-wasm-simd-threaded.jsep.js');
function validateFile(path: string): void {
npmlog.info('Build', `Ensure file: ${path}`);
if (!fs.pathExistsSync(path)) {
throw new Error(`file does not exist: ${path}`);
}
if (fs.statSync(path).size === 0) {
throw new Error(`file is empty: ${path}`);
}
}
if (WASM) {
npmlog.info('Build', 'Validating WebAssembly artifacts...');
try {
validateFile(WASM_BINDING_JS_PATH);
validateFile(WASM_BINDING_THREADED_JS_PATH);
validateFile(WASM_BINDING_SIMD_THREADED_JSEP_JS_PATH);
validateFile(WASM_BINDING_THREADED_WORKER_JS_PATH);
validateFile(WASM_WASM_PATH);
validateFile(WASM_THREADED_WASM_PATH);
validateFile(WASM_SIMD_WASM_PATH);
validateFile(WASM_SIMD_THREADED_WASM_PATH);
validateFile(WASM_SIMD_JSEP_WASM_PATH);
validateFile(WASM_SIMD_THREADED_JSEP_WASM_PATH);
} catch (e) {
npmlog.error('Build', `WebAssembly files are not ready. build WASM first. ERR: ${e}`);
throw e;
}
npmlog.info('Build', 'Validating WebAssembly artifacts... DONE');
const VERSION = require(path.join(__dirname, '../package.json')).version;
const COPYRIGHT_BANNER = `/*!
* ONNX Runtime Web v${VERSION}
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
`;
npmlog.info('Build', 'Minimizing file "ort-wasm-threaded.js"...');
try {
const terser = spawnSync(
'npx',
[
'terser', WASM_BINDING_THREADED_JS_PATH, '--compress', 'passes=2', '--format', 'comments=false', '--mangle',
'reserved=[_scriptDir,startWorker]', '--module'
],
{shell: true, encoding: 'utf-8', cwd: ROOT_FOLDER});
if (terser.status !== 0) {
console.error(terser.error);
process.exit(terser.status === null ? undefined : terser.status);
}
fs.writeFileSync(WASM_BINDING_THREADED_MIN_JS_PATH, terser.stdout);
fs.writeFileSync(WASM_THREADED_JS_PATH, `${COPYRIGHT_BANNER}${terser.stdout}`);
validateFile(WASM_BINDING_THREADED_MIN_JS_PATH);
validateFile(WASM_THREADED_JS_PATH);
} catch (e) {
npmlog.error('Build', `Failed to run terser on ort-wasm-threaded.js. ERR: ${e}`);
throw e;
}
npmlog.info('Build', 'Minimizing file "ort-wasm-threaded.js"... DONE');
npmlog.info('Build', 'Minimizing file "ort-wasm-simd-threaded.jsep.js"...');
try {
const terser = spawnSync(
'npx',
[
'terser', WASM_BINDING_SIMD_THREADED_JSEP_JS_PATH, '--compress', 'passes=2', '--format', 'comments=false',
'--mangle', 'reserved=[_scriptDir,startWorker]', '--module'
],
{shell: true, encoding: 'utf-8', cwd: ROOT_FOLDER});
if (terser.status !== 0) {
console.error(terser.error);
process.exit(terser.status === null ? undefined : terser.status);
}
fs.writeFileSync(WASM_BINDING_SIMD_THREADED_JSEP_MIN_JS_PATH, terser.stdout);
fs.writeFileSync(WASM_SIMD_THREADED_JSEP_JS_PATH, `${COPYRIGHT_BANNER}${terser.stdout}`);
validateFile(WASM_BINDING_SIMD_THREADED_JSEP_MIN_JS_PATH);
validateFile(WASM_SIMD_THREADED_JSEP_JS_PATH);
} catch (e) {
npmlog.error('Build', `Failed to run terser on ort-wasm-threaded.js. ERR: ${e}`);
throw e;
}
npmlog.info('Build', 'Minimizing file "ort-wasm-simd-threaded.jsep.js"... DONE');
npmlog.info('Build', 'Minimizing file "ort-wasm-threaded.worker.js"...');
try {
const terser = spawnSync(
'npx',
[
'terser', WASM_BINDING_THREADED_WORKER_JS_PATH, '--compress', 'passes=2', '--format', 'comments=false',
'--mangle', 'reserved=[_scriptDir,startWorker]', '--toplevel'
],
{shell: true, encoding: 'utf-8'});
if (terser.status !== 0) {
console.error(terser.error);
process.exit(terser.status === null ? undefined : terser.status);
}
fs.writeFileSync(WASM_BINDING_THREADED_MIN_WORKER_JS_PATH, terser.stdout);
fs.writeFileSync(WASM_THREADED_WORKER_JS_PATH, `${COPYRIGHT_BANNER}${terser.stdout}`);
validateFile(WASM_BINDING_THREADED_MIN_WORKER_JS_PATH);
validateFile(WASM_THREADED_WORKER_JS_PATH);
} catch (e) {
npmlog.error('Build', `Failed to run terser on ort-wasm-threaded.worker.js. ERR: ${e}`);
throw e;
}
npmlog.info('Build', 'Minimizing file "ort-wasm-threaded.worker.js"... DONE');
}
npmlog.info('Build', 'Building bundle...');
{
npmlog.info('Build.Bundle', 'Running webpack to generate bundles...');
const webpackArgs = ['webpack', '--env', `--bundle-mode=${MODE}`];
if (ANALYZER) {
webpackArgs.push('--env', '-a');
}
if (FILTER) {
webpackArgs.push('--env', `-f=${FILTER}`);
}
npmlog.info('Build.Bundle', `CMD: npx ${webpackArgs.join(' ')}`);
const webpack = spawnSync('npx', webpackArgs, {shell: true, stdio: 'inherit', cwd: ROOT_FOLDER});
if (webpack.status !== 0) {
console.error(webpack.error);
process.exit(webpack.status === null ? undefined : webpack.status);
}
npmlog.info('Build.Bundle', 'Running webpack to generate bundles... DONE');
}
npmlog.info('Build', 'Building bundle... DONE');