Converting native function of MQL5 to GPU using OpenCL
Asked Answered
T

0

6

I have written a function in MQL5 for creating an indicator. Here I am attached the indicator file.

Here is the OnCalculate() of the indicator:

int OnCalculate(const int rates_total, const int prev_calculated,const int begin,const double &price[])
  {
//--- check for bars count

   if(rates_total<InpMAPeriod-1+begin)
      return(0);// not enough bars for calculation
//--- first calculation or number of bars was changed
   if(prev_calculated==0)

      ArrayInitialize(ExtLineBuffer,0);      


//--- sets first bar from what index will be draw
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod-1+begin);

  switch(InpMAMethod)
     {
      case MODE_EMA:  //CalculateEMA(rates_total,prev_calculated,begin,price);        

      Execute_Me(price,"CalculateEMA",rates_total,prev_calculated,begin);


      break;
      case MODE_LWMA: //CalculateLWMA(rates_total,prev_calculated,begin,price);       

      Execute_Me(price,"CalculateLWMA",rates_total,prev_calculated,begin);

      break;
      case MODE_SMMA: //CalculateSmoothedMA(rates_total,prev_calculated,begin,price);
      Execute_Me(price,"CalculateSmoothedMA",rates_total,prev_calculated,begin);

      break;
      case MODE_SMA:  

              Execute_Me(price,"CalculateSimpleMA",rates_total,prev_calculated,begin);      
           break;
     }
return(rates_total);
  }

Kindly, help me in converting the function to GPU based instead of CPU based. Else let me know the suggestion for using the GPU of my system.

On Request, EDITED:

