public virtual void InitMiningPairs(IEnumerable <MiningPair> miningPairs) { // now should be ordered _miningPairs = GetSortedMiningPairs(miningPairs); // update log group try { var devs = _miningPairs.Select(pair => $"{pair.Device.DeviceType}:{pair.Device.ID}"); var devsTag = $"devs({string.Join(",", devs)})"; var algo = _miningPairs.First().Algorithm.AlgorithmName; var algoTag = $"algo({algo})"; _logGroup = $"{_baseTag}-{algoTag}-{devsTag}"; } catch (Exception e) { Logger.Error(_logGroup, $"Error while setting _logGroup: {e.Message}"); } // init algo, ELP and finally miner specific init // init algo var singleType = MinerToolkit.GetAlgorithmSingleType(_miningPairs); _algorithmType = singleType.Item1; bool ok = singleType.Item2; if (!ok) { Logger.Info(_logGroup, "Initialization of miner failed. Algorithm not found!"); throw new InvalidOperationException("Invalid mining initialization"); } // init ELP, _miningPairs are ordered and ELP parsing keeps ordering if (MinerOptionsPackage != null) { var miningPairsList = _miningPairs.ToList(); var ignoreDefaults = MinerOptionsPackage.IgnoreDefaultValueOptions; var generalParams = ExtraLaunchParametersParser.Parse(miningPairsList, MinerOptionsPackage.GeneralOptions, ignoreDefaults); var temperatureParams = ExtraLaunchParametersParser.Parse(miningPairsList, MinerOptionsPackage.TemperatureOptions, ignoreDefaults); _extraLaunchParameters = $"{generalParams} {temperatureParams}".Trim(); } // miner specific init Init(); }
/// <summary> /// Provides available port for miner API binding /// </summary> public virtual int GetAvaliablePort() { Dictionary <string, List <int> > reservedPorts = null; if (MinerReservedApiPorts != null && MinerReservedApiPorts.UseUserSettings) { reservedPorts = MinerReservedApiPorts.AlgorithmReservedPorts; } var(reservedPortsKey, ok) = MinerToolkit.GetAlgorithmSettingsKey(_miningPairs); if (ok && reservedPorts != null && reservedPorts.ContainsKey(reservedPortsKey) && reservedPorts[reservedPortsKey] != null) { var reservedPortsRange = reservedPorts[reservedPortsKey]; var port = FreePortsCheckerManager.GetAvaliablePortInRange(reservedPortsRange); // retrive custom user port if (port > -1) { return(port); } } // if no custom port return a port in the default range return(FreePortsCheckerManager.GetAvaliablePortFromSettings()); // use the default range }
public BenchmarkProcess(string binPath, string workingDir, string commandLine, Dictionary <string, string> environmentVariables = null) { Handle = MinerToolkit.CreateBenchmarkProcess(binPath, workingDir, commandLine, environmentVariables); }
public virtual async Task <BenchmarkResult> StartBenchmark(CancellationToken stop, BenchmarkPerformanceType benchmarkType = BenchmarkPerformanceType.Standard) { using (var tickCancelSource = new CancellationTokenSource()) { // determine benchmark time // settup times var benchmarkTime = MinerBenchmarkTimeSettings.ParseBenchmarkTime(new List <int> { 40, 60, 140 }, MinerBenchmarkTimeSettings, _miningPairs, benchmarkType); // in seconds var maxTicks = MinerBenchmarkTimeSettings.ParseBenchmarkTicks(new List <int> { 1, 3, 9 }, MinerBenchmarkTimeSettings, _miningPairs, benchmarkType); var maxTicksEnabled = MinerBenchmarkTimeSettings.MaxTicksEnabled; //// use demo user and disable the watchdog var commandLine = MiningCreateCommandLine(); var(binPath, binCwd) = GetBinAndCwdPaths(); Logger.Info(_logGroup, $"Benchmarking started with command: {commandLine}"); Logger.Info(_logGroup, $"Benchmarking settings: time={benchmarkTime} ticks={maxTicks} ticksEnabled={maxTicksEnabled}"); var bp = new BenchmarkProcess(binPath, binCwd, commandLine, GetEnvironmentVariables()); // disable line readings and read speeds from API bp.CheckData = null; var benchmarkTimeout = TimeSpan.FromSeconds(benchmarkTime + 5); var benchmarkWait = TimeSpan.FromMilliseconds(500); var t = MinerToolkit.WaitBenchmarkResult(bp, benchmarkTimeout, benchmarkWait, stop, tickCancelSource.Token); var stoppedAfterTicks = false; var validTicks = 0; var ticks = benchmarkTime / 10; // on each 10 seconds tick var result = new BenchmarkResult(); var benchmarkApiData = new List <ApiData>(); for (var tick = 0; tick < ticks; tick++) { if (t.IsCompleted || t.IsCanceled || stop.IsCancellationRequested) { break; } await Task.Delay(10 * 1000, stop); // 10 seconds delay if (t.IsCompleted || t.IsCanceled || stop.IsCancellationRequested) { break; } var ad = await GetMinerStatsDataAsync(); var adTotal = ad.AlgorithmSpeedsTotal(); var isTickValid = adTotal.Count > 0 && adTotal.All(pair => pair.speed > 0); benchmarkApiData.Add(ad); if (isTickValid) { ++validTicks; } if (maxTicksEnabled && validTicks >= maxTicks) { stoppedAfterTicks = true; break; } } // await benchmark task if (stoppedAfterTicks) { try { tickCancelSource.Cancel(); } catch {} } await t; if (stop.IsCancellationRequested) { return(t.Result); } // calc speeds // TODO calc std deviaton to reduce invalid benches try { var nonZeroSpeeds = benchmarkApiData.Where(ad => ad.AlgorithmSpeedsTotal().Count > 0 && ad.AlgorithmSpeedsTotal().All(pair => pair.speed > 0)) .Select(ad => (ad, ad.AlgorithmSpeedsTotal().Count)).ToList(); var speedsFromTotals = new List <(AlgorithmType type, double speed)>(); if (nonZeroSpeeds.Count > 0) { var maxAlgoPiarsCount = nonZeroSpeeds.Select(adCount => adCount.Count).Max(); var sameCountApiDatas = nonZeroSpeeds.Where(adCount => adCount.Count == maxAlgoPiarsCount).Select(adCount => adCount.ad).ToList(); var firstPair = sameCountApiDatas.FirstOrDefault(); var speedSums = firstPair.AlgorithmSpeedsTotal().Select(pair => new KeyValuePair <AlgorithmType, double>(pair.type, 0.0)).ToDictionary(x => x.Key, x => x.Value); // sum foreach (var ad in sameCountApiDatas) { foreach (var pair in ad.AlgorithmSpeedsTotal()) { speedSums[pair.type] += pair.speed; } } // average foreach (var algoId in speedSums.Keys.ToArray()) { speedSums[algoId] /= sameCountApiDatas.Count; } result = new BenchmarkResult { AlgorithmTypeSpeeds = firstPair.AlgorithmSpeedsTotal().Select(pair => (pair.type, speedSums[pair.type])).ToList(), Success = true }; } } catch (Exception e) { Logger.Warn(_logGroup, $"benchmarking AlgorithmSpeedsTotal error {e.Message}"); } // return API result return(result); } }
public virtual Task <object> StartMiningTask(CancellationToken stop) { //const int ERROR_FILE_NOT_FOUND = 0x2; //const int ERROR_ACCESS_DENIED = 0x5; // tsc for started process var startProcessTaskCompletionSource = new TaskCompletionSource <object>(); var binPathBinCwdPair = GetBinAndCwdPaths(); var binPath = binPathBinCwdPair.Item1; var binCwd = binPathBinCwdPair.Item2; var commandLine = MiningCreateCommandLine(); var environmentVariables = GetEnvironmentVariables(); var stopActionExec = false; _miningProcessTask = Task.Run(() => { using (_stopMinerTaskSource = new CancellationTokenSource()) using (var stopMinerTask = CancellationTokenSource.CreateLinkedTokenSource(stop, _stopMinerTaskSource.Token)) using (var miningProcess = MinerToolkit.CreateMiningProcess(binPath, binCwd, commandLine, environmentVariables)) using (var quitMiningProcess = stopMinerTask.Token.Register(() => ExitMiningProcess(miningProcess))) { lock (_lock) { _miningProcess = miningProcess; } try { // BEFORE ThrowIfIsStop(stopMinerTask.IsCancellationRequested); if (this is IBeforeStartMining bsm) { bsm.BeforeStartMining(); } ThrowIfIsStop(stopMinerTask.IsCancellationRequested); // Logging Logger.Info(_logGroup, $"Starting miner binPath='{binPath}'"); Logger.Info(_logGroup, $"Starting miner binCwd='{binCwd}'"); Logger.Info(_logGroup, $"Starting miner commandLine='{commandLine}'"); var environmentVariablesLog = environmentVariables == null ? "<null>" : string.Join(";", environmentVariables.Select(x => x.Key + "=" + x.Value)); Logger.Info(_logGroup, $"Starting miner environmentVariables='{environmentVariablesLog}'"); ThrowIfIsStop(stopMinerTask.IsCancellationRequested); // exec START custom scripts if any, must be here if blocking ExecMinerCustomActionSettings(true); if (!miningProcess.Start()) { Logger.Info(_logGroup, $"Error occured while starting a new process: {miningProcess.ToString()}"); startProcessTaskCompletionSource.SetResult(new InvalidOperationException("Could not start process: " + miningProcess)); return; } startProcessTaskCompletionSource.SetResult(true); ThrowIfIsStop(stopMinerTask.IsCancellationRequested); if (this is IAfterStartMining asm) { asm.AfterStartMining(); } ThrowIfIsStop(stopMinerTask.IsCancellationRequested); // block while process is running miningProcess.WaitForExit(); // exec STOP custom scripts if any, must be here if blocking stopActionExec = true; ExecMinerCustomActionSettings(false); } //catch (Win32Exception ex2) //{ // ////if (ex2.NativeErrorCode == ERROR_FILE_NOT_FOUND) throw ex2; // //Logger.Info(_logGroup, $"Win32Exception Error occured in StartMining : {ex2.ToString()}"); // //Task.Delay(MinerToolkit.MinerRestartDelayMS, _stopMiner.Token).Wait(); //} catch (StopMinerWatchdogException) { Logger.Info(_logGroup, $"Watchdog stopped in StartMining"); startProcessTaskCompletionSource.SetResult(false); } catch (Exception e) { Logger.Error(_logGroup, $"Error occured in StartMining : {e.Message}"); startProcessTaskCompletionSource.SetResult(e); } finally { if (!stopActionExec) { // exec STOP custom scripts if any, last resort it will not block but it is a fallback option ExecMinerCustomActionSettings(false); } } } }); return(startProcessTaskCompletionSource.Task); }