Script: Test OpenCL - pagina 2

 
Svetosha:
E a cosa servono queste opportunità se non sono utili))))))
I fratelli Wright hanno volato per soli 20 metri (quindi un volo dimostrativo), l'uso della loro invenzione è il volo intercontinentale (come si suol dire, senti la differenza).
 
Zeleniy: L'ovulo prima del concepimento. Ancora non capisco perché metterlo fuori, sarebbe meglio fare qualcosa di utile e non finalizzato.
Svetosha: E l'uso di queste opportunità se non sono utili))))))

Le innovazioni sono molto spesso accolte alla baionetta da questi "praticanti sermyazhnye", che giudicano i problemi universali dal punto di vista del loro naso, per il quale nulla puzza.

E poi, quando il beneficio è visibile a tutti, si dimenticano tranquillamente dei loro attacchi.

 
Mathemat:

Le innovazioni sono molto spesso accolte al rovescio da questi "praticanti grigi", che giudicano i problemi universali dal punto di vista del loro naso, per il quale nulla puzza.

E poi, quando tutti vedono i benefici, si dimenticano tranquillamente dei loro attacchi.

Sì, OpenCL è davvero interessante. Ad essere onesti, non ho seguito la situazione con 5 per molto tempo. L'assorbimento degli ordini è sempre lo stesso?
 
VDev:
L'assorbimento degli ordini è ancora presente?

Non è che ci sia ancora.

Non può essere altrimenti.

 

A partire dalla prossima build, saranno disponibili nuove funzionalità per creare risorse grafiche al volo utilizzando le funzioni ResourceCreate().

Ecco uno script riscritto e semplificato che non scarica le immagini sul disco, funziona più velocemente e senza conflitti di accesso alle risorse sul disco:

//+------------------------------------------------------------------+
//|OpenCLTest.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. | |
//| http://www.mql5.com
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//---
#define SIZE_X 512
#define SIZE_Y 512
//+------------------------------------------------------------------+
//| Codice funzione OpenCL|
//+------------------------------------------------------------------+
const string cl_src=
                    "__kernel void MFractal(                                    \r\n"
                    "                       float x0,                           \r\n"
                    "                       float y0,                           \r\n"
                    "                       float x1,                           \r\n"
                    "                       float y1,                           \r\n"
                    "                       uint  max,                          \r\n"
                    "              __global uint *out)                          \r\n"
                    "  {                                                        \r\n"
                    "   size_t  w = get_global_size(0);                         \r\n"
                    "   size_t  h = get_global_size(1);                         \r\n"
                    "   size_t gx = get_global_id(0);                           \r\n"
                    "   size_t gy = get_global_id(1);                           \r\n"
                    "   float dx = x0 + gx * (x1-x0) / (float) w;               \r\n"
                    "   float dy = y0 + gy * (y1-y0) / (float)h;                \r\n"
                    "   float x  = 0;                                           \r\n"
                    "   float y  = 0;                                           \r\n"
                    "   float xx = 0;                                           \r\n"
                    "   float yy = 0;                                           \r\n"
                    "   float xy = 0;                                           \r\n"
                    "   uint i = 0;                                             \r\n"
                    "   while ((xx+yy)<4 && i<max)                              \r\n"
                    "     {                                                     \r\n"
                    "      xx = x*x;                                            \r\n"
                    "      yy = y*y;                                            \r\n"
                    "      xy = x*y;                                            \r\n"
                    "      y = xy+xy+dy;                                        \r\n"
                    "      x = xx-yy+dx;                                        \r\n"
                    "      i++;                                                 \r\n"
                    "     }                                                     \r\n"
                    "   if(i==max)                                              \r\n"
                    "      out[w*gy+gx] = 0;                                    \r\n"
                    "   else                                                    \r\n"
                    "      out[w*gy+gx] = (uint)((float)0xFFFFFF/(float)max)*i; \r\n"
                    "  }                                                        \r\n";
