如何在 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..).
主机端:
- 您将初始化数据(就像您在任何 C 程序中所做的那样)
- 使用 clCreateBuffer() 创建缓冲区对象(将其视为在设备上保留内存)(类似地为输出分配)
- 使用clEnqueueWriteBuffer()将初始化后的数据发送到设备(到之前保留的space)
- 使用 clEnqueueNDRangeKernel() 调用内核(现在设备有内核代码和数据)
设备端:
- 执行内核代码
- 主机
将输出数据写入保留space
主机端:
- 设备完成其执行后,主机使用 clEnqueueReadBuffer() 从设备读取数据。
通过此流程,您已将计算卸载到设备并将输出读取到主机。
注意:
这个解释不是100%准确,我试着用更简单的方式来解释。我建议您阅读 (https://www.khronos.org/registry/OpenCL/specs/opencl-1.2.pdf)
中的第 3 章
我在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..).
主机端:
- 您将初始化数据(就像您在任何 C 程序中所做的那样)
- 使用 clCreateBuffer() 创建缓冲区对象(将其视为在设备上保留内存)(类似地为输出分配)
- 使用clEnqueueWriteBuffer()将初始化后的数据发送到设备(到之前保留的space)
- 使用 clEnqueueNDRangeKernel() 调用内核(现在设备有内核代码和数据)
设备端:
- 执行内核代码
- 主机 将输出数据写入保留space
主机端:
- 设备完成其执行后,主机使用 clEnqueueReadBuffer() 从设备读取数据。
通过此流程,您已将计算卸载到设备并将输出读取到主机。
注意:
这个解释不是100%准确,我试着用更简单的方式来解释。我建议您阅读 (https://www.khronos.org/registry/OpenCL/specs/opencl-1.2.pdf)
中的第 3 章