Fortran issue with undefined statements in subroutine - compilation

I have a bunch of errors coming up that say that my variables are not variables and that my statements are undefined. This subroutine is needed to compile my larger program, so I just copy pasted it at the end of my program. It didn't work if I compiled them together on different files.
How would I go about fixing those "undefined" issues? Is it because of the way I copy pasted my subroutine at the end of my program?
(I compiled with g77 and with gfortran, same thing happens)
geomalb.f:1088.6:
TEMP(J)= TLINAL(J)
1
Error: Unclassifiable statement at (1)
geomalb.f:1089.6:
DEN(J)= DLINAL(J)
1
Error: Unclassifiable statement at (1)
geomalb.f:1090.6:
PRESS(J)=PLINAL(J)
1
Error: Unclassifiable statement at (1)
geomalb.f:1110.6:
XMU(J)=28.0134*XN2(J)+2.158*H2(J)+16.0426*CH4(J)+39.948*AR(J)
1
Error: Unclassifiable statement at (1)
geomalb.f:1132.6:
1001 IF (IPRINT .LT. 0) RETURN
1
Error: Bad continuation line at (1)
geomalb.f:1152.72:
ENDDO
1
Error: Statement label in ENDDO at (1) doesn't match DO label
geomalb.f:1130.72:
IF (DT .LT. 0.001) GO TO 1001
1
Error: Label 1001 referenced at (1) is never defined
geomalb.f:72.27:
CALL ATMSETUP(NLEVEL,Z,RHCH4,FH2,FARGON,TEMP,PRESS,DEN,XMU,
1
Warning: Rank mismatch in argument 'z' at (1) (scalar and rank-1)
Here is the subroutine part of the program:
SUBROUTINE ATMSETUP(NLEVEL,Z,RHCH4,FH2,FARGON,TEMP,PRESS,DEN,XMU,
& CH4,H2,XN2,AR,IPRINT)
PARAMETER (NMAX=201)
DIMENSION CH4(1),H2(1),XN2(1),AR(1)
DIMENSION TLINAL(NMAX),DLINAL(NMAX),PLINAL(NMAX)
CALL LINDAL(NLEVEL,Z,TLINAL,DLINAL,PLINAL)
DO J=1,NLEVEL
TEMP(J)= TLINAL(J)
DEN(J)= DLINAL(J)
PRESS(J)=PLINAL(J)
ENDDO
DO 1000 ITS =1,20
CH4(NLEVEL)=PCH4(TEMP(NLEVEL))*RHCH4/PRESS(NLEVEL)
DO 134 J=NLEVEL-1,1,-1
CH4SAT=PCH4(TEMP(J))/PRESS(J)
CH4(J)=AMIN1(CH4SAT,CH4(NLEVEL),CH4(J+1))
134 CONTINUE
DO 20 J=1,NLEVEL
H2(J)=FH2
IF (FARGON .LT. 0.) THEN
AR(J)=(-FARGON-28.0134+25.8554*H2(J)+11.9708*CH4(J))/11.9346
ELSE
IF (FARGON .EQ. 0.) THEN
AR(J)=0.0
ELSE
AR(J)=FARGON
ENDIF
ENDIF
XN2(J)=1.0 - H2(J) - CH4(J) -AR(J)
XMU(J)=28.0134*XN2(J)+2.158*H2(J)+16.0426*CH4(J)+39.948*AR(J)
20 CONTINUE
SUMT=PLINAL(1)*6.02E23/10.
SUMB=SUMT
TLAST=TEMP(NLEVEL)
DO J=2,NLEVEL
DENF=294.1/(XN2(J)*294.1 + CH4(J)*410. + H2(J)*136. + AR(J)*277.8)
DEN(J) = DLINAL(J)*DENF
ADEN=(DEN(J)-DEN(J-1))/ALOG(DEN(J)/DEN(J-1))
SUMT=SUMT+(EFFG(Z(J))*ADEN)*( Z(J-1)-Z(J))*XMU(J)
ADEN=(DLINAL(J)-DLINAL(J-1))/ALOG(DLINAL(J)/DLINAL(J-1))
SUMB=SUMB+(EFFG(Z(J))*ADEN)*( Z(J-1)-Z(J))*28.01340
PRESS(J)=PLINAL(J)*SUMT/SUMB
TEMP(J) =TLINAL(J)*(SUMT/SUMB)*(1./DENF)
ENDDO
30 CONTINUE
DT= ABS(TEMP(NLEVEL)-TLAST)
IF (DT .LT. 0.001) GO TO 1001
1000 CONTINUE
1001 IF (IPRINT .LT. 0) RETURN
WRITE (6,139)RHCH4,FH2,FARGON,DT
DO 135 J=1,NLEVEL-1
WRITE(6,140)J,Z(J),PRESS(J),DEN(J),TEMP(J),
& CH4(J)*PRESS(J)/PCH4(TEMP(J))
& ,CH4(J)*100.,XN2(J)*100.,H2(J)*100.,AR(J)*100.,XMU(J)
& ,(TEMP(J+1)-TEMP(J))/(Z(J+1)-Z(J))
135 CONTINUE
J=NLEVEL
WRITE(6,140)J,Z(J),PRESS(J),DEN(J),TEMP(J),
& CH4(J)*PRESS(J)/PCH4(TEMP(J))
& ,CH4(J)*100.,XN2(J)*100.,H2(J)*100.,AR(J)*100.,XMU(J)
139 FORMAT(///' BACKGROUNG ATMOSPHERE AT LEVELS'/
& ' SURFACE HUMIDITY OF CH4:',F5.3,' H2 MIXING RATIO:',F6.4,
& ' ARGON SETTING:',F8.4/' FINAL CONVERGENCE ON TEMP:',F10.5
& ' LINDAL ET AL SCALING'/
&' LVL ALTITUDE P(BARS) DEN(CM-3) TEMP RH-CH4'
& , ' %CH4 %N2 %H2 %AR MU DT/DZ' )
140 FORMAT(1X,I3,F8.3,1P2E10.3,0PF7.2,F5.2,2F6.2,2F5.2,4F6.2)
RETURN
ENDDO
END

You will need a
DIMENSION DEN(1), PRESS(1), TEMP(1)
statement in the subroutine. Otherwise the subroutine does not "know" that these variables are to be treated as arrays.

Related

Parallelization of an openMP nested do loop

I have a nested do loop in an openmp fortran 77 code that I am unable to parallelize (the code gives a segmentation fault error when it is run). I have a very similar nested do loop in a different subroutine of the same code that runs parallel with no issues.
Here is the nested do loop that I am having problems with:
do n=1,num_p
C$OMP PARALLEL DO DEFAULT(SHARED), PRIVATE(l,i1,i2,j1,j2,k1,k2
C$OMP& ,i,j,k,i_t,j_t,i_ddf,j_ddf,ddf_dum)
do l=1,n_l(n)
call del_fn(l,n)
i1=p_iw(l,n)
i2=p_ie(l,n)
j1=p_js(l,n)
j2=p_jn(l,n)
k1=p_kb(l,n)
k2=p_kt(l,n)
do i=i1,i2
i_ddf=i-i1+1
if(i .lt. 1) then
i_t=nx+i
elseif (i .gt. nx) then
i_t=i-nx
else
i_t=i
endif
do j=j1,j2
j_ddf=j-j1+1
if(j .lt.1) then
j_t=ny+j
elseif(j .gt. ny) then
j_t=j-ny
else
j_t=j
endif
do k=k1,k2
ddf(l,n,i_ddf,j_ddf,k-k1+1) = ddf_dum(i_t,j_t,k)
enddo
enddo
enddo
enddo
C$OMP END PARALLEL DO
enddo
I have narrowed the problem down to ddf_dum(i_t,j_t,k). When this term is turned off (say I replace it by 0.d0), the code runs fine.
On the other hand, I have a very similar nested do loop that runs parallel with no issues. Below is that nested do loop that runs parallel with no issues. Can anyone please identify what I am missing here?
do n=1,1
C$OMP PARALLEL DO DEFAULT(SHARED), PRIVATE(l,i1,i2,j1,j2,k1,k2
C$OMP& ,i,j,k,i_f,j_f,i_ddf,j_ddf)
do l=1,n_l(n)
i1=p_iw(l,n)
i2=p_ie(l,n)
j1=p_js(l,n)
j2=p_jn(l,n)
k1=p_kb(l,n)
k2=p_kt(l,n)
u_forcing(l,n)= (u_p(l,n)-up_tilde(l,n))/dt
v_forcing(l,n)= (v_p(l,n)-vp_tilde(l,n))/dt
w_forcing(l,n)= (w_p(l,n)-wp_tilde(l,n))/dt
do i=i1,i2
i_ddf=i-i1+1
if(i .lt. 1) then
i_f=nx+i
elseif (i .gt. nx) then
i_f=i-nx
else
i_f=i
endif
do j=j1,j2
j_ddf=j-j1+1
if(j .lt.1) then
j_f=ny+j
elseif(j .gt. ny) then
j_f=j-ny
else
j_f=j
endif
do k=k1,k2
forcing_x(i_f,j_f,k)=forcing_x(i_f,j_f,k)+u_forcing(l,n)
& *ddf_n(l,n,i_ddf,j_ddf,k-k1+1)*dv_l(l,n)
forcing_y(i_f,j_f,k)=forcing_y(i_f,j_f,k)+v_forcing(l,n)
& *ddf_n(l,n,i_ddf,j_ddf,k-k1+1)*dv_l(l,n)
forcing_z(i_f,j_f,k)=forcing_z(i_f,j_f,k)+w_forcing(l,n)
& *ddf_n(l,n,i_ddf,j_ddf,k-k1+1)*dv_l(l,n)
enddo
enddo
enddo
enddo
C$OMP END PARALLEL DO
enddo
As you noted, your problem is ddf_dum. It should be a shared variable, not private, because it is only being read from and never written to. You are getting a segfault because you are attempting to access uninitialized memory on all the threads that aren't your master thread.
A good rule of thumb that you could have used to find this mistake yourself: all variables that are only found on the RHS of your equal signs within your parallel region should always be shared.

Parallel Fortran Program Crash

I have some code that has been optimized and parallelized with OpenMP.
The code works fine with small datasets (tested with 4,000 datapoints) but fails with larger datasets (tested with 12,000 datapoints). I compiled with gfortran (gcc 4.9.3) on Windows 7 under Cygwin.
The program reads data into arrays and calculates some statistics using parameters from an input parameter file:
real,allocatable :: x(:),y(:),z(:),vr(:,:),azm(:),atol(:),
+ bandwh(:),dip(:),dtol(:),bandwd(:)
real*8,allocatable :: sills(:),dis(:),gam(:),hm(:),
+ tm(:),hv(:),tv(:),np(:)
integer,allocatable :: ivtail(:),ivhead(:),ivtype(:)
character*12,allocatable :: names(:)
Here are user defined parameters to run the program
real EPSLON,VERSION
real xlag,xltol,tmin,tmax
integer nd,nlag,ndir,nvarg,isill,test
character outfl*512
This section is related to OpenMP. There are definitions of reduced varaibles for OpenMP.
parameter(PI=3.14159265)
real uvxazm(100),uvyazm(100),uvzdec(100),
+ uvhdec(100),csatol(100),csdtol(100)
logical omni
integer threadId,numThreads
real*8,allocatable :: reducedVariables(:,:,:)
integer extractValue
integer i,j,id,ii,il,it,iv,jj
real dx,dy,dz,dxs,dys,dzs,hs,h
integer lagbeg,lagend,ilag
real band,dcazm,dcdec,dxy,gamma,vrh,vrhpr,vrt,vrtpr
real xi,yi,zi
integer liminf,limsup,iinf,isup,k
real xlaginv
The main parallel loop is called here:
c$omp parallel default(firstprivate)
c$omp& shared(x,y,z,reducedVariables,vr)
#ifdef _OPENMP
threadId = int(OMP_get_thread_num())+1
print *,'Thread ',threadId
#else
threadId = 1
#endif
This section recombines the variables:
#ifdef _OPENMP
c$omp barrier
reducedVariables(1,:,threadId)=dis(:)
reducedVariables(2,:,threadId)=gam(:)
reducedVariables(3,:,threadId)=np(:)
reducedVariables(4,:,threadId)=hm(:)
reducedVariables(5,:,threadId)=tm(:)
reducedVariables(6,:,threadId)=hv(:)
reducedVariables(7,:,threadId)=tv(:)
#endif
c$omp end parallel
#ifdef _OPENMP
dis(:)=0.0
gam(:)=0.0
np(:)=0.0
hm(:)=0.0
tm(:)=0.0
hv(:)=0.0
tv(:)=0.0
do ii=1,numThreads
do jj=1,mxdlv
dis(jj) = dis(jj) + reducedVariables(1,jj,ii)
gam(jj) = gam(jj) + reducedVariables(2,jj,ii)
np(jj) = np(jj) + reducedVariables(3,jj,ii)
hm(jj) = hm(jj) + reducedVariables(4,jj,ii)
tm(jj) = tm(jj) + reducedVariables(5,jj,ii)
hv(jj) = hv(jj) + reducedVariables(6,jj,ii)
tv(jj) = tv(jj) + reducedVariables(7,jj,ii)
end do
end do
#endif
I've debugged with gdb and get the following error:
At line 894 of file gamv.fpp Fortran runtime error: Index '13' of
dimension 1 of array 'np' above upper bound of 12
[Thread 9336.0x1494 exited with code 2] [Thread 9336.0x22f4 exited
with code 2] [Inferior 1 (process 9336) exited with code 02]
The offending section of code:
if(it.eq.1.or.it.eq.5.or.it.ge.9) then
do il=lagbeg,lagend
ii = (id-1)*nvarg*(nlag+2)+(iv-1)*(nlag+2)+il
np(ii) = np(ii) + 1.
dis(ii) = dis(ii) + dble(h)
tm(ii) = tm(ii) + dble(vrt)
hm(ii) = hm(ii) + dble(vrh)
gam(ii) = gam(ii) + dble((vrh-vrt)*(vrh-vrt))
end do
I don't see anywhere that array np was defined as having an upper bound of 12.
Is this an issue with using dynamic arrays with OpenMP?

MPI_TEST: invalid mpi_request

I want to test if mpi_iSend and mpi_iRecv have run fine.
I have 2 request(argument) vectors: one vector for all the mpi_iSend, the other for all the mpi_iRecv.
The point is that the program runs fine until it started to run the cycle for MPI_TEST. I have tried even with 2 numbers (do i=1,2), still the same error.
Fatal error in PMPI_Test: Invalid MPI_Request, error stack:
PMPI_Test(166): MPI_Test(request=0x7fff93fd2220, flag=0x7fff93fd1ffc,
status=0x7fff93fd2890) failed PMPI_Test(121): Invalid MPI_Request
INTEGER :: ierr, myid, istatus(MPI_STATUS_SIZE), num, i, n
INTEGER,parameter :: seed = 86456, numbers=200
INTEGER :: req1(numbers), req2(numbers)
LOGICAL :: flag
CALL MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
IF (myid==0) THEN
DO n=1, numbers
req1(n)=0
req2(n)=0
num=IRAND()
CALL MPI_ISEND(num,1,MPI_INTEGER,1,1,MPI_COMM_WORLD,req1(n),ierr)
CALL MPI_IRECV(best_prime,1,MPI_INTEGER,1,0,MPI_COMM_WORLD,req2(n),ierr)
END DO
ELSE IF (myid==1) THEN
DO i=1, numbers
CALL MPI_TEST(req2(i),flag,istatus,ierr)
IF (flag .eqv. .false.) THEN
WRITE(*,*)'RECV',i,'non-blocking FAIL'
ELSE IF (flag .eqv. .true.) THEN
WRITE(*,*)'RECV',i,'non-blocking SUCCESS'
END IF
END DO
END IF

Fortran Intent (in)

I am having a problem with this simple code, giving me the following error.
Somehow it is saying that there is a conflict with the Intent (in) attribute.
gfortran -o build/lib/larsa.o -c -ffree-form -g -J./build/lib lib/larsa.f
lib/larsa.f:2701.8:
sep, sty, shr &
1
Error: PROCEDURE attribute conflicts with INTENT attribute in 'sep' at (1)
lib/larsa.f:2710.17:
If (Len_trim (sep) > 0) Then
1
Error: 'string' argument of 'len_trim' intrinsic at (1) must be CHARACTER
This is the subroutine
Subroutine write_separator_new &
( &
sep, sty, shr &
)
Character (len=*), Intent(in) :: sep, sty
Integer, Intent(in), Optional :: shr
Character (len=65) :: a, fmt
If (Len_trim (sep) > 0) Then
a = Repeat (sep(1), 60)
Else
Write (*,*) ""
End If
End Subroutine write_separator_new
Indexing of character strings requires :
a = Repeat (sep(1:1), 60)
The compiler assumed sep is a a function, because you used it as such and not as a character string.

Compile errors with Fortran90

All, I've been fighting these errors for hours, here's my code:
program hello
implicit none
integer :: k, n, iterator
integer, dimension(18) :: objectArray
call SetVariablesFromFile()
do iterator = 1, 18
write(*,*) objectArray(iterator)
end do
contains
subroutine SetVariablesFromFile()
IMPLICIT NONE
integer :: status, ierror, i, x
open(UNIT = 1, FILE = 'input.txt', &
ACTION = 'READ',STATUS = 'old', IOSTAT = ierror)
if(ierror /= 0) THEN
write(*, *) "Failed to open input.txt!"
stop
end if
do i = 1, 18
objectArray(i) = read(1, *, IOSTAT = status) x
if (status > 0) then
write(*,*) "Error reading input file"
exit
else if (status < 0) then
write(*,*) "EOF"
exit
end if
end do
close(1)
END subroutine SetVariablesFromFile
end program hello
I'm getting compile errors:
make: * [hello.o] Error1
Syntax error in argument list at (1)
I read online that the latter error could be due to a long line of code exceeding 132 characters, which doesn't appear to be the problem.I have no where to begin on the first error... any help would be much appreciated!
This,
objectArray(i) = read(1, *, IOSTAT = status) x
is not valid Fortran. You need to write it as,
read(1,*,iostat=status) objectArray(i)
Setting it in this correct form, I received no compiler errors with ifort 12.1, nor with gfortran 4.4.3

Resources