Fortran Arrays in C++ ausdrücken



  • Guten Morgen @ all,

    ich bin dabei ein paar alte Codes von Fortran nach C++ zu übersetzen. Dabei habe ich das Gefühl das meine Lösung für Arrays höchst ineffizient ist. Vieleicht könnt ihr mir ein paar Tips geben wie man es besser machen kann.

    Es handelt sich um Konstrukte wie diesen

    PROGRAM
    REAL*8 A(-1:nx+1,-1:ny+1,10)
    INTEGER nx, ny
    
    CALL FOO(A(-1,-1,5), nx, ny)
    END
    
    SUBROUTINE FOO(Arr2D, nx, ny)
    INTEGER nx, ny
    REAL*8 Arr2D(-1:nx+1, -1,ny+1)
    
    ...
    
    RETURN
    END
    

    Nun das die Indizes nicht bei 0 Anfangen habe ich über eine Klasse mit dem operator() gelöst. Das ist aber schon unschön da ich für je für 1D, 2D, ..., 7D eine eigene Klasse bauche.
    Für die Übergabe an FOO ist mir nicht dümmeres eingefallen als die Referenz von A(-1, -1, 5) zu übergeben und den Zeiger in FOO auf eine 2D Klasse zuzuweisen. Die Klasse ist im Konstruktor so geschrieben, das wenn sie einen Zeiger als letztes Argument erhält den Speicher als gegeben annimmt und nicht allokiert/deallokiert.

    Das sieht dann etwa so aus

    int main()
    {
      int nx = 5;
      int ny = 5;
      FtnArr3D(-1, nx+1, -1, ny+1, 1, 10); // allokiert den Speicher
    
      FOO(&A(-1, -1, 5));
    }
    
    void FOO(void* __a, int nx, int ny)
    {
      FtnArr2D(__a, -1, nx+1, -1, ny+1); // Speicher wird nicht allokiert
    }
    

    Wie könnte das besser vor allem effiezienter gestaltet werden?


  • Mod

    andreasgeorg schrieb:

    Wie könnte das besser vor allem effiezienter gestaltet werden?

    Indem man nicht versucht, in C++ FORTRAN zu programmieren. Es ist zwar bekannt, dass man in jeder Sprache FORTRAN programmieren kann, aber ich bin mir nicht so ganz sicher, ob das so 100% ernst gemeint ist 😉 .

    Was ist denn deine Motivation, Iteratoren, Templates & Co. gegen selbstgefrickelte Arrays zu tauschen?



  • Die Frage ist schon ernst gemeint.

    Der Hintergrund ist das wir hier z.T. sehr alte Fortran Codes haben aber diese aber nicht komplet neu entwickeln wollen.

    Das mit den selbst gefrickelten Arrays war mein erster Versuch mit der aus FORTRAN gegebenen Speicherstruktur umzugehen. Das das keine gute Lösung wird hatte ich ja Eingangs schon geschrieben. Mir fehlt halt nur so der Ansatz wie ich mit Indizes ungleich 0 und der Übergabe eines z.B. 3D Arrays als 2D Array umgehen soll/kann.


  • Mod

    andreasgeorg schrieb:

    Der Hintergrund ist das wir hier z.T. sehr alte Fortran Codes haben aber diese aber nicht komplet neu entwickeln wollen.

    Man kann durchaus Fortran und C++ in einem Programm mischen. Wird schließlich alles compiliert. Man muss bloß einen gemeinsamen Nenner bei den Datenstrukturen finden.

    Das mit den selbst gefrickelten Arrays war mein erster Versuch mit der aus FORTRAN gegebenen Speicherstruktur umzugehen. Das das keine gute Lösung wird hatte ich ja Eingangs schon geschrieben. Mir fehlt halt nur so der Ansatz wie ich mit Indizes ungleich 0 und der Übergabe eines z.B. 3D Arrays als 2D Array umgehen soll/kann.

    Ist das denn so schwer, Arraycode leicht anzupassen, dass er bei 0 anfängt und dass die Übergaben im C++-Stil sind? Du musst doch sowieso Zeile für Zeile übersetzen, wenn du den Fortrancode nach C++ übertragen möchtest. Da kann man doch auch ein paar Indizes anpassen.



  • Bitte auch daran denken, dass FORTRAN Arrays in Column Order (also Spalte zuerst und dann Zeilen) ablegt und C/C++ etc als Row Order (Zeile zuerst, dann Spalte). Du solltest also externe Daten transponieren, bevor Du sie in C++ verarbeitest.


  • Mod

    multi_array oder auch std::valarray sind ggf. einen Blick wert.



  • RowOrder schrieb:

    Bitte auch daran denken, dass FORTRAN Arrays in Column Order (also Spalte zuerst und dann Zeilen) ablegt und C/C++ etc als Row Order (Zeile zuerst, dann Spalte). Du solltest also externe Daten transponieren, bevor Du sie in C++ verarbeitest.

    Vielen Dank für den Hinweis, das ist mir bewußt - habe ich auch in meiner Frickellösung beachtet.

    camper schrieb:

    multi_array oder auch std::valarray sind ggf. einen Blick wert.

    Danke, werde ich mir mal ansehen.


Anmelden zum Antworten