[SOLVED] A compile time error in GFortran I don't understand
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
A compile time error in GFortran I don't understand
It is a Ubuntu VM. I am trying to use a Fast Fourier Transform module given here. I get an error which is in this code block:
Code:
! COMPUTE THE TRANSFORM
! ---------------------
i = 1
IF (ip > 0) THEN
CALL gpfa2f(a, b, trigs, inc, jump, n, ip, lot, ISIGN)
i = i + 2 * ( 2**ip)
END IF
IF (iq > 0) THEN
CALL gpfa3f(a, b, trigs(i), inc, jump, n, iq, lot, ISIGN)
i = i + 2 * (3**iq)
END IF
IF (ir > 0) THEN
CALL gpfa5f(a, b, trigs(i), inc, jump, n, ir, lot, ISIGN)
END IF
The second call gpfa3f is actually the line #201. I get this error:
Quote:
four3.f08:201.20:
CALL gpfa3f(a, b, trigs(i), inc, jump, n, iq, lot, ISIGN)
1
Error: Element of assumed-shaped or pointer array passed to array dummy argument 'trigs' at (1)
four3.f08:205.20:
CALL gpfa5f(a, b, trigs(i), inc, jump, n, ir, lot, ISIGN)
1
Error: Element of assumed-shaped or pointer array passed to array dummy argument 'trigs' at (1)
! COMPUTE THE TRANSFORM
! ---------------------
i = 1
IF (ip > 0) THEN
CALL gpfa2f(a, b, trigs, inc, jump, n, ip, lot, ISIGN)
i = i + 2 * ( 2**ip)
END IF
IF (iq > 0) THEN
CALL gpfa3f(a, b, trigs(i), inc, jump, n, iq, lot, ISIGN)
i = i + 2 * (3**iq)
END IF
IF (ir > 0) THEN
CALL gpfa5f(a, b, trigs(i), inc, jump, n, ir, lot, ISIGN)
END IF
First, I have no experience with GFORTRAN, and it looks nothing like the fortran I used back in the '70s. But one thing that sticks out the me is the variables in the calls. In the first, you are passing 'trigs' which is apparently an array, and passed by pointer to an array. In the second two calls, you are passing an element from the array 'trigs', which would be passed as the value itself rather than as a pointer to a cell.
Of course, they are different functions, and your calls could be correct. But that's where I would start, confirming the type of each of the variables in the calls.
I will try to answer a couple of issues raised here. First, it is a 32 bit Ubuntu. For some reason I could not install a 64 bit on my 64 bit machine, now I don't recall why. Secondly, answering Toadbrooks: it is not my code. I provided a link to the source code I copied exactly. I also noticed that an array is passed in the first call and an array's member, a number, is passed in the second two calls. I deliberately included the first call for comparison. Still I don't have a good answer. I kind of afraid to change the code but perhaps I will have to. Thanks.
What do you mean driver? I drive myself to work, :-) Just kidding. I posted a link to that software. I copied the whole package faithfully but I cannot answer any questions, because I do not understand that part of the code, I do not understand the error message. Thanks, suicidaleggroll.
Alex, your code or not, you are going to have to look for the definition of the 3 CALLed procedures. There should be a type definition somewhere near the top of the code for each of those routines. That will help you determine if what you are passing is the correct type or not, especially given that is what the error message seems to mean to me.
If you can't, you can't. But I can't offer much more help than that.
MANY years ago, I came across an Integer Programming model in Fortran. I wanted it, but all I had in 1978 was a machine that spoke BASIC. I managed to convert it from Fortran to Basic, and got it working. Took weeks and I couldn't have done it if I wasn't skilled in both languages. You may be attempting the impossible. (Which doesn't mean you shouldn't try, but the point at which you can't determine the type of the variables you are passing versus the type the routines require might be as far as you will get.)
What do you mean driver? I drive myself to work, :-) Just kidding. I posted a link to that software. I copied the whole package faithfully but I cannot answer any questions, because I do not understand that part of the code, I do not understand the error message. Thanks, suicidaleggroll.
I thought you had a full program that was calling one or more of these subroutines, in which case you would have needed to define trigs in that driver.
However, I see now you're just trying to compile the module by itself. In that case, it looks like an error in the code. I REALLY don't like the way this is written. They're passing a single element of the array into the function, and then accessing it as if the entire array was passed in.
Code:
CALL gpfa3f(a, b, trigs(i), inc, jump, n, iq, lot, ISIGN)
and then gpfa3f:
Code:
SUBROUTINE gpfa3f(a, b, trigs, inc, jump, n, mm, lot, ISIGN)
...
REAL (dp), INTENT(IN) :: trigs(*)
...
DO k = ink, jstep-ink, ink
co1 = trigs(kk+1)
...
kk = kk + 2*la
END DO
Just because fortran is pass by reference, that doesn't mean you can treat EVERYTHING as a pointer.
I deal a lot with fortran, and I've seen a lot of really bad code, but I've never seen somebody do this. I would start by modifying the call and declaration for gpfa3f and gpfa5f. Pass "i" in as a separate parameter, so the call would look like:
Code:
CALL gpfa3f(a, b, trigs, i, inc, jump, n, mm, log, ISIGN)
And the function declaration would look like:
Code:
SUBROUTINE gpfa3f(a, b, trigs, trigidx, inc, jump, n, mm, lot, ISIGN)
Then change the declaration of trigs in gpfa3f and gpfa5f from:
Code:
REAL (dp), INTENT(IN) :: trigs(*)
to:
Code:
REAL (dp), INTENT(IN) :: trigs(:)
to match the other subroutines getting the full copy
and finally, every time trigs is accessed inside gpfa3f and gpfa5f, add trigidx (or whatever you want to call it) to the index, for example change this:
co1 = trigs(kk+1)
to this
co1 = trigs(trigidx+kk+1)
At least I assume that's what the original developer is intending to do.
Fortran is usually very portable, AS LONG AS people write it properly. I deal a lot with old code, and running something from 2002 on a modern compiler rarely takes much effort UNLESS the original developer took a bunch of shortcuts and assumptions. For example, I have one HUGE code that can't be built using any compiler more recent than 2005 because they did crap like this all of the place:
Code:
real :: a(50), b(50)
do i=1,100
a(i) = 0
enddo
purposefully overflowing a with the assumption that a and b will be contiguous in memory and it will overflow into b, instead of just doing it properly:
Code:
real :: a(50), b(50)
do i=1,50
a(i) = 0
b(i) = 0
enddo
or
Code:
real :: a(100)
do i=1,100
a(i) = 0
enddo
Last edited by suicidaleggroll; 12-09-2014 at 10:10 AM.
Reason: improving clarity
Alex, your code or not, you are going to have to look for the definition of the 3 CALLed procedures. There should be a type definition somewhere near the top of the code for each of those routines. That will help you determine if what you are passing is the correct type or not, especially given that is what the error message seems to mean to me.
If you can't, you can't. But I can't offer much more help than that.
MANY years ago, I came across an Integer Programming model in Fortran. I wanted it, but all I had in 1978 was a machine that spoke BASIC. I managed to convert it from Fortran to Basic, and got it working. Took weeks and I couldn't have done it if I wasn't skilled in both languages. You may be attempting the impossible. (Which doesn't mean you shouldn't try, but the point at which you can't determine the type of the variables you are passing versus the type the routines require might be as far as you will get.)
The subroutine definitions are in the linked code:
Code:
SUBROUTINE gpfa(a, b, trigs, inc, jump, n, lot, ISIGN)
IMPLICIT NONE
REAL (dp), INTENT(IN OUT) :: a(:)
REAL (dp), INTENT(IN OUT) :: b(:)
REAL (dp), INTENT(IN) :: trigs(:)
INTEGER, INTENT(IN) :: inc
INTEGER, INTENT(IN) :: jump
INTEGER, INTENT(IN) :: n
INTEGER, INTENT(IN OUT) :: lot
INTEGER, INTENT(IN) :: ISIGN
Code:
SUBROUTINE gpfa2f(a, b, trigs, inc, jump, n, mm, lot, ISIGN)
IMPLICIT NONE
REAL (dp), INTENT(IN OUT) :: a(*)
REAL (dp), INTENT(IN OUT) :: b(*)
REAL (dp), INTENT(IN) :: trigs(*)
INTEGER, INTENT(IN) :: inc
INTEGER, INTENT(IN) :: jump
INTEGER, INTENT(IN) :: n
INTEGER, INTENT(IN) :: mm
INTEGER, INTENT(IN) :: lot
INTEGER, INTENT(IN) :: ISIGN
Code:
SUBROUTINE gpfa3f(a, b, trigs, inc, jump, n, mm, lot, ISIGN)
REAL (dp), INTENT(IN OUT) :: a(*)
REAL (dp), INTENT(IN OUT) :: b(*)
REAL (dp), INTENT(IN) :: trigs(*)
INTEGER, INTENT(IN) :: inc
INTEGER, INTENT(IN) :: jump
INTEGER, INTENT(IN) :: n
INTEGER, INTENT(IN) :: mm
INTEGER, INTENT(IN) :: lot
INTEGER, INTENT(IN) :: ISIGN
Code:
SUBROUTINE gpfa5f(a, b, trigs, inc, jump, n, mm, lot, ISIGN)
IMPLICIT NONE
REAL (dp), INTENT(IN OUT) :: a(*)
REAL (dp), INTENT(IN OUT) :: b(*)
REAL (dp), INTENT(IN) :: trigs(*)
INTEGER, INTENT(IN) :: inc
INTEGER, INTENT(IN) :: jump
INTEGER, INTENT(IN) :: n
INTEGER, INTENT(IN) :: mm
INTEGER, INTENT(IN) :: lot
INTEGER, INTENT(IN) :: ISIGN
Thank you, everyone who helped. I marked all the posts as helpful and they really are. On a practical side, I simply removed the index (i) but did not pass it separately to the subroutines. I want to try it without doing it and should I run into trouble, hopefully, I can always do it later. Many thanks, - A.
With Fast Fourier Transform there is a simple way to verify if the process is correct. You do a reverse transform and if everything is proper, you should get approximately the original result.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.