Skip to content

Commit 1288443

Browse files
committed
feat: add WebNN module and integrate WebNN view component with routing
1 parent 903125e commit 1288443

File tree

10 files changed

+128
-1
lines changed

10 files changed

+128
-1
lines changed

app/home/home.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ <h2>Home</h2>
1010
<li><a href="/main-menu">Main Menu</a></li>
1111
<li><a href="/material-icons">Material Icons</a></li>
1212
<li><a href="/activity-state">Activity State</a></li>
13+
<li><a href="/web-nn">Web NN</a></li>
1314
</ul>

app/routes.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ export const routes = Object.freeze({
66
"dynamic-columns": "/dynamic-layout",
77
"main-menu": "/main-menu",
88
"material-icons": "/material-icons",
9-
"activity-state": "/activity-state"
9+
"activity-state": "/activity-state",
10+
"web-nn": "/web-nn"
1011
});

app/web-nn/web-nn.css

Whitespace-only changes.

app/web-nn/web-nn.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h2>WebNN</h2>

app/web-nn/web-nn.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { WebNNModule, OperandDescriptorBuilder } from "../../src/modules/webnn.js";
2+
3+
export default class WebNNView extends HTMLElement {
4+
static tag = "webnn-view";
5+
6+
#context;
7+
8+
constructor() {
9+
super();
10+
this.attachShadow({ mode: "open" });
11+
}
12+
13+
async connectedCallback() {
14+
this.shadowRoot.innerHTML = await api.call("component", "load_html", {
15+
url: import.meta.url,
16+
});
17+
18+
const operandType = await WebNNModule.createOperandType({ dimensions: [2, 2]});
19+
const graphBuilder = await WebNNModule.createGraph();
20+
21+
const constant2 = graphBuilder.constant(new OperandDescriptorBuilder().build(), new Float32Array([0.2]));
22+
console.log(constant2);
23+
}
24+
}
25+
26+
customElements.define(WebNNView.tag, WebNNView);

src/modules/webnn.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import DeviceType from "./webnn/device-type.js";
2+
import PowerOptions from "./webnn/power-options.js";
3+
import DataType from "./webnn/data-type.js";
4+
import OperandDescriptorBuilder from "./webnn/builders/operand-descriptor-builder.js";
5+
6+
class WebNNModule {
7+
static async available() {
8+
return navigator.ml !== undefined;
9+
}
10+
11+
static createOperandDescriptor(args = {}) {
12+
const { dataType = DataType.FLOAT32, shape = [] } = args;
13+
return { dataType, shape };
14+
}
15+
16+
static createOperandType(args= {}) {
17+
const { dataType = DataType.FLOAT32, dimensions = [] } = args;
18+
return { dataType, dimensions };
19+
}
20+
21+
static async createContextOption(args = {}) {
22+
const { deviceType = DeviceType.GPU, powerPreference = PowerOptions.DEFAULt } = args;
23+
return { deviceType, powerPreference };
24+
}
25+
26+
static async createContext(args = {}) {
27+
const options = await this.createContextOption(args.options);
28+
return await navigator.ml.createContext(options);
29+
}
30+
31+
static async createGraph(args = {}) {
32+
// https://www.w3.org/TR/webnn/#mlgraphbuilder
33+
const { context = await this.createContext() } = args;
34+
return new MLGraphBuilder(context);
35+
}
36+
}
37+
38+
export {
39+
WebNNModule,
40+
DeviceType,
41+
PowerOptions,
42+
DataType,
43+
OperandDescriptorBuilder
44+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import DataType from "./../data-type.js";
2+
3+
export default class OperandDescriptorBuilder {
4+
#dataType;
5+
#shape;
6+
7+
constructor(dataType = DataType.FLOAT32, shape = []) {
8+
this.#dataType = dataType;
9+
this.#shape = shape;
10+
}
11+
12+
setDataType(dataType) {
13+
this.#dataType = dataType;
14+
return this;
15+
}
16+
17+
setShape(shape) {
18+
this.#shape = shape;
19+
return this;
20+
}
21+
22+
build() {
23+
return {
24+
dataType: this.#dataType,
25+
shape: this.#shape
26+
};
27+
}
28+
}

src/modules/webnn/data-type.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const DataType = Object.freeze({
2+
FLOAT16 : "float16",
3+
FLOAT32 : "float32",
4+
INT32 : "int32",
5+
UINT32 : "uint32",
6+
INT64 : "int64",
7+
UINT64 : "uint64",
8+
INT8 : "int8",
9+
UINT8 : "uint8"
10+
});
11+
12+
export default DataType;

src/modules/webnn/device-type.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const DeviceType = Object.freeze({
2+
CPU: "cpu",
3+
GPU: "gpu",
4+
NPU: "npu"
5+
});
6+
7+
export default DeviceType;

src/modules/webnn/power-options.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const PowerOptions = Object.freeze({
2+
DEFAULt : "default",
3+
LOW : "low-power",
4+
HIGH : "high-performance"
5+
});
6+
7+
export default PowerOptions;

0 commit comments

Comments
 (0)