Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WARNING the following symbols are missing

228 views
Skip to first unread message

ali_n...@yahoo.com

unread,
Jan 1, 2021, 9:27:02 AM1/1/21
to
I write code that uses the module structure.

The module consisted of subroutine and function. Some of them are called by the main prog and others are called by subroutines that placed in the module.

Here is the important part of the module which related to my problem:

module de

implicit none

public :: dsftdw ...
Private :: dless ...

contains
.
.
.
subroutine dsftdw ( l, u, k, lda, a, MAAP )

implicit none

integer(kind =3) :: lda
integer(kind =3) :: k
integer(kind =3) :: l
integer(kind =3) :: MAAP(:)
integer(kind =3) :: u
real(kind =3) :: a(lda,*)
logical :: dless
integer(kind =3) :: i
integer(kind =3) :: j
integer(kind =3) :: t

i = l
j = 2 * i
t = MAAP(i)

do

if ( u < j ) then
exit
end if

if ( j < u ) then
if ( dless ( k, a(1,maap(j)), a(1,maap(j+1)) ) ) then
j = j + 1
end if
end if

if ( dless ( k, a(1,maap(j)), a(1,t)) ) then
exit
end if

MAAP(i) = MAAP(j)
i = j
j = 2 * i

end do

MAAP(i) = t

end subroutine
.
.
.
function dless ( k, p, q )

implicit none

real(kind =3) :: cmax
logical :: dless
integer(kind =3) :: i
integer(kind =3) k
real(kind =3) :: p(k)
real(kind =3) :: q(k)
real(kind =3) :: tol

tol = 100.0D+00 * epsilon ( tol )

do i = 1, k

cmax = max ( abs ( p(i) ), abs ( q(i) ) )

if ( abs ( p(i) - q(i) ) <= tol * cmax .or. cmax <= tol ) then
cycle
end if

if ( p(i) < q(i) ) then
dless = .true.
else
dless = .false.
end if

return

end do

dless = .false.

end function
.
.
.
end module
(MAIN PROG BLOCK)

The module placed with the Main program in the same code.
The above subroutine is independent of the main program and function is just employed in the module subroutine.

When I BUILD this code, it shows this warning:

> WARNING the following symbols are missing

And when I run the code, it shows this error:

> run-time error: Call to missing routine

Error is back to the function which was called in the module subroutine.

This program is run in PLATO (Fortran 95).

I will appreciate any comments that give me a little help and forgive me for writing shortcomings.

Ron Shepard

unread,
Jan 1, 2021, 11:43:34 AM1/1/21
to
On 1/1/21 8:26 AM, ali_n...@yahoo.com wrote:
> subroutine dsftdw ( l, u, k, lda, a, MAAP )
[...]
> logical :: dless
[...]

This local declaration overrides the module function within this
subroutine. Thus the subsequent reference is looking for an external
function of that name, which apparently does not exist, and if it did,
then you would not be computing what you think you are computing. Just
remove this declaration to fix your problem.

Here are some other general comments about your code.

It is problematic to use integer literals for kind values. You should
instead use parameters. Don't use the same parameter for the integer and
real kinds, even if they happen to have the same value for your compiler.

