Skip to content
This repository
Browse code

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...
commit 3753e48b1a0da83a9e9d5915e0b80f10ae2bca48 1 parent ff1c73c
m0mchil authored

Showing 2 changed files with 39 additions and 22 deletions. Show diff stats Hide diff stats

  1. +24 17 BitcoinMiner.py
  2. +15 5 poclbm.py
41 BitcoinMiner.py
@@ -4,7 +4,7 @@
4 4 from log import *
5 5 from sha256 import *
6 6 from struct import pack
7   -from threading import Thread
  7 +from threading import Thread, Lock
8 8 from time import sleep, time
9 9 from util import *
10 10 import pyopencl as cl
@@ -15,10 +15,11 @@
15 15 from adl3 import ADLPMActivity, ADL_Overdrive5_CurrentActivity_Get, \
16 16 ADLTemperature, ADL_Overdrive5_Temperature_Get, ADL_Adapter_NumberOfAdapters_Get, \
17 17 AdapterInfo, LPAdapterInfo, ADL_Adapter_AdapterInfo_Get, ADL_Adapter_ID_Get, \
18   - ADLError, ADL_OK
  18 + ADL_OK
19 19 from ctypes import sizeof, byref, c_int, cast
20 20 from collections import namedtuple
21 21 ADL_PRESENT = True
  22 + adl_lock = Lock()
22 23 except ImportError:
23 24 pass
24 25
@@ -42,11 +43,13 @@ def __init__(self, device_index, options):
42 43 self.worksize = self.frameSleep= self.rate = self.estimated_rate = 0
43 44 self.vectors = False
44 45
45   - if ADL_PRESENT:
46   - self.adapterIndex = self.get_adapter_info()[self.options.device].iAdapterIndex
  46 + self.adapterIndex = None
  47 + if ADL_PRESENT and self.device.type == cl.device_type.GPU:
  48 + with adl_lock:
  49 + self.adapterIndex = self.get_adapter_info()[self.device_index].iAdapterIndex
47 50
48 51 def id(self):
49   - return str(self.options.platform) + ':' + str(self.device_index) + ':' + self.device_name
  52 + return str(self.options.platform) + ':' + str(self.device_index) + ':' + self.device_name
50 53
51 54 def start(self):
52 55 self.should_stop = False
@@ -116,7 +119,7 @@ def mining_thread(self):
116 119 self.kernel.set_arg(18, f[3])
117 120 self.kernel.set_arg(19, f[4])
118 121
119   - if temperature < self.options.cutoff_temp:
  122 + if temperature < self.cutoff_temp:
120 123 self.kernel.set_arg(14, pack('I', base))
121 124 cl.enqueue_nd_range_kernel(queue, self.kernel, (global_threads,), (self.worksize,))
122 125
@@ -127,14 +130,15 @@ def mining_thread(self):
127 130 else:
128 131 threads_run_pace = 0
129 132 last_rated_pace = time()
130   - sleep(self.options.cutoff_interval)
  133 + sleep(self.cutoff_interval)
131 134
132 135 now = time()
133   - if ADL_PRESENT:
  136 + if self.adapterIndex:
134 137 t = now - last_temperature
135   - if temperature >= self.options.cutoff_temp or t > 1:
  138 + if temperature >= self.cutoff_temp or t > 1:
136 139 last_temperature = now
137   - temperature = self.get_temperature()
  140 + with adl_lock:
  141 + temperature = self.get_temperature()
138 142
139 143 t = now - last_rated_pace
140 144 if t > 1:
@@ -160,7 +164,7 @@ def mining_thread(self):
160 164 self.estimated_rate = Decimal(new_accept) * (work.targetQ) / min(int(now - start_time), self.options.estimate) / 1000
161 165 self.estimated_rate = Decimal(self.estimated_rate) / 1000
162 166
163   - self.servers.status_updated()
  167 + self.servers.status_updated(self)
164 168 last_rated = now; threads_run = 0
165 169
166 170 queue.finish()
@@ -185,11 +189,11 @@ def mining_thread(self):
185 189 cl.enqueue_write_buffer(queue, output_buffer, output)
186 190
187 191 if not self.servers.update_time:
188   - if nonces_left < 3 * global_threads * self.options.frames:
  192 + if nonces_left < 3 * global_threads * self.frames:
189 193 self.update = True
190 194 nonces_left += 0xFFFFFFFFFFFF
191 195 elif 0xFFFFFFFFFFF < nonces_left < 0xFFFFFFFFFFFF:
192   - say_line('warning: job finished, miner is idle')
  196 + say_line('warning: job finished, %s is idle', self.id())
193 197 work = None
194 198 elif now - last_n_time > 1:
195 199 work.time = bytereverse(bytereverse(work.time) + 1)
@@ -269,12 +273,14 @@ def get_adapter_info(self):
269 273 adapter_info = []
270 274 num_adapters = c_int(-1)
271 275 if ADL_Adapter_NumberOfAdapters_Get(byref(num_adapters)) != ADL_OK:
272   - raise ADLError("ADL_Adapter_NumberOfAdapters_Get failed.")
  276 + say_line("ADL_Adapter_NumberOfAdapters_Get failed, cutoff temperature disabled for %s", self.id())
  277 + return
