-
Notifications
You must be signed in to change notification settings - Fork 571
/
Copy pathopenclpow.py
111 lines (92 loc) · 3.22 KB
/
openclpow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"""
Module for Proof of Work using OpenCL
"""
import logging
import os
from struct import pack
import paths
from bmconfigparser import config
from state import shutdown
try:
import numpy
import pyopencl as cl
libAvailable = True
except ImportError:
libAvailable = False
logger = logging.getLogger('default')
ctx = False
queue = False
program = False
gpus = []
enabledGpus = []
vendors = []
hash_dt = None
def initCL():
"""Initlialise OpenCL engine"""
global ctx, queue, program, hash_dt # pylint: disable=global-statement
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 config.safeGet("bitmessagesettings", "opencl") == platform.vendor:
enabledGpus.extend(platform.get_devices(
device_type=cl.device_type.GPU))
if platform.vendor not in vendors:
vendors.append(platform.vendor)
except: # nosec B110 # noqa:E722 # pylint:disable=bare-except
pass
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[:]
except Exception:
logger.error("OpenCL fail: ", exc_info=True)
del enabledGpus[:]
def openclAvailable():
"""Are there any OpenCL GPUs available?"""
return bool(gpus)
def openclEnabled():
"""Is OpenCL enabled (and available)?"""
return bool(enabledGpus)
def do_opencl_pow(hash_, target):
"""Perform PoW using OpenCL"""
output = numpy.zeros(1, dtype=[('v', numpy.uint64, 1)])
if not enabledGpus:
return output[0][0]
data = numpy.zeros(1, dtype=hash_dt, order='C')
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
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:
raise Exception("Interrupted")
# logger.debug("Took %d tries.", progress)
return output[0][0]