def start(self): i = 0 while True: if i % 10 == 0: self.devices = Nvidia().refresh(True) else: self.devices = Nvidia().refresh() for device_id in self.devices.keys(): device = self.devices[device_id] if "ignore_devices" in Config().keys() and Config().get( 'ignore_devices') and device['id'] in Config().get( 'ignore_devices'): continue self.speeds[device_id] = self.calculate_fan_speed(device) self.regulate_power_level(device) self.adjust_fan_speeds() if "automatically_reload_config_on_change" in Config().keys( ) and Config().get("automatically_reload_config_on_change"): if Config().reload_if_changed(): self.target_temperature = Config().get( 'target_temperature') self.fan_speed_temperature_ratio = Config().get( 'fan_speed_temperature_ratio') os.environ["DISPLAY"] = ":%d" % ( Config().get('xorg_display_no')) time.sleep(1) i += 1
def regulate_power_level(self, device, force=False): card_limit = Config().get("temperature_limit") if not card_limit: card_limit = 80 if os.path.exists("/var/run/minotaur/%d.powerlimit" % (device['id'])): desired_limit = float( open("/var/run/minotaur/%d.powerlimit" % (device['id'])).read()) else: desired_limit = device['default_power_limit_f'] temp = device['gpu_t_i'] limit = device['limit_f'] if temp >= card_limit: deduction = 10 * (2**(temp - card_limit)) new_limit = desired_limit - deduction if new_limit < device['min_power_limit_f']: new_limit = device['min_power_limit_f'] if new_limit != limit: Log().add( 'warning', 'device %d: temperature is at %dC, throttling power limit to %dW' % (device['id'], temp, new_limit)) Nvidia().set_power_limit(device['id'], new_limit) if not device['id'] in self.throttled: self.throttled.append(device['id']) else: if device['id'] in self.throttled and limit < desired_limit: Log().add( 'info', 'device %d: temperature is at %dC, restoring optimum power limit of %dW' % (device['id'], temp, desired_limit)) Nvidia().set_power_limit(device['id'], desired_limit) self.throttled.remove(device['id']) elif force: if int(device['limit_f']) != int(desired_limit): Log().add( 'info', 'device %d: setting power limit %dW' % (device['id'], desired_limit)) Nvidia().set_power_limit(device['id'], desired_limit)
def sigint_handler(self, a, b): Log().add( 'info', 'interrupt received, setting fans to 85% and cards to default power limit' ) Nvidia().set_all_fans(85) for device_id in self.devices.keys(): if self.devices[device_id]['default_power_limit_f']: Nvidia().set_power_limit( device_id, self.devices[device_id]['default_power_limit_f']) sys.exit(0)
def sighup_handler(self, x, y): Log().add('info', 'SIGHUP caught, reloading config and benchmark data') Config().reload() Calibration().load() Miners().reload_config() for device in Nvidia().get_nvidia_devices(): if not self.device_in_list(device): device.update() if device.state == 'active': device.log( 'info', 'currently running algorithm %s with %s [profile=%s] [region=%s]' % (device.algos[0]['algo'], device.algos[0]['miner'], device.profile, device.algos[0]['region'])) elif device.state == 'calibrating': device.log( 'info', 'calibration in progress with algorithm %s using %s [region=%s]' % (device.algos[0]['algo'], device.algos[0]['miner'], device.algos[0]['region'])) self.devices.append(device) for device in self.devices: if device.state == 'active': device.apply_profile() Log().add('info', 'reload complete')
def print_algorithms(self): algorithms = Config().get('algorithms.single') + Config().get( 'algorithms.double') Calibration().load() device_classes = Nvidia().get_nvidia_device_classes() for device_class in device_classes: data = {} for algorithm in algorithms: data[algorithm] = {} for miner_name in Config().get('miners'): miner = eval('%s()' % (miner_name.title())) if algorithm in miner.supported_algorithms(): data[algorithm][miner_name] = Calibration( ).get_miner_hashrate_for_algorithm_on_device( miner_name, algorithm, device_class) else: data[algorithm][miner_name] = "-" self.display_device_algorithm_table(device_class, data) print "\nnote: - means not supported\n"
def __init__(self): Config().load() if len(sys.argv) > 1 and sys.argv[1] == "--silent": Log().silent() Log().add('info', 'gpustatd %s starting up' % (Version().get())) if self.already_running(): Log().add('fatal', 'gpustatd is already running') self.create_pid_file() self.throttled = [] self.target_temperature = Config().get('target_temperature') self.fan_speed_temperature_ratio = Config().get( 'fan_speed_temperature_ratio') os.environ["DISPLAY"] = ":%d" % (Config().get('xorg_display_no')) Log().add('info', 'scanning devices') self.devices = Nvidia().refresh(True) self.speeds = {} for device_id in self.devices.keys(): self.speeds[device_id] = self.devices[device_id]['fan'] self.self_test()
def run(self): hwList = [] nv = Nvidia(self.distribution, self.log) ati = ATI(self.distribution, self.log) bc = Broadcom(self.distribution, self.log) pae = PAE(self.distribution, self.log) # Collect supported hardware hwNvidia = nv.getNvidia() hwATI = ati.getATI() hwBroadcom = bc.getBroadcom() hwPae = pae.getPae() # Combine all found hardware in a single list for line in hwNvidia: hwList.append(line) for line in hwATI: hwList.append(line) for line in hwBroadcom: hwList.append(line) for line in hwPae: hwList.append(line) return hwList
def installPAE(self): try: cmdPae = 'apt-get -y --force-yes install linux-headers-686-pae linux-image-686-pae' # Check if already installed status = functions.getPackageStatus('linux-headers-686-pae') if status == packageStatus[0]: cmdPae += ' --reinstall' self.log.write('PAE kernel install command: ' + cmdPae, 'pae.installPAE', 'debug') self.ec.run(cmdPae) # Check for Nvidia nv = Nvidia(self.distribution, self.log) nvList = nv.getNvidia() self.log.write('Nvidia info: ' + str(nvList), 'pae.installPAE', 'debug') for nvInfo in nvList: if nvInfo[2] == packageStatus[0]: self.log.write('Install Nvidia drivers', 'pae.installPAE', 'info') nv.installNvidia() # Remove xorg.conf #xorg = '/etc/X11/xorg.conf' #if os.path.exists(xorg): # shutil.move(xorg, xorg + '.ddm') # self.log.write('Moved ' + xorg + ' to ' + xorg + '.ddm', 'pae.installPAE', 'info') except Exception, detail: self.log.write(detail, 'pae.installPAE', 'error')
def cleanup(self, all=0, device_id=None): if all: Miners().cleanup_workers(True) elif not all and not device_id: Miners().cleanup_workers(False) else: device = Device({"id": device_id}) Nvidia().set_default_profile(device) Miners().stop_device(device) sys.exit(0)
def pin(self, device_id, pool_name, pin_miner_name, algorithm, region): device_ids = [] if device_id == 'all': for device in Nvidia().get_nvidia_devices(): device_ids.append(device.id) else: for device_id in device_id.split(","): device_ids.append(int(device_id)) if len(device_ids) == 0: Log().add('fatal', 'no devices selected') for device_id in device_ids: device = Device({"id": int(device_id)}) if pool_name not in Config().get('pools').keys(): Log().add('fatal', 'unknown pool') if not algorithm in Config().get( 'algorithms.single') and not algorithm in Config().get( 'algorithms.double'): Log().add('fatal', 'unknown algorithm') if pool_name != 'nicehash': region = None else: if region not in ['eu', 'usa', 'hk', 'jp', 'in', 'br']: Log().add('fatal', 'valid region is required for nicehash') Miners().poll() Miners().get_device_state(device) if device.state == "calibrating": Log().add( 'fatal', 'not pinning device %d - currently calibrating' % (device.id)) pin = { "pool_name": pool_name, "miner_name": pin_miner_name, "algorithm": algorithm, "region": region } with open("/var/run/minotaur/pin%d" % (device.id), "w") as f: f.write(yaml.dump(pin)) Log().add( 'info', 'pinned device %d to miner: %s pool %s algorithm: %s region: %s' % (device.id, pin_miner_name, pool_name, algorithm, region))
def do_self_test(self): for device_id in self.devices.keys(): device = self.devices[device_id] if not "ignore_devices" in Config().keys() or not Config().get( 'ignore_devices') or device['id'] not in Config().get( 'ignore_devices'): if not Nvidia().set_fan_control_state(device['id'], 1): Log().add( 'fatal', 'failed to toggle the fan control state for device: %d' % (device['id'])) self.fan_states[device['id']] = True self.regulate_power_level(device, True) return True
def adjust_fan_speeds(self): fan_speed_changes = {} for device_id in self.devices.keys(): if self.devices[device_id]['fan'] != self.speeds[device_id]: if Config().get('informative'): Log().add( 'debug', '%d: device temp: %s target temperature: %s target fan speed: %d' % (device_id, self.devices[device_id]['gpu_t_i'], self.target_temperature, self.speeds[device_id])) fan_speed_changes[device_id] = self.speeds[device_id] if len(fan_speed_changes) > 0: Nvidia().apply_fan_speed_changes(fan_speed_changes)
def run(self): # Instantiate driver classes nv = Nvidia(self.distribution, self.log) ati = ATI(self.distribution, self.log) bc = Broadcom(self.distribution, self.log) pae = PAE(self.distribution, self.log) for code in self.hwCodesWithStatusList: if code[0] == hwCodes[0]: if code[1] == packageStatus[0]: nv.removeNvidia() elif code[0] == hwCodes[1]: if code[1] == packageStatus[0]: ati.removeATI() elif code[0] == hwCodes[2]: if code[1] == packageStatus[0]: bc.removeBroadcom() elif code[0] == hwCodes[3]: if code[1] == packageStatus[0]: pae.removePAE()
def unpin(self, device_id): device_ids = [] if device_id == 'all': for device in Nvidia().get_nvidia_devices(): device_ids.append(device.id) else: for device_id in device_id.split(","): device_ids.append(int(device_id)) if len(device_ids) == 0: Log().add('fatal', 'no devices selected') for device_id in device_ids: device_id = int(device_id) if os.path.exists("/var/run/minotaur/pin%d" % (device_id)): os.remove("/var/run/minotaur/pin%d" % (device_id)) Log().add('info', 'unpinned device %d' % (device_id)) else: Log().add('info', 'device %d is not pinned' % (device_id))
def pin_calibration(self, device_id): pin = {"calibration": True} device_ids = [] if device_id == 'all': for device in Nvidia().get_nvidia_devices(): device_ids.append(device.id) else: for device_id in device_id.split(","): device_ids.append(int(device_id)) if len(device_ids) == 0: Log().add('fatal', 'no devices selected') for device_id in device_ids: device = Device({"id": int(device_id)}) with open("/var/run/minotaur/pin%d" % (device.id), "w") as f: f.write(yaml.dump(pin)) Log().add('info', 'pinned device %d to calibration' % (device.id))
def scan_devices(self): self.devices = Nvidia().get_nvidia_devices() Calibration().load() if len(self.devices) < 1: Log().add('fatal', "no nvidia GPUs found") Log().add("info", "found %d nvidia GPUs" % (len(self.devices))) Calibration().check_calibrated_algorithms(self.devices) Log().add('info', 'retrieving state from miner backends') Miners().poll() for device in self.devices: device.update() if device.state == 'active': device.log( 'info', 'currently running algorithm %s with %s [profile=%s] [region=%s]' % (device.algos[0]['algo'], device.algos[0]['miner'], device.profile, device.algos[0]['region'])) device.apply_profile() elif device.state == 'calibrating': device.log( 'info', 'calibration in progress with algorithm %s using %s [region=%s]' % (device.algos[0]['algo'], device.algos[0]['miner'], device.algos[0]['region'])) device.period_start = self.startup_time device.grubtime = device.period_start + ( 60 * random.randrange(15, 1424))
def get_max_hashrate_and_power_draw(self, miner, device, time_limit): max_power_draw = 0 timeout = 30 count = 0 while len(device.algos) == 0: time.sleep(1) Miners.poll() count += 1 if count >= 30: device.log('fatal', 'timed out waiting for worker to start') algorithm = device.algos[0]['algo'] if "_" in algorithm: readings_a = [] readings_b = [] else: readings = [] time_start = time.time() count = 0 err = 0 reading_count = 0 stable = False variance_pc = None while stable == False and (time.time() - time_start) <= time_limit: time.sleep(1) if count % 5 == 0: Miners().poll() if not Miners().is_up(miner.name): device.log('fatal', 'miner API went away, aborting') Miners().get_device_state(device) if len(device.algos) == 0: device.log('fatal', 'worker was stopped by an external process') rate_a, rate_b = device.algos[0]['hashrate'] if "_" in algorithm: r_len = len(readings_a) else: r_len = len(readings) if r_len > 0: if "_" in algorithm: variance_pc, n = Calibration().get_variance( readings_a + [rate_a], readings_b + [rate_b]) else: variance_pc, n = Calibration().get_variance(readings + [rate_a]) device.log( 'info', 'hashrate: %s (variance %.2f%%)' % (device.hashrate_str(), variance_pc)) else: device.log('info', 'hashrate: %s' % (device.hashrate_str())) if rate_a == 0: if reading_count >= 3: device.log('warning', 'hashrate dropped to 0!') if device.state != 'calibrating': device.log( 'fatal', 'our worker was stopped by an external process, aborting.' ) err += 1 if err >= 10: device.stop() device.log( 'fatal', 'failed to get a hashrate reading from the worker' ) else: if "_" in algorithm: readings_a.append(rate_a) readings_b.append(rate_b) else: readings.append(rate_a) if variance_pc != None and Calibration().is_stable( variance_pc, n): device.log('info', 'hashrate stabilised') stable = True reading_count += 1 count += 1 metrics = Nvidia().get_nvidia_metrics_for_device(device.id) if metrics['power_f']: max_power_draw = metrics['power_f'] else: max_power_draw = None if stable == False: device.stop(True) device.log( 'error', 'hashrate failed to stabilise after %d minutes\ntry increasing the timeout or loosen the stabilisation tolerance by increasing the "hashrate_stabilisation_tolerance" parameter' % (time_limit / 60)) return [None, None] if "_" in algorithm: hashrate = [ Calibration().get_nominal_hashrate_from_range(readings_a), Calibration().get_nominal_hashrate_from_range(readings_b) ] else: hashrate = Calibration().get_nominal_hashrate_from_range(readings) return [hashrate, max_power_draw]
def ensure_control_state(self, device_id, state): if self.fan_states[device_id] != state: Nvidia().set_fan_control_state(device_id, state) self.fan_states[device_id] = state
def print_devices(self): for device in Nvidia().get_nvidia_devices(1): print "%d: %s [class: %s]" % (device.id, device.name, device.dclass) sys.exit()
def calibrate(self, device_params, pool, miner_name, algorithm, region, quick, overwrite, force): devices = Nvidia().get_nvidia_devices(1) if pool == 'nicehash' and region not in [ 'eu', 'usa', 'hk', 'jp', 'in', 'br' ]: Log().add('fatal', 'a valid region is required for nicehash') devices_to_calibrate = [] device_classes = [] for device_param in device_params.split(','): if device_param.isdigit(): if int(device_param) >= len(devices): Log().add('fatal', 'device %d not found' % (int(device_param))) else: devices_to_calibrate.append(devices[int(device_param)]) else: found = False for device in devices: if device.name == device_param: devices_to_calibrate.append(device) found = True elif (device_param == 'all' or device.dclass == device_param ) and device.dclass not in device_classes: devices_to_calibrate.append(device) device_classes.append(device.dclass) found = True if not found: Log().add('fatal', 'device %s not found' % (device_param)) log_dir = Config().get('logging.calibration_log_dir') if not log_dir: log_dir = "/var/log/minotaur" if miner_name == "all": miners = [] for miner_name in Config().get('miners').keys(): if Config().get('miners')[miner_name]['enable']: miners.append(eval("%s()" % (miner_name.title()))) else: if not miner_name in Config().get('miners').keys(): Log().add('fatal', 'miner %s is not configured' % (miner_name)) miners = [eval("%s()" % (miner_name.title()))] if len(miners) == 0: Log().add('fatal', "no miners available") if pool == 'all': pools = [] for pool_name in Config().get('pools').keys(): if Config().get('pools.%s.enable' % (pool_name)): pools.append(pool_name) elif pool not in Config().get('pools').keys(): Log().add('fatal', 'unknown pool: %s' % (pool)) else: pools = [pool] algorithms = {} for pool_name in pools: algorithms[pool_name] = {} for miner in miners: if not pool_name in Pools().pools.keys(): Log().add('fatal', 'pool %s is not enabled' % (pool_name)) pool = Pools().pools[pool_name] if miner.name not in pool.supported_miners: continue if algorithm == "all": algorithms[pool_name][ miner.name] = miner.supported_algorithms() else: algorithms[pool_name][miner.name] = [] for algo_param in algorithm.split(","): if algo_param == 'all': algorithms[pool_name][ miner.name] = miner.supported_algorithms() else: if algo_param[0] == '!': exclude_algo = algo_param[1:] if miner.name in algorithms.keys( ) and exclude_algo in algorithms[miner.name]: algorithms[pool_name][miner.name].remove( exclude_algo) else: if algo_param in miner.supported_algorithms(): algorithms[pool_name][miner.name].append( algo_param) print "" self.calibration_banner() print "" n = 0 for device in devices_to_calibrate: log_file = "%s/calibration_%d.log" % (log_dir, device.id) Log().set_log_file(log_file) for pool_name in algorithms.keys(): for miner in miners: if miner.name in algorithms[pool_name].keys(): for algorithm in algorithms[pool_name][miner.name]: n += 1 if algorithm in Config( ).get('algorithms.single') or algorithm in Config( ).get('algorithms.double'): Calibration().load() if not overwrite and Calibration().get( '%s.%s.%s' % (device.dclass, miner.name, algorithm)): device.log( 'info', 'not overwriting existing calibration data for miner %s algorithm %s (use --overwrite to override)' % (miner.name, algorithm)) else: Calibrate().start(device, pool_name, miner, algorithm, region, quick, force) else: Log().add( 'warning', 'algorithm %s is not in the config file - skipping' % (algorithm)) Log().add('info', 'nothing to do.')
def run(self): self.create_pid_file() self.initialise() signal.signal(signal.SIGINT, self.sigint_handler) signal.signal(signal.SIGTERM, self.sigint_handler) signal.signal(signal.SIGHUP, self.sighup_handler) power_draw_readings = self.load_power_draw_readings() profitability_readings = self.load_profitability_readings() main_loop_index = 0 self.miner_state = {} self.pool_refresh = None while True: if main_loop_index == 0: if self.pool_refresh == None or ( time.time() - self.pool_refresh ) >= Config().get('pool_refresh_interval'): Pools().refresh() self.pool_refresh = time.time() show_mbtc_total = False Miners().poll() for i in range(0, len(self.devices)): device = self.devices[i] device.update() device.log_stats() if not device.can_run(): continue #device.grubtime = self.startup_time += (60 * random.randrange(15, 1424)) # if device.grub == False and time.time() >= device.grubtime and time.time() <= (device.grubtime + (60 * 15)): # device.log('info', 'starting 15min donation period to the author') # device.grub = True # # Miners().schedule('restart', device) # elif device.grub == True and time.time() < device.grubtime or time.time() > (device.grubtime + (60 * 15)): # device.log('info', 'stopping donation period') # device.grub = False # device.period_start += 86400 # device.grubtime = device.period_start + (60 * random.randrange(15, 1424)) # # while not self.grubtime_is_unique(device.grubtime, i): # device.grubtime = device.period_start + (60 * random.randrange(15, 1424)) # # Miners().schedule('restart', device) # else: if True: if not device.running(): if Config().get('debug'): device.log( 'debug', 'device not running - starting worker') Miners().schedule('start', device) else: switched = False if not device.pin: if Pools().should_switch(device): Miners().schedule('restart', device) switched = True if not switched and Config( ).get('calibration.update_calibration_data_over_time' ): Calibration().handle_device_update(device) queued_device_ids = Miners().queue.keys() Miners().execute_queue() for device in self.devices: if device.state == 'active' and device.id not in queued_device_ids and not device.warming_up( ): show_mbtc_total = True device.log( 'info', '%s/%s[%s]: %s' % (device.algos[0]['pool'], device.algos[0]['algo'], device.algos[0]['miner'], device.hashrate_str())) device.check_hashrate() total_power, total_power_limit, total_mbtc_per_day = Nvidia( ).get_device_metrics(self.devices) if show_mbtc_total: Log().add( 'info', 'total profitability: %.2f mBTC/day' % (total_mbtc_per_day)) power_draw_readings = self.update_power_draw_readings( power_draw_readings, total_power + Config().get('system_draw_watts')) profitability_readings = self.update_profitability_readings( profitability_readings, total_mbtc_per_day) # load in calibration data from other devices that may be calibrating Calibration().load() Miners().wait_for_queue() time.sleep(1) main_loop_index += 1 if main_loop_index >= Config().get('refresh_interval'): main_loop_index = 0
def start(self, device, pool_name, miner, algorithm, region, quick=False, force=False): self.miner = miner self.device = device self.default_profile = Config().get('device_profiles.default') Miners().reload_config() device.pin = { 'pool_name': pool_name, 'miner_name': miner.name, 'algorithm': algorithm, 'region': region } if not Config().get('calibration'): Log().add('fatal', "calibration config missing from config file") for key in [ "hashrate_stabilisation_timeout_mins", "hashrate_stabilisation_tolerance", "hashrate_stabilisation_consecutive_readings_required", "algorithm_start_timeout" ]: if Config().get('calibration.%s' % (key)) == None: Log().add('fatal', "missing config option: calibration.%s" % (key)) if Config().get('calibration.power_tuning.enable'): for key in ["decrement_watts", "acceptable_loss_percent"]: if not Config().get('calibration.power_tuning.%s' % (key)): Log().add( 'fatal', "missing config option: calibration.power_tuning.%s" % (key)) Config().set('pools.%s.append_device_id_to_worker_name' % (pool_name), False) if pool_name == 'miningpoolhub': if Config().get('pools.miningpoolhub.hub_workers.%s' % (algorithm))[-5:] != 'CALIB': Config().set( 'pools.miningpoolhub.hub_workers.%s' % (algorithm), Config().get('pools.miningpoolhub.hub_workers.%s' % (algorithm)) + 'CALIB') else: if Config().get('pools.%s.worker_name' % (pool_name))[-5:] != 'CALIB': Config().set( 'pools.%s.worker_name' % (pool_name), Config().get('pools.%s.worker_name' % (pool_name)) + "CALIB") if quick: Config().set('calibration.power_tuning.enable', False) profile = Profiles().get_for_device_algo(device, algorithm) Log().add('info', ' device id: %d' % (device.id)) Log().add('info', ' pool: %s' % (pool_name)) Log().add('info', ' device class: %s' % (device.dclass)) Log().add('info', 'device profile: %s' % (profile.name)) Log().add('info', ' miner: %s' % (miner.name)) Log().add('info', ' algorithm: %s' % (algorithm)) Log().add('info', ' region: %s' % (region)) Miners().poll() Miners().get_device_state(device) if device.state != 'inactive': if device.state == 'calibrating': device.log( 'fatal', 'this device is already being used for calibration') if force: device.log('info', 'terminating existing worker') if not device.stop(True): device.log('fatal', 'failed to stop existing worker') else: device.log( 'fatal', 'unable to start calibration - device is in use (use --force to override)' ) self.set_pin(device.id) default_power_limit = device.default_power_limit_f min_power_limit = device.min_power_limit_f max_power_limit = device.max_power_limit_f if max_power_limit == 0: device.log('info', 'device does not support power monitoring') else: device.log('info', 'max power limit: %d W' % (max_power_limit)) device.log( 'info', 'stabilisation tolerance: %.2f%%' % (Config().get('calibration.hashrate_stabilisation_tolerance'))) if Config().get('debug'): device.log('debug', 'loading default profile') Nvidia().set_default_profile(device) if Config().get('debug'): device.log('debug', 'initialising pools') Pools() sample_timeout = Config().get( 'calibration.hashrate_stabilisation_timeout_mins') if default_power_limit != None and Config().get( 'calibration.power_tuning.enable'): device.log( 'info', 'starting initial run at max power limit [timeout=%dmins]' % (sample_timeout)) else: device.log( 'info', 'starting single run [timeout=%dmins]' % (sample_timeout)) Miners().poll() Miners().get_device_state(device) if device.state != 'calibrating': if not device.start(True): device.log('fatal', 'worker failed to start') if Config().get('calibration.power_tuning.enable'): if not device.power_supported(): device.log('info', 'device does not support power monitoring') else: device.set_power_limit(max_power_limit) initial_hashrate, initial_max_power_draw = self.get_max_hashrate_and_power_draw( miner, device, sample_timeout * 60) if initial_hashrate == None: device.log( 'info', 'skipping algorithm as we failed to get a stable reading') print "" return if initial_max_power_draw != None and initial_max_power_draw > max_power_limit: initial_max_power_draw = max_power_limit device.log( 'info', 'benchmark hashrate: %s' % (Units().hashrate_str(initial_hashrate))) if initial_max_power_draw != None: device.log('info', 'max power draw: %.2f' % (initial_max_power_draw)) initial_power_limit = int(math.ceil(initial_max_power_draw)) hashrate = initial_hashrate if initial_max_power_draw == None: power_limit = None elif Config().get('calibration.power_tuning.enable'): if max_power_limit == 0 or min_power_limit == 0 or default_power_limit == 0: device.log( 'error', 'device did not give us sane values for its min/max/default power limits' ) device.log( 'error', 'unable to proceed with power calibration - device may not support changing the power limit' ) power_limit = default_power_limit else: power_limit = initial_power_limit device.log('info', 'tuning power limit for optimum efficiency') hashrate, power_limit = self.do_power_calibration( device, power_limit, miner, hashrate, min_power_limit) else: power_limit = default_power_limit Nvidia().set_default_profile(device) self.unset_pin(device.id) device.log('info', 'storing calibration data') Calibration().update_calibration_data(device.dclass, miner.name, algorithm, hashrate, power_limit) if not device.stop(True): device.log('fatal', "failed to stop the miner process") print "" device.log( 'info', ' calibrated hashrate: %s' % (Units().hashrate_str(hashrate))) if power_limit != None: device.log('info', 'calibrated power limit: %.2f W' % (power_limit)) print ""