¿Cuál es una buena manera de ejecutar estudios de parámetros en C ++?


29

El problema

Actualmente estoy trabajando en una simulación de elementos finitos Navier Stokes y me gustaría investigar los efectos de una variedad de parámetros. Algunos parámetros se especifican en un archivo de entrada o mediante las opciones de una línea de comando; otros parámetros se proporcionan como indicadores en un Makefile, por lo que mi código debe volver a compilarse cada vez que cambio esas opciones. Me interesaría recibir algunos consejos sobre una buena forma de explorar sistemáticamente el espacio de parámetros.

  • ¿Existen bibliotecas / frameworks C ++ / Python útiles que puedan ayudar con este tipo de cosas? Por ejemplo, descubrir boost.Program_options fue de gran ayuda ya que es posible sobrecargar las opciones del archivo de entrada con argumentos de línea de comando. También he visto a algunas personas usar un archivo de trabajo que describe cada caso con bastante eficacia y un colega sugirió que escribir parámetros en archivos vtu como bloques de comentarios también podría funcionar.
  • ¿Quizás no valga la pena invertir mucho tiempo en esto? ¿Es solo una distracción y una pérdida de tiempo, y lo mejor es simplemente músculo durante el proceso de prueba de fuerza bruta y ad hoc?

Algunos pensamientos

Actualmente estoy haciendo las cosas principalmente a mano y me he encontrado con los siguientes problemas:

  • Nombramiento de casos de prueba . Traté de almacenar resultados en carpetas nombradas con los parámetros de ejecución separados con guiones bajos, por ejemplo Re100_dt02_BDF1.... Estos se vuelven rápidamente largos o difíciles de leer / crípticos si se abrevian demasiado. Además, los parámetros de números reales incluyen uno .que es incómodo / feo.
  • Registro de datos de ejecución . A veces me gustaría ver los resultados escritos en el terminal y también guardados en un archivo de texto. Esta respuesta de StackOverflow, por ejemplo, es algo útil, pero las soluciones parecen ser un poco intrusivas.
  • Trazado de datos según el parámetro . Toma bastante tiempo recopilar datos relevantes de una variedad de archivos de registro en un solo archivo que luego puedo trazar, con un sistema mejor tal vez esto sea más fácil.
  • Registro de comentarios sobre los datos . Después de examinar los resultados, escribo algunos comentarios en un archivo de texto, pero a veces es difícil mantener esto sincronizado con las carpetas de resultados.

Mucho depende de lo que quieras decir con "explorar". Por favor, indique sus objetivos con mayor precisión.
Arnold Neumaier

Respuestas:


10

Solo algunos comentarios sobre dos de sus puntos:

  • Registro de datos de ejecución : su mejor apuesta es probablemente canalizar la salida a través del comando tee , que debería estar disponible en la mayoría de los shells.

  • Trazar datos según el parámetro : supongo que es cuestión de gustos, pero cuando tengo que hacer una agregación de datos compleja, almaceno los resultados en texto plano, los leo en Matlab como matrices y hago todos los cálculos, trazados e incluso la salida de LaTeX desde allí. Obviamente, cualquier lenguaje de programación / scripting con el que esté más familiarizado le dará mejores resultados.


Gracias, el teecomando es muy útil
Matija Kecman

11

Si desea escribir algo de propósito general, puede hacerlo con scripts de shell si es algo muy simple, como sugiere Pedro , o agregarlo en un lenguaje de programación matemático de nivel superior como Python o MATLAB. Estoy de acuerdo en que los archivos de texto sin formato son útiles para pequeñas cantidades de datos, pero probablemente debería cambiar a datos binarios para algo más grande que unos pocos megabytes.

Por otro lado, si solo está haciendo una estimación de parámetros, recomendaría usar un software específicamente adecuado para esto. Varios investigadores de mi universidad han tenido buena suerte con DAKOTA , una caja de herramientas de cuantificación de incertidumbre de Sandia National Laboratories ( disponible bajo una Licencia Pública General Menor GNU ).

Aquí hay un extracto de la página de Sandia que describe DAKOTA:

