Aumentando la longevidad de archivo del código

11

¿Existe una lista publicada de las mejores prácticas para garantizar la longevidad del código, con miras a resultados científicos reproducibles? (por ejemplo, código abierto, prácticas de documentación, selección de dependencias, selección de un idioma, máquinas virtuales, etc.).

Conozca cualquier estudio (o falta de eso, ejemplos / anécdotas) que haya intentado estimar la vida media de un código científico típico u otro software (¿si es una pregunta razonable?)

cboettig
fuente

Respuestas:

8

Me viene a la mente la longevidad planificada de TeX:

“Desde esos comienzos en 1977, el proyecto de investigación de TeX en el que me embarqué fue impulsado por dos objetivos principales. El primer objetivo era la calidad: queríamos producir documentos que no solo fueran agradables, sino que realmente fueran los mejores. (...) El segundo objetivo principal era el archivo: crear sistemas que fueran independientes de los cambios en la tecnología de impresión tanto como sea posible. Cuando llegó la próxima generación de dispositivos de impresión, quería poder retener la misma calidad ya lograda, en lugar de tener que resolver todos los problemas de nuevo. Quería diseñar algo que aún pudiera usarse en 100 años. "- Donald E. Knuth: Tipografía digital, p. 559 (citado de http://de.wikipedia.org/wiki/TeX )

Basado en los libros de Knuth sobre tipografía digital, incluso una reimplementación completa de TeX y METAFONT debería ser posible. Incluyen anotaciones y explicaciones para todo el código.

Al exigir que sus resultados sean estables durante décadas, se enfrenta a un tipo de dilema de congelación. Por un lado, desea facilitar la reproducción de sus resultados al 100%, por lo que congela su software / entorno. Por otro lado, alguien que esté interesado en reproducir sus resultados en el futuro seguramente querrá aprovecharlo. Esta persona estará atrapada con un software muy antiguo, lo que hace que sea muy difícil cambiar algo. Para todo lo que se basa en varios paquetes externos, unos pocos años son suficientes para hacer que las cosas sean prácticamente inmutables.

Para TeX, la congelación se anuncia en el artículo de 1990

El futuro de TEX y METAFONT http://www.ntg.nl/maps/05/34.pdf

"Creo firmemente que un sistema inmutable tiene un gran valor, a pesar de que es axiomático que cualquier sistema complejo pueda mejorarse. Por lo tanto, creo que no es prudente realizar" mejoras "adicionales en los sistemas llamados TEX y METAFONT. Consideremos estos sistemas como puntos fijos, que deberían dar los mismos resultados dentro de 100 años que producen hoy ".

El sistema ideal combinaría la reproducibilidad con la capacidad de cambio. Intentar ser tan autónomo, simple y bien probado como sea posible sin duda ayuda.

Disculpe si estaba desviando demasiado de la pregunta original. [Publicación cruzada de 'Científicos para la investigación reproducible', [email protected]]

Litera Matthias
fuente
Gracias por traer esto sobre Matthias. Y bienvenido a scicomp!
Aron Ahmadia
2
Creo que el ejemplo de TeX en realidad no es muy bueno, aunque generalmente se considera el caso clásico de un sistema congelado. Creo que la razón es que ya nadie usa TeX directamente. Las personas usan látex junto con su infinidad de paquetes y no están congelados. Como consecuencia, creo que los documentos (La) TeX están tan sujetos a cambios como todo lo demás. Para mí, TeX es como una máquina virtual: puede mantenerlo congelado, pero mientras el código construido sobre él siga cambiando, no se gana nada.
Wolfgang Bangerth
Gracias, creo que este es un excelente estudio de caso desde el punto de vista del desarrollo de software, que puede ser bastante diferente del punto de vista científico. El hecho de que todo el mundo necesite construir indirectamente sobre TeX puede no ser ideal para un software ampliamente utilizado, pero puede ser una demostración ideal de que el código científico aún podría ejecutarse con éxito y desarrollarse décadas después. ¿Pero seguramente Knuth hizo más simplemente para evitar cambios y actualizaciones para lograr una estabilidad de 100 años?
cboettig
4

Existen muchos desafíos técnicos que hacen que la reproducibilidad exacta bit por bit de los resultados computacionales sea extremadamente difícil de lograr.

A nivel de software, los cambios en el código o en cualquiera de las bibliotecas utilizadas por el código obviamente pueden causar resultados diferentes. Te sorprendería la cantidad de bibliotecas de soporte que pueden terminar vinculadas a un código científico típico.