//+------------------------------------------------------------------+
//| Funzione di avvio del programma di script|
//+------------------------------------------------------------------+
void OnStart()
  {
   int cl_ctx;
   int cl_prg;
   int cl_krn;
   int cl_mem;
//-- inizializzazione degli oggetti OpenCL
   if((cl_ctx=CLContextCreate())==INVALID_HANDLE)
     {
      Print("OpenCL not found");
      return;
     }
   if((cl_prg=CLProgramCreate(cl_ctx,cl_src))==INVALID_HANDLE)
     {
      CLContextFree(cl_ctx);
      Print("OpenCL program create failed");
      return;
     }
   if((cl_krn=CLKernelCreate(cl_prg,"MFractal"))==INVALID_HANDLE)
     {
      CLProgramFree(cl_prg);
      CLContextFree(cl_ctx);
      Print("OpenCL kernel create failed");
      return;
     }
   if((cl_mem=CLBufferCreate(cl_ctx,SIZE_X*SIZE_Y*sizeof(uint),CL_MEM_READ_WRITE))==INVALID_HANDLE)
     {
      CLKernelFree(cl_krn);
      CLProgramFree(cl_prg);
      CLContextFree(cl_ctx);
      Print("OpenCL buffer create failed");
      return;
     }
//--- pronti per l'esecuzione
   float x0       =-2;
   float y0       =-0.5;
   float x1       =-1;
   float y1       = 0.5;
   uint  max      = 20000;
   uint  offset[2]={0,0};
   uint  work  [2]={SIZE_X,SIZE_Y};
   string objname ="OpenCL_"+IntegerToString(ChartID());
   string resname ="Mandelbrot_"+IntegerToString(ChartID());
//--- impostazione dei parametri immutabili delle funzioni OpenCL
   CLSetKernelArg(cl_krn,4,max);
   CLSetKernelArgMem(cl_krn,5,cl_mem);
//--- creazione dell'oggetto per la visualizzazione grafica
   ObjectCreate(0,objname,OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetInteger(0,objname,OBJPROP_XDISTANCE,4);
   ObjectSetInteger(0,objname,OBJPROP_YDISTANCE,26);
//--- creare un'immagine vuota iniziale
   uint buf[];

   ArrayResize(buf,SIZE_X*SIZE_Y);
   ResourceCreate(resname,buf,SIZE_X,SIZE_Y,0,0,SIZE_X,COLOR_FORMAT_XRGB_NOALPHA);
   ObjectSetString(0,objname,OBJPROP_BMPFILE,"::"+resname);
//--- rendering, fino a quando non saremo fermati dall'esterno
   while(!IsStopped())
     {
      uint x=GetTickCount();
      //--- impostazione dei parametri flottanti
      CLSetKernelArg(cl_krn,0,x0);
      CLSetKernelArg(cl_krn,1,y0);
      CLSetKernelArg(cl_krn,2,x1);
      CLSetKernelArg(cl_krn,3,y1);
      //-- renderizzazione della cornice
      CLExecute(cl_krn,2,offset,work);
      //--- prendere i dati della cornice
      CLBufferRead(cl_mem,buf);
      //--- emissione del tempo di rendering
      Comment(IntegerToString(GetTickCount()-x)+" msec per frame");
      //--- salvare la cornice in memoria e disegnarla
      ResourceCreate(resname,buf,SIZE_X,SIZE_Y,0,0,SIZE_X,COLOR_FORMAT_XRGB_NOALPHA);
      ChartRedraw();
      //-- una piccola pausa e l'aggiornamento dei parametri per il fotogramma successivo
      Sleep(10);
      x0+=0.001 f;
      x1-=0.001 f;
      y0+=0.001 f;
      y1-=0.001 f;
     }
//--- rimozione degli oggetti OpenCL
   CLBufferFree(cl_mem);
   CLKernelFree(cl_krn);
   CLProgramFree(cl_prg);
   CLContextFree(cl_ctx);
//--- rimuovere l'oggetto
   ObjectDelete(0,objname);
  }
//+------------------------------------------------------------------+


In questo modo è possibile creare qualsiasi immagine dinamica a 32 bit con canali alfa per un rendering dettagliato.

Le risorse create dinamicamente entrano nel gestore delle risorse e sono disponibili per tutti i programmi MQL5 del terminale.


 
Renat saranno disponibili nuove possibilità di creare risorse grafiche al volo utilizzando le funzioni ResourceCreate().
Sarà annunciata solo la funzione ResourceCreate() o sarà preparata una classe per lavorare con oggetti grafici/primitivi?
 
IgorM:
verrà annunciata solo la funzione ResourceCreate() o verrà preparata una classe per lavorare con gli oggetti grafici/primitivi?

Questa funzione sarà già disponibile.

Con il suo aiuto è già possibile creare le proprie librerie per disegnare nel proprio buffer e poi legarle agli oggetti. In questo modo è possibile liberarsi completamente delle librerie di disegno esterne nei file BMP esterni.

Ecco un piccolo esempio: è possibile disegnare direttamente nel buffer buf e poi creare una risorsa basata su di esso e assegnarla a un oggetto.

   uint buf[];

   ArrayResize(buf,SIZE_X*SIZE_Y);
   ResourceCreate(resname,buf,SIZE_X,SIZE_Y,0,0,SIZE_X,COLOR_FORMAT_XRGB_NOALPHA);
   ObjectSetString(0,objname,OBJPROP_BMPFILE,"::"+resname);


Poco dopo creeremo una libreria di primitive per disegnare negli stessi buffer utilizzando le funzioni di accelerazione 2D native. Questo permetterà di disegnare molto più velocemente.

 
Renat:

Questa funzione sarà già disponibile.

Con il suo aiuto è già possibile creare le proprie librerie per disegnare nel proprio buffer e poi legarle agli oggetti. In questo modo è possibile liberarsi completamente delle librerie di disegno esterne nei file BMP esterni.


Questa funzione sarà disponibile per tutti gli MQL, e non solo per lavorare con OpenCL?

e qual è la situazione del canale alfa nelle risorse BMP create?

 
Un po' più tardi faremo una libreria di primitive per disegnare negli stessi buffer usando le funzioni native di accelerazione 2D.

Capisco, ma imho, è meglio che gli sviluppatori annuncino subito sia la nuova funzione che la classe base per lavorare con la grafica, altrimenti si ricomincerà a "gridare dalla sala" sulle difficoltà di programmazione su mql5.

SZY: è solo a me che il link "rispondi" non funziona? Invece di citare un post, appare la finestra "Nuovo commento".

 

sergeev 2012.03.19 17:25 #

e qual è la situazione con il canale alfa nelle risorse BMP create?
così sembra funzionare