NeuroNetworksBook/Include/realization/opencl.mqh

173 lines
14 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:12:34 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| opencl.mqh |
//| Copyright 2021, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| >4:;NG05< 181;8>B5:8 |
//+------------------------------------------------------------------+
#include <OpenCL\OpenCL.mqh>
//+------------------------------------------------------------------+
//| Class CMyOpenCL |
//| 07=0G5=85: ;0AA >@30=870F88 @01>BK A :>=B5:AB>< OpenCL |
//+------------------------------------------------------------------+
class CMyOpenCL : public COpenCL
{
public:
CMyOpenCL(void) {};
~CMyOpenCL(void) {};
template<typename T>
int AddBufferFromArray(T &data[], const uint data_array_offset, const uint data_array_count, const uint flags);
int AddBufferFromArray(matrix &data, const uint data_array_offset, const uint flags);
bool CheckBuffer(const int index);
//---
bool BufferFromMatrix(const int buffer_index, MATRIX &data, const uint data_array_offset, const uint flags);
bool BufferRead(const int buffer_index, MATRIX &data, const uint cl_buffer_offset);
bool BufferWrite(const int buffer_index, MATRIX &data, const uint cl_buffer_offset);
};
//+------------------------------------------------------------------+
//| 5B>4 A>740=8O 1CD5@0 2 :>=B5:AB5 OpenCL |
//+------------------------------------------------------------------+
template<typename T>
int CMyOpenCL::AddBufferFromArray(T &data[], const uint data_array_offset, const uint data_array_count, const uint flags)
{
//--- >8A5 A2>1>4=>3> M;5<5=B0 2 48=0<8G5A:>< <0AA825 C:070B5;59
int result = -1;
for(int i = 0; i < m_buffers_total; i++)
{
if(m_buffers[i] != INVALID_HANDLE)
continue;
result = i;
break;
}
//--- A;8 2A>1>4=K9 M;5<5=B=5 =0945= 4>102;O5< =>2K9 M;5<5= 2 <0AA82
if(result < 0)
{
if(ArrayResize(m_buffers, m_buffers_total + 1) > 0)
{
m_buffers_total = ArraySize(m_buffers);
result = m_buffers_total - 1;
m_buffers[result] = INVALID_HANDLE;
}
else
return result;
}
//--- !>740Q< 1CD5@ 2 :>=B5:AB5 OpenCL
if(!BufferFromArray(result, data, data_array_offset, data_array_count, flags))
return -1;
//---
return result;
}
//+------------------------------------------------------------------+
//| 5B>4 A>740=8O 1CD5@0 2 :>=B5:AB5 OpenCL |
//+------------------------------------------------------------------+
int CMyOpenCL::AddBufferFromArray(matrix &data, const uint data_array_offset, const uint flags)
{
//--- >8A5 A2>1>4=>3> M;5<5=B0 2 48=0<8G5A:>< <0AA825 C:070B5;59
int result = -1;
for(int i = 0; i < m_buffers_total; i++)
{
if(m_buffers[i] != INVALID_HANDLE)
continue;
result = i;
break;
}
//--- A;8 2A>1>4=K9 M;5<5=B=5 =0945= 4>102;O5< =>2K9 M;5<5= 2 <0AA82
if(result < 0)
{
if(ArrayResize(m_buffers, m_buffers_total + 1) > 0)
{
m_buffers_total = ArraySize(m_buffers);
result = m_buffers_total - 1;
m_buffers[result] = INVALID_HANDLE;
}
else
return result;
}
//--- !>740Q< 1CD5@ 2 :>=B5:AB5 OpenCL
if(!BufferFromMatrix(result, data, data_array_offset, flags))
return -1;
return result;
}
//+------------------------------------------------------------------+
//| 5B>4 ?@>25@:8 459AB28B5;L=>AB8 C:070B5;O =0 1CD5@ ?> 8=45:AC |
//| 2 48=0<8G5A:>< <0AA825 |
//+------------------------------------------------------------------+
bool CMyOpenCL::CheckBuffer(const int index)
{
if(index < 0 || index > m_buffers_total)
return false;
return m_buffers[index] != INVALID_HANDLE;
}
//+------------------------------------------------------------------+
//| BufferFromMatrix |
//+------------------------------------------------------------------+
bool CMyOpenCL::BufferFromMatrix(const int buffer_index, MATRIX &data, const uint data_array_offset, const uint flags)
{
//--- check parameters
if(m_context == INVALID_HANDLE || m_program == INVALID_HANDLE)
return(false);
if(buffer_index < 0 || buffer_index >= m_buffers_total)
return(false);
//--- buffer does not exists, create it
if(m_buffers[buffer_index] == INVALID_HANDLE)
{
uint size_in_bytes = (typename(MATRIX)=="matrix" ? sizeof(double) : sizeof(float))*(int)(data.Rows()*data.Cols());
int buffer_handle = CLBufferCreate(m_context, size_in_bytes, flags);
if(buffer_handle != INVALID_HANDLE)
{
m_buffers[buffer_index] = buffer_handle;
}
else
return(false);
}
//--- write data to OpenCL buffer
ResetLastError();
if(!CLBufferWrite(m_buffers[buffer_index], data_array_offset, data))
{
PrintFormat("Write to buffer error %d", GetLastError());
return(false);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| BufferRead |
//+------------------------------------------------------------------+
bool CMyOpenCL::BufferRead(const int buffer_index, MATRIX &data, const uint cl_buffer_offset)
{
//--- check parameters
if(buffer_index < 0 || buffer_index >= m_buffers_total || data.Rows() <= 0)
return(false);
if(m_buffers[buffer_index] == INVALID_HANDLE)
return(false);
if(m_context == INVALID_HANDLE || m_program == INVALID_HANDLE)
return(false);
//--- read data from OpenCL buffer
if(!CLBufferRead(m_buffers[buffer_index], cl_buffer_offset, data))
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| BufferWrite |
//+------------------------------------------------------------------+
bool CMyOpenCL::BufferWrite(const int buffer_index, MATRIX &data, const uint cl_buffer_offset)
{
//--- check parameters
if(buffer_index < 0 || buffer_index >= m_buffers_total || data.Rows() <= 0)
return(false);
if(m_buffers[buffer_index] == INVALID_HANDLE)
return(false);
if(m_context == INVALID_HANDLE || m_program == INVALID_HANDLE)
return(false);
//--- write data to OpenCL buffer
if(!CLBufferWrite(m_buffers[buffer_index], cl_buffer_offset, data))
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+