TXT ファイル形式 - 2023.2 日本語

AI エンジン ツールおよびフロー ユーザー ガイド (UG1076)

Document ID
UG1076
Release Date
2023-12-04
Version
2023.2 日本語

入力ファイル

入力/出力ストリームのデフォルトのビット幅は 32 ビットです。ビット幅は、シミュレーション入力ファイルの各行のサンプル数を指定します。次の表に、データ型および PLIO データ幅に基づく入力ファイルの各行のサンプルの解釈を示します。次の表に、データ型および PLIO データ幅に基づく入力ファイルの各行のサンプルの解釈を示します。

表 1. データ型および PLIO 幅
データ型 PLIO 32 ビット PLIO 64 ビット PLIO 128 ビット
adf::input_plio in = adf::input_plio::create("DataIn1", adf::plio_32_bits, "input.txt"); adf::input_plio in = adf::input_plio::create("DataIn1", adf::plio_64_bits, "input.txt"); adf::input_plio in = adf::input_plio::create("DataIn1", adf::plio_128_bits, "input.txt");
int8 1 行につき 4 個の値。次に例を示します。

6 8 3 2

1 行につき 8 個の値。次に例を示します。

6 8 3 2 6 8 3 2

1 行につき 16 個の値。次に例を示します。

6 8 3 2 6 8 3 2 6 8 3 2 6 8 3 2

int16 1 行につき 2 個の値。次に例を示します。

24 18

1 行につき 4 個の値。次に例を示します。

24 18 24 18

1 行につき 8 個の値。次に例を示します。

24 18 24 18 24 18 24 18

int32 1 行につき 1 個の値。

2386

1 行につき 2 個の値。次に例を示します。

2386 2386

1 行につき 4 個の値。次に例を示します。

2386 2386 2386 2386

int64 N/A 45678 1 行につき 2 個の値。次に例を示します。

45678 95578

cint16 1 行につき 1 個の cint 値 (実数、虚数)。次に例を示します。

1980 485

1 行につき 2 個の cint 値。次に例を示します。

1980 45 180 85

1 行につき 4 個の cint 値。次に例を示します。

1980 485 180 85 980 48 190 45

cint32 N/A 1 行につき 1 個の cint 値 (実数、虚数)。次に例を示します。

1980 485

1 行につき 2 個の cint 値。次に例を示します。

1980 45 180 85

float 1 行につき 1 個の浮動小数点値。次に例を示します。

893.5689

1 行につき 2 個の浮動小数点値。次に例を示します。

893.5689 3459.3452

1 行につき 4 個の浮動小数点値。次に例を示します。

893.5689 39.32 459.352 349.345

cfloat N/A 1 行につき 1 個の浮動小数点 cfloat 値 (実数、虚数)。次に例を示します。

893.5689 24156.456

1 行につき 2 個の浮動小数点 cfloat 値 (実数、虚数)。次に例を示します。

893.5689 24156.456 93.689 256.46

PLIO およびパケット ストリーム インターフェイスの要件

TXT ファイルを使用して PLIO ポートおよびパケット ストリーム インターフェイスを表すデータを提供する場合、次の TXT ファイル要件に従う必要があります。

  1. tkeep は常に有効です。False に設定されている tkeep 信号はサポートされません。
  2. インターフェイスの幅に応じて、1 つの行に複数のデータ サンプルを組み合わせて送信できます。最初のデータ サンプルは、インターフェイスの最下位ビットで送信されます。たとえば、データ型が int16 で、AI エンジンと PL 間のインターフェイスが 64 ビット幅の場合、行 0 1 2 30x0003000200010000 として AI エンジンに送信されます。
    0 1 2 3
  3. TXT ファイルの tlast は、次の行の tlast が 1 に等しいことを示します。tlast が 1 の場合、AI エンジンに送信されるデータ サンプル数は AI エンジンと PL 間インターフェイスの幅と同じ、またはそれ以下にすることができます。たとえば、データ型が int16 で、AI エンジンと PL 間インターフェイスが 64 ビット幅の場合、最終行 4 5tlast を使用して 0x00050004 として AI エンジンに送信されます。
    0 1 2 3
    tlast
    4 5
  4. パケット ストリーム インターフェイスでは、tlast が 1 の場合はパケットの最後を表します。パケット ヘッダーは、符号なし 10 進数のフォーマットに指定する必要があります。たとえば、AI エンジンと PL 間インターフェイスが 64 ビット幅の場合、次の行はパケット ヘッダー 0x8fff0000 (符号なし 10 進数の 2415853568) を送信します。
    tlast
    2415853568
    データ型が int16 で、AI エンジンと PL 間インターフェイスが 64 ビット幅のパケット ストリーム インターフェイスの場合、次の行はパケット ヘッダー 0x8fff0000、パケット データ 0x0、およびパケット データ 0xfffeffff を AI エンジンに送信します。
    2415853568 0
    tlast
    -1 -2

