Fortran A specification statement cannot appear in the executable section (fortran)

  • Thread starter Thread starter Hercuflea
  • Start date Start date
  • Tags Tags
    Fortran Section
Click For Summary
The discussion revolves around a Fortran code error related to the placement of a subroutine within the main program. The compiler errors indicate that specification statements cannot be included in the executable section, which is resolved by moving the subroutine outside the main program. Participants highlight that modern Fortran allows for subroutines to be included using the "contains" statement, or better yet, organized within modules. There are also concerns about passing the correct data types to the subroutine, as mismatched types can lead to unexpected outputs. Overall, the conversation emphasizes proper structure and type management in Fortran programming.
Hercuflea
Messages
593
Reaction score
49
I'm working on a code to compute the Kahan summation of two arrays. I'm a bit new to fortran so my error is probably obvious, but I have no idea why. It seems as if I have declared the subroutine according to standard that I have read on the internet. The code is still a work in progress so I haven't written the OMP part yet. I'm getting the following errors from the ifort compiler:

summation.f90(18): error #6236: A specification statement cannot appear in the executable section.
subroutine compute(n)
----^
summation.f90(19): error #6236: A specification statement cannot appear in the executable section.
integer,parameter::dp2=selected_real_kind(15,300)
--------^
summation.f90(20): error #6236: A specification statement cannot appear in the executable section.
integer::i,count,t_stop,tick
--------^
summation.f90(21): error #6236: A specification statement cannot appear in the executable section.
real(kind=dp2),allocatable,dimension(:)::a,b
--------^
summation.f90(22): error #6236: A specification statement cannot appear in the executable section.
real(kind=dp2)::sum1

Here's my code:
Code:
program summation
    implicit none
    include 'omp_lib.h'
    integer,parameter::dp1=selected_real_kind(15,300)
    call compute(10.0d3)
    call compute(2.0d0*(10.0d3))
    call compute(5.0d0*(10.0d3))
    call compute(10.0d4)
    call compute(2.0d0*(10.0d4))
    call compute(5.0d0*(10.0d4))
    call compute(10.0d5)
    call compute(2.0d0*(10.0d5))
    call compute(5.0d0*(10.0d5))
    call compute(10.0d6)
    call compute(2.0d0*(10.0d6))
    call compute(5.0d0*(10.0d6))

    subroutine compute(n)
        integer,parameter::dp2=selected_real_kind(15,300)
        integer::i,count,t_stop,tick
        real(kind=dp2),allocatable,dimension(:)::a,b
        real(kind=dp2)::sum1
        allocate(A(n))
        allocate(B(n))
        tick=1
        count=0
        t_stop=2*(10**20)
        call system_clock(count,tick,t_stop)
        sum1=0.0_dp2

        do i=1,n
        a(i)=i
        b(i)=a(i)*a(i)
        a(i)=a(i)+sqrt(abs(sin(b(i))))*2.34
        sum1=sum1+a(i)
        end do
        write(*,*) n, sum1, count
        deallocate(a)
        deallocate(b)

    end subroutine compute
end program summation
 
Technology news on Phys.org
The problem you are having with your code is that you are defining the subroutine compute in the middle of the main program summation.

If you move all of the lines between subroutine compute ... end subroutine compute, inclusive, and put them after end program summation, this will be less confusing to the compiler.

Fortran works on the program unit concept, where all of the statements for the main program are kept separate from the statements which define any subroutines or user-defined functions which may be used.
 
Hercuflea said:
I'm working on a code to compute the Kahan summation of two arrays. I'm a bit new to fortran so my error is probably obvious, but I have no idea why. It seems as if I have declared the subroutine according to standard that I have read on the internet. The code is still a work in progress so I haven't written the OMP part yet. I'm getting the following errors from the ifort compiler:

