Opencl MQL5错误中的数组访问无效
我试图访问通过调用签名传递到系统调用的Opencl MQL5错误中的数组访问无效,opencl,mql5,metatrader5,Opencl,Mql5,Metatrader5,我试图访问通过调用签名传递到系统调用的OnCalculation()事件处理程序中的数组 它是这样写的: int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[],
OnCalculation()
事件处理程序中的数组
它是这样写的:
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[]
)
{
/* The rest code is written here
...
*/
}
我正在尝试将代码与OpenCL函数合并,以便程序使用GPU进行大量计算。但问题是,当我试图将OnCalculation()
中的值传递给内核执行时,会出现错误。请参阅OnCalculation()中编写的以下代码
获取以下错误:
'time'-无效的数组访问ADX.mq5 285 31
“高”-无效的阵列访问ADX.mq5 286 31
“低”-无效的阵列访问ADX.mq5 287 31
我不知道为什么会发生这个问题。我无法从OnCalculation()
传递数组
请帮我做些什么?这里不可能只引用MQL5array[]
对象
OpenCL启动了一个全新的代码执行生态系统,MQL5端数据必须在那里和后面正确地“传输”
使用将接收到的阵列加倍的模拟普通GPU内核:
const string // by default some GPU doesn't support doubles
cl_SOURCE = "#pragma OPENCL EXTENSION cl_khr_fp64 : enable \r\n" // cl_khr_fp64 directive is used to enable work with doubles
" \r\n"
"__kernel void Test_GPU( __global double *data, \r\n" // [0]____GPU-kernel-side_CALL-SIGNATURE
" const int N, \r\n" // [1]____GPU-kernel-side_CALL-SIGNATURE
" const int N_arrays \r\n" // [2]____GPU-kernel-side_CALL-SIGNATURE
" ) \r\n"
"{ \r\n"
" uint kernel_index = get_global_id( 0 ); \r\n"
" if ( kernel_index > N_arrays ) return; \r\n"
" \r\n"
" uint local_start_offset = kernel_index * N; \r\n"
" for ( int i = 0; i < N; i++ ) \r\n"
" data[i+local_start_offset] *= 2.0; \r\n"
"} \r\n";
// AFTER FIRST TESTING THE OpenCL DEVICES & THEIR CAPABILITIES ... ( see prev. posts )
#define ARRAY_SIZE 100 // size of the array
#define TOTAL_ARRAYS 5 // total arrays
// ONE CAN:
//--- SET OpenCL-specific handles' holders
int cl_CONTEXT, // an OpenCL-Context handle
cl_PROGRAM, // an OpenCL-Program handle
cl_KERNEL, // an OpenCL Device-Kernel handle
cl_BUFFER; // an OpenCL-buffer handle
uint cl_offset[] = { 0 }; //--- prepare CLExecute() params
uint cl_work[] = { TOTAL_ARRAYS }; //--- global work size
double DataArray2[]; //--- global mapping-object for data aimed to reach the GPU
ArrayResize( DataArray2, //--- size it to fit data in
ARRAY_SIZE * TOTAL_ARRAYS
);
for ( int j = 0; j < TOTAL_ARRAYS; j++ ) //--- fill mapped-arrays with data
{ uint local_offset = j * ARRAY_SIZE; //--- set local start offset for j-th array
for ( int i = 0; i < ARRAY_SIZE; i++ ) //--- for j-th array
DataArray2[i+local_offset] = MathCos(i+j); //--- fill array with some data
}
谢谢,但这是什么DataArray2
?是我试图传递给内核的存储阵列吗?哦,当然是,一个映射对象,也就是说,可以将多个数据区域存储到其中(使用一些((zone\u I\u offset,zone\u I\u dtype,zone\u size),…)
(de-)映射描述符),但传递一个这样的数组[]
使用记录在案的系统间接口服务连接到OpenCL eco系统。这是一个伟大而强大的工具,不是吗?是否可以使用CLBufferWrite
并将其传递给内核进行处理?你能分享一下你的想法吗?
const string // by default some GPU doesn't support doubles
cl_SOURCE = "#pragma OPENCL EXTENSION cl_khr_fp64 : enable \r\n" // cl_khr_fp64 directive is used to enable work with doubles
" \r\n"
"__kernel void Test_GPU( __global double *data, \r\n" // [0]____GPU-kernel-side_CALL-SIGNATURE
" const int N, \r\n" // [1]____GPU-kernel-side_CALL-SIGNATURE
" const int N_arrays \r\n" // [2]____GPU-kernel-side_CALL-SIGNATURE
" ) \r\n"
"{ \r\n"
" uint kernel_index = get_global_id( 0 ); \r\n"
" if ( kernel_index > N_arrays ) return; \r\n"
" \r\n"
" uint local_start_offset = kernel_index * N; \r\n"
" for ( int i = 0; i < N; i++ ) \r\n"
" data[i+local_start_offset] *= 2.0; \r\n"
"} \r\n";
// AFTER FIRST TESTING THE OpenCL DEVICES & THEIR CAPABILITIES ... ( see prev. posts )
#define ARRAY_SIZE 100 // size of the array
#define TOTAL_ARRAYS 5 // total arrays
// ONE CAN:
//--- SET OpenCL-specific handles' holders
int cl_CONTEXT, // an OpenCL-Context handle
cl_PROGRAM, // an OpenCL-Program handle
cl_KERNEL, // an OpenCL Device-Kernel handle
cl_BUFFER; // an OpenCL-buffer handle
uint cl_offset[] = { 0 }; //--- prepare CLExecute() params
uint cl_work[] = { TOTAL_ARRAYS }; //--- global work size
double DataArray2[]; //--- global mapping-object for data aimed to reach the GPU
ArrayResize( DataArray2, //--- size it to fit data in
ARRAY_SIZE * TOTAL_ARRAYS
);
for ( int j = 0; j < TOTAL_ARRAYS; j++ ) //--- fill mapped-arrays with data
{ uint local_offset = j * ARRAY_SIZE; //--- set local start offset for j-th array
for ( int i = 0; i < ARRAY_SIZE; i++ ) //--- for j-th array
DataArray2[i+local_offset] = MathCos(i+j); //--- fill array with some data
}
//--- INIT OpenCL
if ( INVALID_HANDLE == ( cl_CONTEXT = CLContextCreate() ) )
{ Print( "EXC: CLContextCreate() error = ", GetLastError() );
return( 1 ); // ---------------^ EXC/RET
}
//--- NEXT create OpenCL program
if ( INVALID_HANDLE == ( cl_PROGRAM = CLProgramCreate( cl_CONTEXT,
cl_SOURCE
)
)
)
{ Print( "EXC: CLProgrameCreate() error = ", GetLastError() );
CLContextFree( cl_CONTEXT );
return( 1 ); // ----------------^ EXC/RET
}
//--- NEXT create OpenCL kernel
if ( INVALID_HANDLE == ( cl_KERNEL = CLKernelCreate( cl_PROGRAM,
"Test_GPU"
)
)
)
{ Print( "EXC: CLKernelCreate() error = ", GetLastError() );
CLProgramFree( cl_PROGRAM );
CLContextFree( cl_CONTEXT );
return( 1 ); // --------------^ EXC/RET
}
//--- TRY: create an OpenCL cl_BUFFER object mapping
if ( INVALID_HANDLE == ( cl_BUFFER = CLBufferCreate( cl_CONTEXT,
(uint) ( ARRAY_SIZE * TOTAL_ARRAYS * sizeof( double ),
CL_MEM_READ_WRITE
)
)
)
{ Print( "EXC: CLBufferCreate() error == ", GetLastError() );
CLKernelFree( cl_KERNEL );
CLProgramFree( cl_PROGRAM );
CLContextFree( cl_CONTEXT );
return(1); // ----------------^ EXC/RET
}
//--- NEXT: set OpenCL cl_KERNEL GPU-side-kernel call-parameters
CLSetKernelArgMem( cl_KERNEL, 0, cl_BUFFER ); // [0]____GPU-kernel-side_CALL-SIGNATURE
CLSetKernelArg( cl_KERNEL, 1, ARRAY_SIZE ); // [1]____GPU-kernel-side_CALL-SIGNATURE
CLSetKernelArg( cl_KERNEL, 2, TOTAL_ARRAYS ); // [2]____GPU-kernel-side_CALL-SIGNATURE
//--- NEXT: write data into to OpenCL cl_BUFFER mapping-object
CLBufferWrite( cl_BUFFER,
DataArray2
);
//--- MAY execute OpenCL kernel
CLExecute( cl_KERNEL, 1, cl_offset, cl_work );
//--- MAY read data back, from OpenCL cl_BUFFER mapping-object
CLBufferRead( cl_BUFFER, DataArray2 );
CLBufferFree( cl_BUFFER ); //--- FINALLY free OpenCL buffer cl_BUFFER mapping-object
CLKernelFree( cl_KERNEL ); //--- FINALLY free OpenCL kernel object
CLProgramFree( cl_PROGRAM ); //--- FINALLY free OpenCL programme object / handle
CLContextFree( cl_CONTEXT ); //--- FINALLY free OpenCL cl_CONTEXT object / handle