Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Routine execution via subroutine-call-and-return or via branch-and-conditional-branch-back

Said_E_
Beginner
936 Views

Dear all,

I have routines to be executed repeatedly by different parts of my program. Because routine variables are publicly declared, so these routines may be put in a subroutine under 'contains' section and be called from any where in the program, or, be put in an isolated part of the program where I can branch to it from any where and at the end of the routine I branch back conditionally to where I came from, based on a pointer value. Sometimes I use branch-and-conditional-branch-back instead of subroutine-call-and-return because the computer hangs, even if it branch back into a 'Do' or 'If' block. And sometimes I do vice versa. I need an explanation why the computer hangs either ways.The computer is i3-PC, operating system is Win 7 (64-bit), the compiler is ifort 11.01.051, and I use MSMPI.

Best regards.

Prof. Dr. Said El Noshokaty

0 Kudos
15 Replies
Steven_L_Intel1
Employee
936 Views

I think we'd need an example program that shows the behavior. Descriptions and paraphrases often omit critical information. I'll also comment that you're using a quite-old compiler version.

I'd recommend against using branches for such things. Make them module procedures and call them. If you use whole-program optimization (/Qipo), the compiler may inline and do additional optimizations.

0 Kudos
Said_E_
Beginner
936 Views

Dear Mr, Lionel,

Please find attached the real program after omitting the unnecessary parts. The program hangs and runs successfully only when 'CALL DECOMPOSE' statement was substituted by branch statement, and conditionally branch back statement at the end of 'DECOMPOSE' routine.

 Best regards.

Prof. Dr. Said El Noshokaty

0 Kudos
Steven_L_Intel1
Employee
936 Views

This is an MPI application which has lots of dependency on things outside Fortran. I can't help you with this. If you can eliminate the MPI and still see a problem, let me know.

0 Kudos
Said_E_
Beginner
936 Views

Dear Mr, Lionel,

Last month I tried to follow my problem with Microsoft team to figure out why the program hangs while using MS MPI. Their reason is that I might be using a Fortran program!? Then they asked about the compiler version. When told, discussion ended!?. I have now a situation that looks like a puzzle. Please advise. Is Intel Fortran has any difficulty with Open MPI?

Best regards.

Prof. Dr. Said El Noshokaty

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
936 Views

Said,

While I cannot definitively say what is wrong with the program (or compiler), I can suggest something you can look at. From a very brief look at your code, it appears that you have a "master" section (TASKID.EQ.0), and an "everything else" section (TASKID.NE.0), and the two code sections never merge.

What you will have to be careful of is you cannot have an explicit or implicit synch all. Not all images reach the same synch all point in the program. While I did not see any synch's in your program, you will need to research if anything you are doing has an implicit synchronization call.

Your program is small enough such that you can insert TRACE statements that write to your pseudo printer (on unit 8), include flush such that the most recent trace is in file when program hangs/crashes. Using the FPP (preprocessor) would be easy since you can define a macro that in trace mode write to unit 8 including the source line number __LINE__. In release mode, the macro TRACE can be defined as blank, such that it does nothing. Once you find/remove the error, then you can remove the macros and compile without FPP.

Jim Dempsey

0 Kudos
Said_E_
Beginner
936 Views

Hi Jim,

Welcome onboard. As you have noticed, the program is very simple. Data is sent from the master process (0), by the first Do block of subroutine 'Decompose', to two subordinate processes (1 and 2) , by the code beginning at 10003. After processing, information is sent from the subordinate process, by the code beginning at 10008, to the master process, by the second Do block of  subroutine 'Decompose'. I already traced execution. It hangs at the end of subroutine 'Decompose'. If this subroutine is processed by branch-and-conditional-branch-back instead of call-and-return, as a work around, the program is successfully completed. You feel as if branch-and-conditional-branch-back has provided each send and receive operation the required time to synchronize!? Also, you feel like there is a condition which was bypassed by applying  branch-and-conditional-branch-back. This is not the only work around. Inserting some printing statements or re-designing the If block at the end of the subroutine can also help.