integer, parameter :: ip = 3, wp = 3 ! this could be in the de
! module or in its own module.
[...[
integer(ip) :: lda
[...]
real(wp) :: a(lda,*)
[...]

This way, when you change compilers, or change precision, you only need
to change one line, not dozens (or thousands or millions) of lines.

I suggest that you not use mixed precision arithmetic without reason.
Instead of

tol = 100.0D+00 * epsilon ( tol )

write something like

tol = 100.0_wp * epsilon ( tol )

instead. Also, tol could itself be a parameter, since its value does not
change.

real(wp), parameter :: tol = 100.0_wp * epsilon ( tol )

You have a multiline if block

if ( p(i) < q(i) ) then
dless = .true.
else
dless = .false.
end if

that could be written simply as

dless = p(i) < q(i)

Why make it complicated for you or for others to understand later?

$.02 -Ron Shepard

Robin Vowels

unread,
Jan 1, 2021, 9:14:22 PM1/1/21
to
.
And that are they?
.
> And when I run the code, it shows this error:
>
> > run-time error: Call to missing routine
.
And what is that?
.

ali_n...@yahoo.com

unread,
Jan 2, 2021, 3:39:53 AM1/2/21
to
On Friday, January 1, 2021 at 8:13:34 PM UTC+3:30, Ron Shepard wrote:
> On 1/1/21 8:26 AM, ali_n...@yahoo.com wrote:
> > subroutine dsftdw ( l, u, k, lda, a, MAAP )
...
> $.02 -Ron Shepard

I appreciate your complete answer. It seems your answer is correct and efficient.

However, when I edited the code (based on your comment) the mentioned error was fixed but, another error was appeared:

Run-time error: Attempt to call a routine with argument number two containing too few array elements.

I scrutinized the error by PLATO debugging system. I find that for the first call of "dless" by "dsftdw", it works well. When "dless" is called again by "dsftdw", the above problem was appeared.

I will appreciate any comments that give me a little help, also forgive me for my writing shortcomings.

gah4

unread,
Jan 2, 2021, 5:16:04 AM1/2/21
to
On Saturday, January 2, 2021 at 12:39:53 AM UTC-8, ali_n...@yahoo.com wrote:

(snip)

> Run-time error: Attempt to call a routine with argument number two containing too few array elements.

> I scrutinized the error by PLATO debugging system. I find that for the first call of "dless" by "dsftdw",
> it works well. When "dless" is called again by "dsftdw", the above problem was appeared.

> I will appreciate any comments that give me a little help, also forgive me for my writing shortcomings.

This use of assumed size arrays is normally difficult to do bounds checking for, and so most
compilers don't do it at all. It seems that yours does.

At this point, I have to believe the message, and that you are actually going outside the array.

Without knowing the size of the array, the values in MAAP, and specfically the ones being used,
it is hard to say more.

Print out the size of a(), which you might have to do in the calling program, as Fortran doesn't
normally pass that. Also, the elements of MAAP being used on each call.

I presume that k and lda are equal. Print out those, too.

It might be that the final values aren't printed if they are still in the buffer,
but hopefully they are.

Ian

unread,
Jan 2, 2021, 5:51:24 AM1/2/21
to
You are trying to pass a scalar actual argument to an array dummy argument is my guess
(though I'm not quite sure how it compiled in the first place, but then again you don't show us the whole code):

Calling site:
if ( dless ( k, a(1,maap(j)), a(1,maap(j+1)) ) ) then


Function:
function dless ( k, p, q )
...
integer(kind =3) k
real(kind =3) :: p(k)
real(kind =3) :: q(k)


Try

If ( dless ( k, a(:,maap(j)), a(:,maap(j+1)) ) ) then

and analogous in all places you reference dless.

Also note real(kind=3) is not portable,

Ian

FortranFan

unread,
Jan 2, 2021, 8:57:44 AM1/2/21
to
On Saturday, January 2, 2021 at 3:39:53 AM UTC-5, ali_n...@yahoo.com wrote:

> .. when I edited the code (based on your comment) the mentioned error was fixed but, another error was appeared:
>
> ..
> I will appreciate any comments that give me a little help ..


@ali_n...@yahoo.com,

Since you're looking to debug some specific problem(s) in a program in Fortran, you may also want to try the Fortran Discourse site:
https://fortran-lang.discourse.group/

Contrary to plain text only and no attachments restriction of this forum, the above Discourse site provides facilities to syntax highlight your Fortran code, include images and equations and attach files, etc. All of this helps make the community engagement easier and modern and that can provide you with further useful feedback.

And as you will know, the more relevant and *visual* the details you share, the better the quality of the responses you will receive.

Ron Shepard

unread,
Jan 2, 2021, 12:26:21 PM1/2/21
to
On 1/2/21 4:51 AM, Ian wrote:
> You are trying to pass a scalar actual argument to an array dummy argument is my guess
> (though I'm not quite sure how it compiled in the first place, but then again you don't show us the whole code):
>
> Calling site:
> if ( dless ( k, a(1,maap(j)), a(1,maap(j+1)) ) ) then
>
>
> Function:
> function dless ( k, p, q )
> ...
> integer(kind =3) k
> real(kind =3) :: p(k)
> real(kind =3) :: q(k)

This is the standard way to pass columns of a matrix up through f77, and
it still conforms to the standard now. It is based on storage sequence
association. You are right, if this code were being written with modern
syntax, then array slices and assumed shape declarations would be used,
but I don't think this is a problem with the source code.

$.02 -Ron Shepard

Ian

unread,
Jan 2, 2021, 12:34:11 PM1/2/21
to
Yes, I know the f77 method, I just thought with an interface in scope it would fail to compile as the rank doesn't match.

Thanks - learnt something. Something I don't like, but that seems to be life at the moment,

Ian

Ian

unread,
Jan 2, 2021, 12:37:09 PM1/2/21
to
Ahhhh, OK - it fails for assumed shape, now I understand,

Ian

gah4

unread,
Jan 2, 2021, 6:12:06 PM1/2/21
to
On Saturday, January 2, 2021 at 9:26:21 AM UTC-8, Ron Shepard wrote:
> On 1/2/21 4:51 AM, Ian wrote:
> > You are trying to pass a scalar actual argument to an array dummy argument is my guess
> > (though I'm not quite sure how it compiled in the first place, but then again you don't show us the whole code):
> >
> > Calling site:
> > if ( dless ( k, a(1,maap(j)), a(1,maap(j+1)) ) ) then

> > Function:
> > function dless ( k, p, q )

> > integer(kind =3) k
> > real(kind =3) :: p(k)
> > real(kind =3) :: q(k)
> This is the standard way to pass columns of a matrix up through f77, and
> it still conforms to the standard now. It is based on storage sequence
> association. You are right, if this code were being written with modern
> syntax, then array slices and assumed shape declarations would be used,
> but I don't think this is a problem with the source code.

If it is columns (or rows, I always forget) then k and lda should be equal, and even more,
there shouldn't need to be two variables.

Since there are two variables, it is less obvious what it is doing.

For those who don't know, the called program as allowed access to array elements
from the one in the actual argument to the end of the array. The message sounds like
it is completely outside the array, but without the values.


ali_n...@yahoo.com

unread,
Jan 3, 2021, 2:57:41 AM1/3/21
to
Thanks for your comment. Yes, this code is a part of GEOMPACK3 module which basically written in F77.
A deep search on the web to find a source code for the Voronoi diagram led me to this module. Indeed, after setting it to F95, it doesn't work.

Árpád Lukács

unread,
Jan 3, 2021, 4:31:07 AM1/3/21
to
There's a Fortran 90 version as well, in John Burkardt's collection:
https://people.math.sc.edu/Burkardt/f_src/geompack3/geompack3.html

JCampbell

unread,
Jan 3, 2021, 8:13:45 AM1/3/21
to
With FTN95 /checkmate, it does check the original size/allocation for argument "real(kind =3) :: a(lda,*)".
I agree that you should check the values or MAAP to confirm if you are addressing "p(k)" from "a(1,maap(j))" or perhaps j for maap(j)
Unfortunately you don't provide the original declaration of "a" or "MAAP"
If you are using PLATO with /CheckMate, you should be able to interogate these values in SDBG.

ali_n...@yahoo.com

unread,
Jan 3, 2021, 1:47:01 PM1/3/21
to
Thanks for your comment. I used that code and actually, that code is based on the F77. So I try hard to conform it with F95 (PLATO) and it seems now it works properly.

ali_n...@yahoo.com

unread,
Jan 3, 2021, 1:49:47 PM1/3/21
to
Thanks so much for your comment. I edited the code based on Ron shepard and lan.
Now I can say, it seems it works properly.

Ron Shepard

unread,
Jan 3, 2021, 3:10:06 PM1/3/21
to
On 1/3/21 12:46 PM, ali_n...@yahoo.com wrote:
>> There's a Fortran 90 version as well, in John Burkardt's collection:
>> https://people.math.sc.edu/Burkardt/f_src/geompack3/geompack3.html
> Thanks for your comment. I used that code and actually, that code is based on the F77. So I try hard to conform it with F95 (PLATO) and it seems now it works properly.

The f90 code at that link does not use modules, everything is an
external function (as was the original f77 code, of course), so that is
why the redundant declaration in the module procedure stopped your code
from working correctly.

There are dozens of reasons why one should use modules with modern
fortran, so that part of your code is good. But those redundant
declarations are one of the gotcha's when moving external subroutines
into modules. All of us have made that mistake in the past, and all of
us will make it again in the future.

$.02 -Ron Shepard
0 new messages