int Execute_Me(
                 const double &price[],
                 string Function_Name_In_Kernel,
                 int rates_total,
                 int prev_calculated,
                 int begin
                 )
 {
   string str;   
   int cl_ctx = CLContextCreate(CL_USE_GPU_ONLY);
   int cl_prg=CLProgramCreate(cl_ctx,cl_program,str);
   int cl_krn=0;
   int cl_mem=CLBufferCreate(cl_ctx,ArraySize(price)*sizeof(double),CL_MEM_READ_WRITE), 
       cl_price=CLBufferCreate(cl_ctx,ArraySize(price)*sizeof(double),CL_MEM_READ_WRITE);


   //--- calculation
   int  offset[3]={0,0};
   int  work  [3]={512,512};
   if(cl_ctx==INVALID_HANDLE)
     {
      Print("OpenCL not found: ", GetLastError() );
      return(0);

     }

   //if(CLGetInfoString(cl_ctx,CL_DEVICE_NAME,str)) 
   //   Print("OpenCL device name: ",str);
   if(cl_prg==INVALID_HANDLE)
     {
      CLContextFree(cl_ctx);

      Print("OpenCL program create failed: ", str);
      return(0);
     }
     if(cl_prg==ERR_INVALID_PARAMETER )
     {
      CLContextFree(cl_ctx);

      Print("OpenCL program create failed: ", str);
      return(0);
     }
     if(cl_prg==ERR_NOT_ENOUGH_MEMORY )
     {
      CLContextFree(cl_ctx);

      Print("OpenCL program create failed: ", str);
      return(0);
     }
     if(cl_prg==ERR_OPENCL_PROGRAM_CREATE )
     {
      CLContextFree(cl_ctx);

      Print("OpenCL program create failed: ", str);
      return(0);
     }

     cl_krn = CLKernelCreate(cl_prg,Function_Name_In_Kernel);
           if(cl_krn==ERR_OPENCL_INVALID_HANDLE )
           {
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               Print("OpenCL kernel create failed : ERR_OPENCL_INVALID_HANDLE");
               return(0);
           }
           if(cl_krn==ERR_INVALID_PARAMETER )
           {
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               Print("OpenCL kernel create failed : ERR_INVALID_PARAMETER");
               return(0);
           }
           if(cl_krn==ERR_OPENCL_TOO_LONG_KERNEL_NAME  )
           {
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               Print("OpenCL kernel create failed : ERR_OPENCL_TOO_LONG_KERNEL_NAME");
               return(0);
           }
           if(cl_krn==ERR_OPENCL_KERNEL_CREATE )
           {
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               Print("OpenCL kernel create failed : ERR_OPENCL_KERNEL_CREATE");
               return(0);
           }

           if(cl_mem==INVALID_HANDLE)
           {
               CLKernelFree(cl_krn);
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               Print("OpenCL buffer create failed: cl_mem INVALID_HANDLE");
               return(0);
           }
           if(cl_mem==ERR_NOT_ENOUGH_MEMORY )
           {
               CLKernelFree(cl_krn);
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               Print("OpenCL buffer create failed: cl_mem ERR_NOT_ENOUGH_MEMORY ");
               return(0);
           }
           if(cl_mem==ERR_OPENCL_BUFFER_CREATE )
           {
               CLKernelFree(cl_krn);
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               Print("OpenCL buffer create failed: cl_mem ERR_OPENCL_BUFFER_CREATE ");
               return(0);
           }

           if(cl_price==INVALID_HANDLE)
           {
               CLKernelFree(cl_krn);
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               CLBufferFree(cl_mem);
               Print("OpenCL buffer create failed: cl_price ");
               return(0);
           }
           if(cl_price==ERR_NOT_ENOUGH_MEMORY)
           {
               CLKernelFree(cl_krn);
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               CLBufferFree(cl_mem);
               Print("OpenCL buffer create failed: cl_price ERR_NOT_ENOUGH_MEMORY");
               return(0);
           }
           if(cl_price==ERR_OPENCL_BUFFER_CREATE)
           {
               CLKernelFree(cl_krn);
               CLProgramFree(cl_prg);
               CLContextFree(cl_ctx);
               CLBufferFree(cl_mem);
               Print("OpenCL buffer create failed: cl_price ERR_OPENCL_BUFFER_CREATE ");
               return(0);
           }

           if(!CLSetKernelArgMem(cl_krn,4,cl_price))
            Print("Input Bufer Not Set");
          //else Print("Input Buffer Set");
           if(!CLSetKernelArgMem(cl_krn,5,cl_mem))
            Print("Output Bufer Not Set");
           //else Print("Output Buffer Set");

           if(!CLBufferWrite(cl_price, price))
           Print("Could not copy Input buffer"); 
           //else Print("Copied: ",cl_price);    
           if(!CLBufferWrite(cl_mem, ExtLineBuffer))
           Print("Could not copy Input buffer"); 
           //else Print("Copied: ",cl_mem);  

           //else Print("Input Buffer Copied");
           if(!CLSetKernelArg(cl_krn,0,rates_total))
           Print("Could Not Set Arg 0");
           //else Print("Set Arg 0");
           if(!CLSetKernelArg(cl_krn,1,prev_calculated))
           Print("Could Not Set Arg 1");
           //else Print("Set Arg 1");
           if(!CLSetKernelArg(cl_krn,2,begin))
           Print("Could Not Set Arg2");
           //else Print("Set Arg 2");
           if(!CLSetKernelArg(cl_krn,3,InpMAPeriod))
           Print("Could Not Set Arg3: ",GetLastError());


           //else Print("Set Arg 3");
           //CLSetKernelArg(cl_krn,4,cl_price);

           if(!CLExecute(cl_krn))//,1,offset,work))
           Print("Kernel not executed",GetLastError());
           //else Print("Executing Now!");
           //if(CLExecutionStatus(cl_krn) == 0) Print("Completed");
           //if(CLExecutionStatus(cl_krn) == 1) Print("CL_RUNNING");
           //if(CLExecutionStatus(cl_krn) == 2) Print("CL_SUBMITTED");
           //if(CLExecutionStatus(cl_krn) == 3) Print("CL_QUEUED");
           //if(CLExecutionStatus(cl_krn) == -1)Print("Error Occurred:", GetLastError());

           if(!CLBufferRead(cl_mem,ExtLineBuffer))
           Print("Buffer Copy Nothing: ", GetLastError());

      CLBufferFree(cl_price);
      CLBufferFree(cl_mem);
      CLKernelFree(cl_krn);
      CLProgramFree(cl_prg);
      CLContextFree(cl_ctx);


  return(1);
 } 

Here is the Kernel file: Opencl Kernel for the program

Takeover answered 25/4, 2018 at 10:17 Comment(5)
of course we need to see Execute_Me() function to make any judgment, and by the way, it is really a bad idea to pass parameters by string, especially if you want to speed up the process : string processing is rather slow so convert strings to enums firstGamekeeper
@DanielKniaz ok I will share the execute me function and the kernel processing the process.Takeover
@DanielKniaz Now I guess everything is pretty much clearer. Please let me know what else you are in need of.Takeover
First, could you describe what is wrong with your application ? Second, you aren't using any kernel ID access such as get_global_id(0) or get_local_id(0) in any of your kernel.Inclination
@Inclination See I just want to convert the MQL5 function to OpenCL kernel. I have tried but I guess it is not working. Second, my kernel is not multi core function what I see in the task manager. help me make it correct please.Takeover

© 2022 - 2024 — McMap. All rights reserved.