PyBitmessage/src/openclpow.py

73 lines
2.3 KiB
Python

import numpy
from struct import pack, unpack
import time
import hashlib
import random
import pyopencl as cl
hash_dt = numpy.dtype([('target', numpy.uint64), ('v', numpy.str_, 73)])
ctx = False
queue = False
program = False
try:
if (len(cl.get_platforms()) > 0):
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
f = open('/usr/src/PyBitmessage/src/kernel.cl', 'r')
fstr = ''.join(f.readlines())
program = cl.Program(ctx, fstr).build()
except:
ctx = False
def has_opencl():
return (ctx != False)
def do_opencl_pow(hash, target):
output = numpy.zeros(1, dtype=[('v', numpy.uint64, 1)])
if (ctx == False):
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, cl.get_platforms()[0].get_devices()[0])
kernel.set_arg(0, hash_buf)
kernel.set_arg(1, dest_buf)
start = time.time()
#startpos = random.getrandbits(32) << 32 | random.getrandbits(32)
#startpos = random.getrandbits(32)
startpos = 0
progress = 0
globamt = worksize*2000
while output[0][0] == 0:
kernel.set_arg(2, pack("<Q", startpos))
cl.enqueue_nd_range_kernel(queue, kernel, (globamt,), (worksize,))
cl.enqueue_read_buffer(queue, dest_buf, output)
queue.finish()
#startpos == (globamt + startpos) & 0xFFFFFFFFFFFFFFFF
startpos += globamt
progress += globamt
sofar = time.time() - start
print sofar, progress / sofar, "hashes/sec"
taken = time.time() - start
print progress, taken
return output[0][0]
if __name__ == "__main__":
target = 54227212183L
initialHash = "3758f55b5a8d902fd3597e4ce6a2d3f23daff735f65d9698c270987f4e67ad590b93f3ffeba0ef2fd08a8dc2f87b68ae5a0dc819ab57f22ad2c4c9c8618a43b3".decode("hex")
nonce = do_opencl_pow(initialHash.encode("hex"), target)
trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8])
print "{} - value {} < {}".format(nonce, trialValue, target)