@simulatte/webgpu 0.2.1 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ import type {
2
+ BoundDoeNamespace,
3
+ DoeKernelDispatchOptions,
4
+ DoeNamespace,
5
+ DoeRunComputeOptions,
6
+ } from "./doe.js";
7
+ import type {
8
+ DoeRuntime,
9
+ DoeRuntimeRunResult,
10
+ ProviderInfo,
11
+ } from "./full.js";
12
+
13
+ export interface ComputeGPUBuffer {
14
+ readonly size: number;
15
+ readonly usage: number;
16
+ mapAsync(mode: number, offset?: number, size?: number): Promise<void>;
17
+ getMappedRange(offset?: number, size?: number): ArrayBuffer;
18
+ assertMappedPrefixF32?(expected: number[], count: number): boolean;
19
+ unmap(): void;
20
+ destroy(): void;
21
+ }
22
+
23
+ export interface ComputeBindGroupLayout {}
24
+
25
+ export interface ComputeBindGroup {}
26
+
27
+ export interface ComputePipelineLayout {}
28
+
29
+ export interface ComputeQuerySet {
30
+ destroy(): void;
31
+ }
32
+
33
+ export interface ComputeComputePipeline {
34
+ getBindGroupLayout(index: number): ComputeBindGroupLayout;
35
+ }
36
+
37
+ export interface ComputePassEncoder {
38
+ setPipeline(pipeline: ComputeComputePipeline): void;
39
+ setBindGroup(index: number, bindGroup: ComputeBindGroup): void;
40
+ dispatchWorkgroups(x: number, y?: number, z?: number): void;
41
+ dispatchWorkgroupsIndirect(indirectBuffer: ComputeGPUBuffer, indirectOffset?: number): void;
42
+ writeTimestamp?(querySet: ComputeQuerySet, queryIndex: number): void;
43
+ end(): void;
44
+ }
45
+
46
+ export interface ComputeCommandEncoder {
47
+ beginComputePass(descriptor?: GPUComputePassDescriptor): ComputePassEncoder;
48
+ copyBufferToBuffer(
49
+ source: ComputeGPUBuffer,
50
+ sourceOffset: number,
51
+ target: ComputeGPUBuffer,
52
+ targetOffset: number,
53
+ size: number
54
+ ): void;
55
+ resolveQuerySet?(
56
+ querySet: ComputeQuerySet,
57
+ firstQuery: number,
58
+ queryCount: number,
59
+ destination: ComputeGPUBuffer,
60
+ destinationOffset: number
61
+ ): void;
62
+ finish(): GPUCommandBuffer;
63
+ }
64
+
65
+ export interface ComputeQueue {
66
+ submit(commandBuffers: GPUCommandBuffer[]): void;
67
+ writeBuffer(
68
+ buffer: ComputeGPUBuffer,
69
+ bufferOffset: number,
70
+ data: BufferSource,
71
+ dataOffset?: number,
72
+ size?: number
73
+ ): void;
74
+ onSubmittedWorkDone(): Promise<void>;
75
+ }
76
+
77
+ export interface ComputeGPUDevice {
78
+ readonly queue: ComputeQueue;
79
+ readonly limits: GPUSupportedLimits;
80
+ readonly features: GPUSupportedFeatures;
81
+ createBuffer(descriptor: GPUBufferDescriptor): ComputeGPUBuffer;
82
+ createShaderModule(descriptor: GPUShaderModuleDescriptor): GPUShaderModule;
83
+ createComputePipeline(descriptor: GPUComputePipelineDescriptor): ComputeComputePipeline;
84
+ createComputePipelineAsync(descriptor: GPUComputePipelineDescriptor): Promise<ComputeComputePipeline>;
85
+ createBindGroupLayout(descriptor: GPUBindGroupLayoutDescriptor): ComputeBindGroupLayout;
86
+ createBindGroup(descriptor: GPUBindGroupDescriptor): ComputeBindGroup;
87
+ createPipelineLayout(descriptor: GPUPipelineLayoutDescriptor): ComputePipelineLayout;
88
+ createCommandEncoder(descriptor?: GPUCommandEncoderDescriptor): ComputeCommandEncoder;
89
+ createQuerySet?(descriptor: GPUQuerySetDescriptor): ComputeQuerySet;
90
+ destroy(): void;
91
+ }
92
+
93
+ export interface ComputeGPUAdapter {
94
+ readonly limits: GPUSupportedLimits;
95
+ readonly features: GPUSupportedFeatures;
96
+ requestDevice(descriptor?: GPUDeviceDescriptor): Promise<ComputeGPUDevice>;
97
+ destroy(): void;
98
+ }
99
+
100
+ export interface ComputeGPU {
101
+ requestAdapter(options?: GPURequestAdapterOptions): Promise<ComputeGPUAdapter | null>;
102
+ }
103
+
104
+ export interface RequestDeviceOptions {
105
+ adapterOptions?: GPURequestAdapterOptions;
106
+ deviceDescriptor?: GPUDeviceDescriptor;
107
+ createArgs?: string[] | null;
108
+ }
109
+
110
+ export interface ComputeDoeRunComputeOptions extends DoeRunComputeOptions<ComputeGPUBuffer> {}
111
+
112
+ export interface ComputeDoeKernelDispatchOptions extends DoeKernelDispatchOptions<ComputeGPUBuffer> {}
113
+
114
+ export interface ComputeDoeKernel {
115
+ readonly device: ComputeGPUDevice;
116
+ readonly entryPoint: string;
117
+ dispatch(options: ComputeDoeKernelDispatchOptions): Promise<void>;
118
+ }
119
+
120
+ export interface ComputeBoundDoeNamespace
121
+ extends BoundDoeNamespace<ComputeGPUDevice, ComputeGPUBuffer, ComputeDoeKernel, ComputeDoeRunComputeOptions> {}
122
+
123
+ export interface ComputeDoeNamespace
124
+ extends DoeNamespace<
125
+ ComputeGPUDevice,
126
+ ComputeGPUBuffer,
127
+ ComputeDoeKernel,
128
+ ComputeBoundDoeNamespace,
129
+ ComputeDoeRunComputeOptions
130
+ > {}
131
+
132
+ export const globals: Record<string, unknown>;
133
+ export function create(createArgs?: string[] | null): ComputeGPU;
134
+ export function setupGlobals(target?: object, createArgs?: string[] | null): ComputeGPU;
135
+ export function requestAdapter(
136
+ adapterOptions?: GPURequestAdapterOptions,
137
+ createArgs?: string[] | null
138
+ ): Promise<ComputeGPUAdapter | null>;
139
+ export function requestDevice(options?: RequestDeviceOptions): Promise<ComputeGPUDevice>;
140
+ export function providerInfo(): ProviderInfo;
141
+ export function createDoeRuntime(options?: {
142
+ binPath?: string;
143
+ libPath?: string;
144
+ }): DoeRuntime;
145
+ export function runDawnVsDoeCompare(options: Record<string, unknown>): DoeRuntimeRunResult;
146
+
147
+ export const doe: ComputeDoeNamespace;
148
+
149
+ declare const _default: {
150
+ create: typeof create;
151
+ globals: typeof globals;
152
+ setupGlobals: typeof setupGlobals;
153
+ requestAdapter: typeof requestAdapter;
154
+ requestDevice: typeof requestDevice;
155
+ providerInfo: typeof providerInfo;
156
+ createDoeRuntime: typeof createDoeRuntime;
157
+ runDawnVsDoeCompare: typeof runDawnVsDoeCompare;
158
+ doe: ComputeDoeNamespace;
159
+ };
160
+
161
+ export default _default;
package/src/compute.js ADDED
@@ -0,0 +1,277 @@
1
+ import * as full from './index.js';
2
+ import { doe } from './doe.js';
3
+
4
+ function unwrap(value) {
5
+ return value && typeof value === 'object' && '_raw' in value ? value._raw : value;
6
+ }
7
+
8
+ function wrap_buffer(raw) {
9
+ return {
10
+ _raw: raw,
11
+ size: raw.size,
12
+ usage: raw.usage,
13
+ async mapAsync(mode, offset, size) {
14
+ return raw.mapAsync(mode, offset, size);
15
+ },
16
+ getMappedRange(offset, size) {
17
+ return raw.getMappedRange(offset, size);
18
+ },
19
+ assertMappedPrefixF32(expected, count) {
20
+ return raw.assertMappedPrefixF32(expected, count);
21
+ },
22
+ unmap() {
23
+ return raw.unmap();
24
+ },
25
+ destroy() {
26
+ return raw.destroy();
27
+ },
28
+ };
29
+ }
30
+
31
+ function wrap_bind_group_layout(raw) {
32
+ return { _raw: raw };
33
+ }
34
+
35
+ function wrap_bind_group(raw) {
36
+ return { _raw: raw };
37
+ }
38
+
39
+ function wrap_pipeline_layout(raw) {
40
+ return { _raw: raw };
41
+ }
42
+
43
+ function wrap_compute_pipeline(raw) {
44
+ return {
45
+ _raw: raw,
46
+ getBindGroupLayout(index) {
47
+ return wrap_bind_group_layout(raw.getBindGroupLayout(index));
48
+ },
49
+ };
50
+ }
51
+
52
+ function wrap_compute_pass(raw) {
53
+ return {
54
+ _raw: raw,
55
+ setPipeline(pipeline) {
56
+ return raw.setPipeline(unwrap(pipeline));
57
+ },
58
+ setBindGroup(index, bind_group) {
59
+ return raw.setBindGroup(index, unwrap(bind_group));
60
+ },
61
+ dispatchWorkgroups(x, y = 1, z = 1) {
62
+ return raw.dispatchWorkgroups(x, y, z);
63
+ },
64
+ dispatchWorkgroupsIndirect(indirect_buffer, indirect_offset = 0) {
65
+ return raw.dispatchWorkgroupsIndirect(unwrap(indirect_buffer), indirect_offset);
66
+ },
67
+ writeTimestamp(query_set, query_index) {
68
+ if (typeof raw.writeTimestamp !== 'function') {
69
+ throw new Error('timestamp query writes are unsupported on the compute surface');
70
+ }
71
+ return raw.writeTimestamp(unwrap(query_set), query_index);
72
+ },
73
+ end() {
74
+ return raw.end();
75
+ },
76
+ };
77
+ }
78
+
79
+ function wrap_command_encoder(raw) {
80
+ return {
81
+ _raw: raw,
82
+ beginComputePass(descriptor) {
83
+ return wrap_compute_pass(raw.beginComputePass(descriptor));
84
+ },
85
+ copyBufferToBuffer(source, source_offset, target, target_offset, size) {
86
+ return raw.copyBufferToBuffer(
87
+ unwrap(source),
88
+ source_offset,
89
+ unwrap(target),
90
+ target_offset,
91
+ size,
92
+ );
93
+ },
94
+ resolveQuerySet(query_set, first_query, query_count, destination, destination_offset) {
95
+ if (typeof raw.resolveQuerySet !== 'function') {
96
+ throw new Error('query resolution is unsupported on the compute surface');
97
+ }
98
+ return raw.resolveQuerySet(
99
+ unwrap(query_set),
100
+ first_query,
101
+ query_count,
102
+ unwrap(destination),
103
+ destination_offset,
104
+ );
105
+ },
106
+ finish() {
107
+ return raw.finish();
108
+ },
109
+ };
110
+ }
111
+
112
+ function wrap_queue(raw) {
113
+ return {
114
+ _raw: raw,
115
+ submit(command_buffers) {
116
+ return raw.submit(command_buffers.map(unwrap));
117
+ },
118
+ writeBuffer(buffer, buffer_offset, data, data_offset, size) {
119
+ return raw.writeBuffer(unwrap(buffer), buffer_offset, data, data_offset, size);
120
+ },
121
+ async onSubmittedWorkDone() {
122
+ if (typeof raw.onSubmittedWorkDone === 'function') {
123
+ return raw.onSubmittedWorkDone();
124
+ }
125
+ },
126
+ };
127
+ }
128
+
129
+ function wrap_query_set(raw) {
130
+ return {
131
+ _raw: raw,
132
+ destroy() {
133
+ return raw.destroy();
134
+ },
135
+ };
136
+ }
137
+
138
+ function wrap_device(raw) {
139
+ return {
140
+ _raw: raw,
141
+ queue: wrap_queue(raw.queue),
142
+ limits: raw.limits,
143
+ features: raw.features,
144
+ createBuffer(descriptor) {
145
+ return wrap_buffer(raw.createBuffer(descriptor));
146
+ },
147
+ createShaderModule(descriptor) {
148
+ return raw.createShaderModule(descriptor);
149
+ },
150
+ createComputePipeline(descriptor) {
151
+ return wrap_compute_pipeline(raw.createComputePipeline(descriptor));
152
+ },
153
+ async createComputePipelineAsync(descriptor) {
154
+ return wrap_compute_pipeline(await raw.createComputePipelineAsync(descriptor));
155
+ },
156
+ createBindGroupLayout(descriptor) {
157
+ return wrap_bind_group_layout(raw.createBindGroupLayout(descriptor));
158
+ },
159
+ createBindGroup(descriptor) {
160
+ const entries = (descriptor.entries ?? []).map((entry) => ({
161
+ ...entry,
162
+ resource: entry.resource && typeof entry.resource === 'object' && 'buffer' in entry.resource
163
+ ? { ...entry.resource, buffer: unwrap(entry.resource.buffer) }
164
+ : entry.resource,
165
+ }));
166
+ return wrap_bind_group(raw.createBindGroup({
167
+ ...descriptor,
168
+ layout: unwrap(descriptor.layout),
169
+ entries,
170
+ }));
171
+ },
172
+ createPipelineLayout(descriptor) {
173
+ return wrap_pipeline_layout(raw.createPipelineLayout({
174
+ ...descriptor,
175
+ bindGroupLayouts: (descriptor.bindGroupLayouts ?? []).map(unwrap),
176
+ }));
177
+ },
178
+ createCommandEncoder(descriptor) {
179
+ return wrap_command_encoder(raw.createCommandEncoder(descriptor));
180
+ },
181
+ createQuerySet(descriptor) {
182
+ if (typeof raw.createQuerySet !== 'function') {
183
+ throw new Error('query sets are unsupported on the compute surface');
184
+ }
185
+ return wrap_query_set(raw.createQuerySet(descriptor));
186
+ },
187
+ destroy() {
188
+ return raw.destroy();
189
+ },
190
+ };
191
+ }
192
+
193
+ function wrap_adapter(raw) {
194
+ return {
195
+ _raw: raw,
196
+ features: raw.features,
197
+ limits: raw.limits,
198
+ async requestDevice(descriptor) {
199
+ return wrap_device(await raw.requestDevice(descriptor));
200
+ },
201
+ destroy() {
202
+ return raw.destroy();
203
+ },
204
+ };
205
+ }
206
+
207
+ function wrap_gpu(raw) {
208
+ return {
209
+ _raw: raw,
210
+ async requestAdapter(options) {
211
+ return wrap_adapter(await raw.requestAdapter(options));
212
+ },
213
+ };
214
+ }
215
+
216
+ export const globals = full.globals;
217
+
218
+ export function create(create_args = null) {
219
+ return wrap_gpu(full.create(create_args));
220
+ }
221
+
222
+ export function setupGlobals(target = globalThis, create_args = null) {
223
+ for (const [name, value] of Object.entries(globals)) {
224
+ if (target[name] === undefined) {
225
+ Object.defineProperty(target, name, {
226
+ value,
227
+ writable: true,
228
+ configurable: true,
229
+ enumerable: false,
230
+ });
231
+ }
232
+ }
233
+ const gpu = create(create_args);
234
+ if (typeof target.navigator === 'undefined') {
235
+ Object.defineProperty(target, 'navigator', {
236
+ value: { gpu },
237
+ writable: true,
238
+ configurable: true,
239
+ enumerable: false,
240
+ });
241
+ } else if (!target.navigator.gpu) {
242
+ Object.defineProperty(target.navigator, 'gpu', {
243
+ value: gpu,
244
+ writable: true,
245
+ configurable: true,
246
+ enumerable: false,
247
+ });
248
+ }
249
+ return gpu;
250
+ }
251
+
252
+ export async function requestAdapter(adapter_options = undefined, create_args = null) {
253
+ return create(create_args).requestAdapter(adapter_options);
254
+ }
255
+
256
+ export async function requestDevice(options = {}) {
257
+ const adapter = await requestAdapter(options?.adapterOptions, options?.createArgs ?? null);
258
+ return adapter.requestDevice(options?.deviceDescriptor);
259
+ }
260
+
261
+ export const providerInfo = full.providerInfo;
262
+ export const createDoeRuntime = full.createDoeRuntime;
263
+ export const runDawnVsDoeCompare = full.runDawnVsDoeCompare;
264
+
265
+ export default {
266
+ create,
267
+ globals,
268
+ setupGlobals,
269
+ requestAdapter,
270
+ requestDevice,
271
+ providerInfo,
272
+ createDoeRuntime,
273
+ runDawnVsDoeCompare,
274
+ doe,
275
+ };
276
+
277
+ export { doe };
package/src/doe.d.ts ADDED
@@ -0,0 +1,84 @@
1
+ export type DoeBufferUsage =
2
+ | "upload"
3
+ | "readback"
4
+ | "uniform"
5
+ | "storage-read"
6
+ | "storage-readwrite";
7
+
8
+ export type DoeWorkgroups = number | [number, number, number];
9
+
10
+ export type DoeBindingAccess =
11
+ | "uniform"
12
+ | "storage-read"
13
+ | "storage-readwrite";
14
+
15
+ export interface DoeCreateBufferOptions {
16
+ size: number;
17
+ usage: DoeBufferUsage | DoeBufferUsage[] | number;
18
+ label?: string;
19
+ mappedAtCreation?: boolean;
20
+ }
21
+
22
+ export interface DoeCreateBufferFromDataOptions {
23
+ usage?: DoeBufferUsage | DoeBufferUsage[] | number;
24
+ label?: string;
25
+ }
26
+
27
+ export interface DoeReadBufferOptions {
28
+ size?: number;
29
+ offset?: number;
30
+ label?: string;
31
+ }
32
+
33
+ export interface DoeBindingBuffer<TBuffer> {
34
+ buffer: TBuffer;
35
+ access?: DoeBindingAccess;
36
+ }
37
+
38
+ export interface DoeRunComputeOptions<TBuffer> {
39
+ code: string;
40
+ entryPoint?: string;
41
+ bindings?: Array<TBuffer | DoeBindingBuffer<TBuffer>>;
42
+ workgroups: DoeWorkgroups;
43
+ label?: string;
44
+ }
45
+
46
+ export interface DoeKernelDispatchOptions<TBuffer> {
47
+ bindings?: Array<TBuffer | DoeBindingBuffer<TBuffer>>;
48
+ workgroups: DoeWorkgroups;
49
+ label?: string;
50
+ }
51
+
52
+ export interface BoundDoeNamespace<TDevice, TBuffer, TKernel, TRunComputeOptions> {
53
+ readonly device: TDevice;
54
+ createBuffer(options: DoeCreateBufferOptions): TBuffer;
55
+ createBufferFromData<T extends ArrayBufferView>(
56
+ data: T | ArrayBuffer,
57
+ options?: DoeCreateBufferFromDataOptions
58
+ ): TBuffer;
59
+ readBuffer<T extends ArrayBufferView>(
60
+ buffer: TBuffer,
61
+ type: { new(buffer: ArrayBuffer): T },
62
+ options?: DoeReadBufferOptions
63
+ ): Promise<T>;
64
+ runCompute(options: TRunComputeOptions): Promise<void>;
65
+ compileCompute(options: TRunComputeOptions): TKernel;
66
+ }
67
+
68
+ export interface DoeNamespace<TDevice, TBuffer, TKernel, TBoundDoe, TRunComputeOptions> {
69
+ bind(device: TDevice): TBoundDoe;
70
+ createBuffer(device: TDevice, options: DoeCreateBufferOptions): TBuffer;
71
+ createBufferFromData<T extends ArrayBufferView>(
72
+ device: TDevice,
73
+ data: T | ArrayBuffer,
74
+ options?: DoeCreateBufferFromDataOptions
75
+ ): TBuffer;
76
+ readBuffer<T extends ArrayBufferView>(
77
+ device: TDevice,
78
+ buffer: TBuffer,
79
+ type: { new(buffer: ArrayBuffer): T },
80
+ options?: DoeReadBufferOptions
81
+ ): Promise<T>;
82
+ runCompute(device: TDevice, options: TRunComputeOptions): Promise<void>;
83
+ compileCompute(device: TDevice, options: TRunComputeOptions): TKernel;
84
+ }