Proporcionamos una variedad de métodos para permitir que un usuario ejecute una colección de simulaciones por computadora para evaluar la sensibilidad de los resultados del modelo con respecto a las entradas del modelo. Las categorías comunes incluyen estudios de parámetros, métodos de muestreo y diseño de experimentos. En los estudios de parámetros, uno pasa algunos parámetros de entrada a través de un rango mientras mantiene otros parámetros de entrada fijos y evalúa cómo varía la salida. En los métodos de muestreo, uno genera muestras a partir de una distribución de espacio de entrada y calcula la respuesta de salida en los valores de entrada. Los métodos de muestreo específicos disponibles en DAKOTA incluyen Monte Carlo, Latin Hypercube y (próximamente) cuasi-Monte Carlo. En el diseño de experimentos, la salida se evalúa en un conjunto de puntos de "diseño" de entrada elegidos para muestrear el espacio de manera representativa. El diseño específico de los métodos experimentales disponibles en DAKOTA incluye los diseños Box-Behnken, Central Composite y Factorial. Las métricas de sensibilidad son una forma matemática de expresar la dependencia de las salidas con las entradas. Hay una variedad de métricas de sensibilidad disponibles en Dakota, como los coeficientes de correlación simples y parciales, y las correlaciones de rango. Nuestra investigación actual se enfoca en métodos para generar métricas de sensibilidad con un número mínimo de corridas, y en una estimación óptima de parámetros en modelos de computadora usando técnicas de análisis bayesianas.


Otra herramienta como esta es SUSA desarrollada por GRS en Alemania. Pero este no es gratis.
GertVdE

El problema con los formatos binarios es que son más difíciles de mantener, no es raro que un formato de archivo evolucione con el tiempo, por lo tanto, analizar y admitir un formato binario puede ser un problema. En mi experiencia, el texto plano, la compresión (gzip) y un poco de línea de comando o python para unir todo funcionan bien incluso para unos pocos cientos de GB.
fcruz

1
@fcruz sí, o bzip2y 7zipque ofrecen relaciones de compresión aún mejores para el texto.
Ajasja

8

Para mi trabajo de doctorado, me encuentro con problemas similares a los suyos. Sin embargo, dado que no es mi código lo que estoy usando, no tengo la misma flexibilidad que usted. Dicho esto, tengo algunas sugerencias.

Como sugirió Pedro, está el comando tee. Pero, si no está disponible, o si desea algo integrado en su propio software, le sugiero que consulte la boost::iostreamsbiblioteca. Proporciona mecanismos para definir fuentes de entrada y sumideros de salida que la biblioteca estándar no hace. En particular, existe el tee_deviceque le permite conectar dos sumideros de salida a su flujo, y otros flujos pueden actuar como sumideros. Esto le permitiría hacer que la salida simultánea stdouty una configuración de archivo de registro dependieran.

boost::program_options1iniboost::program_optionsboost::property_tree

Para recopilar los datos de los diferentes cálculos, recorro todos los archivos de datos que me gustaría incluir en un conjunto, luego uso awk para producir una sola línea en el archivo y canalizo todos los resultados en mi salida. Esto puede tomar un par de minutos, pero desafortunadamente no tengo un método mejor.

En cuanto al procesamiento / comentario de sus datos, no puedo enfatizar lo suficiente la utilidad del formato del cuaderno de Mathematica. Me permite organizar mis observaciones, especulaciones y visualizaciones, todo en un solo lugar. Sin embargo, mis portátiles suelen superar los 100 MB. En buena medida, Mathematica funciona tan bien como Matlab en tareas de matriz. Además, se puede utilizar para tomar notas con formato matemático completo en tiempo real.

Desearía tener una mejor solución al problema de nombres, y es bastante pernicioso. Puede valer la pena considerar enviar algunos de sus datos a una base de datos debido a esto. Sin embargo, si no desea hacer eso, considere usar los atributos extendidos en XFS para capturar información más completa sobre su simulación y almacenar su archivo de configuración con los datos que se utilizaron para generar.

1. Como ejemplo donde se necesitan archivos de configuración jerárquica, un amigo mío estaba examinando los efectos de diferentes geometrías de punta en AFM y cada geometría tenía un conjunto diferente de parámetros. Además, junto con esto, estaba probando varios esquemas de cálculo para poder compararlos con el experimento, y tenían parámetros muy diferentes.


