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(
|
shared.config.set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str(int(float(
|
||||||
self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text()) * shared.networkDefaultPayloadLengthExtraBytes)))
|
self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text()) * shared.networkDefaultPayloadLengthExtraBytes)))
|
||||||
|
|
||||||
if openclpow.has_opencl() and self.settingsDialogInstance.ui.checkBoxOpenCL.isChecked() != shared.safeConfigGetBoolean("bitmessagesettings", "opencl"):
|
if self.settingsDialogInstance.ui.checkBoxOpenCL.currentText().toUtf8() != shared.safeConfigGet("bitmessagesettings", "opencl"):
|
||||||
shared.config.set('bitmessagesettings', 'opencl', str(self.settingsDialogInstance.ui.checkBoxOpenCL.isChecked()))
|
shared.config.set('bitmessagesettings', 'opencl', self.settingsDialogInstance.ui.checkBoxOpenCL.currentText().toUtf8())
|
||||||
|
|
||||||
acceptableDifficultyChanged = False
|
acceptableDifficultyChanged = False
|
||||||
|
|
||||||
|
@ -4082,14 +4082,18 @@ class settingsDialog(QtGui.QDialog):
|
||||||
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')) / shared.networkDefaultPayloadLengthExtraBytes)))
|
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')) / shared.networkDefaultPayloadLengthExtraBytes)))
|
||||||
|
|
||||||
# OpenCL
|
# OpenCL
|
||||||
if openclpow.has_opencl():
|
if openclpow.openclAvailable():
|
||||||
self.ui.checkBoxOpenCL.setEnabled(True)
|
self.ui.comboBoxOpenCL.setEnabled(True)
|
||||||
else:
|
else:
|
||||||
self.ui.checkBoxOpenCL.setEnabled(False)
|
self.ui.comboBoxOpenCL.setEnabled(False)
|
||||||
if shared.safeConfigGetBoolean("bitmessagesettings", "opencl"):
|
self.ui.comboBoxOpenCL.clear()
|
||||||
self.ui.checkBoxOpenCL.setChecked(True)
|
self.ui.comboBoxOpenCL.addItem("None")
|
||||||
else:
|
self.ui.comboBoxOpenCL.addItems(openclpow.vendors)
|
||||||
self.ui.checkBoxOpenCL.setChecked(False)
|
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
|
# Namecoin integration tab
|
||||||
nmctype = shared.config.get('bitmessagesettings', 'namecoinrpctype')
|
nmctype = shared.config.get('bitmessagesettings', 'namecoinrpctype')
|
||||||
|
|
|
@ -298,9 +298,9 @@ class Ui_settingsDialog(object):
|
||||||
self.labelOpenCL = QtGui.QLabel(self.tabMaxAcceptableDifficulty)
|
self.labelOpenCL = QtGui.QLabel(self.tabMaxAcceptableDifficulty)
|
||||||
self.labelOpenCL.setObjectName(_fromUtf8("labelOpenCL"))
|
self.labelOpenCL.setObjectName(_fromUtf8("labelOpenCL"))
|
||||||
self.gridLayout_7.addWidget(self.labelOpenCL, 4, 0, 1, 1)
|
self.gridLayout_7.addWidget(self.labelOpenCL, 4, 0, 1, 1)
|
||||||
self.checkBoxOpenCL = QtGui.QCheckBox(self.tabMaxAcceptableDifficulty)
|
self.comboBoxOpenCL = QtGui.QComboBox(self.tabMaxAcceptableDifficulty)
|
||||||
self.checkBoxOpenCL.setObjectName = (_fromUtf8("checkBoxOpenCL"))
|
self.comboBoxOpenCL.setObjectName = (_fromUtf8("comboBoxOpenCL"))
|
||||||
self.gridLayout_7.addWidget(self.checkBoxOpenCL, 4, 1, 1, 1)
|
self.gridLayout_7.addWidget(self.comboBoxOpenCL, 4, 1, 1, 1)
|
||||||
self.tabWidgetSettings.addTab(self.tabMaxAcceptableDifficulty, _fromUtf8(""))
|
self.tabWidgetSettings.addTab(self.tabMaxAcceptableDifficulty, _fromUtf8(""))
|
||||||
self.tabNamecoin = QtGui.QWidget()
|
self.tabNamecoin = QtGui.QWidget()
|
||||||
self.tabNamecoin.setObjectName(_fromUtf8("tabNamecoin"))
|
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_13.setText(_translate("settingsDialog", "Maximum acceptable total difficulty:", None))
|
||||||
self.label_14.setText(_translate("settingsDialog", "Maximum acceptable small message 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.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_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_17.setText(_translate("settingsDialog", "Host:", None))
|
||||||
self.label_18.setText(_translate("settingsDialog", "Port:", None))
|
self.label_18.setText(_translate("settingsDialog", "Port:", None))
|
||||||
|
|
|
@ -9,7 +9,7 @@ from debug import logger
|
||||||
from foldertree import AccountMixin
|
from foldertree import AccountMixin
|
||||||
from helper_sql import *
|
from helper_sql import *
|
||||||
from l10n import getTranslationLanguage
|
from l10n import getTranslationLanguage
|
||||||
from openclpow import has_opencl
|
from openclpow import openclAvailable, openclEnabled
|
||||||
from proofofwork import bmpow
|
from proofofwork import bmpow
|
||||||
from pyelliptic.openssl import OpenSSL
|
from pyelliptic.openssl import OpenSSL
|
||||||
import shared
|
import shared
|
||||||
|
@ -107,7 +107,7 @@ def createSupportMessage(myapp):
|
||||||
portablemode = "True" if shared.appdata == shared.lookupExeFolder() else "False"
|
portablemode = "True" if shared.appdata == shared.lookupExeFolder() else "False"
|
||||||
cpow = "True" if bmpow else "False"
|
cpow = "True" if bmpow else "False"
|
||||||
#cpow = QtGui.QApplication.translate("Support", cpow)
|
#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)
|
#openclpow = QtGui.QApplication.translate("Support", openclpow)
|
||||||
locale = getTranslationLanguage()
|
locale = getTranslationLanguage()
|
||||||
try:
|
try:
|
||||||
|
|
109
src/openclpow.py
109
src/openclpow.py
|
@ -5,7 +5,7 @@ import hashlib
|
||||||
import random
|
import random
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from shared import codePath, safeConfigGetBoolean, shutdown
|
from shared import codePath, safeConfigGetBoolean, safeConfigGet, shutdown
|
||||||
from debug import logger
|
from debug import logger
|
||||||
|
|
||||||
libAvailable = True
|
libAvailable = True
|
||||||
|
@ -13,6 +13,8 @@ ctx = False
|
||||||
queue = False
|
queue = False
|
||||||
program = False
|
program = False
|
||||||
gpus = []
|
gpus = []
|
||||||
|
enabledGpus = []
|
||||||
|
vendors = []
|
||||||
hash_dt = None
|
hash_dt = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -22,13 +24,20 @@ except:
|
||||||
libAvailable = False
|
libAvailable = False
|
||||||
|
|
||||||
def initCL():
|
def initCL():
|
||||||
global ctx, queue, program, gpus, hash_dt
|
global ctx, queue, program, gpus, hash_dt, vendors
|
||||||
try:
|
try:
|
||||||
hash_dt = numpy.dtype([('target', numpy.uint64), ('v', numpy.str_, 73)])
|
hash_dt = numpy.dtype([('target', numpy.uint64), ('v', numpy.str_, 73)])
|
||||||
for platform in cl.get_platforms():
|
try:
|
||||||
gpus.extend(platform.get_devices(device_type=cl.device_type.GPU))
|
for platform in cl.get_platforms():
|
||||||
if (len(gpus) > 0):
|
gpus.extend(platform.get_devices(device_type=cl.device_type.GPU))
|
||||||
ctx = cl.Context(devices=gpus)
|
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)
|
queue = cl.CommandQueue(ctx)
|
||||||
f = open(os.path.join(codePath(), "bitmsghash", 'bitmsghash.cl'), 'r')
|
f = open(os.path.join(codePath(), "bitmsghash", 'bitmsghash.cl'), 'r')
|
||||||
fstr = ''.join(f.readlines())
|
fstr = ''.join(f.readlines())
|
||||||
|
@ -36,60 +45,64 @@ def initCL():
|
||||||
logger.info("Loaded OpenCL kernel")
|
logger.info("Loaded OpenCL kernel")
|
||||||
else:
|
else:
|
||||||
logger.info("No OpenCL GPUs found")
|
logger.info("No OpenCL GPUs found")
|
||||||
ctx = False
|
enabledGpus = []
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("OpenCL fail: ", exc_info=True)
|
logger.error("OpenCL fail: ", exc_info=True)
|
||||||
ctx = False
|
enabledGpus = []
|
||||||
|
|
||||||
def has_opencl():
|
def openclAvailable():
|
||||||
global ctx
|
global gpus
|
||||||
return (ctx != False)
|
return (len(gpus) > 0)
|
||||||
|
|
||||||
|
def openclEnabled():
|
||||||
|
global enabledGpus
|
||||||
|
return (len(enabledGpus) > 0)
|
||||||
|
|
||||||
def do_opencl_pow(hash, target):
|
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)])
|
output = numpy.zeros(1, dtype=[('v', numpy.uint64, 1)])
|
||||||
if (ctx == False):
|
if (len(enabledGpus) == 0):
|
||||||
return output[0][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
|
|
||||||
|
|
||||||
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.set_arg(0, hash_buf)
|
data = numpy.zeros(1, dtype=hash_dt, order='C')
|
||||||
kernel.set_arg(1, dest_buf)
|
data[0]['v'] = ("0000000000000000" + hash).decode("hex")
|
||||||
|
data[0]['target'] = target
|
||||||
|
|
||||||
start = time.time()
|
hash_buf = cl.Buffer(ctx, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=data)
|
||||||
progress = 0
|
dest_buf = cl.Buffer(ctx, cl.mem_flags.WRITE_ONLY, output.nbytes)
|
||||||
globamt = worksize*2000
|
|
||||||
|
|
||||||
while output[0][0] == 0 and shutdown == 0:
|
kernel = program.kernel_sha512
|
||||||
kernel.set_arg(2, pack("<Q", progress))
|
worksize = kernel.get_work_group_info(cl.kernel_work_group_info.WORK_GROUP_SIZE, enabledGpus[0])
|
||||||
cl.enqueue_nd_range_kernel(queue, kernel, (globamt,), (worksize,))
|
|
||||||
cl.enqueue_read_buffer(queue, dest_buf, output)
|
kernel.set_arg(0, hash_buf)
|
||||||
queue.finish()
|
kernel.set_arg(1, dest_buf)
|
||||||
progress += globamt
|
|
||||||
sofar = time.time() - start
|
start = time.time()
|
||||||
# logger.debug("Working for %.3fs, %.2f Mh/s", sofar, (progress / sofar) / 1000000)
|
progress = 0
|
||||||
if shutdown != 0:
|
globamt = worksize*2000
|
||||||
raise Exception ("Interrupted")
|
|
||||||
taken = time.time() - start
|
while output[0][0] == 0 and shutdown == 0:
|
||||||
# logger.debug("Took %d tries.", progress)
|
kernel.set_arg(2, pack("<Q", progress))
|
||||||
return output[0][0]
|
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:
|
if libAvailable:
|
||||||
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)
|
||||||
|
|
||||||
|
|
|
@ -108,10 +108,10 @@ def _doGPUPoW(target, initialHash):
|
||||||
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)
|
||||||
if 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.')))
|
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)
|
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.")
|
raise Exception("GPU did not calculate correctly.")
|
||||||
if shared.shutdown != 0:
|
if shared.shutdown != 0:
|
||||||
raise StopIteration("Interrupted")
|
raise StopIteration("Interrupted")
|
||||||
|
@ -144,7 +144,7 @@ def estimate(difficulty, format = False):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def getPowType():
|
def getPowType():
|
||||||
if shared.safeConfigGetBoolean('bitmessagesettings', 'opencl') and openclpow.has_opencl():
|
if openclpow.openclEnabled():
|
||||||
return "OpenCL"
|
return "OpenCL"
|
||||||
if bmpow:
|
if bmpow:
|
||||||
return "C"
|
return "C"
|
||||||
|
@ -154,7 +154,7 @@ def run(target, initialHash):
|
||||||
if shared.shutdown != 0:
|
if shared.shutdown != 0:
|
||||||
raise
|
raise
|
||||||
target = int(target)
|
target = int(target)
|
||||||
if shared.safeConfigGetBoolean('bitmessagesettings', 'opencl') and openclpow.has_opencl():
|
if openclpow.openclEnabled():
|
||||||
# trialvalue1, nonce1 = _doGPUPoW(target, initialHash)
|
# trialvalue1, nonce1 = _doGPUPoW(target, initialHash)
|
||||||
# trialvalue, nonce = _doFastPoW(target, initialHash)
|
# trialvalue, nonce = _doFastPoW(target, initialHash)
|
||||||
# print "GPU: %s, %s" % (trialvalue1, nonce1)
|
# print "GPU: %s, %s" % (trialvalue1, nonce1)
|
||||||
|
|
Reference in New Issue
Block a user