Model Composer の
THROUGHPUT_FACTOR
プラグマを使用すると、xmcImportFunction
ブロックのスループットを一部制御できます。THROUGHPUT_FACTOR
プラグマは、次の例に示すように SUPPORTS_STREAMING
プラグマと一緒に関数ヘッダー ファイルに追加できます。#pragma XMC THROUGHPUT_FACTOR TF_param: 1,2,4
#pragma XMC SUPPORTS_STREAMING
template<int ROWS, int COLS, int TF_param>
void DilationWrap(const uint8_t src[ROWS][COLS], uint8_t dst[ROWS][COLS])
この例のプラグマの構文は、次のようになります。
#pragma XMC THROUGHPUT_FACTOR TF_param: 1,2,4
説明:
- 上記の例では、
TF_param
はint
型のテンプレート パラメーターである必要があります。 - 関数でサポートされる特定のスループット係数を指定するのはあくまでオプションですが、推奨されます。上記の例では、
1,2,4
はプラグマ内でサポートされるスループット係数を正の整数で指定しており、値 1 を含める必要があります。スループット係数を明示的に指定しない場合、TF_param
は Model Composer でサポートされる 16 までの正のスループット係数に対して有効となります。
インプリメンテーションのスループットの制御 で説明したように、モデルのスループット係数は Model Composer Hub ブロックで指定します。Hub ブロックのスループット係数は、ユーザーが指定できます。指定した係数値は、
xmcImportFunction
ブロックの THROUGHPUT_FACTOR
値の 1 つに均等に分割されます。 重要: Hub ブロックのスループット係数が一致しない場合、または
xmcImportFunction
ブロックで指定した THROUGHPUT_FACTOR
に均等に分割されない場合は、そのブロック関数のスループットは 1 になります。次の要件に注意してください。
-
THROUGHPUT_FACTOR
プラグマは、template 関数に使用する必要があります。 -
THROUGHPUT_FACTOR
プラグマは、SUPPORTS_STREAMING
プラグマと一緒に使用する必要があります。 -
xmcImportFunction
ブロックに指定できるTHROUGHPUT_FACTOR
プラグマは 1 つのみです。 - ブロック関数は、cyclic、factor=TF の
ARRAY_RESHAPE
指示子を持つ実際の引数を使用して呼び出します (次の例を参照)。ARRAY_RESHAPE
の詳細は、 『Vitis リファレンス ガイド』 (UG1702) の HLS プラグマ を参照してください。 - 関数のスカラー以外の入力引数からの読み出しアクセスは、ストリーミング要件に準拠する必要があり、AMD Vitis™ HLS で TF 読み出しのグループを 1 つの再形成された配列の読み出しにまとめることができます。
- 関数のスカラー以外の出力引数からの書き込みアクセスは、ストリーミング要件に準拠する必要があり、AMD Vitis™ HLS で TF 書き込みのグループを 1 つの再形成された配列の書き込みにまとめることができます。
次は、
SUPPORTS_STREAMING
および THROUGHPUT_FACTOR
プラグマの両方を指定する関数の例です。#include <stdint.h>
#pragma XMC THROUGHPUT_FACTOR TF: 1, 2, 4, 8, 16
#pragma XMC SUPPORTS_STREAMING
template<int TF>
void mac(const int32_t In1[240], const int32_t In2[240], const int32_t In3[240],
int32_t Out1 [240])
{
#pragma HLS ARRAY_RESHAPE variable=In1 cyclic factor=TF
#pragma HLS ARRAY_RESHAPE variable=In2 cyclic factor=TF
#pragma HLS ARRAY_RESHAPE variable=In3 cyclic factor=TF
#pragma HLS ARRAY_RESHAPE variable=Out1 cyclic factor=TF
for (uint32_t k0 = 0; k0 < 240 / TF; ++k0) {
#pragma HLS pipeline II=1
int32_t Product_in2m[TF];
int32_t Sum_in2m[TF];
int32_t Product_in1m[TF];
int32_t Sum_outm[TF];
for (uint32_t k1 = 0; k1 < TF; ++k1) {
Product_in2m[k1] = In2[(k0 * TF + k1)];
}
for (uint32_t k1 = 0; k1 < TF; ++k1) {
Sum_in2m[k1] = In3[(k0 * TF + k1)];
}
for (uint32_t k1 = 0; k1 < TF; ++k1) {
Product_in1m[k1] = In1[(k0 * TF + k1)];
}
for (uint32_t k1 = 0; k1 < TF; ++k1) {
int32_t Product_in2s;
int32_t Sum_in2s;
int32_t Product_in1s;
int32_t Product_outs;
int32_t Sum_outs;
Product_in2s = Product_in2m[k1];
Sum_in2s = Sum_in2m[k1];
Product_in1s = Product_in1m[k1];
Product_outs = Product_in1s * Product_in2s;
Sum_outs = Product_outs + Sum_in2s;
Sum_outm[k1] = Sum_outs;
}
for (uint32_t k1 = 0; k1 < TF; ++k1) {
Out1[(k0 * TF + k1)] = Sum_outm[k1];
}
}
}