private async Task MinerSpeedsLoop(CancellationTokenSource ct) { Logger.Info("EXCAVATOR-MinerSpeedsLoop", $"STARTING"); try { var workers = string.Join(",", _miningPairs.Select((_, i) => $@"""{i}""")); var workersReset = @"{""id"":1,""method"":""workers.reset"",""params"":[__WORKERS__]}".Replace("__WORKERS__", workers); Func <bool> isActive = () => !ct.Token.IsCancellationRequested; while (isActive()) { try { _ = await ApiDataHelpers.GetApiDataAsync(_apiPort, workersReset + "\r\n", _logGroup); if (isActive()) { await ExcavatorTaskHelpers.TryDelay(TimeSpan.FromSeconds(30), ct.Token); } // get speeds var ad = await GetMinerStatsDataAsyncPrivate(); lock (_lock2) { _lastApiData = ad; } // speed print and reset _ = await ApiDataHelpers.GetApiDataAsync(_apiPort, @"{""id"":1,""method"":""worker.print.efficiencies"",""params"":[]}" + "\r\n", _logGroup); } catch (TaskCanceledException e) { break; } catch (Exception e) { } } Logger.Info("EXCAVATOR-MinerSpeedsLoop", $"EXIT WHILE"); } catch (TaskCanceledException e) { } catch (Exception ex) { Logger.Error("EXCAVATOR-API_LOOP", $"error {ex}"); } finally { ct.Dispose(); } }
private async Task <string> ExecuteCommand(string command) { try { var response = await ApiDataHelpers.GetApiDataAsync(_apiPort, command + "\r\n", _logGroup); return(response); } catch (Exception e) { Logger.Error(_logGroup, $"Error occured with command '{command}' error: {e.Message}"); } return(null); }
public async override Task <ApiData> GetMinerStatsDataAsync() { var summaryApiResult = await ApiDataHelpers.GetApiDataAsync(_apiPort, ApiDataHelpers.GetHttpRequestNhmAgentString("summary"), _logGroup); double totalSpeed = 0; int totalPower = 0; var perDeviceSpeedInfo = new Dictionary <string, IReadOnlyList <AlgorithmTypeSpeedPair> >(); var perDevicePowerInfo = new Dictionary <string, int>(); if (!string.IsNullOrEmpty(summaryApiResult)) { // TODO return empty try { var summaryOptvals = summaryApiResult.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var optvalPairs in summaryOptvals) { var pair = optvalPairs.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (pair.Length != 2) { continue; } if (pair[0] == "KHS") { var currentSpeed = double.Parse(pair[1], CultureInfo.InvariantCulture) * 1000; // HPS totalSpeed += currentSpeed; perDeviceSpeedInfo.Add(_miningPairs.FirstOrDefault()?.Device.UUID, new List <AlgorithmTypeSpeedPair>() { new AlgorithmTypeSpeedPair(_algorithmType, currentSpeed * (1 - DevFee * 0.01)) }); } } } catch (Exception e) { Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}"); } } var ad = new ApiData(); ad.AlgorithmSpeedsTotal = new List <AlgorithmTypeSpeedPair> { new AlgorithmTypeSpeedPair(_algorithmType, totalSpeed) }; ad.AlgorithmSpeedsPerDevice = perDeviceSpeedInfo; ad.PowerUsageTotal = totalPower; ad.PowerUsagePerDevice = perDevicePowerInfo; return(ad); }
public async override Task <ApiData> GetMinerStatsDataAsync() { var summaryApiResult = await ApiDataHelpers.GetApiDataAsync(_apiPort, ApiDataHelpers.GetHttpRequestNhmAgentString("summary"), _logGroup); double totalSpeed = 0; int totalPower = 0; if (!string.IsNullOrEmpty(summaryApiResult)) { // TODO return empty try { var summaryOptvals = summaryApiResult.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var optvalPairs in summaryOptvals) { var pair = optvalPairs.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (pair.Length != 2) { continue; } if (pair[0] == "KHS") { totalSpeed = double.Parse(pair[1], CultureInfo.InvariantCulture) * 1000; // HPS } } } catch (Exception e) { Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}"); } } var ad = new ApiData(); ad.AlgorithmSpeedsTotal = new List <AlgorithmTypeSpeedPair> { new AlgorithmTypeSpeedPair(_algorithmType, totalSpeed) }; ad.PowerUsageTotal = totalPower; // cpuMiner is single device so no need for API return(ad); }
public override async Task <ApiData> GetMinerStatsDataAsync() { var ad = new ApiData(); try { const string speeds = @"{""id"":123456789,""method"":""worker.list"",""params"":[]}" + "\r\n"; var response = await ApiDataHelpers.GetApiDataAsync(_apiPort, speeds, _logGroup); ad.ApiResponse = response; var summary = JsonConvert.DeserializeObject <JsonApiResponse>(response); var gpus = _miningPairs.Select(pair => pair.Device.UUID); var perDeviceSpeedInfo = new Dictionary <string, IReadOnlyList <(AlgorithmType type, double speed)> >(); var perDevicePowerInfo = new Dictionary <string, int>(); var totalSpeed = 0d; //var totalSpeed2 = 0d; //var totalPowerUsage = 0; foreach (var gpu in gpus) { var speed = summary.workers.Where(w => w.device_uuid == gpu).SelectMany(w => w.algorithms.Select(a => a.speed)).Sum(); totalSpeed += speed; perDeviceSpeedInfo.Add(gpu, new List <(AlgorithmType type, double speed)>() { (_algorithmType, speed) }); } ad.PowerUsageTotal = 0; ad.AlgorithmSpeedsPerDevice = perDeviceSpeedInfo; ad.PowerUsagePerDevice = perDevicePowerInfo; Logger.Info("EXCAVATOR", response); await Task.CompletedTask; } catch (Exception e) { Logger.Error("EXCAVATOR-API_ERR", e.ToString()); } return(ad); }
public static Task <string> GetApiDataThreads(int port, string logGroup) { var dataToSend = ApiDataHelpers.GetHttpRequestNhmAgentString("threads"); return(ApiDataHelpers.GetApiDataAsync(port, dataToSend, logGroup)); }
public async override Task <ApiData> GetMinerStatsDataAsync() { var api = new ApiData(); var perDeviceSpeedInfo = new Dictionary <string, IReadOnlyList <AlgorithmTypeSpeedPair> >(); var perDevicePowerInfo = new Dictionary <string, int>(); var totalSpeed = 0d; var totalPowerUsage = 0; try { var result = await ApiDataHelpers.GetApiDataAsync(_apiPort, "summary", _logGroup); if (result == "") { return(api); } //total speed if (!string.IsNullOrEmpty(result)) { try { var summaryOptvals = result.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var optvalPairs in summaryOptvals) { var pair = optvalPairs.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (pair.Length != 2) { continue; } if (pair[0] == "KHS") { totalSpeed = double.Parse(pair[1], CultureInfo.InvariantCulture) * 1000; // HPS } } } catch (Exception e) { Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}"); } } var threadsApiResult = await ApiDataHelpers.GetApiDataAsync(_apiPort, "threads", _logGroup); if (!string.IsNullOrEmpty(threadsApiResult)) { try { var gpus = threadsApiResult.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); var apiDevices = new List <IdPowerHash>(); foreach (var gpu in gpus) { var gpuOptvalPairs = gpu.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); var gpuData = new IdPowerHash(); foreach (var optvalPairs in gpuOptvalPairs) { var optval = optvalPairs.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (optval.Length != 2) { continue; } if (optval[0] == "GPU") { gpuData.id = int.Parse(optval[1], CultureInfo.InvariantCulture); } if (optval[0] == "POWER") { gpuData.power = int.Parse(optval[1], CultureInfo.InvariantCulture); } if (optval[0] == "KHS") { gpuData.speed = double.Parse(optval[1], CultureInfo.InvariantCulture) * 1000; // HPS } } apiDevices.Add(gpuData); } foreach (var miningPair in _miningPairs) { var deviceUUID = miningPair.Device.UUID; var deviceID = miningPair.Device.ID; var apiDevice = apiDevices.Find(apiDev => apiDev.id == deviceID); if (apiDevice.Equals(default(IdPowerHash))) { continue; } perDeviceSpeedInfo.Add(deviceUUID, new List <AlgorithmTypeSpeedPair>() { new AlgorithmTypeSpeedPair(_algorithmType, apiDevice.speed * (1 - DevFee * 0.01)) }); perDevicePowerInfo.Add(deviceUUID, apiDevice.power); totalPowerUsage += apiDevice.power; } } catch (Exception e) { Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}"); } } } catch (Exception e) { Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}"); } api.AlgorithmSpeedsTotal = new List <AlgorithmTypeSpeedPair> { new AlgorithmTypeSpeedPair(_algorithmType, totalSpeed * (1 - DevFee * 0.01)) }; api.PowerUsageTotal = totalPowerUsage; api.AlgorithmSpeedsPerDevice = perDeviceSpeedInfo; api.PowerUsagePerDevice = perDevicePowerInfo; return(api); }
public override async Task <BenchmarkResult> StartBenchmark(CancellationToken stop, BenchmarkPerformanceType benchmarkType = BenchmarkPerformanceType.Standard) { using (var tickCancelSource = new CancellationTokenSource()) { var workers = string.Join(",", _miningPairs.Select((_, i) => $@"""{i}""")); var workersReset = @"{""id"":1,""method"":"" workers.reset"",""params"":[__WORKERS__]}".Replace("__WORKERS__", workers); // determine benchmark time // settup times var benchmarkTime = MinerBenchmarkTimeSettings.ParseBenchmarkTime(new List <int> { 20, 40, 60 }, 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 ApiDataHelpers.GetApiDataAsync(_apiPort, workersReset + "\r\n", _logGroup); await ExcavatorTaskHelpers.TryDelay(TimeSpan.FromSeconds(10), stop); if (t.IsCompleted || t.IsCanceled || stop.IsCancellationRequested) { break; } // get speeds var ad = await GetMinerStatsDataAsyncPrivate(); 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); } }