Added POW settings to settings window
This commit is contained in:
parent
2c7d677ccf
commit
373157db45
|
@ -55,6 +55,7 @@ import sound
|
|||
import re
|
||||
import bitmessage_icons_rc # Loads icon resources
|
||||
import workprover.utils
|
||||
import singleworker
|
||||
|
||||
|
||||
try:
|
||||
|
@ -2616,9 +2617,34 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
BMConfigParser().set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str(int(float(
|
||||
self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text()) * defaults.networkDefaultPayloadLengthExtraBytes)))
|
||||
|
||||
if self.settingsDialogInstance.ui.comboBoxOpenCL.currentText().toUtf8() != BMConfigParser().safeGet("bitmessagesettings", "opencl"):
|
||||
BMConfigParser().set('bitmessagesettings', 'opencl', str(self.settingsDialogInstance.ui.comboBoxOpenCL.currentText()))
|
||||
queues.workerQueue.put(('resetPoW', ''))
|
||||
if self.settingsDialogInstance.ui.radioButtonDumbSolver.isChecked():
|
||||
BMConfigParser().set("bitmessagesettings", "powsolver", "dumb")
|
||||
elif self.settingsDialogInstance.ui.radioButtonForkingSolver.isChecked():
|
||||
BMConfigParser().set("bitmessagesettings", "powsolver", "forking")
|
||||
|
||||
BMConfigParser().set(
|
||||
"bitmessagesettings",
|
||||
"processes",
|
||||
str(self.settingsDialogInstance.ui.spinBoxForkingSolverParallelism.value())
|
||||
)
|
||||
elif self.settingsDialogInstance.ui.radioButtonFastSolver.isChecked():
|
||||
BMConfigParser().set("bitmessagesettings", "powsolver", "fast")
|
||||
|
||||
BMConfigParser().set(
|
||||
"bitmessagesettings",
|
||||
"threads",
|
||||
str(self.settingsDialogInstance.ui.spinBoxFastSolverParallelism.value())
|
||||
)
|
||||
elif self.settingsDialogInstance.ui.radioButtonGPUSolver.isChecked():
|
||||
BMConfigParser().set("bitmessagesettings", "powsolver", "gpu")
|
||||
|
||||
BMConfigParser().set(
|
||||
"bitmessagesettings",
|
||||
"opencl",
|
||||
str(self.settingsDialogInstance.ui.comboBoxGPUVendor.currentText().toUtf8())
|
||||
)
|
||||
|
||||
singleworker.setBestSolver()
|
||||
|
||||
acceptableDifficultyChanged = False
|
||||
|
||||
|
@ -4547,18 +4573,43 @@ class settingsDialog(QtGui.QDialog):
|
|||
self.ui.lineEditMaxAcceptableSmallMessageDifficulty.setText(str((float(BMConfigParser().getint(
|
||||
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')) / defaults.networkDefaultPayloadLengthExtraBytes)))
|
||||
|
||||
# OpenCL
|
||||
if openclpow.openclAvailable():
|
||||
self.ui.comboBoxOpenCL.setEnabled(True)
|
||||
else:
|
||||
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) == BMConfigParser().safeGet('bitmessagesettings', 'opencl'):
|
||||
self.ui.comboBoxOpenCL.setCurrentIndex(i)
|
||||
if "forking" not in singleworker.workProver.availableSolvers:
|
||||
self.ui.radioButtonForkingSolver.setEnabled(False)
|
||||
if "fast" not in singleworker.workProver.availableSolvers:
|
||||
self.ui.radioButtonFastSolver.setEnabled(False)
|
||||
if "gpu" not in singleworker.workProver.availableSolvers:
|
||||
self.ui.radioButtonGPUSolver.setEnabled(False)
|
||||
|
||||
solverName = BMConfigParser().safeGet("bitmessagesettings", "powsolver", "gpu")
|
||||
forkingSolverParallelism = BMConfigParser().safeGetInt("bitmessagesettings", "processes")
|
||||
fastSolverParallelism = BMConfigParser().safeGetInt("bitmessagesettings", "threads")
|
||||
GPUVendor = BMConfigParser().safeGet("bitmessagesettings", "opencl")
|
||||
|
||||
if solverName == "dumb":
|
||||
self.ui.radioButtonDumbSolver.setChecked(True)
|
||||
elif solverName == "forking":
|
||||
self.ui.radioButtonForkingSolver.setChecked(True)
|
||||
elif solverName == "fast":
|
||||
self.ui.radioButtonFastSolver.setChecked(True)
|
||||
elif solverName == "gpu":
|
||||
self.ui.radioButtonGPUSolver.setChecked(True)
|
||||
|
||||
self.ui.spinBoxForkingSolverParallelism.setValue(forkingSolverParallelism)
|
||||
self.ui.spinBoxFastSolverParallelism.setValue(fastSolverParallelism)
|
||||
|
||||
vendors = set(singleworker.workProver.availableSolvers["gpu"].vendors)
|
||||
|
||||
if GPUVendor is not None:
|
||||
vendors.add(GPUVendor)
|
||||
|
||||
self.ui.comboBoxGPUVendor.clear()
|
||||
self.ui.comboBoxGPUVendor.addItems(list(vendors))
|
||||
self.ui.comboBoxGPUVendor.setCurrentIndex(0)
|
||||
|
||||
for i in range(self.ui.comboBoxGPUVendor.count()):
|
||||
if self.ui.comboBoxGPUVendor.itemText(i) == GPUVendor:
|
||||
self.ui.comboBoxGPUVendor.setCurrentIndex(i)
|
||||
|
||||
break
|
||||
|
||||
# Namecoin integration tab
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>555</width>
|
||||
<width>616</width>
|
||||
<height>592</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -14,16 +14,6 @@
|
|||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidgetSettings">
|
||||
<property name="currentIndex">
|
||||
|
@ -549,13 +539,13 @@
|
|||
<string>Max acceptable difficulty</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable.</string>
|
||||
<string>Maximum acceptable small message difficulty:</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -585,6 +575,32 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="lineEditMaxAcceptableSmallMessageDifficulty">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="lineEditMaxAcceptableTotalDifficulty">
|
||||
<property name="sizePolicy">
|
||||
|
@ -614,33 +630,142 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Maximum acceptable small message difficulty:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QGroupBox" name="groupBoxSolvers">
|
||||
<property name="title">
|
||||
<string>Proof of work solver</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelSolvers">
|
||||
<property name="text">
|
||||
<string>There are several worker modules to solve POW:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutForkingSolver">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonForkingSolver">
|
||||
<property name="text">
|
||||
<string>Forking solver using multiple processes:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBoxForkingSolverParallelism">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>4096</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacerForkingSolver">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutFastSolver">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonFastSolver">
|
||||
<property name="text">
|
||||
<string>Fast solver in C with multiple threads:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBoxFastSolverParallelism">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>4096</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacerFastSolver">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutDumbSolver">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonDumbSolver">
|
||||
<property name="text">
|
||||
<string>Dumb solver</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacerDumbSolver">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutGPUSolver">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonGPUSolver">
|
||||
<property name="text">
|
||||
<string>GPU solver:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBoxGPUVendor"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacerGPUSolver">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="lineEditMaxAcceptableSmallMessageDifficulty">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="5" column="0" colspan="3">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
@ -653,16 +778,6 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelOpenCL">
|
||||
<property name="text">
|
||||
<string>Hardware GPU acceleration (OpenCL):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="comboBoxOpenCL"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabNamecoin">
|
||||
|
@ -981,6 +1096,16 @@
|
|||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
|
@ -998,6 +1123,7 @@
|
|||
<tabstop>checkBoxSocksListen</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
|
|
|
@ -221,6 +221,66 @@ def disseminateObject(nonce, expiryTime, headlessPayload, objectType, stream, ta
|
|||
|
||||
return inventoryHash, payload
|
||||
|
||||
workProver = workprover.WorkProver(
|
||||
os.path.join(paths.codePath(), "workprover"),
|
||||
helper_random.randomBytes(32),
|
||||
lambda status: queues.UISignalQueue.put(("updateWorkProverStatus", status)),
|
||||
queues.workerQueue
|
||||
)
|
||||
|
||||
debug.logger.info("Availabe solvers: %s", str(workProver.availableSolvers.keys()))
|
||||
|
||||
if "fast" not in workProver.availableSolvers:
|
||||
queues.UISignalQueue.put(("updateStatusBar", (
|
||||
tr._translate(
|
||||
"proofofwork",
|
||||
"C PoW module unavailable. Please build it."
|
||||
), 1
|
||||
)))
|
||||
|
||||
def setBestSolver():
|
||||
solverName = bmconfigparser.BMConfigParser().safeGet("bitmessagesettings", "powsolver", "gpu")
|
||||
forkingSolverParallelism = bmconfigparser.BMConfigParser().safeGetInt("bitmessagesettings", "processes")
|
||||
fastSolverParallelism = bmconfigparser.BMConfigParser().safeGetInt("bitmessagesettings", "threads")
|
||||
GPUVendor = bmconfigparser.BMConfigParser().safeGet("bitmessagesettings", "opencl")
|
||||
|
||||
if forkingSolverParallelism < 1:
|
||||
forkingSolverParallelism = workProver.defaultParallelism
|
||||
|
||||
if fastSolverParallelism < 1:
|
||||
fastSolverParallelism = workProver.defaultParallelism
|
||||
|
||||
maxcores = bmconfigparser.BMConfigParser().safeGetInt("bitmessagesettings", "maxcores", None)
|
||||
|
||||
if maxcores is not None:
|
||||
forkingSolverParallelism = min(maxcores, forkingSolverParallelism)
|
||||
fastSolverParallelism = min(maxcores, fastSolverParallelism)
|
||||
|
||||
if solverName == "gpu" and GPUVendor is None:
|
||||
solverName = "fast"
|
||||
|
||||
while solverName not in workProver.availableSolvers:
|
||||
if solverName == "gpu":
|
||||
solverName = "fast"
|
||||
elif solverName == "fast":
|
||||
solverName = "forking"
|
||||
elif solverName == "forking":
|
||||
solverName = "dumb"
|
||||
|
||||
bmconfigparser.BMConfigParser().set("bitmessagesettings", "powsolver", solverName)
|
||||
bmconfigparser.BMConfigParser().set("bitmessagesettings", "processes", str(forkingSolverParallelism))
|
||||
bmconfigparser.BMConfigParser().set("bitmessagesettings", "threads", str(fastSolverParallelism))
|
||||
bmconfigparser.BMConfigParser().save()
|
||||
|
||||
if solverName in ["dumb", "gpu"]:
|
||||
workProver.commandsQueue.put(("setSolver", solverName, None))
|
||||
elif solverName == "forking":
|
||||
workProver.commandsQueue.put(("setSolver", "forking", forkingSolverParallelism))
|
||||
elif solverName == "fast":
|
||||
workProver.commandsQueue.put(("setSolver", "fast", fastSolverParallelism))
|
||||
|
||||
setBestSolver()
|
||||
|
||||
class singleWorker(threading.Thread, helper_threading.StoppableThread):
|
||||
name = "singleWorker"
|
||||
|
||||
|
@ -235,41 +295,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread):
|
|||
super(self.__class__, self).stopThread()
|
||||
|
||||
def run(self):
|
||||
GPUVendor = bmconfigparser.BMConfigParser().safeGet("bitmessagesettings", "opencl")
|
||||
|
||||
self.workProver = workprover.WorkProver(
|
||||
os.path.join(paths.codePath(), "workprover"),
|
||||
GPUVendor,
|
||||
helper_random.randomBytes(32),
|
||||
lambda status: queues.UISignalQueue.put(("updateWorkProverStatus", status)),
|
||||
queues.workerQueue
|
||||
)
|
||||
|
||||
self.workProver.start()
|
||||
|
||||
parallelism = bmconfigparser.BMConfigParser().safeGetInt("bitmessagesettings", "maxcores")
|
||||
|
||||
if parallelism < 1:
|
||||
parallelism = self.workProver.defaultParallelism
|
||||
|
||||
debug.logger.info("Availabe solvers: %s", str(self.workProver.availableSolvers.keys()))
|
||||
|
||||
if "gpu" in self.workProver.availableSolvers and GPUVendor is not None:
|
||||
self.workProver.commandsQueue.put(("setSolver", "gpu", None))
|
||||
elif "fast" in self.workProver.availableSolvers:
|
||||
self.workProver.commandsQueue.put(("setSolver", "fast", parallelism))
|
||||
elif "forking" in self.workProver.availableSolvers:
|
||||
self.workProver.commandsQueue.put(("setSolver", "forking", parallelism))
|
||||
else:
|
||||
self.workProver.commandsQueue.put(("setSolver", "dumb", None))
|
||||
|
||||
if "fast" not in self.workProver.availableSolvers:
|
||||
queues.UISignalQueue.put(("updateStatusBar", (
|
||||
tr._translate(
|
||||
"proofofwork",
|
||||
"C PoW module unavailable. Please build it."
|
||||
), 1
|
||||
)))
|
||||
workProver.start()
|
||||
|
||||
self.startedWorks = {}
|
||||
|
||||
|
@ -299,16 +325,34 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread):
|
|||
self.requestPubkey(*arguments)
|
||||
elif command == "resetPoW":
|
||||
pass
|
||||
elif command == "GPUError":
|
||||
self.handleGPUError(*arguments)
|
||||
elif command == "taskDone":
|
||||
self.workDone(*arguments)
|
||||
elif command == "stopThread":
|
||||
self.workProver.commandsQueue.put(("shutdown", ))
|
||||
self.workProver.join()
|
||||
workProver.commandsQueue.put(("shutdown", ))
|
||||
workProver.join()
|
||||
|
||||
break
|
||||
|
||||
debug.logger.info("Quitting...")
|
||||
|
||||
def handleGPUError(self):
|
||||
bmconfigparser.BMConfigParser().set("bitmessagesettings", "powsolver", "dumb")
|
||||
|
||||
workProver.commandsQueue.put(("setSolver", "dumb", None))
|
||||
|
||||
debug.logger.error(
|
||||
"Your GPU(s) did not calculate correctly, disabling OpenCL. Please report to the developers"
|
||||
)
|
||||
|
||||
queues.UISignalQueue.put(("updateStatusBar", (
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
"Your GPU(s) did not calculate correctly, disabling OpenCL. Please report to the developers."
|
||||
), 1
|
||||
)))
|
||||
|
||||
def startWork(self, ID, headlessPayload, TTL, expiryTime, byteDifficulty, lengthExtension, logPrefix, callback):
|
||||
debug.logger.info(
|
||||
"%s Starting work %s, payload length = %s, TTL = %s",
|
||||
|
@ -317,7 +361,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread):
|
|||
|
||||
self.startedWorks[ID] = callback
|
||||
|
||||
self.workProver.commandsQueue.put((
|
||||
workProver.commandsQueue.put((
|
||||
"addTask", ID, headlessPayload, TTL, expiryTime,
|
||||
byteDifficulty, lengthExtension
|
||||
))
|
||||
|
@ -588,7 +632,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread):
|
|||
if ID in self.startedWorks:
|
||||
del self.startedWorks[ID]
|
||||
|
||||
self.workProver.commandsQueue.put(("cancelTask", ID))
|
||||
workProver.commandsQueue.put(("cancelTask", ID))
|
||||
|
||||
helper_sql.sqlExecute("""
|
||||
UPDATE "sent" SET "status" = 'broadcastcanceled'
|
||||
|
@ -906,14 +950,14 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread):
|
|||
if ID in self.startedWorks:
|
||||
del self.startedWorks[ID]
|
||||
|
||||
self.workProver.commandsQueue.put(("cancelTask", ID))
|
||||
workProver.commandsQueue.put(("cancelTask", ID))
|
||||
|
||||
ID = "message", ackData
|
||||
|
||||
if ID in self.startedWorks:
|
||||
del self.startedWorks[ID]
|
||||
|
||||
self.workProver.commandsQueue.put(("cancelTask", ID))
|
||||
workProver.commandsQueue.put(("cancelTask", ID))
|
||||
|
||||
state.watchedAckData -= {ackData}
|
||||
|
||||
|
@ -933,7 +977,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread):
|
|||
if ID in self.startedWorks:
|
||||
del self.startedWorks[ID]
|
||||
|
||||
self.workProver.commandsQueue.put(("cancelTask", ID))
|
||||
workProver.commandsQueue.put(("cancelTask", ID))
|
||||
|
||||
status, version, stream, ripe = addresses.decodeAddress(destination)
|
||||
|
||||
|
|
|
@ -30,10 +30,12 @@ class Task(object):
|
|||
|
||||
Status = collections.namedtuple("Status", ["solverName", "solverStatus", "speed", "tasksCount", "difficulty"])
|
||||
|
||||
# Only one instance allowed
|
||||
|
||||
class WorkProver(threading.Thread):
|
||||
# Seed must be 32 bytes
|
||||
|
||||
def __init__(self, codePath, GPUVendor, seed, statusUpdated, resultsQueue):
|
||||
def __init__(self, codePath, seed, statusUpdated, resultsQueue):
|
||||
super(self.__class__, self).__init__()
|
||||
|
||||
self.availableSolvers = {
|
||||
|
@ -56,7 +58,7 @@ class WorkProver(threading.Thread):
|
|||
pass
|
||||
|
||||
try:
|
||||
self.availableSolvers["gpu"] = gpusolver.GPUSolver(codePath, GPUVendor)
|
||||
self.availableSolvers["gpu"] = gpusolver.GPUSolver(codePath)
|
||||
except gpusolver.GPUSolverError:
|
||||
pass
|
||||
|
||||
|
@ -99,23 +101,29 @@ class WorkProver(threading.Thread):
|
|||
self.statusUpdated(Status(self.solverName, status, self.speed, len(self.tasks), self.totalDifficulty))
|
||||
|
||||
def setSolver(self, name, configuration):
|
||||
if name is None and self.solverName is None:
|
||||
pass
|
||||
elif name == self.solverName:
|
||||
self.solver.setConfiguration(configuration)
|
||||
else:
|
||||
if self.solver is not None:
|
||||
self.solver.setConfiguration(None)
|
||||
self.solverName = None
|
||||
self.solver = None
|
||||
|
||||
if name is not None:
|
||||
if name not in self.availableSolvers:
|
||||
name, configuration = "dumb", None
|
||||
|
||||
self.solverName = name
|
||||
self.solver = self.availableSolvers[name]
|
||||
try:
|
||||
if name is None and self.solverName is None:
|
||||
pass
|
||||
elif name == self.solverName:
|
||||
self.solver.setConfiguration(configuration)
|
||||
else:
|
||||
if self.solver is not None:
|
||||
self.solver.setConfiguration(None)
|
||||
self.solverName = None
|
||||
self.solver = None
|
||||
|
||||
if name is not None:
|
||||
if name not in self.availableSolvers:
|
||||
name, configuration = "dumb", None
|
||||
|
||||
self.solverName = name
|
||||
self.solver = self.availableSolvers[name]
|
||||
self.solver.setConfiguration(configuration)
|
||||
except GPUSolverError:
|
||||
self.solverName = None
|
||||
self.solver = None
|
||||
|
||||
self.resultsQueue.put(("GPUError", ))
|
||||
|
||||
self.notifyStatus()
|
||||
|
||||
|
@ -229,8 +237,9 @@ class WorkProver(threading.Thread):
|
|||
try:
|
||||
nonce, iterationsCount = self.solver.search(initialHash, task.target, appendedSeed, timeout)
|
||||
except gpusolver.GPUSolverError:
|
||||
self.setSolver("dumb", 1)
|
||||
self.availableSolvers.pop("gpu")
|
||||
self.setSolver(None, None)
|
||||
|
||||
self.resultsQueue.put(("GPUError", ))
|
||||
|
||||
nonce, iterationsCount = None, 0
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ def loadFastSolver(codePath):
|
|||
except:
|
||||
raise FastSolverError()
|
||||
|
||||
# Only one instance allowed
|
||||
|
||||
class FastSolver(object):
|
||||
def __init__(self, codePath):
|
||||
self.libfastsolver = loadFastSolver(codePath)
|
||||
|
|
|
@ -11,7 +11,7 @@ class GPUSolverError(Exception):
|
|||
pass
|
||||
|
||||
class GPUSolver(object):
|
||||
def __init__(self, codePath, vendor = None):
|
||||
def __init__(self, codePath):
|
||||
global pyopencl
|
||||
|
||||
try:
|
||||
|
@ -19,17 +19,15 @@ class GPUSolver(object):
|
|||
except ImportError:
|
||||
raise GPUSolverError()
|
||||
|
||||
for i in pyopencl.get_platforms():
|
||||
if vendor is not None and i.vendor != vendor:
|
||||
continue
|
||||
self.vendors = {}
|
||||
|
||||
for i in pyopencl.get_platforms():
|
||||
devices = i.get_devices(device_type = pyopencl.device_type.GPU)
|
||||
|
||||
if len(devices) != 0:
|
||||
self.device = devices[0]
|
||||
self.vendors[i.vendor] = devices[0]
|
||||
|
||||
break
|
||||
else:
|
||||
if len(self.vendors) == 0:
|
||||
raise GPUSolverError()
|
||||
|
||||
with open(os.path.join(codePath, "gpusolver.cl")) as file:
|
||||
|
@ -88,14 +86,21 @@ class GPUSolver(object):
|
|||
|
||||
import numpy
|
||||
|
||||
context = pyopencl.Context(devices = [self.device])
|
||||
if configuration is None:
|
||||
configuration = self.vendors.keys()[0]
|
||||
|
||||
computeUnitsCount = self.device.get_info(pyopencl.device_info.MAX_COMPUTE_UNITS)
|
||||
workGroupSize = self.device.get_info(pyopencl.device_info.MAX_WORK_GROUP_SIZE)
|
||||
if configuration not in self.vendors:
|
||||
raise GPUSolverError()
|
||||
|
||||
device = self.vendors[configuration]
|
||||
context = pyopencl.Context(devices = [device])
|
||||
|
||||
computeUnitsCount = device.get_info(pyopencl.device_info.MAX_COMPUTE_UNITS)
|
||||
workGroupSize = device.get_info(pyopencl.device_info.MAX_WORK_GROUP_SIZE)
|
||||
|
||||
self.batchSize = workGroupSize * computeUnitsCount * 256
|
||||
|
||||
self.queue = pyopencl.CommandQueue(context, self.device)
|
||||
self.queue = pyopencl.CommandQueue(context, device)
|
||||
|
||||
program = pyopencl.Program(context, self.source).build()
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ class TestGPUSolver(TestSolver):
|
|||
|
||||
class TestWorkProver(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.thread = __init__.WorkProver(codePath, None, seed, None, None)
|
||||
self.thread = __init__.WorkProver(codePath, seed, None, None)
|
||||
self.thread.start()
|
||||
|
||||
def checkTaskLinks(self):
|
||||
|
|
Reference in New Issue
Block a user