https://www.cdslab.org/paramonte/fortran/2
Current view: top level - main - pm_sampling_kernel.inc.inc.F90 (source / functions) Hit Total Coverage
Test: ParaMonte 2.0.0 :: Serial Fortran - Code Coverage Report Lines: 26 32 81.2 %
Date: 2024-04-08 03:18:57 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       2             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       3             : !!!!                                                                                                                            !!!!
       4             : !!!!    ParaMonte: Parallel Monte Carlo and Machine Learning Library.                                                           !!!!
       5             : !!!!                                                                                                                            !!!!
       6             : !!!!    Copyright (C) 2012-present, The Computational Data Science Lab                                                          !!!!
       7             : !!!!                                                                                                                            !!!!
       8             : !!!!    This file is part of the ParaMonte library.                                                                             !!!!
       9             : !!!!                                                                                                                            !!!!
      10             : !!!!    LICENSE                                                                                                                 !!!!
      11             : !!!!                                                                                                                            !!!!
      12             : !!!!       https://github.com/cdslaborg/paramonte/blob/main/LICENSE.md                                                          !!!!
      13             : !!!!                                                                                                                            !!!!
      14             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      15             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      16             : 
      17     1625463 :                     loopNextMove: do counterDRS = 0, spec%proposalDelayedRejectionCount%val
      18             : #if                     OMP_ENABLED || CAFMPI_SINGLCHAIN_ENABLED
      19             :                         ! stat%numFunCallAcceptedRejectedDelayedUnused is relevant only on the first image, despite being updated by all images
      20             :                         stat%numFunCallAcceptedRejectedDelayedUnused = stat%numFunCallAcceptedRejectedDelayedUnused + spec%image%count
      21             : #endif
      22             : #if                     OMP_ENABLED
      23             :                         do imageID = 1, spec%image%count
      24             :                             call setProposalStateNew(spec, proposal, counterDRS, co_logFuncState(1 : ndim, imageID, counterDRS - 1), co_logFuncState(1 : ndim, imageID, counterDRS), spec%rng, err)
      25             :                             if(err%occurred) then; err%msg = getFine(__FILE__, __LINE__)//PROCEDURE_NAME//SK_": "//err%msg; return; end if
      26             :                         end do
      27             : #else
      28     1079152 :                         call setProposalStateNew(spec, proposal, counterDRS, co_logFuncState(1 : ndim, counterDRS - 1), co_logFuncState(1 : ndim, counterDRS), spec%rng, err)
      29     1079152 :                         if(err%occurred) then; err%msg = getFine(__FILE__, __LINE__)//PROCEDURE_NAME//SK_": "//err%msg; return; end if
      30             : #endif
      31             : !!#if                    (MATLAB_ENABLED || PYTHON_ENABLED || R_ENABLED) && !CAF_ENABLED && !MPI_ENABLED
      32             : !!                       if(err%occurred) then; err%msg = PROCEDURE_NAME//SK_": "//err%msg; return; end if
      33             : !!#elif                  CODECOV_ENABLED || SAMPLER_TEST_ENABLED
      34             : !#if                     CODECOV_ENABLED || SAMPLER_TEST_ENABLED
      35             : !                        ! This block is exclusively used to test the deterministic restart functionality of ParaXXXX samplers.
      36             : !                        ! This block must not be activated under any other circumstances.
      37             : !                        ! This block must be executed by all images.
      38             : !                        !spec%testSamplingCounter = spec%testSamplingCounter + 1_IK
      39             : !                        !err%occurred = err%occurred .or. spec%testSamplingCountTarget < spec%testSamplingCounter
      40             : !                        !if (err%occurred) then
      41             : !                        !    if (spec%testSamplingCounter > spec%testSamplingCountTarget) err%msg = "The simulation was interrupted at the requested sampling count for restart testing purposes."
      42             : !                        !    SET_CAFMPI(call isFailedImage(err%occurred))
      43             : !                        !    return
      44             : !                        !end if
      45             : !#endif
      46             :                         ! The following random function call is only needed in fresh runs to evaluate the acceptance of a proposal.
      47             :                         ! However, it is taken out of the subsequent loops to achieve 100% deterministic reproducibility when
      48             :                         ! a simulation is restarted.
      49     1079152 :                         call setUnifRand(spec%rng, unifrnd)
      50     1625450 :                         if (spec%run%is%new .or. numFunCallAcceptedPlusOne == stat%cfc%nsam) then
      51             : #if                         OMP_ENABLED && (MATLAB_ENABLED || PYTHON_ENABLED || R_ENABLED)
      52             :                             block
      53             :                                 real(RKD) :: avgTimePerFunCall, avgCommPerFunCall
      54             :                                 !avgTimePerFunCall = epsilon(0._RKD); avgCommPerFunCall = epsilon(0._RKD)
      55             :                                 !block
      56             :                                 !use pm_io
      57             :                                 !call disp%skip(count = 2)
      58             :                                 !call disp%show("before")
      59             :                                 !call disp%show("co_logFuncState(:, 1 : spec%image%count, counterDRS)")
      60             :                                 !call disp%show( co_logFuncState(:, 1 : spec%image%count, counterDRS) )
      61             :                                 !call disp%skip(count = 2)
      62             :                                 !end block
      63             :                                 mold = getLogFunc(co_logFuncState(:, 1 : spec%image%count, counterDRS), avgTimePerFunCall, avgCommPerFunCall)
      64             :                                 !block
      65             :                                 !use pm_io
      66             :                                 !call disp%skip(count = 2)
      67             :                                 !call disp%show("after")
      68             :                                 !call disp%show("co_logFuncState(:, 1 : spec%image%count, counterDRS)")
      69             :                                 !call disp%show( co_logFuncState(:, 1 : spec%image%count, counterDRS) )
      70             :                                 !call disp%skip(count = 2)
      71             :                                 !end block
      72             :                                 stat%avgTimePerFunCall = stat%avgTimePerFunCall + avgTimePerFunCall
      73             :                                 stat%avgCommPerFunCall = stat%avgCommPerFunCall + avgCommPerFunCall
      74             :                             end block
      75             : #elif                       OMP_ENABLED
      76             :                             block
      77             :                                 use pm_timer, only: getTime => getTimeOMP
      78             :                                 real(RKD) :: start, avgTimePerFunCall
      79             :                                 avgTimePerFunCall = 0._RKD
      80             :                                 stat%timer%clock = stat%timer%time()
      81             :                                 ! preliminary tests indicate that false sharing is not a concern here.
      82             :                                 ! nevertheless, the current implementation attempts to avoid it by assuming a 128-byte cacheline.
      83             :                                !!$omp parallel do reduction(+ : avgTimePerFunCall) num_threads(spec%image%count) default(none) shared(co_logFuncState, counterDRS, ndim, spec) private(imageID, start, logFuncState)
      84             :                                 !$omp parallel do reduction(+ : avgTimePerFunCall) num_threads(spec%image%count) default(none) shared(co_logFuncState, counterDRS, ndim, spec, logFuncState) private(imageID, start)
      85             :                                 do imageID = 1, spec%image%count
      86             :                                     start = getTime()
      87             :                                     logFuncState(1, imageID) = getLogFunc(co_logFuncState(1 : ndim, imageID, counterDRS))
      88             :                                     !avgTimePerFunCall(imageID * JUMP) = getTime() - start
      89             :                                     !co_logFuncState(0, imageID, counterDRS) = getLogFunc(co_logFuncState(1 : ndim, imageID, counterDRS))
      90             :                                     avgTimePerFunCall = avgTimePerFunCall + (getTime() - start)
      91             :                                 end do
      92             :                                 !$omp end parallel do
      93             :                                 co_logFuncState(0, :, counterDRS) = logFuncState(1, :)
      94             :                                 avgTimePerFunCall = avgTimePerFunCall / spec%image%count
      95             :                                 stat%avgTimePerFunCall = stat%avgTimePerFunCall + avgTimePerFunCall
      96             :                                 stat%avgCommPerFunCall = stat%avgCommPerFunCall + stat%timer%time() - stat%timer%clock - avgTimePerFunCall
      97             :                             end block
      98             : #else
      99     1079152 :                             stat%timer%clock = stat%timer%time()
     100     1079152 :                             co_logFuncState(0, counterDRS) = getLogFunc(co_logFuncState(1 : ndim, counterDRS))
     101     1079152 :                             stat%avgTimePerFunCall = stat%avgTimePerFunCall + stat%timer%time() - stat%timer%clock
     102             : #endif
     103             :                             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     104             :                             ! accept or reject the proposed state
     105             :                             !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     106             : 
     107             : #if                         OMP_ENABLED
     108             :                             do imageID = 1, spec%image%count
     109             : #endif
     110     1079152 :                                 if (CO_LOGFUNCSTATE(0, imageID, -1) <= CO_LOGFUNCSTATE(0, imageID, counterDRS)) then ! accept the proposed state.
     111      142897 :                                     CO_ACCR(imageID, counterDRS) = 1._RKC
     112      142897 :                                     CO_ACCR(imageID, -1) = real(counterDRS, RKC)
     113      794861 :                                     CO_LOGFUNCSTATE(0 : ndim, imageID, -1) = CO_LOGFUNCSTATE(0 : ndim, imageID, counterDRS)
     114             : #if                                 OMP_ENABLED || !CAFMPI_SINGLCHAIN_ENABLED
     115             :                                     exit loopNextMove
     116             : #endif
     117      936255 :                                 elseif (CO_LOGFUNCSTATE(0, imageID, counterDRS) < GET_ELL(maxLogFuncRejectedProposal, imageID)) then ! reject the proposed state. This step should be reachable only when proposalDelayedRejectionCount > 0
     118      209101 :                                     CO_ACCR(imageID, counterDRS) = 0._RKC ! proposal rejected XXX is this correct? could `co_accr` be absolute zero?
     119             :                                 else ! accept with probability co_accr.
     120      727154 :                                     if (counterDRS == 0_IK) then ! This should be equivalent to GET_ELL(maxLogFuncRejectedProposal, imageID) == NEGBIG_RK
     121      691831 :                                         logFuncDiff = CO_LOGFUNCSTATE(0, imageID, counterDRS) - CO_LOGFUNCSTATE(0, imageID, -1)
     122      691831 :                                         if (logFuncDiff < log(tiny(0._RKC))) then ! xxx should the condition for LOGHUGE_RK be also added?
     123           0 :                                             CO_ACCR(imageID, counterDRS) = 0._RKC
     124             :                                         else
     125      691831 :                                             CO_ACCR(imageID, counterDRS) = exp(logFuncDiff)
     126             :                                         end if
     127             :                                     else    ! ensure no arithmetic overflow/underflow. ATTN: GET_ELL(maxLogFuncRejectedProposal, imageID) < co_logFuncState(0, counterDRS) < co_logFuncState(0, -1)
     128             :                                         CO_ACCR(imageID, counterDRS) & ! LCOV_EXCL_LINE
     129             :                                         = getLogSubExp(smaller = GET_ELL(maxLogFuncRejectedProposal, imageID), larger = CO_LOGFUNCSTATE(0, imageID, counterDRS)) & ! LCOV_EXCL_LINE
     130       35323 :                                         - getLogSubExp(smaller = GET_ELL(maxLogFuncRejectedProposal, imageID), larger = CO_LOGFUNCSTATE(0, imageID, -1))
     131       35323 :                                         if (CO_ACCR(imageID, counterDRS) < log(tiny(0._RKC))) then
     132           0 :                                             CO_ACCR(imageID, counterDRS) = 0._RKC
     133             :                                         else
     134       35323 :                                             CO_ACCR(imageID, counterDRS) = exp(CO_ACCR(imageID, counterDRS))
     135             :                                         end if
     136             :                                     end if
     137      727154 :                                     if (GET_ELL(unifrnd, imageID) < CO_ACCR(imageID, counterDRS)) then ! accept the proposed state
     138      790286 :                                         CO_LOGFUNCSTATE(0 : ndim, imageID, -1) = CO_LOGFUNCSTATE(0 : ndim, imageID, counterDRS)
     139      142140 :                                         CO_ACCR(imageID, -1) = real(counterDRS, RKC)
     140             : #if                                     OMP_ENABLED || !CAFMPI_SINGLCHAIN_ENABLED
     141      142140 :                                         exit loopNextMove
     142             : #endif
     143             :                                     end if
     144             :                                 end if
     145      794115 :                                 GET_ELL(maxLogFuncRejectedProposal, imageID) = max(GET_ELL(maxLogFuncRejectedProposal, imageID), CO_LOGFUNCSTATE(0, imageID, counterDRS))
     146             : #if                         OMP_ENABLED
     147             :                             end do
     148             : #endif
     149             :                         else ! if dryrun
     150             : #if                         CAFMPI_SINGLCHAIN_ENABLED
     151             :                             if (spec%image%id == stat%cfc%processID(numFunCallAcceptedPlusOne) .and. &
     152             :                                 currentStateWeight + spec%image%id - 1_IK == stat%cfc%sampleWeight(stat%numFunCallAccepted) .and. &
     153             :                                 counterDRS == stat%cfc%delayedRejectionStage(numFunCallAcceptedPlusOne)) then
     154             :                                 co_accr(-1) = real(counterDRS, RKC)
     155             :                                 co_logFuncState(0, counterDRS) = stat%cfc%sampleLogFunc(numFunCallAcceptedPlusOne)
     156             :                                 co_logFuncState(1 : ndim, counterDRS) = stat%cfc%sampleState(1 : ndim,numFunCallAcceptedPlusOne)
     157             :                                 co_logFuncState(0 : ndim, -1) = co_logFuncState(0 : ndim, counterDRS)
     158             :                             end if
     159             : #elif                       OMP_ENABLED
     160             :                             imageID = stat%cfc%processID(numFunCallAcceptedPlusOne)
     161             :                             if (currentStateWeight + imageID - 1_IK == stat%cfc%sampleWeight(stat%numFunCallAccepted) .and. counterDRS == stat%cfc%delayedRejectionStage(numFunCallAcceptedPlusOne)) then
     162             :                                 co_accr(imageID, -1) = real(counterDRS, RKC)
     163             :                                 co_logFuncState(0, imageID, counterDRS) = stat%cfc%sampleLogFunc(numFunCallAcceptedPlusOne)
     164             :                                 co_logFuncState(1 : ndim, imageID, counterDRS) = stat%cfc%sampleState(1 : ndim,numFunCallAcceptedPlusOne)
     165             :                                 co_logFuncState(0 : ndim, imageID, -1) = co_logFuncState(0 : ndim, imageID, counterDRS)
     166             :                                 exit loopNextMove
     167             :                             end if
     168             : #else
     169           0 :                             if (currentStateWeight == stat%cfc%sampleWeight(stat%numFunCallAccepted) .and. counterDRS == stat%cfc%delayedRejectionStage(numFunCallAcceptedPlusOne)) then
     170           0 :                                 co_accr(-1) = real(counterDRS, RKC)
     171           0 :                                 co_logFuncState(0, -1) = stat%cfc%sampleLogFunc(numFunCallAcceptedPlusOne)
     172           0 :                                 co_logFuncState(1 : ndim, -1) = stat%cfc%sampleState(1 : ndim, numFunCallAcceptedPlusOne)
     173             :                                 exit loopNextMove
     174             :                             end if
     175             : #endif
     176             :                         end if
     177             : #if                     CAFMPI_SINGLCHAIN_ENABLED
     178             :                         ! broadcast the sampling status from the all images to all images.
     179             :                         ! This is needed in singleChain parallelism to avoid unnecessary delayed rejection if a proposal is already found.
     180             :                         ! Note that this is not necessary when the delayed rejection is deactivated.
     181             :                         if (0 < spec%proposalDelayedRejectionCount%val) then
     182             :                             if (-0.5_RKC < co_accr(-1)) proposalFoundSinglChainMode = 1 ! -0.5 instead of -1. avoids possible real roundoff errors.
     183             :                             stat%timer%clock = stat%timer%time()
     184             :                             SET_CAF(call co_sum(proposalFoundSinglChainMode))
     185             :                             ! send buffer, recv buffer, buffer size, datatype, mpi reduction operation, comm, ierr
     186             :                             SET_MPI(call mpi_allreduce(proposalFoundSinglChainMode, proposalFoundSinglChainModeReduced, 1, mpi_integer, mpi_sum, mpi_comm_world, ierrMPI))
     187             :                             SET_MPI(proposalFoundSinglChainMode = proposalFoundSinglChainModeReduced)
     188             :                             stat%avgCommPerFunCall = stat%avgCommPerFunCall + stat%timer%time() - stat%timer%clock
     189             :                             if (0_IK < proposalFoundSinglChainMode) exit loopNextMove
     190             :                         end if
     191             : #endif
     192             :                     end do loopNextMove

ParaMonte: Parallel Monte Carlo and Machine Learning Library 
The Computational Data Science Lab
© Copyright 2012 - 2024