2008-11-09 15 views
14

¿Alguien ha convertido un programa grande (el nuestro es de 550,000 líneas) de Fortran 77 a C++? ¿Qué trampas te encontraste? ¿Fue la conversión un éxito? ¿Utilizaste una herramienta como for_c (http://www.cobalt-blue.com/fc/fcmain.htm)? ¿El código C++ resultante fue significativamente más rápido o más lento?Conversión del código de Fortran 77 a C++

+3

Oh wow, no te envidio :) –

+0

¿Por qué estás convirtiendo? –

+4

Conoces la vieja broma: "rm * f es una herramienta automática para convertir toda tu fuente fortran en bloques de disco libres para que puedas comenzar a escribirla correctamente". –

Respuesta

3

una vez que utilizaron esta: http://manpages.ubuntu.com/manpages/hardy/man1/f2c.html para convertir un pequeño programa FORTRAN a C. La conversión fue exitosa. El código no fue significativamente complejo para detectar cualquier tipo de cambio de velocidad.

Debido a que su programa está adjudicar grande que no se sabe muy bien si todo va a funcionar como lo hizo conmigo.

+0

Utilicé f2c en un código fortán de tamaño moderado hace varios años. El código de calidad ya deficiente (términos de legibilidad) se redujo a horrendo después de pasar por la traducción. Tomó un montón de esfuerzo manual para pulir a C legible. – nsanders

9

Hay muchas cosas que considerar.

En realidad, hay dos caminos a seguir. Una es hacer una conversión directa línea por línea a c. Con eso me refiero a cada declaración fortran a un enunciado c equivalente.

El otro camino a seguir es una reescritura, y con 500k + loc eso sería mucho más trabajo. Con ese tipo de tamaño, ciertamente buscaría una herramienta para hacer la traducción, como f2c.

Cuestiones para un puerto recta ...

GOTOS traducen directamente, tendrá que crear etiquetas para los objetivos Goto.

label10:; 

    goto label10; 

La matriz de subscriptores es un problema potencial. c está basado en cero, fortran está basado en 1, por lo que las matrices deben dimensionarse una más grande en el código fortran.

real * 4 bis (10,20) se convierte en

#define XMAX 10 + 1 
#define YMAX 20 + 1 
float a[XMAX][YMAX]; 

permitiendo que el bucle que se escribe así.

for (x = 1; x <= XMAX; x++) 
    for (y = 1; y <= YMAX; y++) 
     a[x][y] = 0.0f; 

acceso c matriz es en orden de fila mayor, mientras FORTRAN es importante columna. que puede ser un problema de rendimiento. si se convierte en un problema, puede resolverlo con algún tipo de definición de macro que invierta el orden o los subíndices de la matriz. De hecho, también podría hacer que el macro restara uno de cada uno de los subíndices para que pareciera una matriz basada en uno, en realidad se correlacionara con una matriz basada en cero.

real * 8 bis (xmax, YMAX) un (4,2) = 3,14

#define A(X,Y) a[Y][X] 
double a[XMAX][YMAX]; 
A(4,2) = 3.14; 

de unidad Fortran io se pueden simular con archivos de tipo stdio. si está utilizando la unidad 19, a continuación,

FILE *fp19 = fopen("file","mode"); 

Puede haber problemas con el control del carro si está utilizando control de carro FORTRAN en sus archivos. Las unidades 5 y 6 se pueden referenciar simplemente con stdin y stdout sin fopen.

Se pueden gestionar muchos formatos con la familia de funciones printf. Puede que tenga que agregar bucles adicionales para lidiar con algunos de los arreglos Fortran io.

WRITE (6, 200) (proy (z, 4), z = 1, 20)

int z; 
for (z = 1, z <= 20; z++) 
    printf("%lf ", proj[z][4]); 


o usando f2c es probablemente la manera más rápida de hacerlo. Entonces estás atrapado con su rtl.
o hacer un puerto directo es una cosa factible de hacer. Tiempo, pero posible
o si desea mantenerlo a largo plazo, recomendaría una reescritura. Muy lento, probablemente más rápido, pero más fácil de mantener a largo plazo

Afortunadamente, en cualquier caso, tiene el programa original para utilizar como referencia para realizar un conjunto de pruebas unitarias que ayuden en el esfuerzo de desarrollo.

