예제 #1
0
파일: Argo.cs 프로젝트: xztaityozx/ptolemy
        /// <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());
        }
예제 #2
0
        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);
        }
예제 #3
0
        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"));
            }
        }
예제 #4
0
        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を指定できません"),