]> zoso.dev Git - nano-pow.git/commitdiff
Move private method above public.
authorChris Duncan <chris@zoso.dev>
Sun, 12 Jan 2025 19:48:05 +0000 (11:48 -0800)
committerChris Duncan <chris@zoso.dev>
Sun, 12 Jan 2025 19:48:05 +0000 (11:48 -0800)
src/classes/gpu.ts

index ed8a9e8842087f969be11b44f59ec44bb3b15b94..a493d12736453f9260a1714cb10f91326bcdf119 100644 (file)
@@ -92,6 +92,72 @@ export class NanoPowGpu {
                NanoPowGpu.init()
        }
 
+       static async #dispatch (seed: bigint, hash: string, threshold: number, passes: number): Promise<DataView> {
+               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
+               const uboView = new DataView(new ArrayBuffer(48))
+               for (let i = 0; i < 64; i += 8) {
+                       const uint32 = hash.slice(i, i + 8)
+                       uboView.setUint32(i / 2, parseInt(uint32, 16))
+               }
+               uboView.setBigUint64(32, seed, true)
+               uboView.setUint32(40, threshold, true)
+               this.#device.queue.writeBuffer(this.#uboBuffer, 0, uboView)
+
+               // Reset `nonce` and `found` to 0u in WORK before each calculation
+               this.#device.queue.writeBuffer(this.#gpuBuffer, 0, new Uint32Array([0, 0, 0]))
+
+                       // Bind UBO read and GPU write buffers
+               const bindGroup = this.#device.createBindGroup({
+                       layout: this.#bindGroupLayout,
+                       entries: [
+                               {
+                                       binding: 0,
+                                       resource: {
+                                               buffer: this.#uboBuffer
+                                       },
+                               },
+                               {
+                                       binding: 1,
+                                       resource: {
+                                               buffer: this.#gpuBuffer
+                                       },
+                               },
+                       ],
+               })
+
+               // Create command encoder to issue commands to GPU and initiate computation
+               const commandEncoder = this.#device.createCommandEncoder()
+               const passEncoder = commandEncoder.beginComputePass()
+
+               // Issue commands and end compute pass structure
+               passEncoder.setPipeline(this.#pipeline)
+               passEncoder.setBindGroup(0, bindGroup)
+               passEncoder.dispatchWorkgroups(passes, passes)
+               passEncoder.end()
+
+               // Copy 8-byte nonce and 4-byte found flag from GPU to CPU for reading
+               commandEncoder.copyBufferToBuffer(this.#gpuBuffer, 0, this.#cpuBuffer, 0, 12)
+
+               // End computation by passing array of command buffers to command queue for execution
+               this.#device.queue.submit([commandEncoder.finish()])
+
+               // Read results back to Javascript and then unmap buffer after reading
+               let data = null
+               try {
+                       await this.#cpuBuffer.mapAsync(GPUMapMode.READ)
+                       await this.#device.queue.onSubmittedWorkDone()
+                       data = new DataView(this.#cpuBuffer.getMappedRange().slice(0))
+                       this.#cpuBuffer.unmap()
+               } catch (err) {
+                       console.warn(`Error getting data from GPU. ${err}`)
+                       return this.#dispatch(seed, hash, threshold, passes)
+               }
+               if (data == null) throw new Error(`Failed to get data from buffer.`)
+               return data
+       }
+
        /**
        * Finds a nonce that satisfies the Nano proof-of-work requirements.
        *
@@ -169,70 +235,4 @@ export class NanoPowGpu {
                if (found && work !== nonce) throw new Error(`Nonce found but does not match work`)
                return found
        }
-
-       static async #dispatch (seed: bigint, hash: string, threshold: number, passes: number): Promise<DataView> {
-               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
-               const uboView = new DataView(new ArrayBuffer(48))
-               for (let i = 0; i < 64; i += 8) {
-                       const uint32 = hash.slice(i, i + 8)
-                       uboView.setUint32(i / 2, parseInt(uint32, 16))
-               }
-               uboView.setBigUint64(32, seed, true)
-               uboView.setUint32(40, threshold, true)
-               this.#device.queue.writeBuffer(this.#uboBuffer, 0, uboView)
-
-               // Reset `nonce` and `found` to 0u in WORK before each calculation
-               this.#device.queue.writeBuffer(this.#gpuBuffer, 0, new Uint32Array([0, 0, 0]))
-
-                       // Bind UBO read and GPU write buffers
-               const bindGroup = this.#device.createBindGroup({
-                       layout: this.#bindGroupLayout,
-                       entries: [
-                               {
-                                       binding: 0,
-                                       resource: {
-                                               buffer: this.#uboBuffer
-                                       },
-                               },
-                               {
-                                       binding: 1,
-                                       resource: {
-                                               buffer: this.#gpuBuffer
-                                       },
-                               },
-                       ],
-               })
-
-               // Create command encoder to issue commands to GPU and initiate computation
-               const commandEncoder = this.#device.createCommandEncoder()
-               const passEncoder = commandEncoder.beginComputePass()
-
-               // Issue commands and end compute pass structure
-               passEncoder.setPipeline(this.#pipeline)
-               passEncoder.setBindGroup(0, bindGroup)
-               passEncoder.dispatchWorkgroups(passes, passes)
-               passEncoder.end()
-
-               // Copy 8-byte nonce and 4-byte found flag from GPU to CPU for reading
-               commandEncoder.copyBufferToBuffer(this.#gpuBuffer, 0, this.#cpuBuffer, 0, 12)
-
-               // End computation by passing array of command buffers to command queue for execution
-               this.#device.queue.submit([commandEncoder.finish()])
-
-               // Read results back to Javascript and then unmap buffer after reading
-               let data = null
-               try {
-                       await this.#cpuBuffer.mapAsync(GPUMapMode.READ)
-                       await this.#device.queue.onSubmittedWorkDone()
-                       data = new DataView(this.#cpuBuffer.getMappedRange().slice(0))
-                       this.#cpuBuffer.unmap()
-               } catch (err) {
-                       console.warn(`Error getting data from GPU. ${err}`)
-                       return this.#dispatch(seed, hash, threshold, passes)
-               }
-               if (data == null) throw new Error(`Failed to get data from buffer.`)
-               return data
-       }
 }