- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Intel fortran documentation says the following about allocatable arrays: "When an allocatable entity is deallocated, it is finalized".
How to correct my code to finalize the elements of the allocatable array list_pts? Here it is the code, it never enters in the FINAL routine:
MODULE module_final TYPE PUNTO REAL(8),POINTER,DIMENSION(:)::rpt LOGICAL::isallocated=.false. CONTAINS FINAL::FINAL_PUNTO END TYPE PUNTO CONTAINS SUBROUTINE FINAL_PUNTO(pt) TYPE(PUNTO)::pt IF(isallocated) THEN DEALLOCATE(pt%rpt) isallocated=.true. ENDIF NULLIFY(pt%rpt) print *,"Inside the final routine of type PUNTO" END SUBROUTINE FINAL_PUNTO SUBROUTINE ALLOC_PUNTO(pt) TYPE(PUNTO)::pt IF(.not.isallocated) THEN ALLOCATE(pt%rpt(3)) isallocated=.true. ENDIF END SUBROUTINE ALLOC_PUNTO END MODULE module_final program main_final USE module_final IMPLICIT NONE TYPE(PUNTO),ALLOCATABLE::list_pts(:) REAL(8),DIMENSION(3),TARGET::pt ALLOCATE(list_pts(2)) CALL ALLOC_PUNTO(list_pts(1)) list_pts(2)%rpt=>pt DEALLOCATE(list_pts) !This deallocate doesn't call the FINAL of the single elements. end program main_final
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Daniel Dopico wrote:.. I tried the subroutine and it doesn't seem to solve the problem ..
@Daniel Dopico,
Note the FINAL subroutine is rank-specific by default: what you show in the original post specifies instructions to finalize a scalar (rank 0) object only. But now you have an object (list_pts) in your program (main_final) which is a rank 1 array. So you would need to either introduce a binding with your derived type (PUNTO) for another FINAL subroutine which accepts a dummy argument which is rank 1 and specifies the instructions to finalize using such an argument. Or you can make your code compact by using the ELEMENTAL attribute on the FINAL subprogram (https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-elemental). Since ELEMENTAL subprograms are PURE by default, during any (temporary?) "debugging" on an ELEMENTAL FINAL subprogram via print statements, you can consider the IMPURE attribute.
You may also want to consider always introducing the INTENT attribute with your subprogram dummy arguments: Fortran standard says FINAL subprogram dummy argument of the passed object shall have the INTENT(INOUT) attribute.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[Deleted]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
While this doesn't help the Final issue, line 15 should be setting isallocated=.false.
Dops, try this:
subroutine sub_final USE module_final IMPLICIT NONE TYPE(PUNTO),ALLOCATABLE::list_pts(:) REAL(8),DIMENSION(3),TARGET::pt ALLOCATE(list_pts(2)) CALL ALLOC_PUNTO(list_pts(1)) list_pts(2)%rpt=>pt DEALLOCATE(list_pts) !This deallocate doesn't call the FINAL of the single elements. end subroutine sub_final program main_final call sub_final end program main_final
I seem to have a fuzzy recollection of finalization issues in the PROGRAM procedure. I do not recall if this was fixed (or an issue).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much Jim.
You are right about line 15. In fact it should be pt%isallocated=.false. and there are a bunch of errors more because I forgot the IMPLICIT NONE in the module.
Anyway, I tried the subroutine and it doesn't seem to solve the problem. In fact the original code (which motivated this sample) doesn't have any main program because it is a library.
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Daniel Dopico wrote:.. I tried the subroutine and it doesn't seem to solve the problem ..
@Daniel Dopico,
Note the FINAL subroutine is rank-specific by default: what you show in the original post specifies instructions to finalize a scalar (rank 0) object only. But now you have an object (list_pts) in your program (main_final) which is a rank 1 array. So you would need to either introduce a binding with your derived type (PUNTO) for another FINAL subroutine which accepts a dummy argument which is rank 1 and specifies the instructions to finalize using such an argument. Or you can make your code compact by using the ELEMENTAL attribute on the FINAL subprogram (https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-elemental). Since ELEMENTAL subprograms are PURE by default, during any (temporary?) "debugging" on an ELEMENTAL FINAL subprogram via print statements, you can consider the IMPURE attribute.
You may also want to consider always introducing the INTENT attribute with your subprogram dummy arguments: Fortran standard says FINAL subprogram dummy argument of the passed object shall have the INTENT(INOUT) attribute.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Fan.
You are right. I misunderstood the documentation. After declaring the subroutine as ELEMENTAL the code enters exactly as you said. It makes sense that you need a rank specific finalization. Moreover I think that it is the first time that I declare an elemental procedure.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Daniel Dopico wrote:.. Moreover I think that it is the first time that I declare an elemental procedure.
If you seek highly performant code for physics and multibody dynamics, strive to make all your Fortran subprograms PURE and also consider the ELEMENTAL attribute as much as possible, particularly with type-bound procedures. Your codes will be enhanced greatly in terms of reliability and robustness and things will get better and better over time as compiler(s) improve in terms of optimization, vectorization, and parallelization capabilities.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>Note the FINAL subroutine is rank-specific by default: what you show in the original post specifies instructions to finalize a scalar (rank 0) object only.
Then this might be an opportunity for a warning by the compiler (-warn:all)
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dops,
I wish to caution you about use of PUNTO in a multi-threaded application whereby the allocating thread exits before the other threads. You will have to assure that this does not happen.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:>>Note the FINAL subroutine is rank-specific by default: what you show in the original post specifies instructions to finalize a scalar (rank 0) object only.
Then this might be an opportunity for a warning by the compiler (-warn:all)
Jim Dempsey
Thanks Jim. Do you mean that the -warn:all warns you about this situation or do you mean that it should warn you but it doesn't?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:Dops,
I wish to caution you about use of PUNTO in a multi-threaded application whereby the allocating thread exits before the other threads. You will have to assure that this does not happen.
Jim Dempsey
I was having a look at the FINAL subroutine for PUNTO and I don't understand the problem. There are no states or module variables inside the FINAL, then, what is the problem for generating parallel code?
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>> what is the problem for generating parallel code?
Now that I think about it, it should be no problem as you cannot get to the dtor (FINAL) while a team is pending.
*** at least for a sane programmer.
For us insane programmers...
program main_final USE omp_lib USE module_final IMPLICIT NONE REAL(8),DIMENSION(3),TARGET::pt !$omp parallel !$omp single block TYPE(PUNTO),ALLOCATABLE::list_pts(:) ALLOCATE(list_pts(omp_get_max_threads()*2)) !$omp task CALL ALLOC_PUNTO(list_pts(omp_get_thread_num()*2)) list_pts(omp_get_thread_num()*2+1)%rpt=>pt !$omp end task DEALLOCATE(list_pts) !This deallocate doesn't call the FINAL of the single elements. end block !$omp end single !$omp end parallel end program main_final
Note, assumes working FINAL, and the explicit DEALLOCATE could be omitted and thus implicit deallocation occurs at end of block. The thread occupying the single section can exit the block while enqueued tasks are running.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:If you seek highly performant code for physics and multibody dynamics, strive to make all your Fortran subprograms PURE and also consider the ELEMENTAL attribute as much as possible, particularly with type-bound procedures. Your codes will be enhanced greatly in terms of reliability and robustness and things will get better and better over time as compiler(s) improve in terms of optimization, vectorization, and parallelization capabilities.
Thank you Fan for your suggestion. I need to revisit my code to pay a closer attention to this. My use of PURE procedures is rare, I incorporated it to some recently developed ones of minor relevance.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page