167 lines
13 KiB
MQL5
167 lines
13 KiB
MQL5
//============================================================================================= MQL5 ===
|
|
// LibreOCL v1.003 (MQL5)
|
|
// Главный модуль обработки событий
|
|
// Librecoin(c)2014-2017
|
|
//============================================================================================= MQL5 ===
|
|
// REVIEWS
|
|
//------------------------------------------------------------------------------------------------------
|
|
// Пример программирования OpenCL.
|
|
//============================================================================================= MQL5 ===
|
|
// IDEAS
|
|
//------------------------------------------------------------------------------------------------------
|
|
// Заносим два значения в кернел, меняем местами и возвращаем обратно.
|
|
//============================================================================================= MQL5 ===
|
|
// PROPERTY
|
|
//------------------------------------------------------------------------------------------------------
|
|
#property copyright "Librecoin(c)2017"
|
|
#property version "1.003"
|
|
#property strict
|
|
#resource "Kernels/Prog01_01B.cl" as string CL_Source//Код кернел-программ можно подключать как ресурс
|
|
//
|
|
//============================================================================================= MQL5 ===
|
|
// Script program start function
|
|
//------------------------------------------------------------------------------------------------------
|
|
void OnStart()
|
|
{
|
|
//CL_USE_ANY = -1;
|
|
//CL_USE_GPU_ONLY = -2;
|
|
//CL_USE_CPU_ONLY = -3;
|
|
//CL_USE_GPU_DOUBLE_ONLY = -4;
|
|
//---
|
|
//----- Включатель отладочной печати
|
|
bool PrintDebugSelector = true;
|
|
//----- Исходный массив значений для перестановки
|
|
double x[] = {1111.1, 9999.9};
|
|
//----- Распечатаем исходные значения элементов массива
|
|
Print("x[0]=", x[0], " x[1]=", x[1]);
|
|
//----- Хендлы для объектов OpenCL
|
|
int h_CL_Context = INVALID_HANDLE; //Хендл контекста
|
|
int h_CL_Program = INVALID_HANDLE; //Хендл программы
|
|
int h_CL_Kernel = INVALID_HANDLE; //Хендл кернела
|
|
int h_CL_Buffer = INVALID_HANDLE; //Хендл буфера
|
|
//----- Создание контекста (среды) для программы OpenCL (выбор девайса)
|
|
{
|
|
if((h_CL_Context = CLContextCreate(CL_USE_GPU_DOUBLE_ONLY)) == INVALID_HANDLE) //CL_USE_ANY - использовать любое доступное устройство с поддержкой OpenCL
|
|
{
|
|
ShutDown(h_CL_Context, h_CL_Program, h_CL_Kernel, h_CL_Buffer);
|
|
return;
|
|
}
|
|
}//if((h_CL_Context=CLContextCreate(CL_USE_ANY))==INVALID_HANDLE)
|
|
//----- Создание в контексте программы на основе кода в строке CL_Source
|
|
string BuildLog = ""; //Лог компиляции
|
|
{
|
|
if((h_CL_Program = CLProgramCreate(h_CL_Context, CL_Source, BuildLog)) == INVALID_HANDLE) //В третьем параметре - лог компиляции
|
|
{
|
|
ShutDown(h_CL_Context, h_CL_Program, h_CL_Kernel, h_CL_Buffer, BuildLog, PrintDebugSelector);
|
|
return;
|
|
}
|
|
}//if((h_CL_Program=CLProgramCreate(h_CL_Context,CL_Source,BuildLog))==INVALID_HANDLE)
|
|
//----- Создание кернела для расчета значений функции от двух переменных
|
|
{
|
|
if((h_CL_Kernel = CLKernelCreate(h_CL_Program, "Exch")) == INVALID_HANDLE) //Имя функции ("Exch") должно соответствовать имени в программной строке CL_Source
|
|
{
|
|
ShutDown(h_CL_Context, h_CL_Program, h_CL_Kernel, h_CL_Buffer);
|
|
return;
|
|
}
|
|
}//if((h_CL_Kernel=CLKernelCreate(h_CL_Program,"Exch"))==INVALID_HANDLE)
|
|
//----- Создание буфера OpenCL для получения значений функции
|
|
{
|
|
if((h_CL_Buffer = CLBufferCreate(h_CL_Context, ArraySize(x) * sizeof(double), CL_MEM_READ_WRITE)) == INVALID_HANDLE)
|
|
{
|
|
ShutDown(h_CL_Context, h_CL_Program, h_CL_Kernel, h_CL_Buffer);
|
|
return;
|
|
}
|
|
}//if((h_CL_Buffer=CLBufferCreate(h_CL_Context,ArraySize(x)*sizeof(double),CL_MEM_READ_WRITE))==INVALID_HANDLE)
|
|
//----- Записываем исходные значения в буфер
|
|
{
|
|
if(CLBufferWrite(h_CL_Buffer, x) <= 0)
|
|
{
|
|
ShutDown(h_CL_Context, h_CL_Program, h_CL_Kernel, h_CL_Buffer);
|
|
return;
|
|
}
|
|
}//if(CLBufferWrite(h_CL_Buffer,x)<=0)
|
|
//----- Передаём значения буфера по хендлу h_CL_Buffer в кернел
|
|
{
|
|
if(!CLSetKernelArgMem(h_CL_Kernel, 0, h_CL_Buffer))
|
|
{
|
|
ShutDown(h_CL_Context, h_CL_Program, h_CL_Kernel, h_CL_Buffer);
|
|
return;
|
|
}
|
|
}//if(CLSetKernelArgMem(h_CL_Kernel,0,h_CL_Buffer))
|
|
//----- Запускаем выполнение кернела
|
|
if(!CLExecute(h_CL_Kernel))
|
|
{
|
|
ShutDown(h_CL_Context, h_CL_Program, h_CL_Kernel, h_CL_Buffer);
|
|
return;
|
|
}
|
|
//if(!CLExecute(h_CL_Kernel))
|
|
//----- Считываем полученные значения в массив x
|
|
Print("Из буфера прочитано ", CLBufferRead(h_CL_Buffer, x), " элементов");
|
|
//----- Распечатываем полученные значения элементов массива
|
|
Print("x[0]=", x[0], " x[1]=", x[1]);
|
|
//----- Удаляем объекты OpenCL
|
|
ShutDown(h_CL_Context, h_CL_Program, h_CL_Kernel, h_CL_Buffer);
|
|
return;
|
|
}//OnStart()
|
|
//
|
|
//============================================================================================= MQL5 ===
|
|
// ShutDown() function
|
|
//------------------------------------------------------------------------------------------------------
|
|
void ShutDown(
|
|
int &i_CL_Context,
|
|
int &i_CL_Program,
|
|
int &i_CL_Kernel,
|
|
int &i_CL_Buffer,
|
|
const string i_BuildLog = "",
|
|
const bool i_PrintDebugSelector = false
|
|
)
|
|
{
|
|
//----- Build Log Print
|
|
{
|
|
if((i_PrintDebugSelector) && (i_BuildLog != ""))
|
|
{
|
|
string LogLines[];
|
|
StringSplit(i_BuildLog, '\n', LogLines);
|
|
int LogLinesCount = ArraySize(LogLines);
|
|
{
|
|
for(int i = 0; i < LogLinesCount; i++)
|
|
{
|
|
Print(LogLines[i]);
|
|
}
|
|
}//for(int i=0; i<LogLinesCount; i++)
|
|
}
|
|
}//if((i_PrintDebugSelector)&&(i_BuildLog!=""))
|
|
//----- Remove buffer
|
|
{
|
|
if(i_CL_Buffer != INVALID_HANDLE)
|
|
{
|
|
CLBufferFree(i_CL_Buffer);
|
|
i_CL_Buffer = INVALID_HANDLE;
|
|
}
|
|
}//if(i_CL_Buffer!=INVALID_HANDLE)
|
|
//---- Remove kernel
|
|
{
|
|
if(i_CL_Kernel != INVALID_HANDLE)
|
|
{
|
|
CLKernelFree(i_CL_Kernel);
|
|
i_CL_Kernel = INVALID_HANDLE;
|
|
}
|
|
}//if(i_CL_Kernel!=INVALID_HANDLE)
|
|
//----- Remove program
|
|
{
|
|
if(i_CL_Program != INVALID_HANDLE)
|
|
{
|
|
CLProgramFree(i_CL_Program);
|
|
i_CL_Program = INVALID_HANDLE;
|
|
}
|
|
}//if(m_program!=INVALID_HANDLE)
|
|
//----- Remove context
|
|
{
|
|
if(i_CL_Context != INVALID_HANDLE)
|
|
{
|
|
CLContextFree(i_CL_Context);
|
|
i_CL_Context = INVALID_HANDLE;
|
|
}
|
|
}//if(m_context!=INVALID_HANDLE)
|
|
}//ShutDown()
|
|
//
|