出力ファイル

シミュレータは、各出力 PLIO ポートごとに、入力 PLIO データ ファイルと同じタイプの宣言を使用して、ストリーム内容を含むファイルを自動的に作成します。

adf::output_plio out1 = adf::output_plio::create("DataOut1",adf::plio_32_bits,"output1.txt");
adf::output_plio out2 = adf::output_plio::create("DataOut2",adf::plio_64_bits,"output2.txt");
adf::output_plio out3 = adf::output_plio::create("DataOut3",adf::plio_128_bits,"output3.txt");
作成される出力ファイルには、入力と同じフォーマットが適用されます。データ型と PLIO のビット幅に応じて、各行に表示されるデータの数が変わります。各出力行にはシミュレータによりタイムスタンプが付けられるので、シミュレーション中のデータ スループットを見積もることができます。タイムスタンプの単位は次のとおりです。
  • ピコ秒 (ps)
  • ナノ秒 (ns)
  • マイクロ秒 (us)
  • ミリ秒 (ms)
  • 秒 (s)

フレームの終わりで TLAST フラグを生成するソースからストリームが送信された場合、この TLAST も出力ファイルに書き込まれます。次に、この出力ファイルの例を示します。

...
T 15984 ns
4552 4555 
T 15988 ns
4558 4561 
T 15992 ns
4564 4567 
T 15996 ns
4570 4573 
T 16 us
4576 4579 
T 16004 ns
4582 4585 
T 16008 ns
4588 4591 
T 16012 ns
4594 4597 
T 16016 ns
4600 4603 
T 16020 ns
4606 4609 
T 16024 ns
TLAST
4612 4615 
T 17940 ns
4618 4621 
T 17944 ns
4624 4627 
T 17948 ns
4630 4633 
T 17952 ns
...
まとめると、PLIO ポートの各出力のフォーマットは次のとおりです。
  • タイムスタンプ
  • TLAST、TKEEP
  • サンプル DATA 値

この PLIO ポートについて、出力ファイルからデザインのスループットを見積もることができます。タイムスタンプは、有効な出力にのみ関連します。PLIO ポートが quiet の場合、出力ファイルには何も表示されません。

スループットは、出力サンプル数をタイムスタンプの差で割った値として算出します。

Throughput = NumberOfSamples / (LastTimestamp - FirstTimestamp)

このシンプルな式では、最後のサンプル出力後に発生するすべてのクロック サイクルが考慮されなければ、スループットが正しく見積もられない可能性があります。

フレームベースの出力の場合、かなり大きく見積もられることがあります。この場合、出力のフォーマットは次のとおりです。
  • フレーム 0 出力 (tstart_0 ~ tend_0)
  • Quiet インターフレーム
  • フレーム 1 出力 (tstart_1 ~ tend_1)
  • Quiet インターフレーム
  • ...
  • フレーム N-1 出力 (tstart_N-1 から tend_N-1)
  • Quiet インターフレーム
  • フレーム N 出力 (tstart_N ~ tend_N)

