ユーザー定義のアクセラレータ クラス - 2023.2 日本語

Vitis 統合ソフトウェア プラットフォームの資料: アプリケーション アクセラレーション開発 (UG1393)

Document ID
UG1393
Release Date
2023-12-13
Version
2023.2 日本語

Vitis では、ソース コードに VPP_ACC クラスから派生したクラスが含まれる場合、ハードウェアおよびホスト コードのコンパイル用に VSC がイネーブルになります。VPP_ACC から派生したクラスは、アクセラレータとしてコンパイルされます。

シングル ソースの C++ モデルでは、VSC アクセラレータ インターフェイスは、C++ ヘッダー ファイルで必要なクラス定義として定義されます。複数のアクセラレータ クラス定義は、1 つのコンパイル ユニット内で (1 つの v++ --compile コマンドとして) 見つけることができます。これらはすべて同じ PL ハードウェアにインプリメントされます。また、複数のコンパイル ユニットで複数のアクセラレータを提供することもできます。ただし、各コンパイル ユニットがそのユニット用の完全なカーネル (または HLS) コードを定義する必要があります。

すべてのユーザー定義のアクセラレータ クラスは、次の条件に従っている必要があります。

  • Vitis の定義済みの VPP_ACC クラスから派生する必要があります。
  • compute() というスタティック メソッドが必要です。
  • compute() の引数と機能は、ユーザーが定義できます。
  • クラステ ンプレートには、次の 2 つの引数があります。
    • 1 つ目の引数は、ユーザー定義のクラス名と同じである必要があります。
    • 2 つ目の引数は、ハードウェアで複製される計算ユニット数です。

次に、アクセラレータ クラス定義 (xmmult) の例を示します。

#include "vpp_acc.hpp"
class xmmult : VPP_ACC<xmmult, /*NCU=*/4>
{
public:
    // Platform port connections
    SYS_PORT(A, DDR[0]);
    SYS_PORT(B, DDR[1]);
    SYS_PORT(C, DDR[2]);
    SYS_PORT_PFM(u50, A, (HBM[0]:HBM[4]:HBM[8]:HBM[12]));
    SYS_PORT_PFM(u50, B, (HBM[1]:HBM[5]:HBM[9]:HBM[13]));
    SYS_PORT_PFM(u50, C, (HBM[2]:HBM[6]:HBM[10]:HBM[14]));
    // Data interfaces
    ACCESS_PATTERN(A, SEQUENTIAL);
    ACCESS_PATTERN(B, RANDOM);
    DATA_COPY(A, A[SZ]);  // move to local memory
    DATA_COPY(B, B[SZ]);
    ZERO_COPY(C);  // direct AXI-mm

    // define the SW entry point of the accelerator
    static void compute(data_t* A, data_t* B, data_t* C);
    // define the HW top-level of the accelerator (HLS top)
    static void mmult(data_t* A, data_t* B, data_t* C);
};

このクラス インターフェイス モデルは、単一の統合ソースでハードウェア システム関連のすべての考慮事項を組み込んでいるので、compute() 関数を使用してアプリケーション層と簡単に統合できるようになっています (compute() API を参照)。compute() 関数は、ハードウェア アクセラレータへのホスト アプリケーションのエントリ ポイントです。

このクラス定義には、compute() 引数を参照するガイダンス マクロも含まれます。これらを使用することで、インプリメンテーション時に VSC で特定のハードウェアを選択できるようになります。詳細は、ガイダンス マクロ を参照してください。

上記の例では、VSC でハードウェアに 4 つの CU (/*NCU=*/4) が含まれるようにコンパイルされる xmmult というアクセラレータ クラスを示しています。アクセラレータには、mmult() 関数内で定義される PE (またはカーネル) コードがあります。このコードは、3 つの引数 A、B、および C を取り込む compute() 内で呼び出されます。これらの引数ごとに、メモリ ポート接続とデータ アクセスの 2 種類のガイダンス マクロが指定されています。

  1. SYS_PORT()SYS_PORT_PFM() マクロを使用したプラットフォーム ポート接続。
    1. これらは通常、Vitis でコンパイル時に使用されるハードウェア プラットフォームで使用可能なグローバル メモリ I/O 接続またはその他の AXI4 インターフェイス接続です。この例では、最初の 3 つの SYS_PORT() マクロが、compute() の 3 つの引数 (A、B、C) を異なる DDR バンク (0、1、2) に接続します。
      ヒント: 各引数の SYS_PORT() ガイダンス マクロ接続は、1 つのメモリ バンクしか指定しないため、xmmult アクセラレータ内のすべての CU インスタンス (NCU=4) に適用されます。
    2. この 3 つの SYS_PORT_PFM() マクロは、グローバル メモリ接続を次の 2 つの方法で適用します。
      1. U50 Alveo カードのように、ターゲット プラットフォーム名に u50 が含まれている場合にのみ適用されます。
      2. 4 つの各 CU ごとに、各引数が異なる HBM バンクに接続されます。これは、各引数の SYS_PORT_PFM() に使用される構文で接続が 4 回指定されるためです。
        SYS_PORT_PFM(u50, A, (HBM[0]:HBM[4]:HBM[8]:HBM[12]));
  2. データ アクセスは、ACCESS_PATTERN()DATA_COPY()ZERO_COPY() マクロを使用して指定します。
    1. ACCESS_PATTERN() マクロは、VSC にデータ転送のためのシーケンシャル アクセスまたはランダム アクセスを推論するよう指示します。この例では、引数 A はシーケンシャル アクセスとして定義されているため、ストリーム接続を使用してインプリメントできます。引数 B はランダムにアクセスされるため、PE mmult() からのランダム データ アクセスをサポートするローカル (オンチップ) メモリ バッファーが必要です。
    2. 引数 A および B の場合、DATA_COPY() マクロが VSC にアクセラレータの横にローカル メモリ (RAM) を推論するように指示します。
    3. ZERO_COPY() マクロは、VSC に引数 C のメモリ マップド AXI (M_AXI) 接続を作成するよう指示します。