OpenCL and MQL5 indicator returning garbage values in the output

To add comments, please log in or register
jaffer wilson
782
jaffer wilson  

Here is the code that I have tried for Simple Moving Average.

const string cl_src = 

"__kernel void CalculateSimpleMA(                                     \r\n"
                                 "int rates_total,                     \r\n"
                                 "int prev_calculated,                \r\n"
                                 "int begin,                          \r\n"
                                 "int InpMAPeriod,                    \r\n"
                                 "__global float *price,              \r\n"
                                 "__global float *ExtLineBuffer          \r\n"
                                 ")                                    \r\n"
         "{                                                           \r\n"
            "int i,limit;\r\n"

           " if(prev_calculated==0)// first calculation\r\n"
           " {"
            "limit=InpMAPeriod+begin;\r\n"

            "for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0;\r\n "     
            "double firstValue=0;\r\n"
            "for(i=begin;i<limit;i++)\r\n"
               "firstValue+=price[i];\r\n"
            "firstValue/=InpMAPeriod;\r\n"
            "ExtLineBuffer[limit-1]=firstValue;\r\n"
            "}\r\n"
           "else limit=prev_calculated-1;\r\n"

            "for(i=limit;i<rates_total;i++)\r\n"
               "ExtLineBuffer[i]=ExtLineBuffer[i-1]+(price[i]-price[i-InpMAPeriod])/InpMAPeriod;\r\n"
         "}                                                           \r\n";



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);


 string str;   
int cl_ctx = CLContextCreate(CL_USE_GPU_ONLY);
   int cl_prg=CLProgramCreate(cl_ctx,cl_src,str);
   int cl_krn=CLKernelCreate(cl_prg,"CalculateSimpleMA");
   int cl_mem=CLBufferCreate(cl_ctx,ArraySize(price)*sizeof(float ),CL_MEM_READ_WRITE), 
       cl_price=CLBufferCreate(cl_ctx,ArraySize(price)*sizeof(float ),CL_MEM_READ_WRITE);

   if(cl_ctx==INVALID_HANDLE)
     {
      Print("OpenCL not found: ", GetLastError() );
      return(0);

     }


   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);
     }
           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);
           }

int  offset[2]={0,0};
   int  work  [2]={512,512};

   switch(InpMAMethod)
     {
      case MODE_SMA:  


           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());


           if(!CLExecute(cl_krn))
           Print("Kernel not executed",GetLastError());

           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());



      ArrayPrint(ExtLineBuffer);

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

   return(rates_total);
  }

The above code works fine but returns garbage values in the output buffer. Kindly, suggest me what I can do to improve the output and get it done smoothly.

kypa
983
kypa  

The error might be coming from kernel values being float and the indicator buffer being double.

jaffer wilson
782
jaffer wilson  
kypa:

The error might be coming from kernel values being float and the indicator buffer being double.

May be. I guess I need to check it out once.

To add comments, please log in or register