return found
}
- // static async dispatch (hash: string, seed: bigint, 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.search(hash, threshold)
- // }
- // if (data == null) throw new Error(`Failed to get data from buffer.`)
- // return data
- // }
+ 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
+ }
}