Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28435 Discussions

'catastrophic error' when allocating array values

Akshay_Siramdas
Beginner
1,263 Views

I'm trying to allocate array value but encountered a catastrophic error while compiling. Here's the function :

function poisson_pressure(P, B, dx, dy) result(P_n)
    real, intent(in) :: B(:,:), dx, dy
    real             :: P(:,:), norm=1, P_n(nx,ny), norm_t=1e-6

    P_n = P

    do while (norm > norm_t)

      P(2:nx-1, 2:ny-1) = ((dy**2 * (P_n(3:,2:ny-1)+P_n(1:nx-2,2:ny-1))) &
                          + (dx**2 * (P_n(2:nx-1,3:)+P_n(2:nx-1,1:ny-2))) &
                          - (dx**2 * dy**2 * B(2:nx-1,2:ny-1))) / (2*(dx**2 + dy**2))

      P(:, ny-1) = 0
      P(1,  = P(2, :)
      P(nx-1,  = P(nx-2,   !!! Line that throws compilation error
      P(:, 1) = P(:, 2)

      norm = l1norm(P, P_n)
      P_n = P
    end do

    return

  end function poisson_pressure

 

The program compiles well if I remove the problematic line. I don't understand why this is happening. I've checked declarations, type, shape etc but nothing bad came up. I'm using

ifort -c foo.F90

 

as compile command.

0 Kudos
15 Replies
mecej4
Honored Contributor III
1,243 Views

The code that you showed is not a proper external function. No compiler will accept it without corrections and without code in a containing scope.

For instance, the variables nx and ny appear to be from a containing outer scope. The line before the "problematic line" is also problematic. It is wrong for l1norm to be implicitly declared with the wrong type. Check the subscript expressions.

If the function is invoked several times, the value of norm at entry will not be 1, and the conditional expression in the DO WHILE statement will probably be evaluated incorrectly.

Your description does not match the code that you posted. Please show the actual code.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,212 Views

mecej4,

In the posted text (program), it appears that the text formatting replace colon, right paren with a non-printing smiley face.

.OR.

the OP copied the file from this forum, and missed the colon, right paren to hidden smiley face.

I am not sure if Past with Fortran formatting still has this problem. Let's see if it does

array(1,:) = 2 ! left side has array(1,: ) without space following :

 

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
1,203 Views

I have reported already the tendency of this forum to replace certain common Fortran syntax with invisible emoji (you can see it only in a brief instant of the display of raw HTML when you edit a post.) 

0 Kudos
JohnNichols
Valued Contributor III
1,200 Views

From me.rice.edu  Professor Akin -- 

program  vector_norm 
!   A simple vector norm program, Fortran 90 version
 implicit none
  integer, parameter :: dp = selected_real_kind(14) ! 14 digits
  integer, parameter :: MAX = 1000;           !  Maximum vector size
  integer n;                                  !  Actual vector size
  integer i;                                  !  Loop controls
  real (kind=dp) :: x(MAX)                    !  The vector
  real (kind=dp) :: L1_norm, L2_norm;         !  Work results

  print *,"Enter the vector length: ";
  read  *, n;                             !  User size input
  print *, n                              !  Echo size

  if ( n > MAX ) then                     !  Check validity
    stop "Vector size exceeds dimension, ERROR"; ! Abort run
  end if

!  Input vector contents
  print *,"Enter the vector: "; 
  read *, (x(i), i=1,n)              !  Read values

  L2_norm = sqrt ( sum ( x(:n)*x(:n) ))   ! L2 norm
  L1_norm = sum ( abs(x(:n)) )/n          ! L1 norm 

  write (6,'(" The L2 norm of [")',advance='no') ! Print header
!   Loop over vector contents, (except last)
  do i = 1, n-1
    write (6, '(f10.4, ",")', advance = 'no') x(i) ! List values
  end do 

!  Now last term
  write (6, '(f10.4, " ] is: ")', advance = 'no') x(n) ! Last value

  print *, L2_norm, "."  ;                    !  Print L2
  print *, "The L1 norm is: ", L1_norm, "." ; !  Print L1
   
end program vector_norm

!  Running with file lab_1.dat;
!  4
!  3.14159265358979 5 12e1 .645
!  gives
! Enter the vector length: 
! 4
! Enter the vector: 
! The L2 norm of [ 3.1416, 5.0000, 120.0000, 0.6450 ] is:  120.146933499.
! The L1 norm is: 32.196648163397448.

 - a nice little program   

0 Kudos
JohnNichols
Valued Contributor III
1,191 Views

Akin's program give the same results in the latest Fortran classic compiler:  which is nice to know. 

Capture1.GIF

0 Kudos
JohnNichols
Valued Contributor III
1,176 Views

L1 norm is just the average length on the positive number line for the independent elements of the vector. 

 

0 Kudos
JohnNichols
Valued Contributor III
1,175 Views

Is the L1 norm invariant under a transformation of the base

0 Kudos
JohnNichols
Valued Contributor III
1,172 Views
  1. L1 Norm is the sum of the magnitudes of the vectors in a space

Is the Fortran code in error?  Because Akins has divided the sum by the number of vectors 

 

0 Kudos
Akshay_Siramdas
Beginner
1,167 Views

It is an internal function. The line before the problematic line had correct closed parentheses but idk why when I posted got removed in formatting. The norm value changes every time `l1norm` is invoked. May I know why repeated calling changes the value of a variable?

The posted code is the actual part of the code!

0 Kudos
JohnNichols
Valued Contributor III
1,152 Views

because nx and ny will have strange value if they exist at all. 

 

0 Kudos
JohnNichols
Valued Contributor III
1,150 Views
function poisson_pressure(P, B, dx, dy) result(P_n)
    real, intent(in) :: B(:,:), dx, dy
    
    integer :: nx = 100
    integer :: ny = 100
    real             :: P(:,:), norm=1, P_n(100,100), norm_t=1e-6

    P_n = P

    do while (norm > norm_t)

      P(2:nx-1, 2:ny-1) = ((dy**2 * (P_n(3:,2:ny-1)+P_n(1:nx-2,2:ny-1))) &
                          + (dx**2 * (P_n(2:nx-1,3:)+P_n(2:nx-1,1:ny-2))) &
                          - (dx**2 * dy**2 * B(2:nx-1,2:ny-1))) / (2*(dx**2 + dy**2))

      P(:, ny-1) = 0
      P(1,:)  = P(2, :)
      P(nx-1,:) = P(nx-2,:)   !!! Line that throws compilation error
      P(:, 1) = P(:, 2)

      !norm = l1norm(P, P_n)
      P_n = P
    end do

    return

  end function poisson_pressure

 

It compiles now - but I need a calling routine, you cannot expect people to do a lot of work.  PS it will not compile until nx and ny are defined and P_n should probably be allocatable. 

0 Kudos
JohnNichols
Valued Contributor III
1,149 Views

also supply an l1norm function 

0 Kudos
Akshay_Siramdas
Beginner
1,145 Views
function l1norm(matA, matB) result(norm_r)
    real, intent(in)   :: matA(:,:), matB(:,:)
    real   :: norm_r

    norm_r = (sum(abs(matA) - abs(matB)))/(sum(abs(matB)))

    return
  end function l1norm

 

This was my 'l1norm' function.

 

Thanks for the help! I also want to know whether repeated allocation to any array will write garbage values to it?

0 Kudos
andrew_4619
Honored Contributor II
1,129 Views

If you wish norm=1 to be set every time this is called you need it to be set by a runtime statement. Not by a compile time initialisation. 

I don't see an allocatables in the sample BTW.

0 Kudos
JohnNichols
Valued Contributor III
1,113 Views

ok -- I am more than a little confused. 

Where did you get your L1 Norm from -- it is a single number returned from a vector of lengths.  The Manhattan Taxi.  

And we need a driving program - something that can be tested in a Fortran compiler.  

I am not trying to be difficult but you are dealing with busy folk who have a much higher level of knowledge of Fortran than I , but my Pure Maths says -- this is just a little weird without some background.  

If you are using the L1 Norm to determine a delta error there are better ways to calculate it I would think. 

 

0 Kudos
Reply