Skip to content

実行時状況の解析

Ushitora Anqou edited this page Sep 13, 2021 · 3 revisions

Iyokanが回路を実行している際の状況を調べる方法をまとめる。基本的にIyokanの次のようなオプションが使用できる。

FIXME: このあたりのオプションはKVSPの実験過程でアドホックに付け加えたものばかりなので、オプション名に一貫性がない・出力ファイルをうまくハンドルするツールがないなどの問題がある。統一的な解決策が必要。

  • --dump-prefix PREFIX
    • 各サイクルごとに、出力ポートに何が出力されているかをファイルに書き出す。この際復号を行うため、別途--secret-keyオプションで秘密鍵を渡す必要がある。オプションの引数には出力ファイル名のプレフィクスを指定する。各サイクルごとにそのプレフィクスを冠したファイルが出力される。
  • --dump-time-csv-prefix PREFIX
    • ゲートのID・種類とともに実行開始時間・終了時間をCSVファイルとして出力する。オプションの引数にはCSVファイル名のプレフィクスを指定する。各サイクルごとにそのプレフィクスを冠したCSVファイルが生成される。
  • --dump-graph-dot-prefix PREFIX
    • 回路を表すDOTファイルを生成する。オプションの引数にはDOTファイル名のプレフィクスを指定する。各サイクルごとにそのプレフィクスを冠したDOTファイルが生成される。
  • --dump-graph-json-prefix PREFIX
    • ゲートのID・種類とともに実行開始時間・終了時間をJSONファイルとして出力する。さらにゲート間の接続情報も出力する。オプションの引数にはJSONファイル名のプレフィクスを指定する。各サイクルごとにそのプレフィクスを冠したJSONファイルが出力される。
  • --stdout-csv
    • サイクルごとに、そのサイクルの開始時間と終了時間を標準出力に出力する。例えばteeなどを使ってファイルに書き出して使用することが想定されている。

--dump-time-csv-prefixの出力結果を解析する

このオプションは次のような出力を生み出す。

"2021-09-12 20:34:43.724","2021-09-12 20:34:43.724","26","65547","OUTPUT","io_out[3]"
"2021-09-12 20:34:43.716","2021-09-12 20:34:43.724","25","65561","XNOR",""
"2021-09-12 20:34:43.708","2021-09-12 20:34:43.708","24","65546","OUTPUT","io_out[2]"
"2021-09-12 20:34:43.708","2021-09-12 20:34:43.716","23","65559","NAND",""
"2021-09-12 20:34:43.700","2021-09-12 20:34:43.708","22","65558","XOR",""
"2021-09-12 20:34:43.700","2021-09-12 20:34:43.708","21","65557","NAND",""
"2021-09-12 20:34:43.691","2021-09-12 20:34:43.700","20","65554","NAND",""
"2021-09-12 20:34:43.690","2021-09-12 20:34:43.690","19","65545","OUTPUT","io_out[1]"
"2021-09-12 20:34:43.687","2021-09-12 20:34:43.687","18","65544","OUTPUT","io_out[0]"
"2021-09-12 20:34:43.681","2021-09-12 20:34:43.690","17","65553","XOR",""
"2021-09-12 20:34:43.681","2021-09-12 20:34:43.691","16","65552","NAND",""
"2021-09-12 20:34:43.673","2021-09-12 20:34:43.687","15","65555","NAND",""
"2021-09-12 20:34:43.673","2021-09-12 20:34:43.687","14","65560","XNOR",""
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.681","13","65549","AND",""
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.672","0","65541","INPUT","io_inB[1]"
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.672","1","65540","INPUT","io_inB[0]"
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.672","2","65537","INPUT","io_inA[1]"
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.687","12","65550","NAND",""
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.672","3","65536","INPUT","io_inA[0]"
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.687","11","65562","XOR",""
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.672","4","65542","INPUT","io_inB[2]"
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.672","5","65538","INPUT","io_inA[2]"
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.681","9","65551","XOR",""
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.672","6","65543","INPUT","io_inB[3]"
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.681","10","65556","XOR",""
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.672","7","65539","INPUT","io_inA[3]"
"2021-09-12 20:34:43.672","2021-09-12 20:34:43.672","8","65548","INPUT","reset[0]"

各カラムは順にゲートの実行開始時間、終了時間、ゲートが記録された順番、ゲートのID、ゲートの種類、ゲートの追加説明を表している。 上のサンプルからも分かるように、このデータはソートされていない。したがって、このデータを解析してソートし、 人間にとってわかりやすい形にするスクリプトが必要である。

例えば次のようなRubyスクリプトを書くことができる。このスクリプトをruby analyze_time_csv.rb input.csv output.csv のように実行すると、input.csvを読み込み、ソートし、実行の様子を表す新しいCSVファイルを出力する。

#!/usr/bin/ruby

require "csv"
require "time"

TIME_FORMAT = "%Y-%m-%d %H:%M:%S.%L"

def dump_vis(rows, outfilename)
  # Find epoch and normalize start/end
  epoch = rows[0][:start]
  cell_width = 0.010 # sec
  rows.each do |row|
    row[:start_cell] = ((row[:start] - epoch) / cell_width).round
    row[:end_cell] = ((row[:end] - epoch) / cell_width).round
  end

  # Make graph in CSV format
  csv_string = CSV.generate do |csv|
    rows.each do |row|
      out = []
      out.fill 1, (row[:start_cell]..row[:end_cell])
      out = [row[:start].strftime(TIME_FORMAT), row[:end].strftime(TIME_FORMAT), row[:index], row[:id], row[:kind], row[:desc]] + out
      csv << out
    end
  end
  open(outfilename, "wb").puts csv_string
end

raise "Usage: #{$0} IN-FILE OUT-FILE" unless ARGV.size == 2

# Read data
rows = []
CSV.foreach(ARGV[0]) do |row|
  rows.push({
    start: Time.strptime(row[0], TIME_FORMAT),
    end: Time.strptime(row[1], TIME_FORMAT),
    index: row[2].to_i,
    id: row[3].to_i,
    kind: row[4].to_s,
    desc: row[5].to_s,
  })
end
# Sort data
rows.sort! do |a, b|
  next 1 if a[:start] > b[:start]
  next -1 if a[:start] < b[:start]
  next 1 if a[:end] > b[:end]
  next -1 if a[:end] < b[:end]
  0
end

exit 1 unless rows.size > 1

dump_vis(rows.dup, ARGV[1])

出力されたCSVファイルをLibreOffice Calcで見ると次のように表示される。G〜L列の「1」は0.01秒刻みでどのゲートが実行されているかを表している。ゲートが順に実行されていることが分かる。 20210913_113356