forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

EQUIVALENCING over differetn array types.

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General
View previous topic :: View next topic  
Author Message
AKS



Joined: 19 Mar 2008
Posts: 29

PostPosted: Fri Jun 26, 2020 4:48 pm    Post subject: EQUIVALENCING over differetn array types. Reply with quote

I have some old Fortran code which looks like the following:
COMMON /RESPN/ NRESP,IPOINT(182),IMOTN(182),ITYPE(182),ILIN(182), ISYM(182)
LOGICAL ILIN,ISYM
DIMENSTION XID(911),YID(182,5)
EQUIVALENCE (IPOINT,YID),(XID,NRESP)

The 3 integer arrays (IPOINT, IMOTN, ITYPE) are loaded correctly with integers from indices 1:54 where 54=NRESP. Similarly for the logical arrays. They have logical values (.TRUE.,.FALSE.) in indices 1:54. All arrays have UNDEFINED in indices 55:182.
When looking at XID and YID, XID(1) has 'invalid floating point number' in the debugger and positions 2:19 have 0.0000 followed by 'invalid floating point number' in positions 20:55 with the remaining values (56:911) being UNDEFINED. There are comparable issues with YID.

This old code had worked at one time. Can anyone suggest how this could be made operational?? Thank you. EJY
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1430

PostPosted: Fri Jun 26, 2020 5:02 pm    Post subject: Reply with quote

There is nothing inherently wrong with the existence of undefined variables, as long as the undefined variables are not referenced, i.e, used in expressions, copied to other variables, output to a file or the console, etc. Rather, you should worry only when execution reaches a point at which a variable is expected to be defined, but turns out not to be so.

Old Fortran programs were written with fixed array sizes that were estimated by the programmer to be large enough for all the input data that the program would be run on. When running on a problem that requires smaller size arrays, it is natural for the upper, unused parts of those arrays to be undefined.

Sometimes the program would run to completion and yield correct results even when some of the arrays were not large enough. That does not establish that the program should run just as well on a different computer with a different compiler.

There is no magical answer to your question. A simple answer is that the old code made certain assumptions that the standard does not allow you to make, but assumptions that were satisfied on the old system (computer hardware, operating system and Fortran compiler). Or, violations of such assumptions did not cause noticeably bad results to be output.

Provide the test source code, input data and expected results, and we may then be able to help or offer leads to follow.

Is the code that you are working with the SMP93-PC program or something related?
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2187
Location: Yateley, Hants, UK

PostPosted: Sat Jun 27, 2020 4:21 pm    Post subject: Reply with quote

Mecej4,

That's an excellent answer, and is probably sufficient for the original question. The assumption in a lot of very old code is that all the variables were the same length. In many computers, REAL, INTEGER and where avaiilable, LOGICAL types were all of two-word length, and when the word was 24 bit, that meant 48 bit precision, or what would be REAL*6 etc. Some computers had 30 or 32 bit words, and one brand, with 60 bit words, only used one word for each variable. If you have REAL*8 and INTEGER*4, the common blocks become different lengths.

A major problem with those old computers was a complete lack of memory, or what we now call RAM. If you have 32k words, and have to have executable code and data in memory, then something had to be done. For code, it was overlaying, where the space was reused by loading in different subprograms as and when required. One of the reasons that one could not rely on a locally defined variable retaining its value between subprogram calls is that there was a good chance it would be overwritten when the pattern of subprograms in memory was changed.

The reuse of memory for data storage used a similar mechanism, so that a COMMON block used to store (say) input coordinates in the early stages of a program could be used to store results. It is after all only a block of memory. You see this in some programs where the arrays declared in a particular subroutine are replaced with others in a subroutine called later in the code. The example by AKS probably reuses the memory withing a particular subroutine.

Running off the end of a COMMON block normally meant running into the start of something else. If that something else was no longer useful, then there was no ill effect, in exactly the same way as reusing memory for more executable code or data, but if the something else was vital, the best you could hope for was a crash to save you from a silly answer that you might believe.

The idea of a fixed length bigger than you ever thought necessary for an array is still a good, simple, idea in some circumstances. I used it in a program that students still use for field surveying exercises. Commercial software has too big a learning curve and too many options for one-day exercises in the use of a total station. Now, as an accomplished surveyor, I might do a couple of hundred sights. The program will handle 15,000, and I've yet to see a student manage a hundred. The 15,000 was only because there was space for the extra zeroes in the source code from 150, a practical limit from when the program was first written and run on PC machines with only 256k RAM, a lot of which was not available to the application.. That was back in 1985, of course, and a lot has changed since then, as the program now runs in Windows.

The really critical point is not to run off the end of a data structure, whether it is an array or a common block, and to do so is a serious failure on the part of the programmer. One example I read about was a camera that stored JPEG images on a memory card. By dint of establishing the average size of an image from those already taken, it can tell that there is enough space left for an additional picture. But when that last picture is taken, because the JPEG compression is different for every image, that last image is too big and cannot be written to the memory card. In the particular example, it crashed the camera software and made the memory card corrupt. The correct approach was to check the actual size relative to the space available, but the software author had not foreseen the situation. (There were other strategies, such as a more aggressive compression, that might have worked.)

But then the problem would not have arisen with fixed length files, such as the uncompressed TIF that an old camera of mine will store, and maybe the software had been written with that in mind.
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2187
Location: Yateley, Hants, UK

PostPosted: Sat Jun 27, 2020 4:22 pm    Post subject: Reply with quote

There is another use of EQUIVALENCE, that appears for example in Kreitzberg and Schneiderman's 'The Elements of Fortran Style', which is to use individual variables, say X, Y and Z, in the code, but having EQUIVALENCEd them to elements 1, 2 and 3 in an array COORDS. The principle was then to use COORDS in a WRITE statement, as those authors observed that as it made the write statement simpler, it eased the job of the compiler and generated faster code. It certainly worked for me on an Elliot-NCR 4120, and made a huge difference back in 1973. But I tried it in FTN95, and it doesn't make a jot of difference. I suppose that looking back at that old code, it would be far from clear why I'd done it.

You see all manner of such things in old source codes, and sometimes no-one alive remembers why they were done.

There is a further downside to the use of fixed array sizes. Suppose for instance that one had a program in which there was an array A (10,10,10) - perfectly adequate at the time. Different runs might have maximum sizes for the three indices, but at one point in the program, there are 3 nested loops. The original programmer always took care that the first index is varied most quickly in the innermost of the 3 loops (as many authors suggest is desirable, including K & S). The program stays in use for decades, and with increasing RAM capacities, some bright spark pushes up the limits in the array to (1000,1000,1000). There, that should make it work forever, as there's still an application for problems that would fit in 10,10,10.

The problem is that the loop nesting is only efficient if the array is used to the full. Only using elements 1 to 10 in the increased size array more or less guarantees multiple cache misses, and in some cases is slower than reversing the order of the nesting! Dear old K & S couldn't have conceived of such a case, and in my experiments I went from 2x faster when using the array in its entirety and getting the nesting correct relative to reversing the nesting order, to 2 times slower when the array was only partly used.

Eddie
Back to top
View user's profile Send private message
AKS



Joined: 19 Mar 2008
Posts: 29

PostPosted: Mon Jun 29, 2020 6:46 pm    Post subject: COMMON BLocks, etc. Reply with quote

All-
Thank you very much for your enlightening responses. I learned Fortran probably at the same time everyone here did. I am surprised that after so many years, there are still issues with old code that are difficult to resolve. Of course, it could be that my rustiness is showing. Nevertheless, I enjoyed reading about everyone's historical issues. EJY
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group