En un nivel inferior, recompilar cualquiera de los códigos o cualquiera de las bibliotecas utilizadas por el código con un nuevo compilador o con diferentes optimizaciones de compilador activadas también puede causar problemas. Una razón es que varias operaciones en el código pueden realizarse en un orden diferente cuando se vuelve a compilar el código. Como la adición de coma flotante no es asociativa (a + b) + c <> a + (b + c), esto puede dar resultados diferentes.

Bien, ¿y si conservamos todo el entorno de software (SO, bibliotecas y código compilado) (p. Ej.) Grabándolo en un CD-Rom de arranque que ejecutará el código. Ahora, ¿podemos estar seguros de que obtendremos los mismos resultados si ejecutamos este código en una computadora diferente?

Sorprendentemente, algunos códigos realmente varían el orden de los cálculos en función de los aspectos del modelo de procesador particular en el que se están ejecutando. Por ejemplo, las bibliotecas de álgebra lineal optimizadas suelen dividir las multiplicaciones de matrices para trabajar en bloques que se adaptarán a la memoria caché. Cuando Intel lanza un nuevo microprocesador con una memoria caché más grande, el código puede ajustar dinámicamente el tamaño del bloque, lo que resulta en una aritmética que se realiza en un orden diferente y da resultados diferentes. Otros códigos ajustan dinámicamente el orden de los cálculos en función de la cantidad de memoria disponible, si ejecuta el código en una computadora con más memoria que bien podría hacer que la aritmética se realice en un orden diferente y, por lo tanto, arroje resultados diferentes.

Las cosas se vuelven increíblemente más complicadas cuando agregas código multiproceso, ya que el historial de ejecución exacto de los diferentes hilos a menudo no es determinista y esto puede hacer que las operaciones aritméticas se realicen en un orden diferente de una ejecución a la siguiente.

En la práctica, lo máximo que realmente puede esperar son resultados similares de una máquina a otra, hasta las tolerancias de precisión de los algoritmos utilizados. por ejemplo, si tengo un problema de búsqueda de raíz y uso la bisección para obtener una raíz dentro de + -1.0e-10, entonces debería estar contento siempre que diferentes máquinas produzcan respuestas que estén de acuerdo con esa tolerancia.

Brian Borchers
fuente
Por cierto, el problema con las diferentes versiones del compilador explica por qué realmente no es suficiente distribuir una versión "congelada" del código fuente: el código compilado que se produce puede variar según la versión del compilador que se use y esto puede conducir a resultados diferentes.
Brian Borchers
2

Ha habido muchos intentos de hacer posible la reproducibilidad y hay toda una literatura sobre este tema. Mi opinión personal de 15 años de software científico es que no es realista, tan insatisfactorio como encuentro esa respuesta. Los problemas son que (i) el software complejo tiene errores y, por lo tanto, no se puede congelar; (ii) el software nunca tiene características completas y por lo tanto el desarrollo continúa; (iii) ¿cuál es el valor de entregar en papel varios cientos de miles de líneas de código?

Como digo, esta respuesta me parece insatisfactoria. Creo que, como campo, la ciencia computacional no ha tenido mucho éxito en la producción de literatura que infunde confianza en que los resultados que publicamos son correctos y reproducibles. Al mismo tiempo, realmente no puedo encontrar formas de hacer las cosas mejor. Por supuesto, es útil liberar el código fuente que acompaña a un documento. Al mismo tiempo, todos los que sean honestos estarán de acuerdo en que los resultados en un documento generalmente serán producidos por diferentes versiones del código que, en la mayoría de los casos, contienen hacks que describen diferentes condiciones de contorno, diferentes lados a la derecha, etc. vienen con diferentes versiones del mismo código. Para empezar, esto es incómodo para el lector, pero es totalmente improductivo si el código es grande, como sucede a menudo hoy en día: mis dos documentos más recientes usaron códigos que tienen alrededor de 20,000 líneas de código y que se basan en el trato. II (600,000 líneas de código) y Trilinos (1.5M líneas de código). ¿Qué información proporciona eso a un lector potencial? (Debo decir que, sin embargo, mis códigos están disponibles).