Best regards.

Prof. Dr. Said El Noshokaty

0 Kudos
jimdempseyatthecove
Honored Contributor III
936 Views

If inserting print statements makes the problem go away, then this is usually an indication of faulty optimization, though in rare cases it exposes race condition issues in your program. What happens when you compile with no optimizations? (/O0)

Jim Dempsey

0 Kudos
Said_E_
Beginner
936 Views

 

Hi Jim,

Sorry, /O0 did not work.

Best regards.

Prof. Dr. Said El Noshokaty

0 Kudos
jimdempseyatthecove
Honored Contributor III
936 Views

Said,

The code example you posted is using the GOTO instead of the CALL.

In looking at this code, your coding style is to use IMPLICIT variables.

It is possible that this may be where your problem lies.
Meaning this can lead to an undefined IMPLICIT variable being used in a subroutine as opposed to a defined variable from the main program (caller).

Insert IMPLICIT NONE, then define the variables and see if your subroutines are assuming a variable is initialized when it is not.

Jim Dempsey

0 Kudos
Said_E_
Beginner
936 Views

Hi Jim,

Same style has been used before in  two other programs. In these programs I used subroutine call and they were run successfully. In the program that hangs I'm using same style. Anyhow I tried IMPLICIT NONE and defining variables in its subroutine as you suggested. This also did not work.

Best regards.

Prof. Dr. Said El Noshokaty

0 Kudos
jimdempseyatthecove
Honored Contributor III
936 Views

The object was not only to define the variables, but rather to assure that a variable (now) defined in the subroutine was not expecting to have been initialized to have same values as seen by the caller. The branch-branch back code would not exhibit this problem, whereas the subroutine may experience the problem.

Jim Dempsey

 

0 Kudos
Said_E_
Beginner
936 Views

Hi Jim,

The function of this subroutine 'DECOMPOSE' is to send values of variables developed in the master process to subordinate processes and receive values of variables developed in subordinate processes and store them in the master process. So, all variables accessed by the subroutine belong to the master process. Forget about this for now. There is a new behavior of the program that took place lately, when I call the subroutine 'DECOMPOSE' instead of branch to it. Another subroutine with the name 'BUILDATAB' is the one which now hangs. What is strange is that  'BUILDATAB' is to be executed far before 'DECOMPOSE'. There is no justification for this new behavior. Again, when I branch to 'DECOMPOSE' instead of calling it, the program runs successfully. 

Best regards.

Prof. Dr. Said El Noshokaty

0 Kudos
jimdempseyatthecove
Honored Contributor III
936 Views

[fortran]
   SUBROUTINE DECOMPOSE
5005  DO R=1,NR
IF (I1.GT.1) THEN
    IF (R.EQ.1) THEN
       IBOTH(I1)=1
    ELSE
       IBOTH(I1)=0
    END IF
END IF
[/fortran]

Variable I1 is not defined. This is an example of local variable in subroutine expected to contain value of (local) variable of caller.

Jim Dempsey

0 Kudos
Said_E_
Beginner
936 Views

Hi Jim,

At the beginning of the sample of the program I have posted, there is a comment that says variable declaration has been omitted. In this declaration, variable 'I1' has been declared. Be quite sure that all variables are public and has been defined in the master process. The subroutine is constructed ONLY to save writing its code twice. Please pay attention to the new behavior of the program posted in my previous comment.   

Best regards.

Prof. Dr. Said El Noshokaty

0 Kudos
Said_E_
Beginner
936 Views

Hi Jim,


I found where the problem is. When I inserted some print statements before calling 'BUILDATAB' subroutine, the program runs successfully even when CALL to all subroutines is used.  The print statements acted as if they slow down subordinate process, while the branch to 'DECOMPOSE' subroutine, which I used to use before, acted as if it speeds up master process. I think it is a synchronization problem between master and subordinates, in spite of the fact that send and receive statements are supposed to synchronize. What do you think I can do to enable synchronization without the need to use such workarounds?

Best regards.

Prof. Dr. Said El Noshokaty

0 Kudos
Reply