Browse files

fix threading issues with ADL

Fail gracefully if no actual ADL (reported problems with 7xxx);
Per device cutoff_temperature and interval;
Some fixes for BitcoinMiner when using HttpTransport
  • Loading branch information...
1 parent ff1c73c commit 3753e48b1a0da83a9e9d5915e0b80f10ae2bca48 @m0mchil committed Sep 28, 2012
Showing with 39 additions and 22 deletions.
  1. +24 −17 BitcoinMiner.py
  2. +15 −5 poclbm.py
View
41 BitcoinMiner.py
@@ -4,7 +4,7 @@
from log import *
from sha256 import *
from struct import pack
-from threading import Thread
+from threading import Thread, Lock
from time import sleep, time
from util import *
import pyopencl as cl
@@ -15,10 +15,11 @@
from adl3 import ADLPMActivity, ADL_Overdrive5_CurrentActivity_Get, \
ADLTemperature, ADL_Overdrive5_Temperature_Get, ADL_Adapter_NumberOfAdapters_Get, \
AdapterInfo, LPAdapterInfo, ADL_Adapter_AdapterInfo_Get, ADL_Adapter_ID_Get, \
- ADLError, ADL_OK
+ ADL_OK
from ctypes import sizeof, byref, c_int, cast
from collections import namedtuple
ADL_PRESENT = True
+ adl_lock = Lock()
except ImportError:
pass
@@ -42,11 +43,13 @@ def __init__(self, device_index, options):
self.worksize = self.frameSleep= self.rate = self.estimated_rate = 0
self.vectors = False
- if ADL_PRESENT:
- self.adapterIndex = self.get_adapter_info()[self.options.device].iAdapterIndex
+ self.adapterIndex = None
+ if ADL_PRESENT and self.device.type == cl.device_type.GPU:
+ with adl_lock:
+ self.adapterIndex = self.get_adapter_info()[self.device_index].iAdapterIndex
def id(self):
- return str(self.options.platform) + ':' + str(self.device_index) + ':' + self.device_name
+ return str(self.options.platform) + ':' + str(self.device_index) + ':' + self.device_name
def start(self):
self.should_stop = False
@@ -116,7 +119,7 @@ def mining_thread(self):
self.kernel.set_arg(18, f[3])
self.kernel.set_arg(19, f[4])
- if temperature < self.options.cutoff_temp:
+ if temperature < self.cutoff_temp:
self.kernel.set_arg(14, pack('I', base))
cl.enqueue_nd_range_kernel(queue, self.kernel, (global_threads,), (self.worksize,))
@@ -127,14 +130,15 @@ def mining_thread(self):
else:
threads_run_pace = 0
last_rated_pace = time()
- sleep(self.options.cutoff_interval)
+ sleep(self.cutoff_interval)
now = time()
- if ADL_PRESENT:
+ if self.adapterIndex:
t = now - last_temperature
- if temperature >= self.options.cutoff_temp or t > 1:
+ if temperature >= self.cutoff_temp or t > 1:
last_temperature = now
- temperature = self.get_temperature()
+ with adl_lock:
+ temperature = self.get_temperature()
t = now - last_rated_pace
if t > 1:
@@ -160,7 +164,7 @@ def mining_thread(self):
self.estimated_rate = Decimal(new_accept) * (work.targetQ) / min(int(now - start_time), self.options.estimate) / 1000
self.estimated_rate = Decimal(self.estimated_rate) / 1000
- self.servers.status_updated()
+ self.servers.status_updated(self)
last_rated = now; threads_run = 0
queue.finish()
@@ -185,11 +189,11 @@ def mining_thread(self):
cl.enqueue_write_buffer(queue, output_buffer, output)
if not self.servers.update_time:
- if nonces_left < 3 * global_threads * self.options.frames:
+ if nonces_left < 3 * global_threads * self.frames:
self.update = True
nonces_left += 0xFFFFFFFFFFFF
elif 0xFFFFFFFFFFF < nonces_left < 0xFFFFFFFFFFFF:
- say_line('warning: job finished, miner is idle')
+ say_line('warning: job finished, %s is idle', self.id())
work = None
elif now - last_n_time > 1:
work.time = bytereverse(bytereverse(work.time) + 1)
@@ -269,12 +273,14 @@ def get_adapter_info(self):
adapter_info = []
num_adapters = c_int(-1)
if ADL_Adapter_NumberOfAdapters_Get(byref(num_adapters)) != ADL_OK:
- raise ADLError("ADL_Adapter_NumberOfAdapters_Get failed.")
+ say_line("ADL_Adapter_NumberOfAdapters_Get failed, cutoff temperature disabled for %s", self.id())
+ return
- AdapterInfoArray = (AdapterInfo * num_adapters.value)()
+ AdapterInfoArray = (AdapterInfo * num_adapters.value)()
if ADL_Adapter_AdapterInfo_Get(cast(AdapterInfoArray, LPAdapterInfo), sizeof(AdapterInfoArray)) != ADL_OK:
- raise ADLError("ADL_Adapter_AdapterInfo_Get failed.")
+ say_line("ADL_Adapter_AdapterInfo_Get failed, cutoff temperature disabled for %s", self.id())
+ return
deviceAdapter = namedtuple('DeviceAdapter', ['AdapterIndex', 'AdapterID', 'BusNumber', 'UDID'])
devices = []
@@ -287,7 +293,8 @@ def get_adapter_info(self):
adapterID = c_int(-1)
if ADL_Adapter_ID_Get(index, byref(adapterID)) != ADL_OK:
- raise ADLError("ADL_Adapter_Active_Get failed.")
+ say_line("ADL_Adapter_Active_Get failed, cutoff temperature disabled for %s", self.id())
+ return
found = False
for device in devices:
View
20 poclbm.py
@@ -45,18 +45,24 @@ def socketwrap(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
group.add_option('-e', '--estimate', dest='estimate', default=900, help='estimated rate time window in seconds, default 900 (15 minutes)', type='int')
group.add_option('-t', '--tolerance', dest='tolerance', default=2, help='use fallback pool only after N consecutive connection errors, default 2', type='int')
group.add_option('-b', '--failback', dest='failback', default=60, help='attempt to fail back to the primary pool after N seconds, default 60', type='int')
-group.add_option('--cutoff_temp', dest='cutoff_temp',default=95, help='(requires github.com/mjmvisser/adl3) temperature at which to skip kernel execution, in C, default=95', type='float')
-group.add_option('--cutoff_interval', dest='cutoff_interval',default=0.01, help='(requires adl3) how long to not execute calculations if CUTOFF_TEMP is reached, in seconds, default=0.01', type='float')
group.add_option('--no-server-failbacks', dest='nsf', action='store_true', help='disable using failback hosts provided by server')
parser.add_option_group(group)
-group = OptionGroup(parser, "OpenCL Options", "Every option except 'platform' can be specified as a comma separated list.")
+group = OptionGroup(parser,
+ "GPU Options",
+ "Every option except 'platform' and 'vectors' can be specified as a comma separated list. "
+ "If there aren't enough entries specified, the last available is used. "
+ "Use --vv to specify per-device vectors usage."
+)
group.add_option('-p', '--platform', dest='platform', default=-1, help='use platform by id', type='int')
group.add_option('-d', '--device', dest='device', default=[], help='device ID, by default will use all GPU devices')
group.add_option('-w', '--worksize', dest='worksize', default=[], help='work group size, default is maximum returned by OpenCL')
group.add_option('-f', '--frames', dest='frames', default=[], help='will try to bring single kernel execution to 1/frames seconds, default=30, increase this for less desktop lag')
group.add_option('-s', '--sleep', dest='frameSleep', default=[], help='sleep per frame in seconds, default 0')
-group.add_option('-v', '--vectors', dest='vectors', default=[], help='use vectors, default false')
+group.add_option('--vv', dest='vectors', default=[], help='use vectors, default false')
+group.add_option('-v', '--vectors', dest='old_vectors',action='store_true', help='use vectors')
+group.add_option('--cutoff_temp', dest='cutoff_temp',default=[], help='(requires github.com/mjmvisser/adl3) temperature at which to skip kernel execution, in C, default=95')
+group.add_option('--cutoff_interval',dest='cutoff_interval',default=[], help='(requires adl3) how long to not execute calculations if CUTOFF_TEMP is reached, in seconds, default=0.01')
parser.add_option_group(group)
(options, options.servers) = parser.parse_args()
@@ -87,7 +93,9 @@ def socketwrap(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
options.worksize = tokenize(options.worksize, 'worksize')
options.frames = tokenize(options.frames, 'frames', [30])
options.frameSleep = tokenize(options.frameSleep, 'frameSleep', cast=float)
-options.vectors = tokenize(options.vectors, 'vectors', [False], bool)
+options.vectors = if_else(options.old_vectors, [True], tokenize(options.vectors, 'vectors', [False], bool))
+options.cutoff_temp = tokenize(options.cutoff_temp, 'cutoff_temp', [95], float)
+options.cutoff_interval = tokenize(options.cutoff_interval, 'cutoff_interval', [0.01], float)
if not options.device:
for i in xrange(len(devices)):
@@ -108,6 +116,8 @@ def socketwrap(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
miners[i].frames = options.frames[min(i, len(options.frames) - 1)]
miners[i].frameSleep = options.frameSleep[min(i, len(options.frameSleep) - 1)]
miners[i].vectors = options.vectors[min(i, len(options.vectors) - 1)]
+ miners[i].cutoff_temp = options.cutoff_temp[min(i, len(options.cutoff_temp) - 1)]
+ miners[i].cutoff_interval = options.cutoff_interval[min(i, len(options.cutoff_interval) - 1)]
servers = None
try:

0 comments on commit 3753e48

Please sign in to comment.