Wolfgang Bangerth
fuente
2
Soy menos pesimista pero aún insatisfecho. Puede informar fácilmente la etiqueta de control de revisión o el número de revisión asociado con el código que produjo los resultados en cualquier documento dado, y un autor totalmente escrupuloso volvería a ejecutar todos los resultados importantes para un artículo determinado con una base de código. No creo que necesite entregar el código en sí si hay un sistema de control de revisión, es de acceso público y las etiquetas están publicadas.
Bill Barth
Claro, podrías hacer eso. La pregunta es simplemente qué haría un lector con la masa de código que le arrojas. Sí, puede ejecutarlo y verificar que los resultados sean los mismos que se muestran. ¿Pero qué demuestra eso? ¿Cómo va a verificar alguien, en la práctica real, no en teoría, que los resultados son correctos?
Wolfgang Bangerth
No, esa es la parte con la que estoy totalmente de acuerdo. A menos que piense que eres una persona sin escrúpulos, no necesito volver a ejecutar tu código para reproducir las respuestas exactamente. Creo que la pregunta más importante es si ha demostrado suficientemente que ha verificado su implementación y si eso se puede validar o no con los experimentos.
Bill Barth
Gracias, pero siento que esto no responde a la pregunta. Ciertamente, hay un amplio espacio para debatir por qué es útil tener código disponible 15 años después , pero en esta pregunta simplemente pregunto si ese código aún se ejecutaría para la mayoría de las personas, dado que lo archivó. Estoy familiarizado con la literatura que alienta el archivo de códigos, pero nadie alentó un archivo global para tarjetas perforadas hace 40 años. ¿Ha aumentado o disminuido la tecnología la vida media del software? Si el código archivado sigue el camino del telégrafo dentro de 5 años, los otros problemas quedan en silencio de todos modos.
cboettig
Estoy bastante seguro de que puede obtener el código escrito hace 15 años para que se ejecute hoy, si con una buena cantidad de trabajo. Estoy seguro de que puede obtener códigos bien escritos a partir de hoy para ejecutarse en 15 años.
Wolfgang Bangerth
2

Para una posible solución a este problema, vea mi proyecto ActivePapers . En resumen, describe cómo los datos y el código pueden empaquetarse junto con dependencias explícitas en versiones específicas de cada componente de software. Esto hace posible reproducir exactamente un cálculo, al tiempo que permite ejecutar software actualizado en los mismos datos.

Debo agregar que ActivePapers no es más que una prueba de concepto y es poco probable que sea de utilidad práctica en el futuro cercano. La razón es que se basa en el principio de que todo el código ejecutable debe existir como código de bytes JVM. Por el momento, esto excluye demasiadas bibliotecas científicas populares. Sin embargo, una vez que se reconoce que la reproducibilidad es importante, las prioridades en las herramientas de programación también pueden cambiar.

Khinsen
fuente
1

Creo que, en lo que respecta a la elección del lenguaje, usar uno estandarizado (por ejemplo, C / Fortran / C ++) calificaría como "mejor práctica". Si un paquete depende de otros 10 libs / paquetes, especialmente aquellos escritos en idiomas oscuros, obviamente eso es malo para la longevidad. Muchos proyectos terminan siendo huérfanos después de un tiempo. No creo que las principales librerías / apis como BLAS / LAPACK, PETSc, FFTW, MPI, etc. desaparezcan pronto. BLAS ya es bastante viejo.

El siguiente código (robado de http://www.math.utah.edu/software/c-with-fortran.html ) es anterior a Fortran 77, utiliza constantes de Hollerith para la manipulación de caracteres pero se compila muy bien 40-50 años después con el compilador GNU Fortran:

stali@x61:~$ cat olde.f

       CALL S(12HHello, world, 12)
       END
       SUBROUTINE S(MSG,N)
       INTEGER K, N, M
       INTEGER MSG(1)
       M = (N + 3) / 4
       WRITE (6,'(20A4)') (MSG(K), K = 1,M)
       END

stali@x61:~$ gfortran -std=legacy olde.f; ./a.out
Hello, world

El código abierto / ponerlo en algún lugar como googlecode, que es menos probable que desaparezca pronto (aunque cerraron la búsqueda de código) es obvio.

stali
fuente
Gracias por el ejemplo! Me gustaría ver comparaciones en otros idiomas, incluidos los lenguajes de secuencias de comandos: ¿los primeros códigos escritos en perl, python o R aún se ejecutan con los mismos resultados? ¿Son más propensos a hacerlo o menos propensos que C o Fortran?
cboettig