インテル® FPGA SDK for OpenCL™プロ・エディション: プログラミング・ガイド

ID 683846
日付 4/01/2019
Public
ドキュメント目次

5.4.5.4. ioチャネル属性を使用したI/Oチャネルの実装

io属性をチャネル宣言に含め、FPGAボードの入力または出力フィーチャーと接続する特別なI/Oチャネルを宣言します。
このフィーチャーには、ネットワーク・インターフェイス、PCIe®、カメラ、データのキャプチャーや処理を行うその他デバイス、プロトコルなどが含まれます。

io("chan_id") 属性は、チャネルが接続するアクセラレーター・ボードのI/Oフィーチャーを指定します。このchan_idは、カスタム・プラットフォームのboard_spec.xmlにリストされているI/Oインターフェイス名です。

ペリフェラル・インターフェイスの使用方法はデバイスの種類によって異なるため、I/Oチャネルをカーネルプログラムに実装する際は、ボードメーカーの資料を参照してください。ご自身のOpenCL™カーネルコードは、ペリフェラル・インターフェイスが生成するデータと互換性がある必要があります。

注意:
  • ボードに直接接続し、I/Oチャネルを介してペリフェラル・デバイスと通信するチャネルには、暗黙的なデータの依存関係が存在する可能性があります。 インテル® FPGA SDK for OpenCL™オフライン・コンパイラーは、これらの依存関係に対する可視性を持たないため、この暗黙的なデータの依存関係は予期しない動作を引き起こす可能性があります。
  • 同じペリフェラルと通信する外部I/Oチャネルは、シーケンシャルな順序に従いません。予期しない動作が発生する可能性があるため、外部デバイスがシーケンシャルな順序を必要としないようにしてください。
  1. カスタム・プラットフォームのboard_spec.xmlファイルを参照し、ご自身のFPGAボードで使用可能な入力および出力フィーチャーを特定してください。

    例えば、board_spec.xmlファイルには次のようなI/Oフィーチャー情報が含まれています。

    <channels>
      <interface name="udp_0" port="udp0_out"  type="streamsource" width="256"
       chan_id="eth0_in"/>
      <interface name="udp_0" port="udp0_in"  type="streamsink" width="256"
       chan_id="eth0_out"/>
      <interface name="udp_0" port="udp1_out"  type="streamsource" width="256"
       chan_id="eth1_in"/>
      <interface name="udp_0" port="udp1_in"  type="streamsink" width="256"
       chan_id="eth1_out"/>
    </channels>

    interface要素のwidth属性は、そのチャネルで使用されるデータタイプの幅をビットで指定します。上の例の場合、uintfloatのデータタイプはどちらも32ビット幅です。他のより大きいデータタイプやベクトル化されたデータタイプは、board_spec.xmlファイルで指定されている適切なビット幅と一致している必要があります。

  2. 次のコード例で示されているようにioチャネル属性を実装します。ioチャネル属性の名前は、board_spec.xmlファイルで指定されているI/Oチャネル名 (chan_id) と一致していなければなりません。
    channel QUDPWord udp_in_IO __attribute__((depth(0)))
                               __attribute__((io("eth0_in"))); 
    channel QUDPWord udp_out_IO __attribute__((depth(0)))
                                __attribute__((io("eth0_out"))); 
    
    __kernel void io_in_kernel (__global ulong4 *mem_read,
                                uchar read_from,
                                int size) 
    {
      int index = 0;
      ulong4 data;
      int half_size = size >> 1;
      while (index < half_size)
      {
        if (read_from & 0x01)
        {
          data = read_channel_intel(udp_in_IO);
        } 
        else
        {
          data = mem_read[index];
        }
        write_channel_intel(udp_in, data);
        index++;
      }
    }
    
    __kernel void io_out_kernel (__global ulong2 *mem_write,
                                 uchar write_to,
                                 int size)
    {
      int index = 0;
      ulong4 data;
      int half_size = size >> 1;
      while (index < half_size)
      {
        ulong4 data = read_channel_intel(udp_out);
        if (write_to & 0x01)
        {
          write_channel_intel(udp_out_IO, data);
        }
        else
        {
          //only write data portion
          ulong2 udp_data;
          udp_data.s0 = data.s0;
          udp_data.s1 = data.s1;
          mem_write[index] = udp_data;
        }
        index++;
      }
    }
    重要: board_spec.xmlファイルの、XML (eXtensible Markup Language) チャネル要素で指定されている各I/Oチャネルに、固有のio("chan_id") ハンドルを宣言してください。