From: Chris Duncan Date: Tue, 7 Jan 2025 22:11:52 +0000 (-0800) Subject: Fix class reference used for static members within static context when this should... X-Git-Url: https://zoso.dev/?a=commitdiff_plain;h=004af0a95b149005a9e668762c6e90c1afe506ae;p=libnemo.git Fix class reference used for static members within static context when this should be used. Small change to initialization so class can be reloaded if necessary. Implement try-catch if getting data from GPU throws so we can reinitialize. --- diff --git a/src/lib/workers/powgpu.ts b/src/lib/workers/powgpu.ts index 054a13b..4105721 100644 --- a/src/lib/workers/powgpu.ts +++ b/src/lib/workers/powgpu.ts @@ -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')