lunes, 10 de octubre de 2011

Code Saturne: Realizando una simulación numérica del experimento

Ya con varias piezas dispuestas para la experiencia del control del cilindro, nos es necesario datos más cercanos a la realidad para probar los módulos por separado. Si bien se podría plantear el experimento y obtener imágenes del mismo, resulta más simple (y flexible) realizar una simulación numérica. A tal efecto, elegimos la librería de código abierto Code Saturne.


Dado que la instalación es un tanto tediosa y se lleva a cabo frecuentemente en el laboratorio, creamos una wiki para el laboratorio y tomamos nota de los pasos utilizando el archivo por lotes: install_saturne.py. Para más información, ver aquí.

La ejecución no deja de ser algo compleja:
  1. Se debe definir la experiencia con su simetría y parámetros físicos
  2. Se debe utilizar un programa de mallado para generar la cuadrícula para simular la física elegida. En este caso se utiliza el programa GID.
  3. Se debe correr el sistema de simulación Code Saturne en alguna de sus variantes
    1. Mediante el entorno gráfico.
    2. Realizando la configuración por archivos y corriendo el sistema por línea de consola. Esta opción es muy común para poder correr los trabajos de forma remota. Se agrega un instructivo a la flamante wiki del laboratorio. Para más información, ver aquí.

En el proceso nos topamos con un blog muy interesante de un estudiante de fluidodinámica del Reino Unido que vale la pena visitar:
http://code-saturne.blogspot.com/


sábado, 17 de septiembre de 2011

Probando el código C/CUDA (o C/C++) usando Matlab

Dado que comunicar Matlab con el código C/CUDA (o C/C++) no es la principal preocupación para la tesis, se aplica un poca investigación al tema y se implementa rápidamente un protocolo que permite comunicar entradas y salidas. En este caso, la comunicación consta de varias matrices de entrada y varias de salida. En todos los casos se trata de números flotantes.
Para que la ejecución del programa escrito en C sea transparente, se crea una función Matlab con el mismo nombre que el programa C, esta función será la encargada de grabar en disco las variables Matlab, llamar al ejecutable escrito en C, esperar que concluya exitosamente y leer las variables de salida desde el disco.
Las variables en disco se crean en una ubicación definida por el código Matlab (generalmente en una carpeta temporal) y se comunican al programa C mediante argumentos

Este esquema tiene un payload asociado a la lectura/escritura en disco de las variables que podría evitarse con algún método más directo...
A futuro, se recomienda utilizar la compilación MEX de Matlab:
http://www.mathworks.com/help/techdoc/matlab_external/f23224.html

jueves, 1 de septiembre de 2011

Librerías sobre Operaciones matemáticas en C/C++

A la hora de realizar los programas de prueba en C/C++, previo a codificarlos en C/CUDA fue necesario definir ciertas funciones de soporte matemáticas.

Como todo sistema de operaciones básicas comenzó con una clase Matrix<T> propia, con operaciones simples como multiplicar o sumar. A medida que el sistema creció, fue necesario implementar transposiciones y vistas de columnas o filas de la matriz. En ese punto, y buscando una implementación de inversión de matrices, resultaba obvia la necesidad de buscar un mejor soporte en librerías existentes.
A continuación, una colección de links relacionados:

Luego de evaluar todas las posibilidades, optamos por los dos primeros links: utilizar GSL y realizar una compilación custom para Windows.

jueves, 14 de julio de 2011

Simulando modelos conocidos

Matlab provee varias funciones que son de utilidad para simular modelos del tipo SISO, MIMO, etc. Una de las más útiles es sim que, dado un conjunto de datos de entrada y/o salida más un modelo ya definido, aplica el modelo a los datos y retorna la salida ulterior.
Veamos un ejemplo:

%genero un modelo según y(n) = u(n) - 2u(n-1)
A = [1] ; B = [1 -2];
modelo = idpoly(A, B);

