From: Nathan on 3 Mar 2010 18:15 Is it possible for arrays to share memory space such that assigning one value to an element in array A will also assign that same value to a different element in array B?... I have some data that is passed into a subroutine from the main function, as well as some data that is generated within this subroutine. Experimental data is as follows: ncompg 2 gconc(1) 0.790000000000000 gconc(2) 0.210000000000000 gconc(3) 0.000000000000000E+000 gconc(4) 0.000000000000000E+000 gconc(5) 0.000000000000000E+000 gconc(6) 493.140000000000 gconc(7) 731.440000000000 gconc(8) 0.000000000000000E+000 gconc(9) 0.000000000000000E+000 gconc(10) 0.000000000000000E+000 tcfg(1) -232.510000000000 tcfg(2) -181.430000000000 tcfg(3) 0.000000000000000E+000 tcfg(4) 0.000000000000000E+000 tcfg(5) 0.000000000000000E+000 tcfg(6) -146.950000000000 tcfg(7) -118.572222222222 tcfg(8) 0.000000000000000E+000 tcfg(9) 0.000000000000000E+000 tcfg(10) 0.000000000000000E+000 pcg(1) 493.140000000000 !note: same as GCONC(6).. why? pcg(2) 731.440000000000 !note: same as GCONC(7).. why? pcg(3) 0.000000000000000E+000 pcg(4) 0.000000000000000E+000 pcg(5) 0.000000000000000E+000 pcg(6) -232.510000000000 pcg(7) -181.430000000000 pcg(8) 0.000000000000000E+000 pcg(9) 0.000000000000000E+000 pcg(10) 0.000000000000000E+000 aceng(1) 3.770000000000000E-002 aceng(2) 2.220000000000000E-002 aceng(3) 0.000000000000000E+000 aceng(4) 0.000000000000000E+000 aceng(5) 0.000000000000000E+000 aceng(6) 3.451213951350862E-085 aceng(7) 6.013470022929141E-154 aceng(8) 6.013470016999068E-154 aceng(9) 6.013470016999068E-154 aceng(10) 6.013470016999068E-154 TCFF(0) 947.929986572266 TCFF(1) 947.929986572266 TCFF(2) 947.929986572266 TCFF(3) 947.929986572266 PCF(0) 180.717024624348 PCF(1) 180.717024624348 PCF(2) 180.717024624348 PCF(3) 180.717024624348 ACENF(0) 0.910000000000000 ACENF(1) 0.910000000000000 ACENF(2) 0.910000000000000 ACENF(3) 0.910000000000000 FCONC(0) 0.250000000000000 FCONC(1) 0.250000000000000 FCONC(2) 0.250000000000000 FCONC(3) 0.250000000000000 nfsteps 4 !was 3 in main function, changed to 4 in subroutine This data is defined as such: IMPLICIT DOUBLE PRECISION (A-H,O-Z) DIMENSION ACENG(10),TCFG(10),PCG(10),GCONC(10) DIMENSION TCFF(0:nfsteps),PCF(0:nfsteps),ACENF(0:nfsteps),FCONC(0:nfsteps) Where nfsteps (was 3, changed to 4 within subroutine) and ncompg are passed into this subroutine from the main function. I understand that it is good practice to keep arrays based on the same index (EITHER 0 or 1), but this code was passed onto me from someone who thought it would be nice to mix it up (I guess). Within the following loop, elements of PCG change as elements of TCFG change, which is not what is written: DO I=0,nfsteps-1 TCFG(I+1+NCOMPG) = TCFF(I) !RHS arrays are 0 based PCG(I+1+NCOMPG) = PCF(I) ACENG(I+1+NCOMPG) = ACENF(I) GCONC(I+1+NCOMPG) = FCONC(I) ENDDO After this loop, the data is as follows: ncompg 2 gconc(1) 296.487940000000 !no idea where this one came from gconc(2) 0.210000000000000 gconc(3) 0.250000000000000 gconc(4) 0.250000000000000 gconc(5) 0.250000000000000 gconc(6) 0.250000000000000 gconc(7) 731.440000000000 gconc(8) 180.717024624348 gconc(9) 180.717024624348 gconc(10) 180.717024624348 tcfg(1) 180.717024624348 !from pcg? tcfg(2) -181.430000000000 tcfg(3) 947.929986572266 tcfg(4) 947.929986572266 tcfg(5) 947.929986572266 tcfg(6) 947.929986572266 tcfg(7) -118.572222222222 tcfg(8) 0.000000000000000E+000 tcfg(9) 0.000000000000000E+000 tcfg(10) 0.000000000000000E+000 pcg(1) 0.250000000000000 !from gconc? pcg(2) 731.440000000000 pcg(3) 180.717024624348 pcg(4) 180.717024624348 pcg(5) 180.717024624348 pcg(6) 180.717024624348 pcg(7) -181.430000000000 pcg(8) 947.929986572266 !from tcfg? pcg(9) 947.929986572266 !from tcfg? pcg(10) 947.929986572266 !from tcfg? aceng(1) 3.770000000000000E-002 aceng(2) 2.220000000000000E-002 aceng(3) 0.910000000000000 aceng(4) 0.910000000000000 aceng(5) 0.910000000000000 aceng(6) 0.910000000000000 aceng(7) 6.013470022929141E-154 aceng(8) 6.013470016999068E-154 aceng(9) 6.013470016999068E-154 aceng(10) 6.013470016999068E-154 It appears to me that the array ACENG is the only one that correctly added the values of ACENF to it without changing other elements in the array. It is beyond me as to why this is happening, and I am hoping that someone else has seen this before and can clue me in. What is very curious to me is why the data from element 6 and on are sometimes changed regardless of whether I tell them to be or not... If I am too vague or you need more information than this, please tell me and I'll do what I can to provide more information. I tried running the loop in a separate "testing" function, and this problem did not occur. (All the data appeared as it should be after the end of the loop...) So, back to my original question, I guess: Can arrays in Fortran share memory locations such that assigning one value to one element of one array will also be assigned to a different element of a different array, regardless of whether you told it to do so? -Nathan
From: Gib Bogle on 3 Mar 2010 18:36 Nathan wrote: > Is it possible for arrays to share memory space such that assigning > one value to an element in array A will also assign that same value to > a different element in array B?... > > I have some data that is passed into a subroutine from the main > function, as well as some data that is generated within this > subroutine. <snip> > This data is defined as such: > IMPLICIT DOUBLE PRECISION (A-H,O-Z) > DIMENSION ACENG(10),TCFG(10),PCG(10),GCONC(10) > DIMENSION > TCFF(0:nfsteps),PCF(0:nfsteps),ACENF(0:nfsteps),FCONC(0:nfsteps) > Take care when passing arrays that have 0-based subscripting. You need to tell the subroutine about the 0-base.
From: Nathan on 3 Mar 2010 18:50 On Mar 3, 3:36 pm, Gib Bogle <g.bo...(a)auckland.no.spam.ac.nz> wrote: > Nathan wrote: > > Is it possible for arrays to share memory space such that assigning > > one value to an element in array A will also assign that same value to > > a different element in array B?... > > > I have some data that is passed into a subroutine from the main > > function, as well as some data that is generated within this > > subroutine. > > <snip> > > > This data is defined as such: > > IMPLICIT DOUBLE PRECISION (A-H,O-Z) > > DIMENSION ACENG(10),TCFG(10),PCG(10),GCONC(10) > > DIMENSION > > TCFF(0:nfsteps),PCF(0:nfsteps),ACENF(0:nfsteps),FCONC(0:nfsteps) > > Take care when passing arrays that have 0-based subscripting. You need to tell > the subroutine about the 0-base. That is the declaration of those variables from within the subroutine, therefore it has been told about the 0 base, right? ACENG(10) tells the program that ACENG ranges from 1-10 ACENF(0:nfsteps) tells the program that ACENF ranges from 0-nfsteps Ah, I left out a piece of information that is probably important. From the main function: DIMENSION ACENG(5),TCGF(5),PCG(5),GCONC(5) (the 0-based ones are the same as in the subroutine) That appears to be the problem. Note that if I only pass in 3 values for each of TCFF,PCF,ACENF,FCONC and 2 values for each of the others, the program works (probably because the total number of components is 5), while when passing in 4 values the program crashes (probably due to there being 6 components when the arrays in the main function only have space for 5)... Thanks for taking a look anyway... It's always these careless mistakes that cause the biggest headaches. -Nathan
From: dpb on 3 Mar 2010 18:52 Nathan wrote: > Is it possible for arrays to share memory space such that assigning > one value to an element in array A will also assign that same value to > a different element in array B?... Certainly, that is the definition of EQUIVALENCE (altho dummy arguments cannot be). .... > nfsteps 4 !was 3 in main function, changed to 4 in subroutine Need to see declarations in _BOTH_ main and subroutine--if they're different you have issues... > This data is defined as such: > IMPLICIT DOUBLE PRECISION (A-H,O-Z) > DIMENSION ACENG(10),TCFG(10),PCG(10),GCONC(10) > DIMENSION > TCFF(0:nfsteps),PCF(0:nfsteps),ACENF(0:nfsteps),FCONC(0:nfsteps) > > Where nfsteps (was 3, changed to 4 within subroutine) and ncompg are > passed into this subroutine from the main function. Are these declarations in calling program or subroutine? Are they the same both places? Oh, so many questions, so little actual information... > > I understand that it is good practice to keep arrays based on the same > index (EITHER 0 or 1), but this code was passed onto me from someone > who thought it would be nice to mix it up (I guess). Well, it requires consistency in usage in a given array or confusion likely reigns; there's no fundamental reason not to use appropriate bounds for any particular array. > Within the following loop, elements of PCG change as elements of TCFG > change, which is not what is written: > > DO I=0,nfsteps-1 > TCFG(I+1+NCOMPG) = TCFF(I) !RHS arrays are 0 based > PCG(I+1+NCOMPG) = PCF(I) > ACENG(I+1+NCOMPG) = ACENF(I) > GCONC(I+1+NCOMPG) = FCONC(I) > ENDDO .... > It is beyond me as to why this is happening, and I am hoping that > someone else has seen this before and can clue me in. Well, the thing about nfsteps be 3 or 4 certainly could be an issue in computing the values of the indices. Also, again, the needed declarations in both routines are necessary to really tell what is going on. In general, w/o trying to delve into it in much depth w/o the missing information, undoubtedly the various arrays are stored in proximity to each other and the indices of one are tromping on another's space. This, as noted above, is undoubtedly owing to a mismatch in declarations and the changing sizes assumed on loop bounds. Unless the bounds are set properly in the subroutine, even setting the bounds-checking compilation flag won't help necessarily, but if you're not using it, find what it is for your compiler and do so. It could be informative. > What is very curious to me is why the data from element 6 and on are > sometimes changed regardless of whether I tell them to be or not... > > If I am too vague or you need more information than this, please tell > me and I'll do what I can to provide more information. > > > I tried running the loop in a separate "testing" function, and this > problem did not occur. (All the data appeared as it should be after > the end of the loop...) > > So, back to my original question, I guess: > Can arrays in Fortran share memory locations such that assigning one > value to one element of one array will also be assigned to a different > element of a different array, regardless of whether you told it to do > so? The answer is, "if it did, you _DID_ tell it to". :) You did that by making a reference outside the bounds of one and that just happened to be where the other resides. Again, bounds checking will tell you where a computed index is outside the bounds of the defined array; problem is you may not be setting them right so that the subroutine thinks they're bigger than the space allocated in the main for them. Supply enough context to actually be able to follow from the main to the subroutine and it'll be clear. In actuality, you probably could cut this down to a working example program of only 15-20 lines that would suffice to be complete. -- > -Nathan
From: Richard Maine on 3 Mar 2010 19:02 Nathan <ngreco32(a)gmail.com> wrote: > Is it possible for arrays to share memory space such that assigning > one value to an element in array A will also assign that same value to > a different element in array B?... Yes. There are ways to do that intentionally. That's pretty much what the equivalence statement does, in particular. These days it is usually considered questionable coding style (for a start, because it does cause confusion). But yes, it can be done. There are also many ways that can happen by accident. If we actually saw the relevant code (is this beginning to sound familliar?), we might better be able to say more. Probably the most common are from exceeding array bounds and having mismatched actual and dummy arguments. But there are others. The code you did show used implicit double precision. As someone noted in the other thread, it is easy to go wrong with that. In particular, it is easy to get argument mismatches by getting the type wrong because of confusions caused by implicit double precision. Also, if you are mixing arrays with lower bounds of 0 and 1, it is easy to get confused and exceed the bounds (in either direction; for current purposes, referencing an element 0 when the lower bound is 1 also counts as "exceeding" a bound, even though the lower one). A particular point that is easy to get confused on is in argument passing with different lower bounds. Lower bounds are *NOT* passed automatically. If you have an actual argument with a lower bound of 0 and pass it to a dummy argument with a lower bound of 1 (or an uspecified lower bound, which implies 1), it will not do what you might think. The elements will all be numbered off by 1 in the subroutine. That is perfectly legal, but can be confusing and can easily result in you referencing beyond the valid bounds. But that's a lot of guessing based on no data. Showing a bunch of values doesn't help without the code - all of the revant code. And that definitely includes the calling routine; if anything, the problem is more likely to be in the calling routine, or at least partly so (such as in the case of argument mismatches). > DIMENSION > TCFF(0:nfsteps),PCF(0:nfsteps),ACENF(0:nfsteps),FCONC(0:nfsteps) > > Where nfsteps (was 3, changed to 4 within subroutine) and ncompg are > passed into this subroutine from the main function. Changing the value nfsteps within the subroutine is very likely to cause confusions. I strongly recommend against it. While it can be legal (depending on other things), the odds of confusing you are very high. If I am reading correctly, the above arrays are all automatic arrays (slightly odd to have an f90 feature like automatic arrays mixed with 70's style sequence numbers that Glenn commented on, though I can see how it could happen). You would need to know that the automatic arrays are sized based on the value of nfsteps when the subroutine was entered - not on any subsequent change). Also realize that any change to nfsteps in the subroutine will propogate back to the calling routine. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
|
Next
|
Last
Pages: 1 2 3 Prev: how to get the output of call system in a variable Next: Is there a log framwork for fortran? |