+0

Sí, me he estado preguntando sobre la matriz de subíndices. En realidad, no me preocupan las matrices de una sola dimensión, sino las matrices de múltiples dimensiones. Por cierto, FOR_C tiene su propia RTL también que sustituye tes para ESCRIBIR y LEER. –

+0

f2c es una herramienta útil si desea compilar Fortran 77 y tener un compilador de C. Es increíblemente malo si quieres convertir Fortran en C o C++ y hacer cualquier cosa con el código generado que no sea compilarlo. –

9

Esto se suma al consejo de EvilTeach. Tenga en cuenta que es bastante fácil codificar Fortran 77 y C/C++, por lo que puede convertir partes de su aplicación de forma incremental y vincularlas con las partes antiguas. Tendrá que pensar en todas las discrepancias de Fortran/c habituales (matrices de filas/columnas principales, indexación de matrices, etc.) si hace esto, pero le ahorraría el esfuerzo de depurar toda su base de código traducida automáticamente a la vez .

Hay muchos códigos híbridos de gran tamaño como este en los laboratorios nacionales (DOE), que tienen una inversión importante en el antiguo código Fortran. Si sigue esta ruta, puede considerar usar Babel, que se desarrolló para permitir que los componentes se compartan entre C, C++, Fortran, Fortran90, Python y Java, todo en la misma aplicación. La motivación para esto en los laboratorios es vincular modelos de física creados por diferentes equipos para simulaciones realmente grandes, pero también podría resultarle útil para la transición de su código. Se mantiene activamente y se usa en muchos proyectos, aunque puede ser un poco demasiado complejo para lo que estás tratando de hacer.

+0

ya. puerto incremental, una muy buena idea. – EvilTeach

+0

Sí, incremental sería factible. Por cierto, ya tenemos 10,000 líneas de código C y C++ en nuestra aplicación. El código F77 está en realidad en una DLL de Win32 que puede llamarse C, C++ o VB. –

2

Es posible que desee consultar Promula. Produce un código C más legible que muchos otros traductores automáticos. No he usado Promula directamente, pero he convertido una buena cantidad de Promula de C a C++. Es fácil limpiar el código C para C++ legal, pero por supuesto se necesita más esfuerzo para hacerlo realmente bueno en C++.

6

Mi reacción es por qué quieres convertirlo.

La cuestión de cómo desarrollar un producto con una gran base de código Fortran fue examinada por numerosas empresas en la década de 1990. Eso es si convertir, quedarse con Fortran o producir un híbrido. Creo que la mayoría optó por el enfoque híbrido, generalmente C++ para la interfaz de usuario y la base de código Fortran original en segundo plano.

Mi sugerencia es ver "Programación en varios idiomas utilizando C++ y FORTRAN 77" de Carsten Arnholm disponible en http://arnholm.org/software/cppf77/cppf77.htm En los primeros días de Internet, este documento estaba bien relacionado.

Este documento describe cómo tener una aplicación que contiene C++ y Fortran. No puedo decir si algunos de los detalles técnicos pueden estar desactualizados, pero este documento salió de un proyecto que quería utilizar C++ para su desarrollo, pero tenía una gran base de código Fortran.

También puede consultar "C++ científica y de ingeniería: una introducción con técnicas avanzadas y ejemplos" de Barton y Nackman, disponible en las buenas librerías. Este libro enseña C++ para los programadores de Fortran. Tiene algunos ejemplos de cómo escribir envoltorios para el código Fortran de C++. Es un buen libro de C++ que ignora el aspecto de Fortran. Fue escrito antes de que se estableciera el estándar, pero las diferencias no son muy grandes.

+0

En nuestra compañía, hemos descubierto que los programadores de Fortran son cada vez más difíciles de encontrar. – EvilTeach

0

He trabajado en una aplicación que, en esencia, fue un código convertido de FORTRAN utilizando for_c. El código que creó era horrible. Fue muy difícil de mantener ya que la mayor parte era indescifrable. Afortunadamente ese código era bastante estable y era raro que se tuviera que hacer algo al respecto.

Sin embargo, esto se hizo hace muchos años, alrededor de los primeros 16 años de Windows. Tal vez for_c es mejor ahora?