如何在 OpenCL 中读取 .csv 文件

How to read a .csv file in OpenCL

我在OpenCL中写了host code。但是我首先需要 read 来自 .csv file. 的数据 我需要确保我在读取文件时所做的是正确的。 (我不确定这是不是在opencl中reding一个文件的方式)

1- 我把写在 c++ 中的 read file function 放在 main 之前。

2 - 然后,我将函数用于混合数据。同样在 main

之前

3-在main函数中,我调用上面两个函数读取数据,然后混合。

4- 然后我编写主机代码部分,其中包括(平台、设备、上下文、队列、缓冲区等)

这是我的代码:

 bool read_data_set(string filename, array<array<int, 20>, 5430>& array_X_dataset, array<int, 5430>& array_Y_dataset) {
    int field0, field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11,
        field12, field13, field14, field15, field16, field17, field18, field19, field20, field21;
    char comma;
    int line = 0;

    ifstream myfile(filename);

    if (myfile.is_open())
    {
        while (myfile
            >> field0 >> comma
            >> field1 >> comma
            >> field2 >> comma
            >> field3 >> comma
            >> field4 >> comma
            >> field5 >> comma
            >> field6 >> comma
            >> field7 >> comma
            >> field8 >> comma
            >> field9 >> comma
            >> field10 >> comma
            >> field11 >> comma
            >> field12 >> comma
            >> field13 >> comma
            >> field14 >> comma
            >> field15 >> comma
            >> field16 >> comma
            >> field17 >> comma
            >> field18 >> comma
            >> field19 >> comma
            >> field20 >> comma
            >> field21)
        {


            array<int, 20> inner_array{ field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11,
            field12, field13, field14, field15, field16, field17, field18, field19, field20 };
            array_X_dataset[line] = inner_array;
            array_Y_dataset[line] = field21;
            line++;

        }

        myfile.close();

    }
    else {
        cout << "Unable to open file";
        return true;
    }
    return false;
}

//functoin to randomly mix the dataset.
void mix_dataset(array<array<int, 20>, 5430>& array_X_dataset, array<int, 5430>& array_Y_dataset) {
    size_t len = array_X_dataset.size();
    for (size_t i = 0; i < len; ++i) {
        size_t swap_index = rand() % len;  // Random number between 0 and len-1.
        if (i == swap_index)
            continue;

        array<int, 20> data_point{  };
        data_point = array_X_dataset[i];
        array_X_dataset[i] = array_X_dataset[swap_index];
        array_X_dataset[swap_index] = data_point;
        int Y = array_Y_dataset[i];
        array_Y_dataset[i] = array_Y_dataset[swap_index];
        array_Y_dataset[swap_index] = Y;
    }
}
int main()
{
    // Read dataset from file.
    string filename = ".//Dataset.csv";
    static array<array<int, 20>, 5430> array_X_dataset{};
    static array<int, 5430> array_Y_dataset{};
    size_t rows = sizeof(array_X_dataset) / sizeof(array_X_dataset[0]);
    size_t cols = sizeof(array_X_dataset[0]) / sizeof(int);

    bool error = read_data_set(filename, array_X_dataset, array_Y_dataset);
    if (error) {
        cout << "Exiting with error while reading dataset file " << filename << endl;
        exit(-1);
    }
  
// Randomly mix the dataset and printout.
// Initialize the seed.
    srand(3);
    mix_dataset(array_X_dataset, array_Y_dataset);

    int array_X_set[5430][20];
    int array_Y_set[5430];

    // copy contents of the mixed std::arrays into plain arrays  
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++)
            array_X_set[i][j] = array_X_dataset[i][j];
        array_Y_set[i] = array_Y_dataset[i];
    }
    
    int X_train[4344][20] = {};
    int Y_train[4344] = {};
    int X_test[1086][20] = {};
    int Y_test[1086] = {};


    //split the dataset using 5 - fold cross validation
    float sum_accurecy = 0.0;
    int fold = 1;
   // cout << "inseret fold num " << endl;
    //cin >> fold;
    split_dataset(fold, array_X_set, array_Y_set, X_train, Y_train, X_test, Y_test);
        
//--------------------------host code--------------------------------------------------------------//

    // Search for an openCL platform
    cl_platform_id fpga_paltform = NULL;
    if (clGetPlatformIDs(1, &fpga_paltform, NULL) != CL_SUCCESS) {
    printf("Unable to get platform_id\n");
    return 1;
  }

    // Search for an openCL device
    cl_device_id fpga_device = NULL;
    if (clGetDeviceIDs(fpga_paltform, CL_DEVICE_TYPE_ALL, 1, &fpga_device, NULL) != CL_SUCCESS) {
    ..............
.................

   

简而言之,OpenCL编程模型包含两部分代码,在主机(CPU)上运行的主机代码(.c/.cpp..)和在设备上运行的内核代码(.cl)(例如:GPU..).

主机端:

  1. 您将初始化数据(就像您在任何 C 程序中所做的那样)
  2. 使用 clCreateBuffer() 创建缓冲区对象(将其视为在设备上保留内存)(类似地为输出分配)
  3. 使用clEnqueueWriteBuffer()将初始化后的数据发送到设备(到之前保留的space)
  4. 使用 clEnqueueNDRangeKernel() 调用内核(现在设备有内核代码和数据)

设备端:

  1. 执行内核代码
  2. 主机
  3. 将输出数据写入保留space

主机端:

  1. 设备完成其执行后,主机使用 clEnqueueReadBuffer() 从设备读取数据。

通过此流程,您已将计算卸载到设备并将输出读取到主机。

注意:

这个解释不是100%准确,我试着用更简单的方式来解释。我建议您阅读 (https://www.khronos.org/registry/OpenCL/specs/opencl-1.2.pdf)

中的第 3 章