]> zoso.dev Git - libnemo.git/commitdiff
Fix class reference used for static members within static context when this should...
authorChris Duncan <chris@zoso.dev>
Tue, 7 Jan 2025 22:11:52 +0000 (14:11 -0800)
committerChris Duncan <chris@zoso.dev>
Tue, 7 Jan 2025 22:11:52 +0000 (14:11 -0800)
src/lib/workers/powgpu.ts

index 054a13b49b148a3f6bf70bc0a060bcdd3722e368..4105721ce33e66aea05f1e5f765527b78a36bb74 100644 (file)
@@ -390,8 +390,12 @@ export class PowGpu extends WorkerInterface {
        static #bindGroupLayout: GPUBindGroupLayout
        static #pipeline: GPUComputePipeline
 
-       // Initialize WebGPU
        static {
+               this.init()
+       }
+
+       // Initialize WebGPU
+       static init () {
                // Request device and adapter
                if (navigator.gpu == null) {
                        throw new Error('WebGPU is not supported in this browser.')
@@ -467,12 +471,12 @@ export class PowGpu extends WorkerInterface {
                if (typeof threshold !== 'number') throw new TypeError(`Invalid threshold ${threshold}`)
 
                // Ensure WebGPU is initialized before calculating, up to a max time frame
-               while (PowGpu.#device == null && performance.now() < 8000) {
+               while (this.#device == null && performance.now() < 8000) {
                        await new Promise(resolve => {
                                setTimeout(resolve, 500)
                        })
                }
-               if (PowGpu.#device == null) throw new Error(`WebGPU device failed to load.`)
+               if (this.#device == null) throw new Error(`WebGPU device failed to load.`)
 
                // Set up uniform buffer object
                // Note: u32 size is 4, but total alignment must be multiple of 16
@@ -484,59 +488,65 @@ export class PowGpu extends WorkerInterface {
                const random = Math.floor((Math.random() * 0xffffffff))
                uboView.setUint32(32, random, true)
                uboView.setUint32(36, threshold, true)
-               PowGpu.#device.queue.writeBuffer(PowGpu.#uboBuffer, 0, uboView)
+               this.#device.queue.writeBuffer(this.#uboBuffer, 0, uboView)
 
                // Reset `found` flag to 0u in WORK before each calculation
-               PowGpu.#device.queue.writeBuffer(PowGpu.#gpuBuffer, 8, new Uint32Array([0]))
+               this.#device.queue.writeBuffer(this.#gpuBuffer, 8, new Uint32Array([0]))
 
                // Bind UBO read and GPU write buffers
-               const bindGroup = PowGpu.#device.createBindGroup({
-                       layout: PowGpu.#bindGroupLayout,
+               const bindGroup = this.#device.createBindGroup({
+                       layout: this.#bindGroupLayout,
                        entries: [
                                {
                                        binding: 0,
                                        resource: {
-                                               buffer: PowGpu.#uboBuffer
+                                               buffer: this.#uboBuffer
                                        },
                                },
                                {
                                        binding: 1,
                                        resource: {
-                                               buffer: PowGpu.#gpuBuffer
+                                               buffer: this.#gpuBuffer
                                        },
                                },
                        ],
                })
 
                // Create command encoder to issue commands to GPU and initiate computation
-               const commandEncoder = PowGpu.#device.createCommandEncoder()
+               const commandEncoder = this.#device.createCommandEncoder()
                const passEncoder = commandEncoder.beginComputePass()
 
                // Issue commands and end compute pass structure
-               passEncoder.setPipeline(PowGpu.#pipeline)
+               passEncoder.setPipeline(this.#pipeline)
                passEncoder.setBindGroup(0, bindGroup)
                passEncoder.dispatchWorkgroups(256, 256, 256)
                passEncoder.end()
 
                // Copy 8-byte nonce and 4-byte found flag from GPU to CPU for reading
                commandEncoder.copyBufferToBuffer(
-                       PowGpu.#gpuBuffer,
+                       this.#gpuBuffer,
                        0,
-                       PowGpu.#cpuBuffer,
+                       this.#cpuBuffer,
                        0,
                        12
                )
 
                // End computation by passing array of command buffers to command queue for execution
-               PowGpu.#device.queue.submit([commandEncoder.finish()])
+               this.#device.queue.submit([commandEncoder.finish()])
 
                // Read results back to Javascript and then unmap buffer after reading
-               await PowGpu.#cpuBuffer.mapAsync(GPUMapMode.READ)
-               await PowGpu.#device.queue.onSubmittedWorkDone()
-               const data = new DataView(PowGpu.#cpuBuffer.getMappedRange())
+               try {
+                       await this.#cpuBuffer.mapAsync(GPUMapMode.READ)
+                       await this.#device.queue.onSubmittedWorkDone()
+               } catch (err) {
+                       console.warn(`Reinitializing after catching error ${err}`)
+                       this.init()
+                       return await this.search(hash, threshold)
+               }
+               const data = new DataView(this.#cpuBuffer.getMappedRange())
                const nonce = data.getBigUint64(0, true)
                const found = !!data.getUint32(8)
-               PowGpu.#cpuBuffer.unmap()
+               this.#cpuBuffer.unmap()
 
                if (found) {
                        const hex = nonce.toString(16).padStart(16, '0')