def decode(self, server, block_header, target, job_id = None, extranonce2 = None): if block_header: job = Object() binary_data = block_header.decode('hex') #data0 = list(unpack('<16I', binary_data[:64])) + ([0] * 48) job.headerX = binary_data[:76] job.dataX = unpack('<19I', job.headerX) job.target = unpack('<8I', target.decode('hex')) job.header = binary_data[:68] job.merkle_end = uint32(unpack('<I', binary_data[64:68])[0]) job.time = uint32(unpack('<I', binary_data[68:72])[0]) job.difficulty = uint32(unpack('<I', binary_data[72:76])[0]) # job.state = sha256(STATE, data0) job.targetQ = 2**256 / int(''.join(list(chunks(target, 2))[::-1]), 16) job.job_id = job_id job.extranonce2 = extranonce2 job.server = server if job.difficulty != self.difficulty: self.set_difficulty(job.difficulty) return job
def mining_thread(self): say_line('started OpenCL miner on platform %d, device %d (%s)', (self.options.platform, self.device_index, self.device_name)) (self.defines, rate_divisor, hashspace) = ('', 1000, 0xFFFFFFFF) self.defines += (' -D%sOUTPUT_SIZE=%s' % (self.defspace, str(self.output_size))) self.defines += (' -D%sOUTPUT_MASK=%s' % (self.defspace, str(self.output_size - 1))) self.defines += (' -D%sENDIAN_LITTLE=%d' % (self.defspace, self.device.endian_little)) self.defines += (' -D%sGPU_AMD=%d' % (self.defspace, self.gpu_amd)) self.defines += (' -I%s%s' % (self.defspace, os.getcwd())) say_line("Compiler defines: %s", self.defines) self.load_kernel() frame = 1.0 / max(self.frames, 3) unit = self.worksize * 256 global_threads = unit * 10 queue = cl.CommandQueue(self.context) last_rated_pace = last_rated = last_n_time = last_temperature = time() base = last_hash_rate = threads_run_pace = threads_run = 0 output = bytearray((self.output_size + 1) * 4) output_buffer = cl.Buffer(self.context, cl.mem_flags.WRITE_ONLY | cl.mem_flags.USE_HOST_PTR, hostbuf=output) self.kernel.set_arg(12, output_buffer) work = None temperature = 0 while True: if self.should_stop: return sleep(self.frameSleep) if (not work) or (not self.work_queue.empty()): try: work = self.work_queue.get(True, 1) except Empty: continue else: if not work: continue nonces_left = hashspace self.queue_kernel_parameters(work) if temperature < self.cutoff_temp: self.kernel.set_arg(11, pack('<I', base)) cl.enqueue_nd_range_kernel(queue, self.kernel, (global_threads,), (self.worksize,)) nonces_left -= global_threads threads_run_pace += global_threads threads_run += global_threads base = uint32(base + global_threads) else: threads_run_pace = 0 last_rated_pace = time() sleep(self.cutoff_interval) now = time() if self.adapterIndex is not None: t = now - last_temperature if temperature >= self.cutoff_temp or t > 1: last_temperature = now with adl_lock: self.temperature = self.get_temperature() temperature = self.temperature t = now - last_rated_pace if t > 1: rate = (threads_run_pace / t) / rate_divisor last_rated_pace = now; threads_run_pace = 0 r = last_hash_rate / rate if r < 0.9 or r > 1.1: global_threads = max(unit * int((rate * frame * rate_divisor) / unit), unit) last_hash_rate = rate t = now - last_rated if t > self.options.rate: self.update_rate(now, threads_run, t, work.targetQ, rate_divisor) last_rated = now; threads_run = 0 queue.finish() cl.enqueue_read_buffer(queue, output_buffer, output) queue.finish() if output[-1]: result = Object() result.header = work.header result.headerX = work.headerX result.merkle_end = work.merkle_end result.time = work.time result.difficulty = work.difficulty result.target = work.target result.dataX = work.dataX[:] result.nonces = output[:] result.job_id = work.job_id result.extranonce2 = work.extranonce2 result.server = work.server result.miner = self self.switch.put(result) output[:] = b'\x00' * len(output) cl.enqueue_write_buffer(queue, output_buffer, output) for miner in self.switch.miners: miner.update = True if not self.switch.update_time: if nonces_left < 6 * global_threads * self.frames: self.update = True nonces_left += 0xFFFFFFFFFFFF elif 0xFFFFFFFFFFF < nonces_left < 0xFFFFFFFFFFFF: say_line('warning: job finished, %s is idle', self.id()) work = None elif now - last_n_time > 1: last_n_time = now self.update_time_counter += 1 if self.update_time_counter >= self.switch.max_update_time: self.update = True self.update_time_counter = 1