OpenCL vendor selector
- when you have multiple OpenCL drivers at the same time, e.g. intel and nvidia, they won't mix leading to crashes. This patch makes it possible to select which driver to use by listing the available vendors
This commit is contained in:
parent
756f85c9f0
commit
e9a3ef465c
|
@ -2408,8 +2408,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
shared.config.set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str(int(float(
|
||||
self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text()) * shared.networkDefaultPayloadLengthExtraBytes)))
|
||||
|
||||
if openclpow.has_opencl() and self.settingsDialogInstance.ui.checkBoxOpenCL.isChecked() != shared.safeConfigGetBoolean("bitmessagesettings", "opencl"):
|
||||
shared.config.set('bitmessagesettings', 'opencl', str(self.settingsDialogInstance.ui.checkBoxOpenCL.isChecked()))
|
||||
if self.settingsDialogInstance.ui.checkBoxOpenCL.currentText().toUtf8() != shared.safeConfigGet("bitmessagesettings", "opencl"):
|
||||
shared.config.set('bitmessagesettings', 'opencl', self.settingsDialogInstance.ui.checkBoxOpenCL.currentText().toUtf8())
|
||||
|
||||
acceptableDifficultyChanged = False
|
||||
|
||||
|
@ -4082,14 +4082,18 @@ class settingsDialog(QtGui.QDialog):
|
|||
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')) / shared.networkDefaultPayloadLengthExtraBytes)))
|
||||
|
||||
# OpenCL
|
||||
if openclpow.has_opencl():
|
||||
self.ui.checkBoxOpenCL.setEnabled(True)
|
||||
if openclpow.openclAvailable():
|
||||
self.ui.comboBoxOpenCL.setEnabled(True)
|
||||
else:
|
||||
self.ui.checkBoxOpenCL.setEnabled(False)
|
||||
if shared.safeConfigGetBoolean("bitmessagesettings", "opencl"):
|
||||
self.ui.checkBoxOpenCL.setChecked(True)
|
||||
else:
|
||||
self.ui.checkBoxOpenCL.setChecked(False)
|
||||
self.ui.comboBoxOpenCL.setEnabled(False)
|
||||
self.ui.comboBoxOpenCL.clear()
|
||||
self.ui.comboBoxOpenCL.addItem("None")
|
||||
self.ui.comboBoxOpenCL.addItems(openclpow.vendors)
|
||||
self.ui.comboBoxOpenCL.setCurrentIndex(0)
|
||||
for i in range(self.ui.comboBoxOpenCL.count()):
|
||||
if self.ui.comboBoxOpenCL.itemText(i) == shared.safeConfigGet('bitmessagesettings', 'opencl'):
|
||||
self.ui.comboBoxOpenCL.setCurrentIndex(i)
|
||||
break
|
||||
|
||||
# Namecoin integration tab
|
||||
nmctype = shared.config.get('bitmessagesettings', 'namecoinrpctype')
|
||||
|
|
|
@ -298,9 +298,9 @@ class Ui_settingsDialog(object):
|
|||
self.labelOpenCL = QtGui.QLabel(self.tabMaxAcceptableDifficulty)
|
||||
self.labelOpenCL.setObjectName(_fromUtf8("labelOpenCL"))
|
||||
self.gridLayout_7.addWidget(self.labelOpenCL, 4, 0, 1, 1)
|
||||
self.checkBoxOpenCL = QtGui.QCheckBox(self.tabMaxAcceptableDifficulty)
|
||||
self.checkBoxOpenCL.setObjectName = (_fromUtf8("checkBoxOpenCL"))
|
||||
self.gridLayout_7.addWidget(self.checkBoxOpenCL, 4, 1, 1, 1)
|
||||
self.comboBoxOpenCL = QtGui.QComboBox(self.tabMaxAcceptableDifficulty)
|
||||
self.comboBoxOpenCL.setObjectName = (_fromUtf8("comboBoxOpenCL"))
|
||||
self.gridLayout_7.addWidget(self.comboBoxOpenCL, 4, 1, 1, 1)
|
||||
self.tabWidgetSettings.addTab(self.tabMaxAcceptableDifficulty, _fromUtf8(""))
|
||||
self.tabNamecoin = QtGui.QWidget()
|
||||
self.tabNamecoin.setObjectName(_fromUtf8("tabNamecoin"))
|
||||
|
@ -475,7 +475,7 @@ class Ui_settingsDialog(object):
|
|||
self.label_13.setText(_translate("settingsDialog", "Maximum acceptable total difficulty:", None))
|
||||
self.label_14.setText(_translate("settingsDialog", "Maximum acceptable small message difficulty:", None))
|
||||
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabMaxAcceptableDifficulty), _translate("settingsDialog", "Max acceptable difficulty", None))
|
||||
self.labelOpenCL.setText(_translate("settingsDialog", "Hardware GPU acceleration (OpenCL)", None))
|
||||
self.labelOpenCL.setText(_translate("settingsDialog", "Hardware GPU acceleration (OpenCL):", None))
|
||||
self.label_16.setText(_translate("settingsDialog", "<html><head/><body><p>Bitmessage can utilize a different Bitcoin-based program called Namecoin to make addresses human-friendly. For example, instead of having to tell your friend your long Bitmessage address, you can simply tell him to send a message to <span style=\" font-style:italic;\">test. </span></p><p>(Getting your own Bitmessage address into Namecoin is still rather difficult).</p><p>Bitmessage can use either namecoind directly or a running nmcontrol instance.</p></body></html>", None))
|
||||
self.label_17.setText(_translate("settingsDialog", "Host:", None))
|
||||
self.label_18.setText(_translate("settingsDialog", "Port:", None))
|
||||
|
|
|
@ -9,7 +9,7 @@ from debug import logger
|
|||
from foldertree import AccountMixin
|
||||
from helper_sql import *
|
||||
from l10n import getTranslationLanguage
|
||||
from openclpow import has_opencl
|
||||
from openclpow import openclAvailable, openclEnabled
|
||||
from proofofwork import bmpow
|
||||
from pyelliptic.openssl import OpenSSL
|
||||
import shared
|
||||
|
@ -107,7 +107,7 @@ def createSupportMessage(myapp):
|
|||
portablemode = "True" if shared.appdata == shared.lookupExeFolder() else "False"
|
||||
cpow = "True" if bmpow else "False"
|
||||
#cpow = QtGui.QApplication.translate("Support", cpow)
|
||||
openclpow = "True" if shared.safeConfigGetBoolean('bitmessagesettings', 'opencl') and has_opencl() else "False"
|
||||
openclpow = str(shared.safeConfigGet('bitmessagesettings', 'opencl')) if openclEnabled() else "None"
|
||||
#openclpow = QtGui.QApplication.translate("Support", openclpow)
|
||||
locale = getTranslationLanguage()
|
||||
try:
|
||||
|
|
103
src/openclpow.py
103
src/openclpow.py
|
@ -5,7 +5,7 @@ import hashlib
|
|||
import random
|
||||
import os
|
||||
|
||||
from shared import codePath, safeConfigGetBoolean, shutdown
|
||||
from shared import codePath, safeConfigGetBoolean, safeConfigGet, shutdown
|
||||
from debug import logger
|
||||
|
||||
libAvailable = True
|
||||
|
@ -13,6 +13,8 @@ ctx = False
|
|||
queue = False
|
||||
program = False
|
||||
gpus = []
|
||||
enabledGpus = []
|
||||
vendors = []
|
||||
hash_dt = None
|
||||
|
||||
try:
|
||||
|
@ -22,13 +24,20 @@ except:
|
|||
libAvailable = False
|
||||
|
||||
def initCL():
|
||||
global ctx, queue, program, gpus, hash_dt
|
||||
global ctx, queue, program, gpus, hash_dt, vendors
|
||||
try:
|
||||
hash_dt = numpy.dtype([('target', numpy.uint64), ('v', numpy.str_, 73)])
|
||||
for platform in cl.get_platforms():
|
||||
gpus.extend(platform.get_devices(device_type=cl.device_type.GPU))
|
||||
if (len(gpus) > 0):
|
||||
ctx = cl.Context(devices=gpus)
|
||||
try:
|
||||
for platform in cl.get_platforms():
|
||||
gpus.extend(platform.get_devices(device_type=cl.device_type.GPU))
|
||||
if safeConfigGet("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:
|
||||
pass
|
||||
if (len(enabledGpus) > 0):
|
||||
ctx = cl.Context(devices=enabledGpus)
|
||||
queue = cl.CommandQueue(ctx)
|
||||
f = open(os.path.join(codePath(), "bitmsghash", 'bitmsghash.cl'), 'r')
|
||||
fstr = ''.join(f.readlines())
|
||||
|
@ -36,60 +45,64 @@ def initCL():
|
|||
logger.info("Loaded OpenCL kernel")
|
||||
else:
|
||||
logger.info("No OpenCL GPUs found")
|
||||
ctx = False
|
||||
enabledGpus = []
|
||||
except Exception as e:
|
||||
logger.error("OpenCL fail: ", exc_info=True)
|
||||
ctx = False
|
||||
enabledGpus = []
|
||||
|
||||
def has_opencl():
|
||||
global ctx
|
||||
return (ctx != False)
|
||||
def openclAvailable():
|
||||
global gpus
|
||||
return (len(gpus) > 0)
|
||||
|
||||
def openclEnabled():
|
||||
global enabledGpus
|
||||
return (len(enabledGpus) > 0)
|
||||
|
||||
def do_opencl_pow(hash, target):
|
||||
global ctx, queue, program, gpus, hash_dt
|
||||
global ctx, queue, program, enabledGpus, hash_dt
|
||||
|
||||
output = numpy.zeros(1, dtype=[('v', numpy.uint64, 1)])
|
||||
if (ctx == False):
|
||||
return output[0][0]
|
||||
output = numpy.zeros(1, dtype=[('v', numpy.uint64, 1)])
|
||||
if (len(enabledGpus) == 0):
|
||||
return output[0][0]
|
||||
|
||||
data = numpy.zeros(1, dtype=hash_dt, order='C')
|
||||
data[0]['v'] = ("0000000000000000" + hash).decode("hex")
|
||||
data[0]['target'] = target
|
||||
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)
|
||||
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, gpus[0])
|
||||
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)
|
||||
kernel.set_arg(0, hash_buf)
|
||||
kernel.set_arg(1, dest_buf)
|
||||
|
||||
start = time.time()
|
||||
progress = 0
|
||||
globamt = worksize*2000
|
||||
start = time.time()
|
||||
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,))
|
||||
cl.enqueue_read_buffer(queue, dest_buf, output)
|
||||
queue.finish()
|
||||
progress += globamt
|
||||
sofar = time.time() - start
|
||||
# logger.debug("Working for %.3fs, %.2f Mh/s", sofar, (progress / sofar) / 1000000)
|
||||
if shutdown != 0:
|
||||
raise Exception ("Interrupted")
|
||||
taken = time.time() - start
|
||||
# logger.debug("Took %d tries.", progress)
|
||||
return output[0][0]
|
||||
while output[0][0] == 0 and shutdown == 0:
|
||||
kernel.set_arg(2, pack("<Q", progress))
|
||||
cl.enqueue_nd_range_kernel(queue, kernel, (globamt,), (worksize,))
|
||||
cl.enqueue_read_buffer(queue, dest_buf, output)
|
||||
queue.finish()
|
||||
progress += globamt
|
||||
sofar = time.time() - start
|
||||
# logger.debug("Working for %.3fs, %.2f Mh/s", sofar, (progress / sofar) / 1000000)
|
||||
if shutdown != 0:
|
||||
raise Exception ("Interrupted")
|
||||
taken = time.time() - start
|
||||
# logger.debug("Took %d tries.", progress)
|
||||
return output[0][0]
|
||||
|
||||
if libAvailable:
|
||||
initCL()
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
|
|
|
@ -108,10 +108,10 @@ def _doGPUPoW(target, initialHash):
|
|||
trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8])
|
||||
#print "{} - value {} < {}".format(nonce, trialValue, target)
|
||||
if trialValue > target:
|
||||
deviceNames = ", ".join(gpu.name for gpu in openclpow.gpus)
|
||||
deviceNames = ", ".join(gpu.name for gpu in openclpow.enabledGpus)
|
||||
shared.UISignalQueue.put(('updateStatusBar', tr._translate("MainWindow",'Your GPU(s) did not calculate correctly, disabling OpenCL. Please report to the developers.')))
|
||||
logger.error("Your GPUs (%s) did not calculate correctly, disabling OpenCL. Please report to the developers.", deviceNames)
|
||||
openclpow.ctx = False
|
||||
openclpow.enabledGpus = []
|
||||
raise Exception("GPU did not calculate correctly.")
|
||||
if shared.shutdown != 0:
|
||||
raise StopIteration("Interrupted")
|
||||
|
@ -144,7 +144,7 @@ def estimate(difficulty, format = False):
|
|||
return ret
|
||||
|
||||
def getPowType():
|
||||
if shared.safeConfigGetBoolean('bitmessagesettings', 'opencl') and openclpow.has_opencl():
|
||||
if openclpow.openclEnabled():
|
||||
return "OpenCL"
|
||||
if bmpow:
|
||||
return "C"
|
||||
|
@ -154,7 +154,7 @@ def run(target, initialHash):
|
|||
if shared.shutdown != 0:
|
||||
raise
|
||||
target = int(target)
|
||||
if shared.safeConfigGetBoolean('bitmessagesettings', 'opencl') and openclpow.has_opencl():
|
||||
if openclpow.openclEnabled():
|
||||
# trialvalue1, nonce1 = _doGPUPoW(target, initialHash)
|
||||
# trialvalue, nonce = _doFastPoW(target, initialHash)
|
||||
# print "GPU: %s, %s" % (trialvalue1, nonce1)
|
||||
|
|
Reference in New Issue
Block a user