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

Should I use a Fortran module?

  1. Aug 16, 2014 #1
    Hello,

    I want to create one file test.f95 where i can keep all my subroutines and use them whenever i create a new program
    new.f95.

    Is the modules the right way to do it?? because when i create a file lets say test.f95 with the module and one other with my main program (new.f95) when i compile test.f95 i get this :

    /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
    (.text+0x20): undefined reference to `main'
    collect2: ld returned 1 exit status


    And if i try to compile my main program (new.f95) i get this:

    /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
    (.text+0x20): undefined reference to `main'
    collect2: ld returned 1 exit status

    My programs are:

    test.f95 ::

    module module1
    integer:: n
    contains

    recursive subroutine sub1(x)
    integer,intent(inout):: x
    integer:: y
    y = 0
    if (x < n) then
    x = x + 1
    y = x**2
    print *, 'x = ', x,', y = ', y
    call sub1(x)
    print *, 'x = ', x,', y = ', y
    end if
    end subroutine sub1

    end module module1

    new.f95 ::

    program main
    use module1
    integer:: x = 0
    print *, 'Enter number of repeats'
    read (*,*) n
    call sub1(x)
    end program main
     
  2. jcsd
  3. Aug 16, 2014 #2

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    What commands did you use to compile the programs?

    Code (Text):

    gfortran new.f95 test.f95
     
    works for me. Or if you want to compile the subroutines separately,
    Code (Text):

    gfortran -c test.f95
    gfortran new.f95 test.o
     
    Maybe the errors are because your IDE doesn't understand what you are doing. (Personally I tend to solve that problem by not using an IDE).
     
  4. Aug 16, 2014 #3
    i compile it using : f95 test.f95 -o test --> ./test

    f95 new.f95 -o new -->./new


    This doesnt work???
     
  5. Aug 16, 2014 #4

    Borek

    User Avatar

    Staff: Mentor

    It doesn't work, because you are not compiling whole project, only part of it. Compiler has no way of knowing where the missing procedures are - you have to tell it explicitly where they are. Either by giving a list of Fortran sources in the command line, or by giving list of sources to compile and objects containing already compiled sources in the "link ready" format.
     
  6. Aug 16, 2014 #5
    So i have to do it the way AlephZero described???
     
  7. Aug 16, 2014 #6

    Borek

    User Avatar

    Staff: Mentor

    Yes.

    It is also possible to use the make utility, then you need to put the information about files in the makefile - but IMHO for small, two file projects it doesn't make sense.
     
  8. Aug 16, 2014 #7

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    One extra comment on that: when you compile test.f95, you will create a "module interface file" called module1.mod. When the compiler reads the "use module1" statement in main.f95, it will automatically read module1.mod, or produce an error message if it can't find it. But the .mod file only contains information about the argument lists of the subroutines in the module, so the compiler can check you are calling them correctly. It doesn't contain the compiled code. You also have to tell the compiler to read test.o.

    Note, if you have several modules, it is simpler to have the module name the same as the source file name, so the code for "module1" is in module1.f95, and compiling it creates module1.mod and module1.o.

    Also, the Fortran 95 standard doesn't say how the module interface information should be stored, and some Fortran systems do store the module interface definition and the compiled code in the same file. But gfortan doesn't do that.
     
  9. Aug 16, 2014 #8

    jtbell

    User Avatar

    Staff: Mentor

    This doesn't work because 'test' does not contain a main program.

    This doesn't work because, although 'new' does contain a main program, it does not contain the subroutine 'sub1'.

    If you use the command:

    f95 new.f95 test.f95 -o new

    this should compile both source files, and link (combine) the output into 'new' which should be a complete executable program that you can run via the commad './new'.

    Or, if you want to do the compiling and linking separately for some reason, you can do this:

    f95 new.f95 -o new.o (creates a file 'new.o' which contains the compiled main program)
    f95 test.f95 -o test.o (creates a file 'test.o' which contains the compiled module with the subroutine)
    f95 new.o test.o -o new (links the two '.o' files and places the result in the executable 'new')
     
  10. Aug 18, 2014 #9
    Thank you all guys.

    I have one last question:

    When i compile my main program with the module (which contains one function and 2 subroutines) i get the following error:

    /tmp/ccToz1RS.o: In function `__statistictests_MOD_kstwo':
    StatiTests.f95:(.text+0x208): undefined reference to `probks_'
    collect2: ld returned 1 exit status

    are you guys familiar with what that means?? (my function name in probks and the module name is statistictests)
     
  11. Aug 18, 2014 #10

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    Without seeing the code, and exactly what you did to compile it, we are just guessing.
     
  12. Aug 18, 2014 #11

    jtbell

    User Avatar

    Staff: Mentor

    'ld' is the "linker" utility that f95 (and most other compilers on Unix-like systems) uses to link compiled modules together into an executable program. The error message means that your program wants to use something named 'probks_', and 'ld' can't find it. It's probably a subroutine or function named 'probks' (with the compiler adding the '_' internally).

    I can offer two guesses: (1) You've simply misspelled the name of one of your own subroutines when you call it. (2) Your program uses a subroutine or function named 'probks' from a third-party library, and you didn't specify the library when you tried to compile the program.

    If it's (2), how you specify the library in the compilation command depends on how and where it's installed on your system.
     
  13. Aug 18, 2014 #12
    MY FILE ( StatiTests.f95) WHICH CONTAINS THE MODULE:

    module StatisticTests

    implicit none



    contains




    SUBROUTINE kstwo(data1,n1,data2,n2,d,prob)
    INTEGER n1,n2
    REAL d,prob,data1(n1),data2(n2)
    !CU USES probks,sort
    INTEGER j1,j2
    REAL d1,d2,dt,en1,en2,en,fn1,fn2,probks
    call sort(n1,data1)
    call sort(n2,data2)
    en1=n1
    en2=n2
    j1=1
    j2=1
    fn1=0.
    fn2=0.
    d=0.
    1 if(j1.le.n1.and.j2.le.n2)then
    d1=data1(j1)
    d2=data2(j2)
    if(d1.le.d2)then
    fn1=j1/en1
    j1=j1+1
    endif
    if(d2.le.d1)then
    fn2=j2/en2
    j2=j2+1
    endif
    dt=abs(fn2-fn1)
    if(dt.gt.d)d=dt
    goto 1
    endif
    en=sqrt(en1*en2/(en1+en2))
    prob=probks((en+0.12+0.11/en)*d)
    return
    END

    FUNCTION probks(alam)
    REAL probks,alam,EPS1,EPS2
    PARAMETER (EPS1=0.001, EPS2=1.e-8)
    INTEGER j
    REAL a2,fac,term,termbf
    a2=-2.*alam**2
    fac=2.
    probks=0.
    termbf=0.
    do 11 j=1,100
    term=fac*exp(a2*j**2)
    probks=probks+term
    if(abs(term).le.EPS1*termbf.or.abs(term).le.EPS2*probks)return
    fac=-fac
    termbf=abs(term)
    11 continue
    probks=1.
    return
    END


    SUBROUTINE sort(n,arr)
    INTEGER n,M,NSTACK
    REAL arr(n)
    PARAMETER (M=7,NSTACK=50)
    INTEGER i,ir,j,jstack,k,l,istack(NSTACK)
    REAL a,temp
    jstack=0
    l=1
    ir=n
    1 if(ir-l.lt.M)then
    do 12 j=l+1,ir
    a=arr(j)
    do 11 i=j-1,1,-1
    if(arr(i).le.a)goto 2
    arr(i+1)=arr(i)
    11 continue
    i=0
    2 arr(i+1)=a
    12 continue
    if(jstack.eq.0)return
    ir=istack(jstack)
    l=istack(jstack-1)
    jstack=jstack-2
    else
    k=(l+ir)/2
    temp=arr(k)
    arr(k)=arr(l+1)
    arr(l+1)=temp
    if(arr(l+1).gt.arr(ir))then
    temp=arr(l+1)
    arr(l+1)=arr(ir)
    arr(ir)=temp
    endif
    if(arr(l).gt.arr(ir))then
    temp=arr(l)
    arr(l)=arr(ir)
    arr(ir)=temp
    endif
    if(arr(l+1).gt.arr(l))then
    temp=arr(l+1)
    arr(l+1)=arr(l)
    arr(l)=temp
    endif
    i=l+1
    j=ir
    a=arr(l)
    3 continue
    i=i+1
    if(arr(i).lt.a)goto 3
    4 continue
    j=j-1
    if(arr(j).gt.a)goto 4
    if(j.lt.i)goto 5
    temp=arr(i)
    arr(i)=arr(j)
    arr(j)=temp
    goto 3
    5 arr(l)=arr(j)
    arr(j)=a
    jstack=jstack+2
    if(jstack.gt.NSTACK)pause
    if(ir-i+1.ge.j-l)then
    istack(jstack)=ir
    istack(jstack-1)=i
    ir=j-1
    else
    istack(jstack)=j-1
    istack(jstack-1)=l
    l=i
    endif
    endif
    goto 1
    END


    end module StatisticTests

    AND MY MAIN PROGRAM:

    program main

    use StatisticTests

    implicit none

    integer i,n1,n2,n3
    real pi,HI,Mfof,RA,DE,Vcdm,CDz
    parameter(pi=3.1415,n1=3071,n2=1032,n3=2005)
    real Z_obs1(n1),Z_obs2(n2),Z_obs3(n3)
    real d12,d23,d31,prob12,prob23,prob31



    open(unit=1,file="halo_cone_mock_lcdmw5_c2592_n1024.dat",status="old")
    open(unit=2,file="halo_cone_mock_rpcdmw5_c2592_n1024.dat",status="old")



    !n1=3071 !# of data-points for the ΛCDM
    !n2=1032 !# of data-points for the RPCDM


    do i=1,n1
    read(1,*) HI,Mfof,Z_obs1(i),RA,DE,Vcdm,CDz !Read data of ΛCDM
    end do

    do i=1,n2
    read(2,*) HI,Mfof,Z_obs2(i),RA,DE,Vcdm,CDz !Read data of RPCDM
    end do




    call kstwo(Z_obs1,n1,Z_obs2,n2,d12,prob12)

    print*,"The KS two-sample test fot the LCDM-RPCDM"
    print*,
    print*,d12,prob12

    end program

    FOR THE COMPLILE : f95 main.f95 StatiTests.f95 -o new

    sorry for the long post :)
     
  14. Aug 18, 2014 #13

    SteamKing

    User Avatar
    Staff Emeritus
    Science Advisor
    Homework Helper

    Suggestion for the OP: When posting source code, please use the
    Code (Text):
     tags around the source statements.  The [CODE] tags help preserve the formatting of the source file, which is lost if it is inserted directly into the Reply Box.
     
  15. Aug 18, 2014 #14

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    I don't understand this yet.

    If you remove the use of modules, the error message goes away.

    But this minimal example compiles and runs OK:

    Code (Text):

    program test

    use mymod

    call sub(x)
    print *,x
    end
     
    Code (Text):

    module mymod

    contains

    subroutine sub(y)
    x = 10
    y = func(x)
    end

    function func(x)
    func = 42 + x
    end

    end module mymod
     
    One way to solve the mystery would be to add one thing at a time to the working example until it stop working, and then figure out why.
     
  16. Aug 18, 2014 #15

    jtbell

    User Avatar

    Staff: Mentor

    I've never used modules, but can you use 'implicit none' at the beginning of a module? I've always used it at the beginning of each subroutine or function.
     
  17. Aug 18, 2014 #16

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    I never used IMPLICIT NONE that way either, but that's not the problem.

    It seems like the compiler thinks you have declared probks twice: once by writing the actual function, and again in subroutine kstwo when you say

    Code (Text):

    REAL d1,d2,dt,en1,en2,en,fn1,fn2,probks
     
    If you change that line to
    Code (Text):

    REAL d1,d2,dt,en1,en2,en,fn1,fn2
     
    it compiles and links OK.

    You can make my trivial example fail the same way, without IMPLICIT NONE. This fails:
    Code (Text):

    module mymod

    contains

    subroutine sub(y)
    real x, y, func
    x = 10
    y = func(x)
    end

    function func(x)
    real func, x
    func = 42 + x
    end

    end module mymod
     
    but this works:
    Code (Text):

    ....
    subroutine sub(y)
    real x, y
    ....
     
    I don't understand this. IMO either this is a very obscure feature of Fortran 95, or else it's a compiler bug. But at least we now know what to do about it!

    Note, in F95 you can write "overloaded functions" similar to C++, where you have several functions with the same name and the compiler calls the correct one based on the type of the parameters passed to it. Maybe the "failed" version is somehow declaring two different functions with the sane name, but of course the link editor can only find one so it gives an error about the other one. But the "proper" way to use overloaded functions is write your own "interface" block between the "module" and "contains" statements, not let it happen by default. :confused:
     
    Last edited: Aug 18, 2014
  18. Aug 18, 2014 #17
    I am truly thankful to you man !!
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Should I use a Fortran module?
Loading...