//============================================================================================= 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()