この場合、各フレーム出力のフレーム間の時間差を考慮する必要があります。これは、N 個の最初のフレーム (0 ~ N-1) のみを使用すれば可能です。スループットの算出式のタイムスタンプを次のように換えます。

  • FirstTimestamp = tstart_0
  • LastTimestamp = tstart_N (最後のフレームの最初の出力タイムスタンプ)

次に、PLIO のスループットを計算する Python スクリプトの例を示します。シミュレーション出力ファイルを解析し、スループットを計算します。


import numpy as np
from math import *
import sys
import argparse

def GetTime_ns(Stamp):
  Time_ns = float(Stamp[1])
  if(Stamp[2] == 'ps'):
    Time_ns = Time_ns/1000.0
  elif(Stamp[2] == 'us'):
    Time_ns = Time_ns*1000.0
  elif(Stamp[2] == 'ms'):
    Time_ns = Time_ns*1000000.0
  elif(Stamp[2] == 's'):
    Time_ns = Time_ns*1000000000.0
  return(Time_ns)


def ReadFile(filename):
  # Detect the number of data per PLIO output
  fdr = open(filename,'r')
  ts = fdr.readline()
  d = fdr.readline()
  dw = d.split()
  fdr.close()


  coltime = 0
  coldata = 1
  numdata = len(dw)
  coltlast = numdata + 1


  # Initializes the output array
  # Format: timestamp (in ns) val1 val2 ... valN TLAST (0 or 1)
  a = np.zeros((0,numdata+2))
  fdr = open(filename,'r')
  line = ' '
  lnum = 0;

  while line !="" :
    line = fdr.readline()
    if line=='':
      continue
    res = line.split()

    if(res[0] != 'T'): # It should be a timestamp
      continue

    l = np.zeros((1,numdata+2))
    # Extract the time stamp
    l[0][0] = GetTime_ns(res)


    line = fdr.readline()
    res = line.split()
    # extract the TLAST
    if(res[0]=='TLAST'):
      tlast = 1
      line = fdr.readline()
      res = line.split()
    else:
      tlast = 0

    l[0,coltlast] = tlast
    # Extract all values
    for i in range(numdata):
      l[0,i+1] = float(res[i])

      # Appends to the whole array
      a = np.append( a , l,axis=0)

  fdr.close()
  return(a)

def Throughput(Filename,IsComplex):
  V = ReadFile(Filename)
  print("\n==============================")
  print(Filename)
  print("\n")

  NRows = V.shape[0]
  NCols = V.shape[1]
  NFullFrames = int(np.sum(V[:,NCols-1]))
  print("Number of Full Frames: " + str(NFullFrames))


  # Basic Throughput computation
  if IsComplex:
    Ratio = 0.5
  else:
    Ratio = 1
  RawThroughputMsps = float(NRows*(NCols-2))/(V[NRows-1,0]-V[0,0])*Ratio*1000.0
  print("Raw Throughput: %.2f" % RawThroughputMsps)

  # If the output is frame based, compute a more precise throughput
  tlast = np.where(V[:,NCols-1] == 1.0)
  if(len(tlast[0])<=1):
    TotalThroughput = RawThroughput
  else:
    tlast = tlast[0]
    EndRow = tlast[len(tlast)-2]+1
    # EndRow is the number of Rows I take into account for the number of datasource
    # The timestamp I am interested in is the timestamp of the next transaction
    TotalThroughputMsps = float(EndRow*(NCols-2))/(V[EndRow,0]-V[0,0])*Ratio*1000.0
    print(" Throughput: %.2f" % TotalThroughputMsps)

  print("\n")

# Entry point of this file
if __name__ == "__main__":
  parser = argparse.ArgumentParser(prog=sys.argv[0], description='Compute the throughput corresponding to some output of AIE Simulations')
  parser.add_argument('--iscomplex', action='store_true', help='Indicates Complex data in the file')
  parser.add_argument('filename',nargs='+')
  Args = sys.argv
  Args.pop(0)
  args = parser.parse_args(Args)

for f in args.filename:
  Throughput(f,args.iscomplex)