Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Trying To COnvert inherited code to F90

  1. Jul 20, 2014 #1
    I have least squares code which I am trying to rewrite in FORTRAN90.
    I have a pair of allocatable arrays declared in MAIN. I pass those unallocated
    arrays to a subroutine where the arrays are allocated and data is assigned.
    However, I get segmentation faults every time I try to run this section of code.

    The salient pieces of code are:
    (from MAIN)
    IMPLICIT NONE
    REAL, ALLOCATABLE, DIMENSION(:) :: X,Y
    ...
    CALL GETDATA(X,Y,N)
    ...
    SUBROUTINE GETDATA(X,Y,N)
    REAL, ALLOCATABLE, DIMENSION(:) :: X,Y
    ...(read in values from file - this works)
    ALLOCATE(X(N), Y(N))
    !N has been determined earlier - and the value is correct.

    When I hit the allocate statement, the program dies. This code should work and I am unsure why it is not. If I do this in main I have no problem. But I do not understand why passing values via a subroutine causes problems.

    Any ideas why this code may not work would be appreciated.

    THanks!
     
  2. jcsd
  3. Jul 20, 2014 #2

    sophiecentaur

    User Avatar
    Science Advisor
    Gold Member

    You use IMPLICIT NONE so, presumably, N is declared somewhere - and also in the subroutine?
    I don't know the more 'recent' versions of Fortran but I do know it does not look after you with arrays and data types like the more modern languages.
    Sorry if that is too trivial an answer but I don't know your level of familiarity with Fortran.
     
  4. Jul 20, 2014 #3
    Sophie,

    I do declare N as an integer in the subroutines. Since I can use subroutines to communicate with MAIN I did not think it necessary to declare it in the MAIN. I would say I have a reasonable experience base with FORTRAN90, though I do not consider myself a world-class developer, just a competent coder.

    If you have further remarks, please do drop them. Since the problem occurs in the subroutine, I am not sure declaring N in the MAIN will have any effect.
     
  5. Jul 20, 2014 #4

    SteamKing

    User Avatar
    Staff Emeritus
    Science Advisor
    Homework Helper

    Since you pass N to the subroutine from a CALL statement in the Main Program, all of the arguments for the subroutine must be declared the same type in both the Main Program and the subroutine itself. If N is declared as INTEGER in the sub, it must also be declared as N in the Main Program, otherwise the data will not align properly, which might be why you're getting segment faults during execution.
     
  6. Jul 20, 2014 #5

    sophiecentaur

    User Avatar
    Science Advisor
    Gold Member

    I remember hearing all sorts of things about how Fortran can let you break the rules. Belt and braces would be my motto.
    When Fortran started life, they had very little speed or memory and there was no time to look after the user. You could even change a constant (eg 1) into another (eg 2) on the way through a subroutine.
     
  7. Jul 20, 2014 #6

    SteamKing

    User Avatar
    Staff Emeritus
    Science Advisor
    Homework Helper

    Whatever. That may have been then, but we are dealing with the here and now.

    The variables passed by the Fortran main program to the subroutine and back again are passed by reference, not by value, as in other languages. If the variables in the subroutine definition don't match up with the variables in the CALL statement, then the program may stray into a portion of the memory where it doesn't belong.

    All the OP has to do is make sure his variable type declaration statements in the main program and the subroutines match up. This shouldn't be an insurmountable task.
     
  8. Jul 20, 2014 #7

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    I'm surprised the OP didn't get a compile error, or at least a warning that N was not declared in main, given the IMPLICIT NONE statement.

    In gfortran, trying to compile
    Code (Text):

    program mainprog
    implicit none
    real x,y
    call sub(x,y,n)
    end
     
    gave me the error I expect to see:
    Code (Text):

    call sub(x,y,n)
                  1
    Error: Symbol 'n' at (1) has no IMPLICIT type
     
     
  9. Jul 20, 2014 #8

    sophiecentaur

    User Avatar
    Science Advisor
    Gold Member

    Which is precisely how the constant 1 can become changed in to a 2. The system was efficient in its use of memory, using that method but it could easily allow the overlaying of two different data types on the same memory location. A constant, written in the code is / was treated as a variable, called 1, with value 1 and it could be read or written to as if it were any other data type. That could not happen if the Implicit None statement were used.

    If there was not a compile error reported then it seems the same thing can still happen. I am surprised, though. Perhaps the actual problem is not in the code we have been shown and there is something more subtle at work. It wouldn't be the first time.
     
  10. Jul 20, 2014 #9
    The irony of showing partial code is that it is already filtered out by the OPs perception of where the problem is...which is a bad idea as, clearly, the OP does not know exactly where the problem is; otherwise, s/he wouldn't be asking for help.

    Please show the entire source code and enclose it with CODE tags (first "go advance" and then click on the icon with the # symbol, then paste the code in between tags).
     
  11. Jul 20, 2014 #10

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    Unless the OP is using an ancient computer or compiler, that is history. These days constants are stored in read-only memory, so you can't overwrite them (but you can crash your program if you try).

    Implicit None didn't prevent overwriting constants.

    FWIW in Fortran 90 you can declare "interfaces" to functions and subroutines, so that the compiler can do full type checking on the arguments. You can explicitly declare that arguments are for input, output, or both, which generate compile-time errors if you break your own rules.
     
  12. Jul 20, 2014 #11

    sophiecentaur

    User Avatar
    Science Advisor
    Gold Member

    DO you really mean ROM? How would that work? - you would need to store a lot of them! But you probably mean something else.

    Yes, I totally agree. I was just showing how wide open Fortran used to be. I wonder why anyone would want to be working in Fortran these days - except for legacy stuff.
     
  13. Jul 20, 2014 #12

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    Modern computer operating systems have the capability of enforcing that areas of memory are read-only to a particular program. When you compile and link the program, the linker creates several "segments" containing different types of data with different access options. When you load and run the program, the OS sets up the "read-only" data in RAM and then denies the program the option to write to it.

    Apart from killing a few old Fortran bugs, this is also useful as a security measure. Malware is also interested in overwriting bits of your program if it gets the opportunity.
     
  14. Jul 20, 2014 #13

    FactChecker

    User Avatar
    Science Advisor
    Gold Member

    Are you reading the data into X and Y or into another storage space? Are X and Y allocated before the data is stored into them?
     
  15. Jul 21, 2014 #14

    FactChecker

    User Avatar
    Science Advisor
    Gold Member

    It look like the allocate in the subroutine requires a SAVE attribute if you want X and Y to remain valid when the program leaves the subroutine.
     
  16. Jul 22, 2014 #15

    sophiecentaur

    User Avatar
    Science Advisor
    Gold Member

    I seem to remember COMMON and EQUIVALENCE commands, too.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Trying To COnvert inherited code to F90
Loading...