summation.f90(18): error #6236: A specification statement cannot appear in the executable section.
subroutine compute(n)
----^
summation.f90(19): error #6236: A specification statement cannot appear in the executable section.
integer,parameter::dp2=selected_real_kind(15,300)
--------^
summation.f90(20): error #6236: A specification statement cannot appear in the executable section.
integer::i,count,t_stop,tick
--------^
summation.f90(21): error #6236: A specification statement cannot appear in the executable section.
real(kind=dp2),allocatable,dimension:))::a,b
--------^
summation.f90(22): error #6236: A specification statement cannot appear in the executable section.
real(kind=dp2)::sum1

Here's my code:
Code:
program summation
    implicit none
    include 'omp_lib.h'
    integer,parameter::dp1=selected_real_kind(15,300)
    call compute(10.0d3)
    call compute(2.0d0*(10.0d3))
    call compute(5.0d0*(10.0d3))
    call compute(10.0d4)
    call compute(2.0d0*(10.0d4))
    call compute(5.0d0*(10.0d4))
    call compute(10.0d5)
    call compute(2.0d0*(10.0d5))
    call compute(5.0d0*(10.0d5))
    call compute(10.0d6)
    call compute(2.0d0*(10.0d6))
    call compute(5.0d0*(10.0d6))

    subroutine compute(n)
        integer,parameter::dp2=selected_real_kind(15,300)
        integer::i,count,t_stop,tick
        real(kind=dp2),allocatable,dimension(:)::a,b
        real(kind=dp2)::sum1
        allocate(A(n))
        allocate(B(n))
        tick=1
        count=0
        t_stop=2*(10**20)
        call system_clock(count,tick,t_stop)
        sum1=0.0_dp2

        do i=1,n
        a(i)=i
        b(i)=a(i)*a(i)
        a(i)=a(i)+sqrt(abs(sin(b(i))))*2.34
        sum1=sum1+a(i)
        end do
        write(*,*) n, sum1, count
        deallocate(a)
        deallocate(b)

    end subroutine compute
end program summation
From what I remember about Fortran, your main program and subroutine should be separate, and not as you have, with the subroutine being contained within the main program.

Code:
program summation
.
.
.
end program summation

subroutine compute(n)
.
.
.
end subroutine compute
 
Wow. I can do advanced math and physics but I miss something simple like this. Thanks guys. I had this same error in my code last week and it caused the entire code to crash...smh. I may have more questions on this code.
 
Hercuflea said:
Wow. I can do advanced math and physics but I miss something simple like this. Thanks guys. I had this same error in my code last week and it caused the entire code to crash...smh. I may have more questions on this code.

In subroutine compute, you create two large arrays for storing a and b, which are entirely unnecessary for calculating the sum. There's no need to store these values of a and b when you just dump the arrays at the end of the subroutine.
 
Actually, that thing about having the subroutine outside the main program is no longer the modern style of doing Fortran (90 and beyond).

The quick fix to your program as posted is to insert a line that says "contains" right before the subroutine.

Even more so, the new style is to use "modules".
 
  • Like
Likes FactChecker
Ok...I'm stuck with this code again. I think I may be calling the subroutine improperly? I pass different values of n to the subroutine but it just keeps outputting that n=0 always. Any idea what I'm doing wrong?

And SteamKing...the instructions from my professor were to allocate the arrays. I think it has to do with efficiency because we are looking at OpenMP efficiency vs. serial. I'm still trying to just get the serial working though.

Code:
program summation
        implicit none
        include 'omp_lib.h'
        integer,parameter::dp1=selected_real_kind(15,300)
        real(kind=dp1)::a
        a=10.0d3
        call compute(a)
        a=2.0*(10.0d3)
        call compute(a)
        a=5.0*(10.0d3)
        call compute(a)
        a=10.0d4
        call compute(a)
        a=2.0*(10.0d4)
        call compute(a)
        a=5.0*(10.0d4)
        call compute(a)
        a=10.0d5
        call compute(a)
        a=2.0*(10.0d5)
        call compute(a)
        a=5.0*(10.0d5)
        call compute(a)
        a=10.0d6
        call compute(a)
        a=2.0*(10.0d6)
        call compute(a)
        a=5.0*(10.0d6)
