-
Notifications
You must be signed in to change notification settings - Fork 191
Logger: move self%buffer and seld%len_buffer to local variables #253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@wclodius2 do you see any possible problems I overlook with these modifications? |
Its a lot mom changes, but as they mostly involve removing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really familiar with the API, but looking over this change rises the question why the logger should be mutable (intent(inout)
) when logging in the first place? I don't see a good reason to allow a procedure to have a side effect by modifying the logger when writing the log.
Making the logger immutable (intent(in)
) seems to work together with this change as expected:
diff --git a/src/stdlib_logger.f90 b/src/stdlib_logger.f90
index 6fd1188..c503645 100644
--- a/src/stdlib_logger.f90
+++ b/src/stdlib_logger.f90
@@ -521,7 +521,7 @@ contains
!! Writes the STRING to UNIT ensuring that the number of characters
!! does not exceed MAX_WIDTH and that the lines after the first
!! one are indented four characters.
- class(logger_type), intent(inout) :: self
+ class(logger_type), intent(in) :: self
integer, intent(out) :: len_buffer
character(*), intent(in) :: string
character(*), intent(in) :: col_indent
@@ -799,7 +799,7 @@ contains
!! end module example_mod
!!
- class(logger_type), intent(inout) :: self
+ class(logger_type), intent(in) :: self
!! The logger to be used in logging the message
character(len=*), intent(in) :: message
!! A string to be written to log_unit
@@ -888,7 +888,7 @@ contains
!! end module example_mod
!!
- class(logger_type), intent(inout) :: self
+ class(logger_type), intent(in) :: self
!! The logger used to send the message
character(len=*), intent(in) :: message
!! A string to be written to log_unit
@@ -941,7 +941,7 @@ contains
!! ...
!! end program example
- class(logger_type), intent(inout) :: self
+ class(logger_type), intent(in) :: self
!! The logger variable to receivee the message
character(len=*), intent(in) :: message
!! A string to be written to LOG_UNIT
@@ -1027,7 +1027,7 @@ contains
!! end module example_mod
!!
- class(logger_type), intent(inout) :: self
+ class(logger_type), intent(in) :: self
!! The logger variable to receive the message
character(len=*), intent(in) :: message
!! A string to be written to log_unit
@@ -1153,7 +1153,7 @@ contains
!! ...
!! end program example
!!
- class(logger_type), intent(inout) :: self
+ class(logger_type), intent(in) :: self
!! The logger variable to receive the message
character(*), intent(in) :: line
!! The line of text in which the error was found.
@@ -1365,7 +1365,7 @@ contains
!! ...
!! end module example_mod
!!
- class(logger_type), intent(inout) :: self
+ class(logger_type), intent(in) :: self
!! The logger to which the message is written
character(len=*), intent(in) :: message
!! A string to be written to LOG_UNIT
There are some points of style in the code. A lot of instances of self with |
This is kind of a pity with OpenMP, a derived type with OpenACC has a mechanism to copyin components of derived types explicitly, but I'm not aware of a similar mechanism in OpenMP.
The OpenMP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks ok and CI tests passed (mostly, despite the issue with MacOS).
Co-authored-by: Sebastian Ehlert <28669218+awvwgk@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, looks good to me now.
@awvwgk Thank you for your comments.
I usually avoid to use With the proposed changes (and the logger being unmutable in the OpenMP parallel region), the following OpenMP code should work without issues: use stdlib_logger, only: logger_type, global => global_logger, success
!$ use omp_lib
implicit none
integer :: i, ithread, nthreads, stat
character(len = 30) :: cdummy, cdummy1
type(logger_type), allocatable :: logger(:)
call global % add_log_file( 'log_file_omp.txt')
nthreads = 1
!$omp parallel
!$ nthreads = omp_get_num_threads()
!$omp end parallel
write(cdummy, '(i0)') nthreads
ithread = 1
cdummy = 'master'
!$omp parallel default(none) &
!$omp shared(global) &
!$omp private(i, ithread, cdummy, cdummy1)
!$omp do
do i = 1, 100
!$ ithread = omp_get_thread_num()+1
!$ write(cdummy, '(i0)') ithread
write(cdummy1, '(i0)') i
!$omp critical
call global % log_message('Thread : ' // trim(cdummy) //&
' | i = ' // trim(cdummy1))
!$omp end critical
end do
!$omp end do
!$omp end parallel
end program The user could omit the OpenMP Question: should such an example be provide in the
I agree with this statement. My main reason is that there are several ways for multi-thread programming. Controlling it outside
Named OpenMP critical section could be used (e.g. 1 named critical section per unit connected to the logger). But, as stated earlier, I don't think it should be the way to go. |
OpenMP |
Indeed, you are right. Thank you for your comment. |
With 4 reviewers agreeing with the changes, I will merge this PR. Thank you all for your reviews and comments. |
I was testing a multi-threading (OpenMP) program with
global_logger
inside an OpenMP loop. I got asegfault
because a thread tried to allocateseld % buffer
while it was already allocated by another thread.As a solution, I moved the variables
self % buffer
andself % len_buffer
into the subroutineslog_messge
andlog_text_error
. I believe that this solution has been already proposed in another discussion (I can't retrieve it).Note that this modification solves the problem of
segfault
, but it does not make the logger thread-safe. AFAIK, to be thread-safe, the logger (or thewrite
statement inside the logger) should be in an OpenMP critical section.