PoW init reordering

- inited by the worker thread on its own init, instead of when the
imports are being evaluated
- also got rid of windows-style newlines in OpenCL PoW
This commit is contained in:
Peter Šurda 2017-08-15 12:24:43 +02:00
parent 58b47bc6de
commit a48dff3bee
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
3 changed files with 114 additions and 112 deletions

View File

@ -42,6 +42,7 @@ class singleWorker(threading.Thread, StoppableThread):
# QThread.__init__(self, parent) # QThread.__init__(self, parent)
threading.Thread.__init__(self, name="singleWorker") threading.Thread.__init__(self, name="singleWorker")
self.initStop() self.initStop()
proofofwork.init()
def stopThread(self): def stopThread(self):
try: try:

View File

@ -1,111 +1,111 @@
#!/usr/bin/env python2.7 #!/usr/bin/env python2.7
from struct import pack, unpack from struct import pack, unpack
import time import time
import hashlib import hashlib
import random import random
import os import os
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
import paths import paths
from state import shutdown from state import shutdown
from debug import logger from debug import logger
libAvailable = True libAvailable = True
ctx = False ctx = False
queue = False queue = False
program = False program = False
gpus = [] gpus = []
enabledGpus = [] enabledGpus = []
vendors = [] vendors = []
hash_dt = None hash_dt = None
try: try:
import numpy import numpy
import pyopencl as cl import pyopencl as cl
except: except:
libAvailable = False libAvailable = False
def initCL(): def initCL():
global ctx, queue, program, hash_dt, libAvailable global ctx, queue, program, hash_dt, libAvailable
if libAvailable is False: if libAvailable is False:
return return
del enabledGpus[:] del enabledGpus[:]
del vendors[:] del vendors[:]
del gpus[:] del gpus[:]
ctx = False ctx = False
try: try:
hash_dt = numpy.dtype([('target', numpy.uint64), ('v', numpy.str_, 73)]) hash_dt = numpy.dtype([('target', numpy.uint64), ('v', numpy.str_, 73)])
try: try:
for platform in cl.get_platforms(): for platform in cl.get_platforms():
gpus.extend(platform.get_devices(device_type=cl.device_type.GPU)) gpus.extend(platform.get_devices(device_type=cl.device_type.GPU))
if BMConfigParser().safeGet("bitmessagesettings", "opencl") == platform.vendor: if BMConfigParser().safeGet("bitmessagesettings", "opencl") == platform.vendor:
enabledGpus.extend(platform.get_devices(device_type=cl.device_type.GPU)) enabledGpus.extend(platform.get_devices(device_type=cl.device_type.GPU))
if platform.vendor not in vendors: if platform.vendor not in vendors:
vendors.append(platform.vendor) vendors.append(platform.vendor)
except: except:
pass pass
if (len(enabledGpus) > 0): if (len(enabledGpus) > 0):
ctx = cl.Context(devices=enabledGpus) ctx = cl.Context(devices=enabledGpus)
queue = cl.CommandQueue(ctx) queue = cl.CommandQueue(ctx)
f = open(os.path.join(paths.codePath(), "bitmsghash", 'bitmsghash.cl'), 'r') f = open(os.path.join(paths.codePath(), "bitmsghash", 'bitmsghash.cl'), 'r')
fstr = ''.join(f.readlines()) fstr = ''.join(f.readlines())
program = cl.Program(ctx, fstr).build(options="") program = cl.Program(ctx, fstr).build(options="")
logger.info("Loaded OpenCL kernel") logger.info("Loaded OpenCL kernel")
else: else:
logger.info("No OpenCL GPUs found") logger.info("No OpenCL GPUs found")
del enabledGpus[:] del enabledGpus[:]
except Exception as e: except Exception as e:
logger.error("OpenCL fail: ", exc_info=True) logger.error("OpenCL fail: ", exc_info=True)
del enabledGpus[:] del enabledGpus[:]
def openclAvailable(): def openclAvailable():
return (len(gpus) > 0) return (len(gpus) > 0)
def openclEnabled(): def openclEnabled():
return (len(enabledGpus) > 0) return (len(enabledGpus) > 0)
def do_opencl_pow(hash, target): def do_opencl_pow(hash, target):
output = numpy.zeros(1, dtype=[('v', numpy.uint64, 1)]) output = numpy.zeros(1, dtype=[('v', numpy.uint64, 1)])
if (len(enabledGpus) == 0): if (len(enabledGpus) == 0):
return output[0][0] return output[0][0]
data = numpy.zeros(1, dtype=hash_dt, order='C') data = numpy.zeros(1, dtype=hash_dt, order='C')
data[0]['v'] = ("0000000000000000" + hash).decode("hex") data[0]['v'] = ("0000000000000000" + hash).decode("hex")
data[0]['target'] = target data[0]['target'] = target
hash_buf = cl.Buffer(ctx, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=data) 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) dest_buf = cl.Buffer(ctx, cl.mem_flags.WRITE_ONLY, output.nbytes)
kernel = program.kernel_sha512 kernel = program.kernel_sha512
worksize = kernel.get_work_group_info(cl.kernel_work_group_info.WORK_GROUP_SIZE, enabledGpus[0]) 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(0, hash_buf)
kernel.set_arg(1, dest_buf) kernel.set_arg(1, dest_buf)
start = time.time() start = time.time()
progress = 0 progress = 0
globamt = worksize*2000 globamt = worksize*2000
while output[0][0] == 0 and shutdown == 0: while output[0][0] == 0 and shutdown == 0:
kernel.set_arg(2, pack("<Q", progress)) kernel.set_arg(2, pack("<Q", progress))
cl.enqueue_nd_range_kernel(queue, kernel, (globamt,), (worksize,)) cl.enqueue_nd_range_kernel(queue, kernel, (globamt,), (worksize,))
cl.enqueue_read_buffer(queue, dest_buf, output) cl.enqueue_read_buffer(queue, dest_buf, output)
queue.finish() queue.finish()
progress += globamt progress += globamt
sofar = time.time() - start sofar = time.time() - start
# logger.debug("Working for %.3fs, %.2f Mh/s", sofar, (progress / sofar) / 1000000) # logger.debug("Working for %.3fs, %.2f Mh/s", sofar, (progress / sofar) / 1000000)
if shutdown != 0: if shutdown != 0:
raise Exception ("Interrupted") raise Exception ("Interrupted")
taken = time.time() - start taken = time.time() - start
# logger.debug("Took %d tries.", progress) # logger.debug("Took %d tries.", progress)
return output[0][0] return output[0][0]
initCL() #initCL()
if __name__ == "__main__": if __name__ == "__main__":
target = 54227212183L target = 54227212183L
initialHash = "3758f55b5a8d902fd3597e4ce6a2d3f23daff735f65d9698c270987f4e67ad590b93f3ffeba0ef2fd08a8dc2f87b68ae5a0dc819ab57f22ad2c4c9c8618a43b3".decode("hex") initialHash = "3758f55b5a8d902fd3597e4ce6a2d3f23daff735f65d9698c270987f4e67ad590b93f3ffeba0ef2fd08a8dc2f87b68ae5a0dc819ab57f22ad2c4c9c8618a43b3".decode("hex")
nonce = do_opencl_pow(initialHash.encode("hex"), target) nonce = do_opencl_pow(initialHash.encode("hex"), target)
trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8]) trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8])
print "{} - value {} < {}".format(nonce, trialValue, target) print "{} - value {} < {}".format(nonce, trialValue, target)

View File

@ -237,6 +237,9 @@ def resetPoW():
# init # init
def init(): def init():
global bitmsglib, bso, bmpow global bitmsglib, bso, bmpow
openclpow.initCL()
if "win32" == sys.platform: if "win32" == sys.platform:
if ctypes.sizeof(ctypes.c_voidp) == 4: if ctypes.sizeof(ctypes.c_voidp) == 4:
bitmsglib = 'bitmsghash32.dll' bitmsglib = 'bitmsghash32.dll'
@ -286,7 +289,5 @@ def init():
bmpow = None bmpow = None
else: else:
bmpow = None bmpow = None
if bmpow is None:
init() buildCPoW()
if bmpow is None:
buildCPoW()