- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As Tim says, local ALLOCATABLE variables are supposed to be automatically deallocated on routine exit. We recently fixed a bug in that area (in 9.0.030) and there may be more. If you find such a case, report it to us.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I will try the RECURSIVE attribute. The subroutine has many use statements and is calling a whole bunch of other subroutines. I saw that the second time I called the routine, variables and data defined in the modules were still there. I even tried CreateThread() to start the routine in a separate thread, but still module variables were around the second time. Maybe if use both RECURSIVE and CreateThread(), the module variables will go away (I hope)?
Lars Petter
CreateThread
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Message Edited by lpe@scandpowerpt.com on 03-06-2006 09:22 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
separate subroutine FISH
Meaning that everything memorywise that happens inside FISH is not to be confused with anything else in the program.
Regards,
Lars Petter
Message Edited by lpe@scandpowerpt.com on 03-06-2006 10:27 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
OpenMP sounds great! Do I have to explicitely define all private variables, or is there some way to define everything in the subroutine private?
Lars Petter
From the documentation:
Data SharingData sharing is specified at the start of a parallel region or worksharing construct by using the SHARED and PRIVATE clauses. All variables in the SHARED clause are shared among the members of a team. The application must do the following:
-
Synchronize access to these variables. All variables in the PRIVATE clause are private to each team member. For the entire parallel region, assuming t team members, there are t+1 copies of all the variables in the PRIVATE clause: one global copy that is active outside parallel regions and a PRIVATE copy for each team member.
-
Initialize PRIVATE variables at the start of a parallel region, unless the FIRSTPRIVATE clause is specified. In this case, the PRIVATE copy is initialized from the global copy at the start of the construct at which the FIRSTPRIVATE clause is specified.
-
Update the global copy of a PRIVATE variable at the end of a parallel region. However, the LASTPRIVATE clause of a DO directive enables updating the global copy from the team member that executed serially the last iteration of the loop.
In addition to SHARED and PRIVATE variables, individual variables and entire common blocks can be privatized using the THREADPRIVATE directive.
Message Edited by lpe@scandpowerpt.com on 03-06-2006 11:06 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Will this work?
PROGRAM FISH
!$OMP PARALLEL DEFAULT(PRIVATE)
!$OMP SECTIONS
!$OMP SECTION
CALL FORGETALL
!$OMP SECTION
CALL FORGETALL
!$OMP END SECTIONS
!$OMP END PARALLEL
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Lars, I think your idea will not work as the module variables are still static.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK.
I will read the Optimizing Applications manual chapter on parallel programming and check out the Threading for Parallel Processing forum. I will have to learn more about these things, in particular as multi-cores seems to be the future. Thank you for the guiding.
Regards,
Lars Petter
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Lars,
It sounds like you want something similar to C++ destructor capability. A problem you have with FORTRAN is the use of RETURN inside the routine whereby you forget to deallocate something. It is real difficult to keep this synchronized and GOTO is often not clean enough. A possible work around is to use a shell subroutine that performs the allocation, then calls the original subroutine, then on returndeallocate the temporary memory. On call to original routine you add one arg which is equivilent to the C++ this pointer.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
separate subroutine FISH
In a way this becomessome sort of"program within program" technology.
:-)
Lars Petter
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In your M_FISH module, define a user defined type that encompasses all the data for the context of your outer most layer subroutine. Then create a shell routine to perform the allocation/deallocation. This way you don't have to worry about a return forgetting to cleanup allocations.
Code:
! go_fishingSub is original subroutine with one additional argument ! The argument myFishingData is the context information ! Allocation and deallocation is performed in one location in ! a shell routine of the original subroutine name (go_fishing) ! This permits untidy returns. subroutine go_fishingSub(myFishingData, A, B, C) use fishing_data use fishing_code ! calling args type(fishing_data_type) :: pFishingData real :: A, B, C ... end subroutine go_fishingSub ! Shell routine using original name ! Allocations performed prior to call to original subroutine ! Deallocation called after subroutine go_fishing(A, B, C) use fishing_data use fishing_code ! calling args real :: A, B, C ! pointer to temporal data type(fishing_data_type), pointer :: pFishingData ! allocate working data set allocate(pFishingData) ! call working routine call go_fishingSub(pFishingData, A, B, C) ! return working data deallocate(pFishingData) end subroutine go_fishing ! Note, go_fishsing is OpenMP safe
Also, use the preprocessor to perform name changes. e.g If your code used
integer :: FishingHoleNumber
Which is now inside myFishingData simply define
#define FishingHoleNumber myFishingData%FishingHoleNumber
This way you do not have to edit any of your code.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I recently converted a legacy F77 into F90 with OpenMP and went through all the headachs you may be having now (over 700 modules). OpenMP is quite easy to use once you have the hang of it. The following is not obvious from the documentation but is so after you use it a few times:
Code:
type TypeThreadContext
SEQUENCE
type
(TypeObject), pointer :: pObjecttype
(TypeTether), pointer :: pTethertype
(TypeFSInput), pointer :: pFSInputinteger
:: LastObjectLoadedend
type TypeThreadContexttype
(TypeThreadContext) :: ThreadContextCOMMON
/CONTEXT/ ThreadContext!$OMP THREADPRIVATE(/CONTEXT/)
In my case I have pointers in each thread private area. You could have your common blocks and static data.
You still have an allocation issue and using the shell subroutine mentioned earlier could eliminate memory leaks.
In tackling a conversion project you want to touch as little of the code as possible.
In my conversion effort the use of the preprocessor and #defines meant that I could compile the same source files the old F77 way and the new F90 w/OpenMP way. There were a few exceptions.
Then once the old code was converted and running I could then add features.
Jim Dempsey
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page