FMI y la misma simulación en todas partes
El modelo no debe desarrollar una personalidad
Un modelo de simulación debe ser aburrido de una forma muy concreta: misma entrada, mismo modelo, misma salida. Eso parece obvio hasta que el modelo pasa de una estación de trabajo a un clúster, de un portátil a hardware en el bucle, de un compilador a otro, o de una herramienta de un proveedor a una oficina de seguridad que no aprecia la danza interpretativa. Entonces, pequeñas diferencias numéricas se convierten en reuniones. Las reuniones se convierten en hojas de cálculo de conciliación. Las hojas de cálculo de conciliación se convierten en el cementerio donde mueren las buenas tardes de ingeniería.
FMI existe para hacer práctico el intercambio de modelos y la co-simulación entre herramientas. La interfaz Functional Mock-up Interface ofrece a los equipos una forma estándar de empaquetar y ejecutar modelos, en lugar de transportar manualmente código de integración frágil de un entorno de simulación a otro. Eso ya es útil. Pero una interfaz estándar no hace automáticamente que la aritmética sea determinista. Los flujos de trabajo tradicionales de FMI suelen depender del comportamiento de coma flotante IEEE 754, de las bibliotecas de la plataforma, de las elecciones del compilador, del orden de ejecución y de las diferencias entre backends. La mayoría de las veces eso es suficiente. Luego deja de serlo, y la diferencia suele descubrirla alguien con una fecha límite y una cara que dice que el departamento de compras prometió que esto sería fácil.
Dweve FMI ataca la parte aburrida y cara: la reproducibilidad. El sitio describe una implementación de FMI en Rust para Model Exchange y Co-Simulation con aritmética determinista de punto fijo, construida sobre Numerus. La forma de la implementación es más amplia que una demo: un espacio de trabajo FMI con múltiples crates que incluye representación de modelos, análisis de esquemas, importación, exportación, tiempo de ejecución, solucionador, orquestación, memoria, backends para CPU, GPU, FPGA, ejecución en el borde y distribuida, FFI, fuzzing, benchmarks, documentación y pruebas. Depende de los crates de Numerus para aritmética de punto fijo y decimal, además de la pila común de Dweve para simulación, registro, manejo de fallos, transporte, tensores y almacenamiento.
El objetivo no es hacer que la simulación suene mística. El objetivo es que el mismo FMU deje de contar historias ligeramente diferentes porque se despertó en una máquina distinta.
FMI da el sobre, pero la aritmética sigue firmando el cheque
Una FMU es un sobre útil. Lleva una descripción del modelo, binarios o artefactos de código fuente, recursos, variables, estados, relojes, dependencias y suficientes metadatos para que otra herramienta pueda instanciar y avanzar el modelo. FMI 3.0 añade relojes más ricos, ejecución programada, mejor tipado de variables y maquinaria de co-simulación. El código fuente de Dweve FMI se organiza en torno a ese sobre: fmi-schema analiza y valida descripciones de modelos, fmi-import carga archivos FMU, fmi-export construye archivos, fmi-model representa variables y estado del modelo, y fmi-runtime gestiona el ciclo de vida, el acceso a variables, los relojes, los eventos, las derivadas y el guardado o restauración de estado.
Ese sobre es necesario, pero no es suficiente. La aritmética subyacente sigue decidiendo si una ejecución es reproducible. La documentación del tiempo de ejecución dice que la aritmética de punto fijo usa Numerus Q31_32 para el cálculo determinista. Los metadatos del espacio de trabajo nombran Q31.32 como el formato fijo predeterminado, Dec64_6 como el formato decimal predeterminado y Q16.16 para el tiempo. La página pública habla de los perfiles Q31.32, Q16.16 y Dec64_6, con MPFR como ruta de referencia. Eso le da al proyecto un contrato claro: la simulación de valores reales debe mapearse en perfiles numéricos deterministas en lugar de dejar que cada backend improvise.
Aquí hay un punto importante de honestidad. Las API orientadas a FMI y las superficies de compatibilidad pueden seguir aceptando o emitiendo valores flotantes porque el estándar y las herramientas existentes así lo esperan. La afirmación que importa no es una pureza teatral en cada frontera. La afirmación que importa es que la ruta determinista central está construida en torno a perfiles de punto fijo Numerus y a la validación contra una referencia de alta precisión donde la comparación tiene sentido. Los adaptadores periféricos pueden hablar el lenguaje exterior. El contrato interno no debería convertirse en un encogimiento de hombros.
El perfil numérico es una decisión del modelo
El punto fijo no es un único ajuste mágico. Un modelo que necesita valores de tiempo compactos, un modelo con amplios rangos físicos y un modelo que reporta cantidades decimales no tienen la misma presión. Q16.16, Q31.32 y Dec64_6 no son pegatinas para una diapositiva. Son contratos distintos sobre rango, resolución, representación y sobre dónde se permite que vivan los errores.
Aquí es donde los equipos de simulación suelen volverse demasiado informales. Tratan el comportamiento numérico como una propiedad de la herramienta en lugar de una propiedad del modelo. Entonces la herramienta cambia, o el backend cambia, o el modelo se integra, y de repente la suposición anterior se convierte en una carga de validación. Dweve FMI convierte el perfil numérico en parte de la arquitectura en lugar de un telón de fondo. Eso es menos glamuroso que una gran demostración. Bien. Las grandes demostraciones rara vez explican quién es el responsable de la frontera del redondeo.
La crate del solucionador cuenta la misma historia. Expone traits de sistemas ODE, RK4, RKF45, Euler, configuración orientada a BDF, control adaptativo de paso, detección de eventos y tiempo de solucionador determinista. La crate de runtime gestiona el ciclo de vida del FMU, los modos de evento y tiempo continuo, el acceso a variables, las derivadas de entrada, las derivadas direccionales y adjuntas, el almacenamiento en caché de Jacobianos, los relojes y la serialización de estado. Nada de eso es útil si la capa numérica no es de fiar cuando se mueve entre hardware. El solucionador puede ser ingenioso. El modelo puede ser elegante. Si la misma ejecución necesita tres conciliaciones, la elegancia es en su mayoría mobiliario.
La co-simulación es donde las pequeñas mentiras se vuelven caras
Un solo FMU ya es bastante trabajo. Varios FMU acoplados entre sí es donde los errores numéricos y operativos se vuelven sociales. Un modelo térmico alimenta a un modelo de control, el modelo de control alimenta a un modelo de actuador, el modelo de actuador alimenta a un modelo mecánico, y todos esperan que el orden de los pasos no esté creando silenciosamente un sinsentido. La co-simulación necesita gestión de conexiones, orden de ejecución, intercambio de datos, coordinación de pasos, manejo de bucles algebraicos y una forma de decir no cuando el grafo es incorrecto.
El código fuente tiene fmi-orchestration para ese trabajo. Gestiona la co-simulación de múltiples FMU, conexiones, detección de ciclos, ordenamiento topológico, programación de particiones, detección y resolución de bucles algebraicos, historial de valores, orden de ejecución, tiempo de simulación y estadísticas de orquestación. Existe fmi-cc para la comunicación entre FMU acoplados y fmi-dist para la ejecución distribuida con coordinadores, registro de nodos, mensajes, solicitudes de paso, respuestas de paso y valores de estado. Ese es el tipo de maquinaria que la gente olvida cuando dice que la integración es simplemente conectar salidas a entradas. Es cableado, sí. También es sincronización, gestión de dependencias, estado, fallos y la prueba de que el cableado hizo lo que decía.
La co-simulación también hace que la determinación sea más importante, no menos. Si un FMU se desvía ligeramente y ese valor alimenta a otro FMU, el desacuerdo puede propagarse. Si el orden de ejecución cambia entre nodos, el desacuerdo puede ocultarse hasta un paso posterior. Si un backend utiliza una ruta matemática ligeramente diferente, el desacuerdo puede parecer comportamiento del modelo. Así es como los equipos terminan depurando física con actas de reuniones. Nadie debería tener que hacer eso a menos que haya sido muy malo en una vida anterior.
Los backends son opciones de despliegue, no nuevas verdades
El árbol de fuentes separa los objetivos de ejecución en crates de backend: CPU, GPU, FPGA, edge y distribuido. El backend de edge se centra en dispositivos con recursos limitados, memoria acotada y baja sobrecarga. El backend de FPGA habla de aritmética de punto fijo, transferencias DMA, gestión de bitstreams, ejecución de kernels y hardware-in-the-loop. El crate distribuido coordina múltiples nodos. La página pública describe las rutas de CPU SIMD, GPU, FPGA, edge y distribuido. Eso no significa que cada objetivo esté igualmente maduro para cada carga de trabajo. Significa que la arquitectura trata la elección de backend como una preocupación de primera clase.
El principio de diseño crucial es que el despliegue debería cambiar dónde se ejecuta la simulación, no qué significa la simulación. Una ruta de CPU puede ser la más fácil para la autoría y la verificación. Una ruta de GPU puede tener sentido para cargas de trabajo paralelas grandes. Una ruta de FPGA puede ser necesaria para tiempo real o hardware-in-the-loop. Una ruta de edge puede ser necesaria cerca de la máquina. La ejecución distribuida puede ser necesaria para sistemas acoplados grandes. Esas son opciones operativas. No deberían crear una nueva identidad numérica para el modelo.
Aquí es también donde el código abierto importa. En seguridad, energía, robótica, dispositivos médicos, automoción, aeroespacial, control industrial y gemelos digitales, las afirmaciones de reproducibilidad no pueden vivir solo en las diapositivas de los proveedores. Alguien tiene que inspeccionar la implementación, fijar una versión, ejecutar las pruebas, leer los casos de fallo y decidir si la evidencia es suficientemente buena. Una implementación FMI de código abierto da a los equipos una mejor ruta hacia esa evidencia. No certifica nada mágicamente. Hace que el trabajo sea inspeccionable, que es el primer paso útil.
La validación debería ser una puerta, no un panel
La historia de validación de Dweve FMI no trata solo de trazas bonitas. El README y el sitio describen comprobaciones de referencia MPFR, equivalencia entre backends, reproducción determinista, pruebas de conformidad, fuzzing y fallos tipificados. El código fuente tiene fmi-test, fmi-fuzz, fmi-bench, fmi-conformance, pruebas de propiedades, harnesses de fuzzing y serialización de estado. Esa es la dirección correcta. En infraestructura de simulación, la validación no debería ser un panel donde una línea roja parezca preocupante y alguien prometa vigilarla. Debería ser una puerta.
La puerta tiene varias partes. La importación tiene que analizar correctamente el archivo FMU y modelDescription. La validación de esquema tiene que rechazar definiciones de variables, dependencias, relojes y atributos inválidos. Las comprobaciones numéricas necesitan un oráculo cuando la afirmación es precisión. La paridad de backend necesita el mismo estado en todos los objetivos de ejecución. La reproducción necesita estado guardado y registros de eventos para reconstruir la ejecución. El fallo necesita errores tipificados, no un informe de discrepancia misterioso que envíe al equipo a bucear entre registros. Una discrepancia debería bloquear una ruta de lanzamiento hasta que se entienda o se acepte explícitamente. Eso suena duro solo si la alternativa aún no te ha pasado la factura.
Dónde importa primero
Los ámbitos evidentes son aquellos donde un error de simulación se convierte en un error físico: automoción, aeroespacial, control industrial, dispositivos médicos, energía, robótica e infraestructuras. Un modelo de freno, un controlador de bomba, un modelo de red eléctrica, una célula robótica, una línea de fábrica o un controlador de HVAC no se vuelve más seguro porque una diapositiva diga gemelo digital. Se vuelve más seguro cuando el modelo, las entradas, el perfil numérico, el backend, la versión y el rastro de reproducción están lo bastante controlados como para poder investigarlos.
También hay un ángulo de contratación, porque por supuesto lo hay. Si cada backend exige una historia de validación independiente, cada cambio de hardware se convierte en un pequeño ejercicio de recertificación. Si el mismo FMU puede demostrarse una vez y luego ejecutarse en el objetivo que se ajusta a la restricción operativa, los equipos ganan libertad sin fingir que la validación es gratis. El sitio lo expresa como demostrar una vez y ejecutar en cualquier lugar. La traducción técnica es algo menos romántica: reducir el número de lugares donde el mismo modelo puede discrepar consigo mismo.
Esto es especialmente relevante en Europa. La soberanía no es solo dónde está el servidor. También es si un caso de seguridad puede inspeccionarse, repetirse y trasladarse sin suplicar permiso a un proveedor. Una implementación abierta, aritmética determinista, reproducción reproducible y paridad de backend no resuelven la política por sí solas. Hacen que la parte técnica dependa menos de una caja negra con un equipo de ventas adjunto.
Qué revisar antes de confiar en ello
La primera pregunta de revisión es qué superficies de FMI 3.0 utiliza realmente tu modelo. Model Exchange, Co-Simulation, Scheduled Execution, relojes, derivadas, eventos, variables binarias, cadenas, arrays y dependencias no son la misma carga de trabajo. Un FMU simple y una simulación acoplada de múltiples FMU ejercen presiones diferentes sobre el runtime y el orquestador.
La segunda pregunta es qué perfil numérico declara el modelo y por qué. Si la respuesta es el que funcionó por defecto en el ejemplo, eso no es un diseño. El perfil debe coincidir con el rango, la resolución, la representación temporal, la tolerancia y el objetivo de despliegue. Debe ser lo bastante visible para que un revisor pueda cuestionarlo sin leer todo el solver.
La tercera pregunta es qué evidencia viaja con un resultado. ¿Qué versión de la fuente? ¿Qué versión del FMU? ¿Qué modelDescription? ¿Qué perfil Numerus? ¿Qué backend? ¿Qué comprobaciones de oráculo? ¿Qué estado de reproducción? ¿Qué pruebas de conformidad o de propiedades? Si esas respuestas están dispersas en una wiki y en la memoria de alguien, la simulación aún no está lista para ser confiable en un flujo de trabajo serio.
La lección
La lección de Dweve FMI no es que los estándares de simulación sean aburridos. Son aburridos exactamente de la manera en que los puentes son aburridos cuando se mantienen en pie. FMI proporciona el envoltorio de intercambio. El punto fijo respaldado por Numerus proporciona la postura aritmética determinista. Los crates de runtime y solver hacen avanzar el modelo. La orquestación conecta los FMU sin fingir que la sincronización es trivial. Los backends mueven la ejecución al hardware que se ajusta al trabajo. La validación convierte la igualdad en una puerta en lugar de una esperanza.
Ese es el trabajo. No una gran afirmación de que los números están resueltos para siempre. No una demo brillante donde todo coincide porque solo se probó un camino. Un sistema de simulación que conoce sus formatos, declara su contrato numérico, se ejecuta en múltiples backends y falla ruidosamente cuando el mismo modelo deja de ser el mismo modelo.
El modelo no debería desarrollar una personalidad. Ya tenemos suficientes en las reuniones.