feat: infer

This commit is contained in:
mozzie 2024-08-08 14:29:57 +08:00
parent a60bd53047
commit d6192f12df
10 changed files with 8528 additions and 5 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
import { Worker } from "worker_threads";
function createWorker(data: Float32Array): Promise<Float32Array> {
return new Promise((resolve, reject) => {
const worker = new Worker("./vino.worker.js");
worker.on("message", (result) => resolve(result as Float32Array));
worker.on("error", reject);
worker.on("exit", (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`));
}
});
worker.postMessage(data);
});
}
class TaskQueue {
private concurrency: number;
private queue: (() => void)[];
private running: number;
constructor(concurrency: number) {
this.concurrency = concurrency;
this.queue = [];
this.running = 0;
}
private async runTask(task: () => Promise<any>): Promise<any> {
this.running++;
try {
const result = await task();
this.running--;
this.next();
return result;
} catch (error) {
this.running--;
this.next();
throw error;
}
}
public addTask(task: () => Promise<any>): Promise<any> {
return new Promise((resolve, reject) => {
const run = () => this.runTask(task).then(resolve).catch(reject);
this.queue.push(run);
this.next();
});
}
private next(): void {
if (this.running < this.concurrency && this.queue.length > 0) {
const task = this.queue.shift();
task?.();
}
}
}
export async function cpuStartInfer() {
const numTasks = 128;
const patchSize = [1, 1, 80, 160, 160];
const taskQueue = new TaskQueue(2); // 设置并发任务数例如2
console.time("总推理用时");
try {
const tasks = Array.from({ length: numTasks }, () => {
const inferSample = new Float32Array(
patchSize.reduce((a, b) => a * b)
).map(() => Math.random() * 2.0 - 1.0);
return taskQueue.addTask(() => createWorker(inferSample));
});
const results = await Promise.all(tasks);
console.log("所有任务完成,结果数量:", results.length);
} catch (e) {
console.error("推理失败:", e);
}
console.timeEnd("总推理用时");
}

View File

@ -0,0 +1,35 @@
import { parentPort } from "worker_threads";
import { addon as ov } from "openvino-node";
const modelXMLPath = "./model.xml";
const deviceName = "CPU";
async function runInference(data: Float32Array): Promise<Float32Array> {
console.time("openvino infer");
const core = new ov.Core();
const model = await core.readModel(modelXMLPath);
const compiledModel = await core.compileModel(model, deviceName);
const patchSize = [1, 1, 80, 160, 160];
const outputLayer = compiledModel.outputs[0];
const tensor = new ov.Tensor(ov.element.f32, patchSize, data);
const inferRequest = compiledModel.createInferRequest();
inferRequest.setInputTensor(tensor);
inferRequest.infer();
const resultInfer = inferRequest.getTensor(outputLayer);
console.timeEnd("openvino infer");
return resultInfer.data;
}
parentPort?.on("message", async (data: Float32Array) => {
try {
const result = await runInference(data);
parentPort?.postMessage(result);
} catch (error) {
parentPort?.postMessage({ error: error.message });
}
});

View File

@ -6,13 +6,14 @@ import {
structureMetadata,
} from "./core/dicom";
import { EVENT_PARSE_DICOM } from "./ipcEvent";
import { cpuStartInfer } from "./core/infer/vino";
/**
*
*/
const registerIpcMainHandlers = (mainWindow: Electron.BrowserWindow | null) => {
if (!mainWindow) return;
ipcMain.on(EVENT_PARSE_DICOM, async (event, file: string) => {
const dirDialog = await dialog.showOpenDialog(mainWindow, {
properties: ["openDirectory"],
@ -27,6 +28,10 @@ const registerIpcMainHandlers = (mainWindow: Electron.BrowserWindow | null) => {
event.reply(EVENT_PARSE_DICOM + ":RES", result);
}
});
ipcMain.handle("openvino", async (event, data) => {
cpuStartInfer();
});
};
export default registerIpcMainHandlers;

View File

@ -42,7 +42,8 @@
"react-resizable-panels": "^2.0.20",
"react-router-dom": "^6.26.0",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"openvino-node": "2024.3.0"
},
"devDependencies": {
"@radix-ui/react-icons": "^1.3.0",

View File

@ -77,6 +77,9 @@ importers:
onnxruntime-node:
specifier: ^1.18.0
version: 1.18.0
openvino-node:
specifier: 2024.3.0
version: 2024.3.0
react:
specifier: ^18.2.0
version: 18.3.1
@ -1636,6 +1639,9 @@ packages:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
browserify-zlib@0.1.4:
resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==}
browserslist@4.23.3:
resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
@ -2287,6 +2293,10 @@ packages:
guid-typescript@1.0.9:
resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==}
gunzip-maybe@1.4.2:
resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==}
hasBin: true
has-flag@3.0.0:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
@ -2395,6 +2405,9 @@ packages:
resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==}
engines: {node: '>= 0.4'}
is-deflate@1.0.0:
resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==}
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@ -2407,6 +2420,10 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
is-gzip@1.0.0:
resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==}
engines: {node: '>=0.10.0'}
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
@ -2752,6 +2769,11 @@ packages:
onnxruntime-web@1.14.0:
resolution: {integrity: sha512-Kcqf43UMfW8mCydVGcX9OMXI2VN17c0p6XvR7IPSZzBf/6lteBzXHvcEVWDPmCKuGombl997HgLqj91F11DzXw==}
openvino-node@2024.3.0:
resolution: {integrity: sha512-uB0tFMdnSFXhkWI/p0fD0Mg47kBrUZKVae0R/kcxlj3nQbEET1GeHNeKCM6qQGQLoe8RxgKx7AZX+93Aq1JqNQ==}
engines: {node: '>=20.5.1'}
os: [win32, darwin, linux]
optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
@ -2783,6 +2805,9 @@ packages:
package-json-from-dist@1.0.0:
resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
pako@0.2.9:
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
@ -2810,6 +2835,9 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
peek-stream@1.1.3:
resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==}
pend@1.2.0:
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
@ -5442,6 +5470,10 @@ snapshots:
dependencies:
fill-range: 7.1.1
browserify-zlib@0.1.4:
dependencies:
pako: 0.2.9
browserslist@4.23.3:
dependencies:
caniuse-lite: 1.0.30001649
@ -6273,6 +6305,15 @@ snapshots:
guid-typescript@1.0.9: {}
gunzip-maybe@1.4.2:
dependencies:
browserify-zlib: 0.1.4
is-deflate: 1.0.0
is-gzip: 1.0.0
peek-stream: 1.1.3
pumpify: 1.5.1
through2: 2.0.5
has-flag@3.0.0: {}
has-flag@4.0.0: {}
@ -6382,6 +6423,8 @@ snapshots:
dependencies:
hasown: 2.0.2
is-deflate@1.0.0: {}
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
@ -6390,6 +6433,8 @@ snapshots:
dependencies:
is-extglob: 2.1.1
is-gzip@1.0.0: {}
is-number@7.0.0: {}
is-path-inside@3.0.3: {}
@ -6677,6 +6722,14 @@ snapshots:
onnxruntime-common: 1.14.0
platform: 1.3.6
openvino-node@2024.3.0:
dependencies:
gunzip-maybe: 1.4.2
https-proxy-agent: 7.0.5
tar-fs: 3.0.6
transitivePeerDependencies:
- supports-color
optionator@0.9.4:
dependencies:
deep-is: 0.1.4
@ -6709,6 +6762,8 @@ snapshots:
package-json-from-dist@1.0.0: {}
pako@0.2.9: {}
parent-module@1.0.1:
dependencies:
callsites: 3.1.0
@ -6728,6 +6783,12 @@ snapshots:
path-type@4.0.0: {}
peek-stream@1.1.3:
dependencies:
buffer-from: 1.1.2
duplexify: 3.7.1
through2: 2.0.5
pend@1.2.0: {}
picocolors@1.0.1: {}

View File

@ -1,7 +1,17 @@
import { Button } from "@/components/ui/button";
const Aorta = () => {
return (
<div className="p-2">
<div className="grid w-full max-w-sm items-center gap-1.5">123</div>
<div className="grid w-full max-w-sm items-center gap-1.5">
<Button
onClick={() => {
window.ipcRenderer.invoke("openvino");
}}
>
</Button>
</div>
</div>
);
};

View File

@ -13,7 +13,6 @@ import {
} from "flexlayout-react";
import "flexlayout-react/style/light.css";
import "./Layout.css";
import { Button } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,

View File

@ -1,5 +1,4 @@
import { Outlet, Link } from "react-router-dom";
import { GoFileDirectory } from "react-icons/go";
import { BsDatabaseFill } from "react-icons/bs";
import { MenuBar } from "./MenuBar";