1
Lo que hago recientemente es que conduzco la simulación desde Mathematica. En lugar de usar archivos de configuración, archivos de entrada, etc. y hacer de la simulación un programa de línea de comandos, simplemente defino una interfaz LibraryLink para Mathematica. De esta manera puedo pasar parámetros o datos de una manera estructurada, y puedo evitar la molestia de tener que manejar todo tipo de opciones de línea de comando / formatos de archivo de entrada-salida. Obtengo acceso instantáneo a la visualización / trazado y puedo automatizar fácilmente la ejecución de la simulación para diferentes parámetros para escenarios complejos.
Szabolcs

(Así es como me levanto con el tema del muestreo adaptativo . Si llamara a mi programa desde la línea de comandos, implementar algo como esto es demasiado trabajo y demasiados problemas para comenzar a hacerlo sin una muy buena razón. La idea no es probable que salga de la experimentación pura Utilizando un sistema de alto nivel como Mathematica hizo la experimentación bastante fácil que la idea surgió de forma natural supongo que uno podría utilizar otros sistemas de alto nivel de la misma manera)...
Szabolcs

Gracias por su útil respuesta, lo echaré un vistazo boost::property_tree. Otro problema boost::program_optionses que parece inutilizable como una biblioteca de solo encabezado, lo cual es incómodo si desea que su aplicación se ejecute en una máquina que solo tiene encabezados de impulso. Por cierto, ¿alguien sabe por qué es esto? Aparentemente es una biblioteca bastante pequeña de todos modos. (Quizás sea mejor publicar esto en la lista de usuarios de impulso)
Matija Kecman

@ mk527 No sé qué se requiere boost::program_optionspara forzar que se convierta en una biblioteca. Sin embargo, ¿ha mirado la utilidad bcp para extraer un subconjunto de impulso?
rcollyer

3

Conozco PyTables cuando instalo PETSC. Y supongo que el método de tabla (o base de datos) es muy adecuado para explorar el espacio de parámetros, aunque todavía no lo he intentado. Podemos registrar cada ejecución con parámetros específicos y luego podemos consultar cualquier agregación que satisfaga algunas condiciones, por ejemplo, podemos arreglar dt, BDF1 y buscar todos los registros relevantes para estudiar la variación debido a los otros parámetros.

Me gustaría saber de personas que realmente están utilizando el método de tabla (o base de datos) para explorar el espacio de parámetros. Lo agradeceré por ejemplos detallados.


3

Explorar el espacio de parámetros como está intentando hacerlo puede volverse muy difícil de manejar rápidamente. Hay tantas formas diferentes de hacerlo que no hay una solución real.

Por lo general, cuando alcanza este límite en su trabajo, es posible que desee investigar los formatos de datos jerárquicos HDF5 . HDF5 le permite almacenar resultados complejos de su simulación en un formato de archivo bien definido. Las ventajas son que sus datos se almacenan en un único formato de archivo bien definido. Puede agregar múltiples ejecuciones de simulación, identificadas por diferentes parámetros, a su archivo, y manipularlas luego. Los datos se pueden comprimir y es bastante fácil de extraer utilizando una variedad de herramientas. Hay apis fáciles para c / c ++ / python, etc. y muchas herramientas de línea de comandos para manipular los archivos. Una desventaja es que escribir en hdf5 no es tan simple como escribir en la consola. Hay muchos programas de ejemplo en HDF5 .


2

Desea mantener una tabla indexada de valores variables. El índice corresponde a una carpeta donde guarda cada entrada y salida de simulación. Por lo tanto, es solo un índice y no tiene que preocuparse por las convenciones de nomenclatura o las jerarquías de carpetas porque buscará qué valores de parámetros corresponden a cada carpeta.

Así que ahora puede usar esta tabla para organizar su procesamiento posterior, trazado (análisis), registro y comentarios. La tabla es central para el flujo de trabajo.