%genero los datos para la simulación:
% ejemplos:
% iddata([], [1:100]') para salida nula y entrada del 1 al 100
% iddata([], idinput(100)) para salida nula y entrada aleatoria -1;1
data = iddata([],[1:10]');

%simulo
simulacion = sim(modelo, data);
plot(simulacion.y);

Bastante sencillo, si se cuenta con los datos de entrada e información sobre el modelo podemos calcular rápidamente la salida. 
Obviamente, se pueden aplicar relaciones mucho más complejas cambiando los coeficientes de A y B. Tanto es así que son esos vectores los que definen la transferencia G(s) que relaciona Y(s) y U(s) (salida con entrada). Entonces, el numerador evaluado en el operador de regresión q se convierte en A(q) mientras que el denominador hace lo propio en B(q). Si observamos con atención, podemos ver esa información en la variable modelo:
>> modelo
Discrete-time IDPOLY model: y(t) = B(q)u(t) + e(t)
B(q) = 1 - 2 q^-1                                                                                   
This model was not estimated from data.           
Sampling interval: 1 

miércoles, 15 de junio de 2011

Y dónde está cutil64.dll??

Muchos de los ejemplos que circulan por internet utilizan esta DLL. Tiene utilitarios generales para CUDA y viene dentro del "GPU Computing SDK examples". Para facilitar las cosas, es conveniente tomar esa librería (la versión correcta y para la plataforma correcta) de su carpeta en el SDK y colocarla dentro de la carpeta de instalación de CUDA. Lo mismo ocurre con los correspondientes archivos .lib.
Entonces, para un sistema 64 bits, copiamos:
  • <NVIDIA GPU Computing SDK Folder>\C\inc\cutil.h en <CUDA Folder>\include
  • <NVIDIA GPU Computing SDK Folder>\C\bin\win64\Release\cutil64.dll en <CUDA Folder>\bin64
  • <NVIDIA GPU Computing SDK Folder>\C\bin\win64\Debug\cutil64D.dll en <CUDA Folder>\bin64
  • <NVIDIA GPU Computing SDK Folder>\C\common\lib\cutil64.lib en <CUDA Folder>\lib64
  • <NVIDIA GPU Computing SDK Folder>\C\common\lib\cutil64D.lib en <CUDA Folder>\lib64
A modo anecdótico, dejo unos comentarios sobre la cutil.dll del release notes de una versión de CUDA:
      - Most samples link to a utility library called "cutil" whose source code
        is in "NVIDIA CUDA SDK\common". The release and emurelease versions of
        these samples link to cutil[32|64].lib and dynamically load
    cutil[32|64].dll. The debug and emudebug versions of these samples link
    to cutil[32D|64D].lib and dynamically load cutil[32D|64D].dll.
        To build the 32-bit and/or 64-bit, release and/or debug configurations
    of the cutil library, use the solution files located in
        "NVIDIA CUDA SDK\common". The output of the compilation goes to
        "NVIDIA CUDA SDK\common\lib":
         - cutil[32|64].lib and cutil[32D|64D].lib are the release and debug
       import libraries,
         - cutil[32|64].dll and cutil[32D|64D].dll are the release and debug
           dynamic-link libraries, which get also copied to
           "NVIDIA CUDA SDK\bin\win[32|64]\[release|emurelease]" and
           "NVIDIA CUDA SDK\bin\win[32|64]\[debug|emudebug]"
       respectively;

lunes, 13 de junio de 2011

Volviendo el tiempo atrás... CUDA 2.3

Lamentablemente, y aunque la sintaxis de CUDA 4 está muy buena, debemos volver a la versión 2.3 sobre Windows y compilar el código del Onera [1] con una resolución del Lucas-Kanade en GPU.

Lamentablemente, como suele suceder, aparecen nuevos problemas a salvar:
  • NVCC sin un compilador no funciona. Necesitamos el Visual Studio...
  • Visual Studio 2008 Express no tiene soporte para procesadores x64 con lo que hay que optar por una versión Trial del Professional.
  • Para compilar por línea de comandos nos quedamos con un ejemplo pequeño de archivo .cu y logramos compilarlo sólo luego de leer un post interesante [2] en el foro de nvidia: es necesario ejecutar un batch que setea el entorno del VS en modo amd64 y luego indicar algunos parámetros extras al NVCC.
  • Dentro del VS2008, NVCC sigue sin compilar. Es necesario actualizar el archivo nvcc.profile para que tenga un include extra del visual:
INCLUDES += "-I$(TOP)/include" "-I$(TOP)/include/cudart" "-IC:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/include" $(_SPACE_)

[1] Onera - FOLKI GPU
[2] Post compilación x64

viernes, 10 de junio de 2011

Eligiendo la cámara - Conclusiones

Ganador momentaneo: PixelFly

Conclusiones generales:
  1. La Pulnix es demasiado lenta. Además no ofrece ninguna ventaja significativa.
  2. La PixelFly tiene un buen tiempo de transmisión con binning activado. Según las pruebas de concepto se obtendrían 10 ms entre frame y frame con lo cual se puede usar esta cámara.
  3. La PixelFly tiene además modo de doble shutter que no fue analizado pero brinda más alternativas.
  4. La SpeedCam, aún siendo la de mejor calidad y velocidad no tuvo buenos resultados. La transferencia resulta muy lenta con lo que queda descartada por el momento.
  5. Es importante aclarar que el análisis se basa en la necesidad de hacer un algoritmo lo más veloz posible y poder realiar cálculos en el momento. En caso de no ser esto así se puede reconsiderar los resultados y optar por la SpeedCam en lugar de la PixelFly, por ejemplo. Esto podría ocurrir en caso que se necesite tiempo extra para realizar procesamiento, no requerir 1 frame cada 10 ms sino 2 frames espaciados en 10 ms para, más tarde, repetir la toma de fotos y el proceso.