end program summation

subroutine compute(n)
        integer,parameter::dp2=selected_real_kind(15,300)
        integer::i,tick,count,t_stop
        real(kind=dp2),allocatable,dimension(:)::a,b
        real(kind=dp2)::sum1
        allocate(a(n))
        allocate(b(n))
        tick=1
        count=0
        t_stop=2*(10**20)
        call system_clock(count,tick,t_stop)
        sum1=0.0_dp2

        do i=1,n
                a(i)=i
                b(i)=a(i)*a(i)
                a(i)=a(i)+sqrt(abs(sin(b(i))))*2.34
                sum1=sum1+a(i)
        end do

        write(*,*) n, sum1, count
        deallocate(a)
        deallocate(b)
end subroutine compute

Code:
           0  0.000000000000000E+000  1480668689
           0  0.000000000000000E+000  1480668692
           0  0.000000000000000E+000  1480668692
           0  0.000000000000000E+000  1480668692
           0  0.000000000000000E+000  1480668693
           0  0.000000000000000E+000  1480668693
           0  0.000000000000000E+000  1480668693
           0  0.000000000000000E+000  1480668693
           0  0.000000000000000E+000  1480668694
           0  0.000000000000000E+000  1480668694
           0  0.000000000000000E+000  1480668694
 
It would be nice to see the latest code, exactly...the one posted initially does not have 'n' declared anywhere...could it be that you have the subroutine somewhere where the "implicit none" has no effect and hence the argument 'n' is an integer and you are passing reals to it?...I am not sure what may be happening during the type-cast of them.

By the way, I don't think "do-loops" allow for real values, do they?
 
gsal said:
It would be nice to see the latest code, exactly...the one posted initially does not have 'n' declared anywhere...could it be that you have the subroutine somewhere where the "implicit none" has no effect and hence the argument 'n' is an integer and you are passing reals to it?...I am not sure what may be happening during the type-cast of them.

By the way, I don't think "do-loops" allow for real values, do they?

You can use reals for do-loop counters, but these are trickier than the more common integer values.
 
  • #10
Hercuflea said:
Ok...I'm stuck with this code again. I think I may be calling the subroutine improperly? I pass different values of n to the subroutine but it just keeps outputting that n=0 always. Any idea what I'm doing wrong?

And SteamKing...the instructions from my professor were to allocate the arrays. I think it has to do with efficiency because we are looking at OpenMP efficiency vs. serial. I'm still trying to just get the serial working though.

Fair enuf. Like gsal said, you are defining a in the main program as a REAL and then passing it to the subroutine, where the subroutine expects an INTEGER. You should declare n in the subroutine as a REAL and see if the output changes. Arguments are passed by reference in Fortran instead of by value, so this may be the source of your problem.
 
  • #11
SteamKing said:
Fair enuf. Like gsal said, you are defining a in the main program as a REAL and then passing it to the subroutine, where the subroutine expects an INTEGER. You should declare n in the subroutine as a REAL and see if the output changes. Arguments are passed by reference in Fortran instead of by value, so this may be the source of your problem.
Ha! thank you, this seems to have fixed my problem. I changed a to an integer and it works.

I tried declaring a to be myint=SELECTED_INT_KIND(32), but it tells me I can't use the syntax integer(kind=myint)::a . I'm not sure why I'm not allowed to do this?
 
  • #12
Hercuflea said:
Ha! thank you, this seems to have fixed my problem. I changed a to an integer and it works.

I tried declaring a to be myint=SELECTED_INT_KIND(32), but it tells me I can't use the syntax integer(kind=myint)::a . I'm not sure why I'm not allowed to do this?

It could be because the syntax should be SELECTED_INTEGER_KIND(n), where n takes values of 1, 2, 3, or such. IDK if 32 is an acceptable value for the parameter in this statement.
 

Similar threads

  • · Replies 16 ·
Replies
16
Views
2K
  • · Replies 3 ·
Replies
3
Views
16K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K