Esta es la idea básica, y estoy describiendo lo que tal vez quieras hacer solo conceptualmente. En mi respuesta inicial, sugerí buscar en el marco que he desarrollado. Más recientemente descubrí Sumatra . Está mucho más desarrollado que mi estudiante de posgrado con problemas de desarrollo individual y nuevo en el esfuerzo de Python, pero creo que trata de hacer demasiado. Se centra en la información de procedencia mientras que mi marco se centra en la eficiencia del flujo de trabajo. También hay jobman , sagrada , y lencet .

Independientemente de lo que elija hacer, le recomiendo python para abordar este tipo de tareas, ya que puede administrar todo su flujo de trabajo con python. Solo como una pequeña historia, vi a mis colegas trabajar con DAKOTA, bash, GNUplot, convenciones de nomenclatura de archivos, octava sed / awk ... etc. para hacer su trabajo computacional. Cada una de estas herramientas está bien por sí misma, pero el poder de Python como un lenguaje de pegamento integrador realmente brilla cuando usas Python para administrar tu trabajo junto con la pila científica de Python. Literalmente no tuve problemas para administrar mi trabajo computacional después de desarrollar mi marco.

/ mi respuesta inicial sigue /

Creo que he resuelto este problema usando python. He pensado en todos estos problemas.

Echa un vistazo a mi repositorio http://msdresearch.blogspot.com/2012/01/parameter-study-management-with-python.html

Sin embargo, a partir de ahora, estoy trabajando para documentar mejor mi marco. (¡es más complicado que completar un archivo Léame!)

-Majid alDosari


1
Hola Majid, gracias por la contribución y bienvenido a SciComp. En general, los sitios de StackExchange desalientan la vinculación a páginas externas y fomentan respuestas detalladas en el sitio mismo. Se desaconsejan los "anuncios" de enlace único. Sugeriría revisar o eliminar esta respuesta, ya que probablemente no se reciba bien en su forma actual.
Aron Ahmadia

entendido. Simplemente no creo que la solución se pueda dar en forma de publicación. El problema es bastante general.
majidaldosari

1
¿Podría al menos resumir su enfoque de estos temas en los que ha pensado?
Christian Clason

1

Tiendo a estar de acuerdo con la siguiente implementación, que desarrollé en el curso de mi trabajo de investigación, como se puede encontrar aquí , aquí y aquí .

Para pasar variables al programa y poder cambiar entonces, uso el paradigma de usar un script bash donde defino

export aValue=10
export bValue=2
export idName=test

y luego usar en C / C ++

char *env_aValue = getenv("aValue");
char *env_bValue = getenv("bValue");
char *env_idName = getenv("idName");

aValue = atoi(env_aValue)
...

Las grandes ventajas de esto es que:

  • se puede acceder en un ámbito global,
  • es portátil al motor de rejilla solar (grupos),
  • se puede cambiar fácilmente en el script bash,
  • es independiente de la plataforma,
  • el número de parámetros puede ser muy grande (potencialmente infinito)

Además, siempre paso un idName, en el que cada archivo escrito por ese ejecutable tendrá una identificación inicial (puede ser seguido por otros parámetros si lo desea), y también reciben un directorio de exportación = idName, que se crea en el bash script, y todos los archivos de ese ejecutable se guardan en él. De esta forma, los resultados se organizan por directorios (opcional).


0

Puede consultar sfepy, que es un programa de elementos finitos codificado casi por completo en python. También tiene un problema de muestra Navier Stokes. El procedimiento operativo de sfepy es muy fácil.


1
No siento que esta respuesta responda la pregunta. El póster tiene una simulación; Tengo la impresión de que quiere envolver un marco alrededor de su simulación existente, en lugar de rehacer completamente su simulación en un software diferente.
Geoff Oxberry

sfepy también funciona como un marco, uno puede usar esto como un solucionador de PDE de caja negra. Pero creo que tienes razón, ya que el póster ya ha dedicado una cantidad significativa de tiempo a la codificación.
ShadowWarrior

0

¿Has pensado en usar una base de datos MySQL? Nunca lo he hecho, pero me imagino que puedes consultar este sistema muy bien. Quizás otros sistemas como MongoDB son mejores. Entonces, esto es solo una idea.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.