273 278
274   - AdapterInfoArray = (AdapterInfo * num_adapters.value)()
  279 + AdapterInfoArray = (AdapterInfo * num_adapters.value)()
275 280
276 281 if ADL_Adapter_AdapterInfo_Get(cast(AdapterInfoArray, LPAdapterInfo), sizeof(AdapterInfoArray)) != ADL_OK:
277   - raise ADLError("ADL_Adapter_AdapterInfo_Get failed.")
  282 + say_line("ADL_Adapter_AdapterInfo_Get failed, cutoff temperature disabled for %s", self.id())
  283 + return
278 284
279 285 deviceAdapter = namedtuple('DeviceAdapter', ['AdapterIndex', 'AdapterID', 'BusNumber', 'UDID'])
280 286 devices = []
@@ -287,7 +293,8 @@ def get_adapter_info(self):
287 293 adapterID = c_int(-1)
288 294
289 295 if ADL_Adapter_ID_Get(index, byref(adapterID)) != ADL_OK:
290   - raise ADLError("ADL_Adapter_Active_Get failed.")
  296 + say_line("ADL_Adapter_Active_Get failed, cutoff temperature disabled for %s", self.id())
  297 + return
291 298
292 299 found = False
293 300 for device in devices:
20 poclbm.py
@@ -45,18 +45,24 @@ def socketwrap(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
45 45 group.add_option('-e', '--estimate', dest='estimate', default=900, help='estimated rate time window in seconds, default 900 (15 minutes)', type='int')
46 46 group.add_option('-t', '--tolerance', dest='tolerance', default=2, help='use fallback pool only after N consecutive connection errors, default 2', type='int')
47 47 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')
48   -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')
49   -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')
50 48 group.add_option('--no-server-failbacks', dest='nsf', action='store_true', help='disable using failback hosts provided by server')
51 49 parser.add_option_group(group)
52 50
53   -group = OptionGroup(parser, "OpenCL Options", "Every option except 'platform' can be specified as a comma separated list.")
  51 +group = OptionGroup(parser,
  52 + "GPU Options",
  53 + "Every option except 'platform' and 'vectors' can be specified as a comma separated list. "
  54 + "If there aren't enough entries specified, the last available is used. "
  55 + "Use --vv to specify per-device vectors usage."
  56 +)
54 57 group.add_option('-p', '--platform', dest='platform', default=-1, help='use platform by id', type='int')
55 58 group.add_option('-d', '--device', dest='device', default=[], help='device ID, by default will use all GPU devices')
56 59 group.add_option('-w', '--worksize', dest='worksize', default=[], help='work group size, default is maximum returned by OpenCL')
57 60 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')
58 61 group.add_option('-s', '--sleep', dest='frameSleep', default=[], help='sleep per frame in seconds, default 0')
59   -group.add_option('-v', '--vectors', dest='vectors', default=[], help='use vectors, default false')
  62 +group.add_option('--vv', dest='vectors', default=[], help='use vectors, default false')
  63 +group.add_option('-v', '--vectors', dest='old_vectors',action='store_true', help='use vectors')
  64 +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')
  65 +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')
60 66 parser.add_option_group(group)
61 67
62 68 (options, options.servers) = parser.parse_args()
@@ -87,7 +93,9 @@ def socketwrap(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
87 93 options.worksize = tokenize(options.worksize, 'worksize')
88 94 options.frames = tokenize(options.frames, 'frames', [30])
89 95 options.frameSleep = tokenize(options.frameSleep, 'frameSleep', cast=float)
90   -options.vectors = tokenize(options.vectors, 'vectors', [False], bool)
  96 +options.vectors = if_else(options.old_vectors, [True], tokenize(options.vectors, 'vectors', [False], bool))
  97 +options.cutoff_temp = tokenize(options.cutoff_temp, 'cutoff_temp', [95], float)
  98 +options.cutoff_interval = tokenize(options.cutoff_interval, 'cutoff_interval', [0.01], float)
91 99
92 100 if not options.device:
93 101 for i in xrange(len(devices)):
@@ -108,6 +116,8 @@ def socketwrap(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
108 116 miners[i].frames = options.frames[min(i, len(options.frames) - 1)]
109 117 miners[i].frameSleep = options.frameSleep[min(i, len(options.frameSleep) - 1)]
110 118 miners[i].vectors = options.vectors[min(i, len(options.vectors) - 1)]
  119 + miners[i].cutoff_temp = options.cutoff_temp[min(i, len(options.cutoff_temp) - 1)]
  120 + miners[i].cutoff_interval = options.cutoff_interval[min(i, len(options.cutoff_interval) - 1)]
111 121
112 122 servers = None
113 123 try:

0 comments on commit 3753e48

Please sign in to comment.
Something went wrong with that request. Please try again.