PyBitmessage-2021-04-27/src/openclpow.py

111 lines
3.2 KiB
Python
Raw Normal View History

#!/usr/bin/env python2.7
2019-10-22 16:23:23 +02:00
"""
Module for Proof of Work using OpenCL
"""
import os
2021-01-16 19:58:40 +01:00
from struct import pack
import paths
from bmconfigparser import BMConfigParser
from debug import logger
from state import shutdown
libAvailable = True
ctx = False
queue = False
program = False
gpus = []
enabledGpus = []
vendors = []
hash_dt = None
try:
import pyopencl as cl
2018-06-21 12:03:17 +02:00
import numpy
except ImportError:
libAvailable = False
2018-06-21 12:03:17 +02:00
def initCL():
2019-10-22 16:23:23 +02:00
"""Initlialise OpenCL engine"""
# pylint: disable=global-statement
global ctx, queue, program, hash_dt, libAvailable
if libAvailable is False:
return
del enabledGpus[:]
del vendors[:]
del gpus[:]
ctx = False
try:
hash_dt = numpy.dtype([('target', numpy.uint64), ('v', numpy.str_, 73)])
try:
for platform in cl.get_platforms():
gpus.extend(platform.get_devices(device_type=cl.device_type.GPU))
if BMConfigParser().safeGet("bitmessagesettings", "opencl") == platform.vendor:
2019-10-22 16:23:23 +02:00
enabledGpus.extend(platform.get_devices(
device_type=cl.device_type.GPU))
if platform.vendor not in vendors:
vendors.append(platform.vendor)
except:
pass
2019-10-22 16:23:23 +02:00
if enabledGpus:
ctx = cl.Context(devices=enabledGpus)
queue = cl.CommandQueue(ctx)
f = open(os.path.join(paths.codePath(), "bitmsghash", 'bitmsghash.cl'), 'r')
fstr = ''.join(f.readlines())
program = cl.Program(ctx, fstr).build(options="")
logger.info("Loaded OpenCL kernel")
else:
logger.info("No OpenCL GPUs found")
del enabledGpus[:]
2019-10-22 16:23:23 +02:00
except Exception:
logger.error("OpenCL fail: ", exc_info=True)
del enabledGpus[:]
2019-10-22 16:23:23 +02:00
def openclAvailable():
2019-10-22 16:23:23 +02:00
"""Are there any OpenCL GPUs available?"""
return bool(gpus)
def openclEnabled():
2019-10-22 16:23:23 +02:00
"""Is OpenCL enabled (and available)?"""
return bool(enabledGpus)
2019-10-22 16:23:23 +02:00
def do_opencl_pow(hash_, target):
"""Perform PoW using OpenCL"""
output = numpy.zeros(1, dtype=[('v', numpy.uint64, 1)])
2019-10-22 16:23:23 +02:00
if not enabledGpus:
return output[0][0]
data = numpy.zeros(1, dtype=hash_dt, order='C')
2019-10-22 16:23:23 +02:00
data[0]['v'] = ("0000000000000000" + hash_).decode("hex")
data[0]['target'] = target
hash_buf = cl.Buffer(ctx, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=data)
dest_buf = cl.Buffer(ctx, cl.mem_flags.WRITE_ONLY, output.nbytes)
kernel = program.kernel_sha512
worksize = kernel.get_work_group_info(cl.kernel_work_group_info.WORK_GROUP_SIZE, enabledGpus[0])
kernel.set_arg(0, hash_buf)
kernel.set_arg(1, dest_buf)
progress = 0
2019-10-22 16:23:23 +02:00
globamt = worksize * 2000
while output[0][0] == 0 and shutdown == 0:
kernel.set_arg(2, pack("<Q", progress))
cl.enqueue_nd_range_kernel(queue, kernel, (globamt,), (worksize,))
try:
cl.enqueue_read_buffer(queue, dest_buf, output)
except AttributeError:
cl.enqueue_copy(queue, output, dest_buf)
queue.finish()
progress += globamt
if shutdown != 0:
2019-10-22 16:23:23 +02:00
raise Exception("Interrupted")
# logger.debug("Took %d tries.", progress)
return output[0][0]