Scripts: Prueba de OpenCL - página 2

 
Svetosha:
Y para qué sirven estas oportunidades si no son útiles)))))))
Los hermanos Wright volaron sólo 20 metros (por así decir un vuelo de demostración), la utilidad de su invento son los vuelos intercontinentales (como se dice sentir la diferencia).
 
Zeleniy: El óvulo antes de la concepción. Todavía no entiendo por qué sacarlo, sería mejor hacer algo útil y no finalizado.
Svetosha: Y el uso de estas oportunidades si no son útiles))))))

Las innovaciones son muy a menudo se reunieron en la bayoneta por tales "practicantes sermyazhnye", que juzgan acerca de los problemas universales desde el punto de vista de su nariz, para los que nada huele.

Y luego, cuando el beneficio es visible para todos, se olvidan con seguridad de sus ataques.

 
Mathemat:

Las innovaciones se encuentran muy a menudo en la otra cara de la moneda con tales "practicantes grises", que juzgan los problemas universales desde el punto de vista de su nariz, para la que nada huele.

Y luego, cuando todo el mundo ve el beneficio, se olvidan tranquilamente de sus ataques.

Sí, OpenCL mola mucho. Para ser sincero, hace tiempo que no sigo la situación con el 5. ¿Sigue existiendo la interabsorción de órdenes?
 
VDev:
¿Sigue existiendo la absorción de pedidos?

No es que siga ahí.

No puede ser de otra manera.

 

A partir de la próxima compilación, estarán disponibles nuevas características para crear recursos gráficos sobre la marcha utilizando las funciones ResourceCreate().

Aquí hay un script reescrito y simplificado que hace sin volcar imágenes al disco, funciona más rápido y sin conflictos de acceso a recursos en el 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
//+------------------------------------------------------------------+
//| Código de función 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";
//+------------------------------------------------------------------+
//| Función de inicio del programa de script|
//+------------------------------------------------------------------+
void OnStart()
  {
   int cl_ctx;
   int cl_prg;
   int cl_krn;
   int cl_mem;
//--- inicialización de objetos 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;
     }
//--- preparándose para la ejecución
   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());
//--- configuración de parámetros de función OpenCL no modificables
   CLSetKernelArg(cl_krn,4,max);
   CLSetKernelArgMem(cl_krn,5,cl_mem);
//--- creación del objeto para visualización de gráficos
   ObjectCreate(0,objname,OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetInteger(0,objname,OBJPROP_XDISTANCE,4);
   ObjectSetInteger(0,objname,OBJPROP_YDISTANCE,26);
//--- crear imagen inicial vacía
   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);
//--- renderización, hasta que no nos detengan desde el exterior
   while(!IsStopped())
     {
      uint x=GetTickCount();
      //--- configuración de parámetros flotantes
      CLSetKernelArg(cl_krn,0,x0);
      CLSetKernelArg(cl_krn,1,y0);
      CLSetKernelArg(cl_krn,2,x1);
      CLSetKernelArg(cl_krn,3,y1);
      //--- renderizar el cuadro
      CLExecute(cl_krn,2,offset,work);
      //--- tomando los datos del marco
      CLBufferRead(cl_mem,buf);
      //--- salida del tiempo de renderizado
      Comment(IntegerToString(GetTickCount()-x)+" msec per frame");
      //--- guardar el marco en memoria y dibujarlo
      ResourceCreate(resname,buf,SIZE_X,SIZE_Y,0,0,SIZE_X,COLOR_FORMAT_XRGB_NOALPHA);
      ChartRedraw();
      //--- una pequeña pausa y actualización de parámetros para el siguiente frame
      Sleep(10);
      x0+=0.001 f;
      x1-=0.001 f;
      y0+=0.001 f;
      y1-=0.001 f;
     }
//--- eliminar objetos OpenCL
   CLBufferFree(cl_mem);
   CLKernelFree(cl_krn);
   CLProgramFree(cl_prg);
   CLContextFree(cl_ctx);
//--- eliminar objeto
   ObjectDelete(0,objname);
  }
//+------------------------------------------------------------------+


Así puede crear cualquier imagen dinámica de 32 bits con canales alfa para un renderizado detallado.

Los recursos creados dinamicamente entran en el gestor de recursos y estan disponibles para todos los programas MQL5 del terminal.


 
Renat se dispondrá de nuevas posibilidades para crear recursos gráficos sobre la marcha mediante las funciones ResourceCreate().
¿sólo se anunciará la función ResourceCreate() o se preparará una clase para trabajar con objetos gráficos/primitivos?
 
IgorM:
¿sólo se anunciará la función ResourceCreate() o se preparará una clase para trabajar con objetos gráficos/primitivos?

Esta función ya estará disponible.

Con su ayuda ya puedes crear tus propias librerías para dibujar en tu propio buffer y luego vincularlas a objetos. Así puede deshacerse completamente de las bibliotecas de dibujo externas en archivos BMP externos.

Aquí tienes un pequeño ejemplo - puedes dibujar directamente en el buffer y luego crear un recurso basado en él y asignarlo a un objeto.

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


Un poco más tarde haremos una librería de primitivas para dibujar en los mismos buffers usando funciones nativas de aceleración 2D. Esto permitirá dibujar mucho más rápido.

 
Renat:

Esta función ya estará disponible.

Con su ayuda ya puede crear sus propias bibliotecas para dibujar en su propio búfer y luego vincularlas a objetos. De este modo podrás deshacerte completamente de las librerías de dibujo externas en archivos BMP externos.


¿esta función estará disponible para todos los MQL, y no sólo para trabajar con OpenCL?

¿y cuál es la situación con el canal alfa en los recursos BMP creados?

 
Un poco mas tarde haremos una libreria de primitivas para dibujar en los mismos buffers usando funciones nativas de aceleracion 2D.

Ya veo, pero imho, es mejor para los desarrolladores anunciar a la vez tanto la nueva función como la clase base para trabajar con gráficos, de lo contrario otra vez empezarán a "gritar desde el pasillo" sobre las dificultades en la programación en mql5.

SZY: ¿es sólo a mí que el enlace "responder" no funciona? en lugar de citar un post, aparece la ventana "Nuevo comentario".

 

sergeev 2012.03.19 17:25 #

y ¿cuál es la situación con el canal alfa en los recursos BMP creados?
parece que funciona