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

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

6.6.4.1. 複数のFPGAデバイスのプログラミング

システムに複数のFPGAデバイスをインストールする場合、ホストコードを変更し、特定のFPGAデバイスをプログラムするようホスト・ランタイムに指示できます。
重要:

ホスト・アプリケーションをFCDにリンクすると、異なるカスタム・プラットフォームから複数のFPGAデバイスをターゲットにすることができます。ただし、16.1よりも前のバージョンのSDKと互換性のあるカスタム・プラットフォームにおいては、この機能に対するサポートが制限されています。

次のように、最大128のFPGAデバイスをシステムに提示できます。

  • それぞれが単一のFPGAで構成されている複数のFPGAアクセラレーター・ボード
  • PCIe®スイッチを介しホストシステムに接続する、単一アクセラレーター・ボード上の複数のFPGA
  • 上記の組み合わせ

ホストランタイムは、それぞれのFPGAデバイスすべてにカーネルをロードすることができます。また、FPGAデバイスは並列に動作できます。

OpenCL FPGAデバイスの診断

ホストは、システムにインストールされているOpenCL™ FPGAのデバイス数を特定する必要があります。
  1. ご自身のマシンにインストールされたFPGA デバイスのリストを照会するには、 aocl diagnose コマンドを呼び出します。
  2. ホスト・アプリケーションに次のコード行を追加し、ホストにOpen CL FPGAのデバイス数を特定させます。
    //Get the platform
    ciErrNum = clGetPlatformID(&cpPlatform);
    
    //Get the devices
    ciErrNum = clGetDeviceIDs(cpPlatform,
                              CL_DEVICE_TYPE_ALL,
                              0,
                              NULL,
                              &ciDeviceCount);
    cdDevices = (cl_device_id * )malloc(ciDeviceCount * sizeof(cl_device_id));
    ciErrNum = clGetDeviceIDs(cpPlatform, 
                              CL_DEVICE_TYPE_ALL,
                              ciDeviceCount,
                              cdDevices,
                              NULL);
    
例えば、システムにOpenCL FPGAデバイスが2つある場合、ciDeviceCountの値は2になり、cdDevicesには、2つのデバイスID (cl_device_id) が含まれます。

デバイス情報の照会

OpenCL™ FPGAデバイスの情報を照会するよう、ホストに指示することができます。
システムにインストールされているOpenCL FPGAデバイスのリストを出力するようホストに指示するには、次のコード行をホスト・アプリケーションに追加します。
char buf[1024];
for (unsigned i = 0; i < ciDeviceCount; i++);
{
    clGetDeviceInfo(cdDevices[i], CL_DEVICE_NAME, 1023, buf, 0);
    printf("Device %d: '%s'\n", i, buf);
}
デバイス情報を照会すると、ホストは次のようにFPGAデバイスの一覧を表示します。

Device <N>: <board_name>: <name_of_FPGA_board>

以下が詳細になります。

  • <N> はデバイスの番号です。
  • <board_name> は、aocコマンドを呼び出す際にFPGAデバイスをターゲットにするボードの指定です。
  • <name_of_FPGA_board> は、FPGAボードに公示されている名前です。

例えばシステムに同一のFPGAボードが2つある場合、ホストは次のような出力を生成します。

Device 0: board_1: Stratix V FPGA Board
Device 1: board_1: Stratix V FPGA Board
注: clGetDeviceInfo関数は、 aoc -list-boards コマンドの呼び出し時にインテル FPGA SDK for OpenCLオフライン・コンパイラーが画面上に表示するボードタイプを返します (board_1など)。アクセラレーター・ボードにFPGAが複数含まれている場合、各デバイスは「ボード」として扱われ、一意の名前が付けられます。

複数のFPGAデバイスへのカーネルのロード

システムに複数のFPGAデバイスが含まれている場合、各FPGAに特定のcl_programオブジェクトを作成し、それらをOpenCL™ランタイムにロードすることができます。

次のホストコードは、複数のFPGAデバイスをプログラムするためのclCreateProgramWithBinaryと、createMultiDeviceProgram関数の使用方法を示しています。

cl_program createMultiDeviceProgram(cl_context context,
                                    const cl_device_id *device_list,
                                    cl_uint num_devices,
                                    const char *aocx_name);

// Utility function for loading file into Binary String
//
unsigned char* load_file(const char* filename, size_t *size_ret)
{
   FILE *fp = fopen(aocx_name,"rb");  
   fseek(fp,0,SEEK_END);
   size_t len = ftell(fp);
   char *result = (unsigned char*)malloc(sizeof(unsigned char)*len);
   rewind(fp);
   fread(result,len,1,fp);
   fclose(fp);   
   *size_ret = len;
   return result;
}

//Create a Program that is compiled for the devices in the "device_list"
//
cl_program createMultiDeviceProgram(cl_context context, 
                                    const cl_device_id *device_list, 
                                    cl_uint num_devices,
                                    const char *aocx_name)
{
    printf("creating multi device program %s for %d devices\n",
           aocx_name, num_devices);
    const unsigned char **binaries =
       (const unsigned char**)malloc(num_devices*sizeof(unsigned char*));
    size_t *lengths=(size_t*)malloc(num_devices*sizeof(size_t));
    cl_int err;
    
    for(cl_uint i=0; i<num_devices; i++)
    {
       binaries[i] = load_file(aocx_name,&lengths[i]);
       if (!binaries[i])
       {
          printf("couldn't load %s\n", aocx_name);
          exit(-1);
       }
    }

    cl_program p = clCreateProgramWithBinary(context, 
                                             num_devices, 
                                             device_list,
                                             lengths,
                                             binaries,
                                             NULL,
                                             &err);
    free(lengths);
    free(binaries);
    
    if (err != CL_SUCCESS)
    {
       printf("Program Create Error\n");
    }  
    return p;
}


// main program 

main () 
{
   // Normal OpenCL setup 
}
program = createMultiDeviceProgram(context,
                                   device_list,
                                   num_devices,
                                   "program.aocx");
clBuildProgram(program,num_devices,device_list,options,NULL,NULL);