- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have a really weird problem with openmp...
We were able to use openmp and fortran for a long time now, in a very complex software.
I'm trying to change ONE routine, and the results, with different "compilation options", are as this:
Using DEBUG, no optimizations: works fine.
No DEBUG, Optimizations for speed: works fine.
No DEBUG, Optimizations for speed, OpenMP: doesn't work.
No DEBUG, no optimizations, OpenMP, works fine.
Like you can see, only when I set (in Visual Studio) Fortran->Optimization->Optimization = No Optimization is that the OpenMP works...
The code that I made looks like this:
subroutine a (param_a, param_b)
real, dimension(:,:), pointer :: param_a
real, dimension(:,:), pointer, optional :: param_b
real :: x
integer :: i, j
if (present(param_b)) then
write(*,*) 'param_b present'
else
write(*,*) 'param_b not present'
endif
x = 0.0
do j = 1, 10
do i = 1, 10
if (present(param_b)) then
x = x + param_b(i, j)
endif
enddo
enddo
end subroutine a
The only place where param_b is used, is inside the if block where I verify if it is present.
In my test case, it is never present and I'm surprized that I get an error at all.
If I comment the line where it is used, or if I comment only the "+ param_b(i, j)", the code then works fine. This is very weird, because param_b is never present (I verified it through the "param_b not present").
I made a simple program test and no error raised at all.
Maybe I have something wrong with my code, of course (and I'm still looking for it), but why only when OpenMP and Optimized for Speed is ON is that I get an error?
If I run the program with a project that pass a value for param_b, than all configurations work without problem.
Any ideas?
Thanks!
I have a really weird problem with openmp...
We were able to use openmp and fortran for a long time now, in a very complex software.
I'm trying to change ONE routine, and the results, with different "compilation options", are as this:
Using DEBUG, no optimizations: works fine.
No DEBUG, Optimizations for speed: works fine.
No DEBUG, Optimizations for speed, OpenMP: doesn't work.
No DEBUG, no optimizations, OpenMP, works fine.
Like you can see, only when I set (in Visual Studio) Fortran->Optimization->Optimization = No Optimization is that the OpenMP works...
The code that I made looks like this:
subroutine a (param_a, param_b)
real, dimension(:,:), pointer :: param_a
real, dimension(:,:), pointer, optional :: param_b
real :: x
integer :: i, j
if (present(param_b)) then
write(*,*) 'param_b present'
else
write(*,*) 'param_b not present'
endif
x = 0.0
do j = 1, 10
do i = 1, 10
if (present(param_b)) then
x = x + param_b(i, j)
endif
enddo
enddo
end subroutine a
The only place where param_b is used, is inside the if block where I verify if it is present.
In my test case, it is never present and I'm surprized that I get an error at all.
If I comment the line where it is used, or if I comment only the "+ param_b(i, j)", the code then works fine. This is very weird, because param_b is never present (I verified it through the "param_b not present").
I made a simple program test and no error raised at all.
Maybe I have something wrong with my code, of course (and I'm still looking for it), but why only when OpenMP and Optimized for Speed is ON is that I get an error?
If I run the program with a project that pass a value for param_b, than all configurations work without problem.
Any ideas?
Thanks!
Link Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can think of lots of possibilities, but without seeing a complete example, not a portion of what the code "looks like", it's hard to be definitive. All I can say right now is that yoiu have not shown that an explicit interface to subroutine A is visible to the caller, and that is required when you have an OPTIONAL argument.
Please show us a complete program that demonstrates the problen. You can attach a ZIP to a reply here.
Please show us a complete program that demonstrates the problen. You can attach a ZIP to a reply here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve :)
First, thanks for the fast answer.
I think I'm unable to send the code because including all the sources and the external libs are +100MB to run the project that shows the problem...
But I'll send a zip with the code of the module that shows the problem.
But you ask about the explicit interface.
Because the subroutines that presents the problem is inside a module and the subroutine that calls it is in the same module, the two are only declared at the top.
Here are the code (I'll put only the code wich involves the problem):
If I comment the "+ IrrigationFlux(i, j)" part of the code, then it runs ok. And this is really weird, because on the study case, IsPresent is always False.
I checked it putting a write instruction right before the if, but if the "+ IrrigationFlux(i, j)" is there, the code blows before reaching the point. Again, if I comment the "+ IrrigationFlux(i, j)" part, a write instruction right before the "if (IsPresent) then" will show that the IsPresent variable is False.
And all the problems happens only with OpenMP and Optimizations on.
But, if I change a litle the code to something like the code below, the error is gone:
With this code, no more errors happens.
If IrrigationFlux is present, than no errors at all, in any configuration, shows up.
First, thanks for the fast answer.
I think I'm unable to send the code because including all the sources and the external libs are +100MB to run the project that shows the problem...
But I'll send a zip with the code of the module that shows the problem.
But you ask about the explicit interface.
Because the subroutines that presents the problem is inside a module and the subroutine that calls it is in the same module, the two are only declared at the top.
Here are the code (I'll put only the code wich involves the problem):
[fortran]ModuleBasin use ModuleAtmosphere only : GetAtmosphereProperty implicit none private private :: AtmosphereProcesses private :: DividePrecipitation subroutine AtmosphereProcesses integer :: STAT_CALL real, dimension(:, :), pointer :: PrecipitationFlux real, dimension(:, :), pointer :: IrrigationFlux logical :: IrrigationExists = .false. call GetAtmosphereProperty (Me%ObjAtmosphere, PrecipitationFlux, ID = Precipitation_, STAT = STAT_CALL) if (STAT_CALL /= SUCCESS_) stop 'AtmosphereProcesses - ModuleBasin - ERR020' call GetAtmosphereProperty (Me%ObjAtmosphere, IrrigationFlux, ID = Irrigation_, STAT = STAT_CALL, ShowWarning = .false.) if (STAT_CALL == SUCCESS_) then IrrigationExists = .true. elseif (STAT_CALL == NOT_FOUND_ERR_) then IrrigationExists = .false. else stop 'AtmosphereProcesses - ModuleBasin - ERR030' endif if (IrrigationExists) then call DividePrecipitation(PrecipitationFlux, IrrigationFlux) else call DividePrecipitation(PrecipitationFlux) endif end subroutine AtmosphereProcesses subroutine DividePrecipitation (PrecipitationFlux, IrrigationFlux) real, dimension(:, :), pointer :: PrecipitationFlux real, dimension(:, :), pointer, optional, intent(IN) :: IrrigationFlux integer :: i, j, STAT_CALL logical :: IsPresent = .false. if (present(IrrigationFlux)) then IsPresent = .true. endif do j = Me%WorkSize%JLB, Me%WorkSize%JUB do i = Me%WorkSize%ILB, Me%WorkSize%IUB if(Me%ExtVar%BasinPoints (i,j) == BasinPoint) then CurrentFlux = PrecipitationFlux(i, j) if (IsPresent) then CurrentFlux = CurrentFlux + IrrigationFlux(i, j) endif endif enddo enddo end subroutine DividePrecipitation[/fortran]This code above will cause an error, even if IsPresent is false (I checked it), when OpenMP and Speed Optimizations are ON.
If I comment the "+ IrrigationFlux(i, j)" part of the code, then it runs ok. And this is really weird, because on the study case, IsPresent is always False.
I checked it putting a write instruction right before the if, but if the "+ IrrigationFlux(i, j)" is there, the code blows before reaching the point. Again, if I comment the "+ IrrigationFlux(i, j)" part, a write instruction right before the "if (IsPresent) then" will show that the IsPresent variable is False.
And all the problems happens only with OpenMP and Optimizations on.
But, if I change a litle the code to something like the code below, the error is gone:
[fortran]subroutine DividePrecipitation (PrecipitationFlux, IrrigationFlux) real, dimension(:, :), pointer :: PrecipitationFlux real, dimension(:, :), pointer, optional, intent(IN) :: IrrigationFlux integer :: i, j, STAT_CALL logical :: IsPresent = .false. real, dimension(:, :), pointer, :: Irri => Null() if (present(IrrigationFlux)) then IsPresent = .true. Irri => IrrigationFlux endif do j = Me%WorkSize%JLB, Me%WorkSize%JUB do i = Me%WorkSize%ILB, Me%WorkSize%IUB if(Me%ExtVar%BasinPoints (i,j) == BasinPoint) then CurrentFlux = PrecipitationFlux(i, j) if (IsPresent) then CurrentFlux = CurrentFlux + Irri(i, j) endif endif enddo enddo end subroutine DividePrecipitation [/fortran]
With this code, no more errors happens.
If IrrigationFlux is present, than no errors at all, in any configuration, shows up.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Check to make sure that the pointer "PercipitationFlux" is valid.
By this I mean it points to a valid array. The test if(associated(PercipitationFlux)) only indicate if the pointer is .not. NULLIFIED as opposed to pointing at a valid array (or contains some random address). What you will need to do is to test the location of the first cell (obtained where you allocated or associated the pointer)and possibly test the contents for a signature (that you placed into the cell).
Jim Dempsey
By this I mean it points to a valid array. The test if(associated(PercipitationFlux)) only indicate if the pointer is .not. NULLIFIED as opposed to pointing at a valid array (or contains some random address). What you will need to do is to test the location of the first cell (obtained where you allocated or associated the pointer)and possibly test the contents for a signature (that you placed into the cell).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Jim :)
PrecipitationFlux, as IrrigationFlux (if present) are always valid.
They ara 2D arrays that are created in another module ModuleAtmosphere and we get a pointer to them using the subroutine GetAtmosphereProperty (see code).
In fact, this module reads a file that contains information to create both matrices. Only that PrecipitationFlux is mandatory and IrrigationFlux isn't.
When I use both PrecipitationFlux and IrrigationFlux, both matrices have valid values (I checked both) at the point they enter the subroutine DividePrecipitation.
In fact, as I said before, the problem shows up only when I do not use IrrigationFlux and yet, only when I compile the code WITH OpenMP and WITH Speed Optimizations. If I shutdown OpenMP OR SpeedOptimizations, everything works fine. AND this problem only occours if I use, in the code, the IrrigationFlux directly. If I change the code to use a pointer to the parameter IrrigationFlux if it's present, then everything works even with OpenMP and SpeedOptimizations ON.
Steve have mentioned that a subroutine that uses optional arguments needs an explicit interface.
But seems (to me) that if the subroutine that calls it is on the same module, this should not be necessary...?
If yet this is necessary, how to code this?
I solved (I think) using a pointer to the parameter instead using the parameter directly, but I would like to discover why I have to do this...
PrecipitationFlux, as IrrigationFlux (if present) are always valid.
They ara 2D arrays that are created in another module ModuleAtmosphere and we get a pointer to them using the subroutine GetAtmosphereProperty (see code).
In fact, this module reads a file that contains information to create both matrices. Only that PrecipitationFlux is mandatory and IrrigationFlux isn't.
When I use both PrecipitationFlux and IrrigationFlux, both matrices have valid values (I checked both) at the point they enter the subroutine DividePrecipitation.
In fact, as I said before, the problem shows up only when I do not use IrrigationFlux and yet, only when I compile the code WITH OpenMP and WITH Speed Optimizations. If I shutdown OpenMP OR SpeedOptimizations, everything works fine. AND this problem only occours if I use, in the code, the IrrigationFlux directly. If I change the code to use a pointer to the parameter IrrigationFlux if it's present, then everything works even with OpenMP and SpeedOptimizations ON.
Steve have mentioned that a subroutine that uses optional arguments needs an explicit interface.
But seems (to me) that if the subroutine that calls it is on the same module, this should not be necessary...?
If yet this is necessary, how to code this?
I solved (I think) using a pointer to the parameter instead using the parameter directly, but I would like to discover why I have to do this...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Since this is in a module, you have the explicit interface. But I think I have an idea.
Remove the initialization of IsPresent from the declaration and explicitly assign .false. to it on entry to the subroutine. The problem is that when you give a local variable an initialization, that implicitly makes it SAVE and therefore it retains its value across calls. If it ever gets set to .true., it will stay that way forever.
Also, the implicit SAVE means it is statically allocated and shared among threads. This is probably not what you want.
Remove the initialization of IsPresent from the declaration and explicitly assign .false. to it on entry to the subroutine. The problem is that when you give a local variable an initialization, that implicitly makes it SAVE and therefore it retains its value across calls. If it ever gets set to .true., it will stay that way forever.
Also, the implicit SAVE means it is statically allocated and shared among threads. This is probably not what you want.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi again, Steve :)
This seems to be good advice.
Indeed, I don't wanna to have an implicit "SAVE" for any variable here.
But I think this is not the problem. I'll explain.
When we run the software the uses this piece of code, we must tell, in a configuration file, if we want to use the "IrrigationFlux" or not. If not, it will not be used for the entire run, no matter what happens. If we say we wanna to use it, it will always be present.
So, if we use it, we use it all the time and it will always be present (and no errors happens).
If we do not use for the beginning, it will never be present.
My tests seuggests that in the scenario case where the run fails, the "IsPresent" have the correct value (.False.), and thus, the fact that we get an exception because of the presence of the "+ IrrigationFlux" inside a "if" block that will never be executed is very weird...
But I'll try what you said and see what happens
Anyway, you gave me an idea to improve some areas of the code using the "save" attribute.
I'll take a look at it :)
This seems to be good advice.
Indeed, I don't wanna to have an implicit "SAVE" for any variable here.
But I think this is not the problem. I'll explain.
When we run the software the uses this piece of code, we must tell, in a configuration file, if we want to use the "IrrigationFlux" or not. If not, it will not be used for the entire run, no matter what happens. If we say we wanna to use it, it will always be present.
So, if we use it, we use it all the time and it will always be present (and no errors happens).
If we do not use for the beginning, it will never be present.
My tests seuggests that in the scenario case where the run fails, the "IsPresent" have the correct value (.False.), and thus, the fact that we get an exception because of the presence of the "+ IrrigationFlux" inside a "if" block that will never be executed is very weird...
But I'll try what you said and see what happens
Anyway, you gave me an idea to improve some areas of the code using the "save" attribute.
I'll take a look at it :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Which exact compiler version are you using? I have a vague recollection of a compiler bug where it would move a use of an OPTIONAL variable outside a test. Or I could be imagining things. If you are using the latest version (12.0.5) then please try to come up with a reproducible test case for us to look at.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hum...
No. I'm using version 11.1, I think (I'm not at the office right now), on Windows XP.
I'm finishing a new machine with Windows 7 and probably will use a 64 bit version of Intel, but don't know exactly the version of it...
I'll have to talk to people back at office on monday to see this.
No. I'm using version 11.1, I think (I'm not at the office right now), on Windows XP.
I'm finishing a new machine with Windows 7 and probably will use a 64 bit version of Intel, but don't know exactly the version of it...
I'll have to talk to people back at office on monday to see this.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page