/// <summary> /// パラメータに従ってシミュレーションを実行する /// </summary> /// <param name="token">キャンセル用のToken</param> /// <param name="request">パラメータ情報</param> /// <returns></returns> public static List <ResultEntity> Run(CancellationToken token, ArgoRequest request) { var hspice = new Hspice(); using var bar = new ProgressBar((int)request.Sweep, "Ptolemy.Argo", new ProgressBarOptions { BackgroundCharacter = '-', ProgressCharacter = '>', BackgroundColor = ConsoleColor.DarkGray, ForegroundColor = ConsoleColor.DarkGreen, CollapseWhenFinished = true, DisplayTimeInRealTime = true, ForegroundColorDone = ConsoleColor.Green }); return(hspice.Run(token, request, () => bar.Tick()).ToList()); }
public static ParameterEntity ConvertToParameterEntity(ArgoRequest ar) { var rt = new ParameterEntity { Vtn = ar.Transistors.Vtn.ToString(), Vtp = ar.Transistors.Vtp.ToString(), NetList = ar.NetList, Time = ar.Time.ToString(), Signals = string.Join(":", ar.Signals), Includes = string.Join(":", ar.Includes), Hspice = ar.HspicePath, HspiceOption = string.Join(":", ar.HspiceOptions), Gnd = ar.Gnd, Vdd = ar.Vdd, IcCommand = string.Join(":", ar.IcCommands), Temperature = ar.Temperature }; ar.ResultFile = rt.Hash(); return(rt); }
public IReadOnlyList <ResultEntity> Run(CancellationToken token, ArgoRequest request, Action intervalAction) { var guid = Guid.NewGuid(); var dir = Path.Combine(workingRoot, $"{request.GroupId}"); FilePath.FilePath.TryMakeDirectory(dir); Directory.SetCurrentDirectory(dir); var spi = Path.Combine(dir, guid + ".spi"); request.WriteSpiScript(spi); try { using var p = new Process { StartInfo = new ProcessStartInfo { UseShellExecute = false, FileName = Environment.OSVersion.Platform == PlatformID.Unix ? "bash" : "powershell.exe", ArgumentList = { "-c", $"{request.HspicePath} {string.Join(" ", request.HspiceOptions)} -i {guid}.spi" }, RedirectStandardOutput = true, RedirectStandardError = true } }; if (!p.Start()) { throw new SimulatorException("Failed start hspice"); } var stdout = p.StandardOutput; var signals = request.Signals; var sweep = request.SweepStart; var records = (expect : request.ExpectedRecords, actual : 0); var rt = new List <ResultEntity>(); string line; while ((line = stdout.ReadLine()) != null || !p.HasExited) { token.ThrowIfCancellationRequested(); if (string.IsNullOrEmpty(line)) { continue; } // 先頭にyが来るとデータの区切り if (line[0] == 'y') { sweep++; intervalAction?.Invoke(); } // Parseできないところは飛ばす if (!TryParseOutput(request.Seed, sweep, line, signals, out var o)) { continue; } foreach (var resultEntity in o.Intersect(request.PlotTimeList, re => re.Time)) { records.actual++; rt.Add(resultEntity); } } p.WaitForExit(); if (p.ExitCode != 0) { throw new SimulatorException($"Failed simulation: {p.StandardError.ReadToEnd()}"); } if (records.expect != records.actual) { throw new SimulatorException( $"Record数が {records.expect} 個予期されていましたが、 {records.actual} 個しか出力されませんでした"); } return(rt); } finally{ File.Delete(spi); File.Delete(Path.Combine(dir, $"{guid}.mc0")); File.Delete(Path.Combine(dir, $"{guid}.st0")); } }
public void Run(CancellationToken token) { var log = new Logger.Logger(); // TimeList var plotTimeList = GeneratePlotTimeEnumerable(PlotTimeRequest, TimeString).ToList(); // Configのデフォルトも見る var transistors = this.Bind(Config.Config.Instance.ArgoDefault.Transistors); if (string.IsNullOrEmpty(NetList) && string.IsNullOrEmpty(Config.Config.Instance.ArgoDefault.NetList)) { throw new AriesException("NetListを空にできません.一番目の引数もしくはコンフィグファイルのArgoDefault.NetListで指定してください"); } // 引数で与えたNetListが優先 NetList = FilePath.FilePath.Expand( string.IsNullOrEmpty(NetList) ? Config.Config.Instance.ArgoDefault.NetList : NetList); var guid = Guid.NewGuid(); // タスクファイルを保存してるディレクトリへのパスを展開 var baseDir = Path.Combine(Config.Config.Instance.WorkingRoot, "aries", "task"); if (!Directory.Exists(baseDir)) { Directory.CreateDirectory(baseDir); } if (!File.Exists(NetList)) { throw new AriesException($"Netlistファイルが見つかりません: {NetList}"); } HspicePath = string.IsNullOrEmpty(HspicePath) ? Environment.GetEnvironmentVariable(Argo.Argo.EnvArgoHspice) : HspicePath; if (string.IsNullOrEmpty(HspicePath) || !File.Exists(HspicePath)) { throw new ArgoException($"Hspice can not found: {HspicePath}"); } try { var totalSweep = TotalSweeps.ParseLongWithSiPrefix(); var seed = Seed.ParseLongWithSiPrefix(); var start = SweepStart.ParseLongWithSiPrefix(); var include = new[] { Includes, Config.Config.Instance.ArgoDefault.Includes, Environment.GetEnvironmentVariable(Argo.Argo.EnvArgoIncludes) ?.Split(',', StringSplitOptions.RemoveEmptyEntries) }; var baseRequest = new ArgoRequest { GroupId = guid, Gnd = Gnd.ParseDecimalWithSiPrefix(), // Includesは引数、コンフィグ、環境変数のうち最初にNullじゃないやつを選ぶ。全部Nullなら空のリスト Includes = include.Any(s => s.Any()) ? include.First(s => s.Any()).ToList() : new List <string>(), Seed = seed, // Signalsは引数がNullならコンフィグを選ぶ Signals = (Signals ?? Config.Config.Instance.ArgoDefault.Signals).ToList(), Sweep = totalSweep, Temperature = Temperature.ParseDecimalWithSiPrefix(), Time = new RangeParameter(TimeString), Transistors = transistors, Vdd = Vdd.ParseDecimalWithSiPrefix(), HspiceOptions = Options.ToList(), HspicePath = HspicePath, IcCommands = IcCommands.ToList(), NetList = NetList, SweepStart = start, PlotTimeList = plotTimeList }; //var dbName = baseRequest.GetHashString(); //baseRequest.ResultFile = dbName; if (SplitOption == "none") { WriteTaskFile(Path.Combine(baseDir, $"{guid}.json"), baseRequest); } else { var(by, size) = SplitOption.Split(':', StringSplitOptions.RemoveEmptyEntries) switch { var s when s.Length != 2 => throw new AriesException( "SplitOptionに与えた引数がフォーマットに従っていません.[seed, sweep]:[size]"), var s when s[1] == "0" => throw new AriesException("[size]に0を指定できません"),