LibreOCL/Lesson01/Part01/Prog01_01A/Prog01_01A.mq5
super.admin 10c769ed25 convert
2025-05-30 15:03:43 +02:00

150 lines
13 KiB
MQL5

//============================================================================================= MQL5 ===
// LibreOCL v1.002 (MQL5)
// Главный модуль обработки событий
// Librecoin(c)2014-2017
//============================================================================================= MQL5 ===
// REVIEWS
//------------------------------------------------------------------------------------------------------
// Пример программирования OpenCL.
//============================================================================================= MQL5 ===
// IDEAS
//------------------------------------------------------------------------------------------------------
// Заносим два значения в кернел, меняем местами и возвращаем обратно.
//============================================================================================= MQL5 ===
// PROPERTY
//------------------------------------------------------------------------------------------------------
#property copyright "Librecoin(c)2017"
#property version "1.002"
#property strict
//============================================================================================= MQL5 ===
// Код функций для OpenCL
//------------------------------------------------------------------------------------------------------
const string CL_Source =
"kernel void Exch(global double *ix) \r\n"
"{ \r\n"
" double z; \r\n"
" z=ix[0]; \r\n"
" ix[0]=ix[1]; \r\n"
" ix[1]=z; \r\n"
"} \r\n";
//
//============================================================================================= MQL5 ===
// Script program start function
//------------------------------------------------------------------------------------------------------
void OnStart()
{
//----- Исходный массив значений для перестановки
double x[2] = {1111.1, 9999.9};
//----- Распечатаем исходные значения элементов массива
Print("x[0]=", x[0], " x[1]=", x[1]);
//----- Хендлы для объектов OpenCL
int h_CL_Context; //Хендл контекста
int h_CL_Program; //Хендл программы
int h_CL_Kernel; //Хендл кернела
int h_CL_Buffer; //Хендл буфера
//----- Создание контекста (среды) для программы OpenCL (выбор девайса)
ResetLastError();
{
if((h_CL_Context = CLContextCreate(CL_USE_ANY)) == INVALID_HANDLE) //CL_USE_ANY - использовать любое доступное устройство с поддержкой OpenCL
{
Print("OpenCL not found, error:", GetLastError());
return;
}
else
{
Print("OpenCL found, Хендл на контекст OpenCL:", h_CL_Context, " Error:", GetLastError());
}
}//if((h_CL_Context=CLContextCreate(CL_USE_ANY))==INVALID_HANDLE)
//----- Создание в контексте программы на основе кода в строке CL_Source
ResetLastError();
string BuildLog = ""; //Лог компиляции
{
if((h_CL_Program = CLProgramCreate(h_CL_Context, CL_Source, BuildLog)) == INVALID_HANDLE) //В третьем параметре - лог компиляции
{
Print("OpenCL program create failed, error:", GetLastError(), " BuildLog=", BuildLog);
CLContextFree(h_CL_Context);
return;
}
else
{
Print("OpenCL program create, Хендл программы OpenCL:", h_CL_Program, " Error:", GetLastError());
}
}//if((h_CL_Program=CLProgramCreate(h_CL_Context,CL_Source,BuildLog))==INVALID_HANDLE)
//----- Создание кернела для расчета значений функции от двух переменных
ResetLastError();
{
if((h_CL_Kernel = CLKernelCreate(h_CL_Program, "Exch")) == INVALID_HANDLE) //Имя функции ("Exch") должно соответствовать имени в программной строке CL_Source
{
Print("OpenCL kernel create failed, error:", GetLastError());
CLProgramFree(h_CL_Program);
CLContextFree(h_CL_Context);
return;
}
else
{
Print("OpenCL kernel create, Хендл кернела OpenCL:", h_CL_Kernel, " Error:", GetLastError());
}
}//if((h_CL_Kernel=CLKernelCreate(h_CL_Program,"Exch"))==INVALID_HANDLE)
//----- Создание буфера OpenCL для получения значений функции
ResetLastError();
{
if((h_CL_Buffer = CLBufferCreate(h_CL_Context, ArraySize(x) * sizeof(double), CL_MEM_READ_WRITE)) == INVALID_HANDLE)
{
Print("OpenCL buffer create failed, error:", GetLastError());
CLKernelFree(h_CL_Kernel);
CLProgramFree(h_CL_Program);
CLContextFree(h_CL_Context);
return;
}
else
{
Print("OpenCL buffer create, Хендл буфера OpenCL:", h_CL_Buffer, " Error:", GetLastError());
}
}//if((h_CL_Buffer=CLBufferCreate(h_CL_Context,ArraySize(x)*sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE)
//----- Записываем исходные значения в буфер
Print("В буфер записано ", CLBufferWrite(h_CL_Buffer, x), " элементов");
//----- Передаём значения буфера по хендлу h_CL_Buffer в кернел
ResetLastError();
{
if(!CLSetKernelArgMem(h_CL_Kernel, 0, h_CL_Buffer))
{
Print("OpenCL set buffer failed, error:", GetLastError());
CLBufferFree(h_CL_Buffer);
CLKernelFree(h_CL_Kernel);
CLProgramFree(h_CL_Program);
CLContextFree(h_CL_Context);
return;
}
else
{
Print("OpenCL set buffer, error:", GetLastError());
}
}//if(CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffer))
//----- Запускаем выполнение кернела
ResetLastError();
{
if(!CLExecute(h_CL_Kernel))
{
Print("OpenCL execute failed, error:", GetLastError());
CLBufferFree(h_CL_Buffer);
CLKernelFree(h_CL_Kernel);
CLProgramFree(h_CL_Program);
CLContextFree(h_CL_Context);
return;
}
else
{
Print("OpenCL execute, error:", GetLastError());
}
}//if(!CLExecute(h_CL_Kernel))
//----- Считываем полученные значения в массив x
Print("Из буфера прочитано ", CLBufferRead(h_CL_Buffer, x), " элементов");
//----- Распечатываем полученные значения элементов массива
Print("x[0]=", x[0], " x[1]=", x[1]);
//----- Удаляем объекты OpenCL
CLBufferFree(h_CL_Buffer);
CLKernelFree(h_CL_Kernel);
CLProgramFree(h_CL_Program);
CLContextFree(h_CL_Context);
return;
}//OnStart()