diff --git a/.gitattributes b/.gitattributes index 1a83b0da51..6aa1fad11b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,3 +4,6 @@ .gitattributes export-ignore .pre-commit-config.yaml export-ignore .bzrignore export-ignore + +# Preserve the frozen report bytes and keep compressed PDF streams out of diffs. +doc/benchmarkfolder/*.pdf binary diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index 6797dffac5..0e9ba9f3ee 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -55,6 +55,15 @@ jobs: - uses: actions/checkout@v5 - uses: ./.github/actions/clean_tmp + - name: "MadLoop NinjaRS interfaces, defaults, and reporting" + if: ${{ !cancelled() }} + run: | + cd $GITHUB_WORKSPACE + command -v gfortran + python3 -m unittest discover -s tests/unit_tests/loop -p 'test_ninjars*.py' + python3 -m unittest discover -s tests/unit_tests/various -p 'test_ninjars*.py' + python3 -m unittest tests.unit_tests.loop.test_loop_poles tests.unit_tests.interface.test_madevent_loop_warnings + # ---- unittest_0 ---- - name: "unittest_0" if: ${{ !cancelled() }} diff --git a/.gitignore b/.gitignore index 33cabecfcd..6f8b9380ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,10 @@ *~ +.benchmark-work/ +.ninjars-build/ +vendor/ninjars/target/ +vendor/ninjars/smoke +vendor/ninjars/ninjars-native-libs.txt +vendor/ninjars/ninjars-link-before.txt __pycache__ *.o *.pyc @@ -81,6 +87,12 @@ tests/input_files/IOTestsComparison/**/*.BackUp # output of ./tests/test_manager.py UNITTEST_proc/ +# Local development references and report plotting caches. +/references/ +/doc/benchmarkfolder/final-report-v1/.mpl-cache/ +/doc/benchmarkfolder/final-report-v1/cli-report.json.gz +/doc/benchmarkfolder/final-report-v1/fonts/*.otf + # models/ only holds UFO models: downloaded ones are ignored, shipped ones kept models/* !models/sm/ diff --git a/Template/LO/Source/dsample.f b/Template/LO/Source/dsample.f index 2cab2ef47d..0c5f10159d 100644 --- a/Template/LO/Source/dsample.f +++ b/Template/LO/Source/dsample.f @@ -432,6 +432,9 @@ subroutine output_run_statistics(outUnit) c c Global c + INTEGER NINJARS_DP_USAGE,NINJARS_QP_USAGE + COMMON/NINJARSSTATS/NINJARS_DP_USAGE,NINJARS_QP_USAGE + DATA NINJARS_DP_USAGE,NINJARS_QP_USAGE/0,0/ INTEGER U_RETURN_CODES(0:9) INTEGER T_RETURN_CODES(0:9) INTEGER H_RETURN_CODES(0:9) @@ -468,6 +471,10 @@ subroutine output_run_statistics(outUnit) write(outUnit,*) ' ' write(outUnit,33) '',U_RETURN_CODES,'' + write(outUnit,'(A,I0,A)') '',NINJARS_DP_USAGE, + & '' + write(outUnit,'(A,I0,A)') '',NINJARS_QP_USAGE, + & '' write(outUnit,33) '',T_RETURN_CODES,'' write(outUnit,33) '',H_RETURN_CODES,'' write(outUnit,*) ''//trim(toStr_real(AVG_TIMING)) diff --git a/Template/NLO/SubProcesses/BinothLHA.f b/Template/NLO/SubProcesses/BinothLHA.f index d6d3521a40..8bf71e7f10 100644 --- a/Template/NLO/SubProcesses/BinothLHA.f +++ b/Template/NLO/SubProcesses/BinothLHA.f @@ -43,6 +43,8 @@ subroutine BinothLHA(p,born_wgt,virt_wgt) integer nsqso, MLResArrayDim c statistics for MadLoop double precision avgPoleRes(2),PoleDiff(2) + INTEGER NINJARS_DP_USAGE,NINJARS_QP_USAGE + COMMON/NINJARSSTATS/NINJARS_DP_USAGE,NINJARS_QP_USAGE integer ntot,nsun,nsps,nups,neps,n100,nddp,nqdp,nini,n10,n1(0:9) common/ups_stats/ntot,nsun,nsps,nups,neps,n100,nddp,nqdp,nini,n10,n1 parameter (nbadmax = 5) @@ -495,6 +497,10 @@ subroutine BinothLHA(p,born_wgt,virt_wgt) n10=n10+1 ! no known ret_code (10) endif n1(mod(ret_code,10))=n1(mod(ret_code,10))+1 ! unit ret code distribution + if (ret_code/100.eq.2.and.mod(ret_code,10).eq.8) + $ NINJARS_DP_USAGE=NINJARS_DP_USAGE+1 + if (ret_code/100.eq.3.and.mod(ret_code,10).eq.2) + $ NINJARS_QP_USAGE=NINJARS_QP_USAGE+1 c Write out the unstable, non-rescued phase-space points (MadLoop return c code is in the four hundreds) or the ones that are found by the pole diff --git a/Template/NLO/SubProcesses/driver_mintFO.f b/Template/NLO/SubProcesses/driver_mintFO.f index 2c854b064a..e96528b1ce 100644 --- a/Template/NLO/SubProcesses/driver_mintFO.f +++ b/Template/NLO/SubProcesses/driver_mintFO.f @@ -56,6 +56,8 @@ Program DRIVER common/SHevents/Hevents character*10 dum c statistics for MadLoop + INTEGER NINJARS_DP_USAGE,NINJARS_QP_USAGE + COMMON/NINJARSSTATS/NINJARS_DP_USAGE,NINJARS_QP_USAGE integer ntot,nsun,nsps,nups,neps,n100,nddp,nqdp,nini,n10,n1(0:9) common/ups_stats/ntot,nsun,nsps,nups,neps,n100,nddp,nqdp,nini,n10,n1 @@ -127,6 +129,8 @@ Program DRIVER do i=0,9 n1(i)=0 enddo + NINJARS_DP_USAGE=0 + NINJARS_QP_USAGE=0 call setrun !Sets up run parameters call setpara('param_card.dat') !Sets up couplings and masses @@ -248,6 +252,8 @@ Program DRIVER write(*,*) "#Unit ",j," = ",n1(j) endif enddo + write(*,*) '#NinjaRS DP = ',NINJARS_DP_USAGE + write(*,*) '#NinjaRS QP = ',NINJARS_QP_USAGE endif write (*,*) 'counters for the granny resonances' diff --git a/Template/NLO/SubProcesses/driver_mintMC.f b/Template/NLO/SubProcesses/driver_mintMC.f index 406a86b06d..7042a9cb2d 100644 --- a/Template/NLO/SubProcesses/driver_mintMC.f +++ b/Template/NLO/SubProcesses/driver_mintMC.f @@ -72,6 +72,8 @@ Program DRIVER character*10 dum integer iFKS_picked c statistics for MadLoop + INTEGER NINJARS_DP_USAGE,NINJARS_QP_USAGE + COMMON/NINJARSSTATS/NINJARS_DP_USAGE,NINJARS_QP_USAGE integer ntot,nsun,nsps,nups,neps,n100,nddp,nqdp,nini,n10,n1(0:9) common/ups_stats/ntot,nsun,nsps,nups,neps,n100,nddp,nqdp,nini,n10,n1 @@ -133,6 +135,8 @@ Program DRIVER do i=0,9 n1(i)=0 enddo + NINJARS_DP_USAGE=0 + NINJARS_QP_USAGE=0 call setrun !Sets up run parameters call setpara('param_card.dat') !Sets up couplings and masses @@ -340,6 +344,8 @@ Program DRIVER write(*,*) "#Unit ",j," = ",n1(j) endif enddo + write(*,*) '#NinjaRS DP = ',NINJARS_DP_USAGE + write(*,*) '#NinjaRS QP = ',NINJARS_QP_USAGE endif write (*,*) 'counters for the granny resonances' diff --git a/Template/loop_material/StandAlone/Cards/MadLoopParams.dat b/Template/loop_material/StandAlone/Cards/MadLoopParams.dat index 29c1a9bad4..0ba41e3551 100644 --- a/Template/loop_material/StandAlone/Cards/MadLoopParams.dat +++ b/Template/loop_material/StandAlone/Cards/MadLoopParams.dat @@ -14,13 +14,26 @@ ! 5 | Samurai ! 6 | Ninja ! 7 | COLLIER +! 8 | NinjaRS (oneloopmaster scalar integrals) ! One can use the combinations to reduce integral,e.g. ! 1|2|3 means first use CutTools, if it is not stable, use PJFry++, ! if it is still unstable, use IREGI. If it failed, use QP of CutTools. ! Notice that any reduction tool not available on the system will be automatically ! skipped. -! When using quadruple precision with Ninja or CutTools, the reduction will +#LoopPoleMode +!-1 +! Default :: -1 +! Select poles of the bare loop integral, leaving finite terms and +! counterterms/R2 unchanged: -1 = legacy backend behavior, 0 = UV+IR, +! 1 = UV only, 2 = IR only, 3 = no poles. +! Modes 1, 2 and 3 require MLReductionLib containing only NinjaRS (8) +! and/or COLLIER (7), including all rescue backends. +! An explicit mode overrides COLLIERComputeUVpoles/IRpoles; -1 keeps +! those legacy switches active for COLLIER and both poles for NinjaRS. +! For example, use MLReductionLib=8|7 and LoopPoleMode=1 for UV poles. + +! When using quadruple precision with Ninja, NinjaRS or CutTools, the reduction will ! always be done in quadruple precision, but the parameters below allow you to ! chose if you want to also recompute the *integrand* in quadruple precision. ! Doing so is slow but might improve the accuracy in some situation. @@ -30,6 +43,9 @@ #UseQPIntegrandForNinja !.TRUE. ! Default :: .TRUE. +#UseQPIntegrandForNinjaRS +!.TRUE. +! Default :: .TRUE. ! ! ================================================================================= diff --git a/Template/loop_material/StandAlone/SubProcesses/MadLoopCommons.inc b/Template/loop_material/StandAlone/SubProcesses/MadLoopCommons.inc index 6943530a29..de4fa708a3 100644 --- a/Template/loop_material/StandAlone/SubProcesses/MadLoopCommons.inc +++ b/Template/loop_material/StandAlone/SubProcesses/MadLoopCommons.inc @@ -270,7 +270,7 @@ C Not stable. C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -282,7 +282,7 @@ C Stable with Ninja in double precision. C U == 7 C Stable with COLLIER. C U == 8 -C Stable with Ninja in quadruple precision. +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -315,14 +315,17 @@ C ELSEIF(MLRed.EQ.6)THEN SET_RET_CODE_U=8 RETURN - ELSE - STOP 'Only CutTools and Ninja can use quardruple precision' + ELSEIF(MLRed.EQ.8)THEN + SET_RET_CODE_U=2 + RETURN + ELSE + STOP 'Only CutTools, Ninja and NinjaRS can use quadruple precision' ENDIF ENDIF - IF(MLRed.GE.1.AND.MLRed.LE.7)THEN + IF(MLRed.GE.1.AND.MLRed.LE.8)THEN SET_RET_CODE_U=MLRed ELSE - STOP 'Only CutTools, PJFry++, IREGI, Golem95, Samurai, Ninja and COLLIER are available' + STOP 'Unknown MadLoop reduction library; supported IDs are 1 through 8' ENDIF END @@ -370,8 +373,11 @@ C Ninja ELSEIF(LIBNUM.EQ.7)THEN C Collier CALL DETECT_COLLIER(NLOOPLINE,RANK,complex_mass,LPASS) + ELSEIF(LIBNUM.EQ.8)THEN +C NinjaRS + CALL DETECT_NINJARS(NLOOPLINE,RANK,complex_mass,LPASS) ELSE - STOP 'Only CutTools, PJFry++, IREGI, Golem95, Samurai, Ninja and COLLIER are available' + STOP 'Unknown MadLoop reduction library; supported IDs are 1 through 8' ENDIF RETURN END @@ -479,6 +485,15 @@ C It can easily be increased if necessary. RETURN END + SUBROUTINE DETECT_NINJARS(NLOOPLINE,RANK,complex_mass,LPASS) +C NinjaRS tensor reduction supports rank at most n+2 in both precisions. + IMPLICIT NONE + INTEGER NLOOPLINE,RANK + LOGICAL complex_mass,LPASS + LPASS=NLOOPLINE.GE.1.AND.RANK.GE.0.AND. + & RANK.LE.NLOOPLINE+2 + END + ## if(collier_available){ SUBROUTINE DETECT_COLLIER(NLOOPLINE,RANK,complex_mass,LPASS) C diff --git a/Template/loop_material/StandAlone/SubProcesses/MadLoopParamReader.f b/Template/loop_material/StandAlone/SubProcesses/MadLoopParamReader.f index d8b4951a10..37c3266305 100644 --- a/Template/loop_material/StandAlone/SubProcesses/MadLoopParamReader.f +++ b/Template/loop_material/StandAlone/SubProcesses/MadLoopParamReader.f @@ -33,6 +33,13 @@ subroutine MadLoopParamReader(filename, printParam) stop 'CTModeRun must be >= -1 and <=6.' endif + else if (buff .eq. '#LoopPoleMode') then + read(666,*,end=999) LoopPoleMode + if (LoopPoleMode.lt.-1.or.LoopPoleMode.gt.3) then + write(*,*) 'LoopPoleMode must be -1, 0, 1, 2 or 3.' + stop 1 + endif + else if (buff .eq. '#COLLIERGlobalCache') then read(666,*,end=999) COLLIERGlobalCache if (COLLIERGlobalCache .lt. -1) then @@ -136,6 +143,9 @@ subroutine MadLoopParamReader(filename, printParam) else if (buff .eq. '#UseQPIntegrandForNinja') then read(666,*,end=999) UseQPIntegrandForNinja + else if (buff .eq. '#UseQPIntegrandForNinjaRS') then + read(666,*,end=999) UseQPIntegrandForNinjaRS + else if (buff .eq. '#UseQPIntegrandForCutTools') then read(666,*,end=999) UseQPIntegrandForCutTools @@ -155,7 +165,7 @@ subroutine MadLoopParamReader(filename, printParam) else if (buff .eq. '#MLReductionLib') then read(666,*,end=999) MLReductionLib_str - MLReductionLib(1:7)=0 + MLReductionLib(1:9)=0 MLReductionLib_str_save=MLReductionLib_str j=0 DO @@ -179,6 +189,8 @@ subroutine MadLoopParamReader(filename, printParam) MLRed=6 ELSEIF(MLReductionLib_char.EQ.'7 ')THEN MLRed=7 + ELSEIF(MLReductionLib_char.EQ.'8 ')THEN + MLRed=8 ELSE PRINT *, 'MLReductionLib is wrong: '// $ TRIM(MLReductionLib_str_save) @@ -242,6 +254,19 @@ subroutine MadLoopParamReader(filename, printParam) 998 continue if(printParam.and..not.paramPrinted) then +C A partial card may omit MLReductionLib. Print the effective list rather +C than the uninitialized local string used only while parsing that entry. + MLReductionLib_str_save='' + DO i=1,9 + IF(MLReductionLib(i).EQ.0) EXIT + WRITE(MLReductionLib_char,'(I1)') MLReductionLib(i) + IF(i.EQ.1) THEN + MLReductionLib_str_save=TRIM(MLReductionLib_char) + ELSE + MLReductionLib_str_save=TRIM(MLReductionLib_str_save)// + & '|'//TRIM(MLReductionLib_char) + ENDIF + ENDDO write(*,*) & '===============================================================' if (couldRead) then @@ -255,6 +280,7 @@ subroutine MadLoopParamReader(filename, printParam) write(*,*) ' > MLReductionLib = ' $ //TRIM(MLReductionLib_str_save) write(*,*) ' > CTModeRun = ',CTModeRun + write(*,*) ' > LoopPoleMode = ',LoopPoleMode write(*,*) ' > MLStabThres = ',MLStabThres write(*,*) ' > NRotations_DP = ',NRotations_DP write(*,*) ' > NRotations_QP = ',NRotations_QP @@ -275,6 +301,8 @@ subroutine MadLoopParamReader(filename, printParam) write(*,*) ' > WriteOutFilters = ',WriteOutFilters write(*,*) ' > UseQPIntegrandForNinja = ', &UseQPIntegrandForNinja + write(*,*) ' > UseQPIntegrandForNinjaRS = ', + &UseQPIntegrandForNinjaRS write(*,*) ' > UseQPIntegrandForCutTools = ', &UseQPIntegrandForCutTools write(*,*) ' > IREGIMODE = ',IREGIMODE @@ -308,7 +336,8 @@ subroutine DefaultParam() MLReductionLib(1)=6 MLReductionLib(2)=7 MLReductionLib(3)=1 - MLReductionLib(4:7)=0 + MLReductionLib(4:9)=0 + LoopPoleMode=-1 IREGIMODE=2 IREGIRECY=.TRUE. COLLIERComputeIRpoles = .TRUE. @@ -339,5 +368,76 @@ subroutine DefaultParam() ImprovePSPoint=2 UseQPIntegrandForCutTools=.True. UseQPIntegrandForNinja=.True. + UseQPIntegrandForNinjaRS=.True. end + + SUBROUTINE ML_SET_LOOP_POLE_MODE(MODE) +C Pending requests have the same global scope as /MADLOOP/ and ML_INIT. +C A setter from any subprocess overrides the card for all subprocesses. + IMPLICIT NONE + INTEGER MODE,REQUESTED_LOOP_POLE_MODE + INCLUDE 'MadLoopParams.inc' + COMMON/ML_LOOP_POLE_REQUEST/REQUESTED_LOOP_POLE_MODE + IF(MODE.LT.-1.OR.MODE.GT.3) THEN + WRITE(*,*) 'LoopPoleMode must be -1, 0, 1, 2 or 3.' + STOP 1 + ENDIF + REQUESTED_LOOP_POLE_MODE=MODE + LoopPoleMode=MODE + END + + SUBROUTINE ML_APPLY_LOOP_POLE_MODE() +C Restore the most recent request after the first global card read. + IMPLICIT NONE + INTEGER REQUESTED_LOOP_POLE_MODE + INCLUDE 'MadLoopParams.inc' + COMMON/ML_LOOP_POLE_REQUEST/REQUESTED_LOOP_POLE_MODE + IF(REQUESTED_LOOP_POLE_MODE.NE.-2) THEN + LoopPoleMode=REQUESTED_LOOP_POLE_MODE + ENDIF + END + + BLOCK DATA ML_LOOP_POLE_REQUEST_INIT +C The shared reader is linked once, even in a multi-subprocess library. + IMPLICIT NONE + INTEGER REQUESTED_LOOP_POLE_MODE + COMMON/ML_LOOP_POLE_REQUEST/REQUESTED_LOOP_POLE_MODE + DATA REQUESTED_LOOP_POLE_MODE/-2/ + END + + SUBROUTINE ML_LOOP_POLE_FLAGS(COMPUTE_UV,COMPUTE_IR) +C The generic selector affects bare loop integrals only. The legacy +C COLLIER switches remain effective when LoopPoleMode is -1. + IMPLICIT NONE + LOGICAL COMPUTE_UV,COMPUTE_IR + INCLUDE 'MadLoopParams.inc' + COMPUTE_UV=COLLIERComputeUVpoles + COMPUTE_IR=COLLIERComputeIRpoles + IF(LoopPoleMode.GE.0) THEN + COMPUTE_UV=LoopPoleMode.EQ.0.OR.LoopPoleMode.EQ.1 + COMPUTE_IR=LoopPoleMode.EQ.0.OR.LoopPoleMode.EQ.2 + ENDIF + END + + SUBROUTINE ML_CHECK_LOOP_POLE_MODE() +C Reject unsupported rescue chains rather than silently returning +C combined poles after a UV-only or IR-only reduction fails. + IMPLICIT NONE + INTEGER I + INCLUDE 'MadLoopParams.inc' + IF(LoopPoleMode.LT.-1.OR.LoopPoleMode.GT.3) THEN + WRITE(*,*) 'LoopPoleMode must be -1, 0, 1, 2 or 3.' + STOP 1 + ENDIF + IF(LoopPoleMode.LE.0) RETURN + DO I=1,9 + IF(MLReductionLib(I).EQ.0) EXIT + IF(MLReductionLib(I).NE.7.AND.MLReductionLib(I).NE.8) THEN + WRITE(*,*) 'LoopPoleMode=1, 2 or 3 requires NinjaRS/COLLIER.' + WRITE(*,*) 'Set MLReductionLib to 8, 7 or 8|7, including', + & ' only supported rescue backends.' + STOP 1 + ENDIF + ENDDO + END diff --git a/Template/loop_material/StandAlone/SubProcesses/MadLoopParams.inc b/Template/loop_material/StandAlone/SubProcesses/MadLoopParams.inc index 008576b237..f849fb87bf 100644 --- a/Template/loop_material/StandAlone/SubProcesses/MadLoopParams.inc +++ b/Template/loop_material/StandAlone/SubProcesses/MadLoopParams.inc @@ -1,30 +1,33 @@ -!==================================================================== -! -! Define common block with all general parameters used by MadLoop -! See their definitions in the file MadLoopParams.dat -! -!==================================================================== -! - integer CTModeInit,CTModeRun,CheckCycle,MaxAttempts, - &CTLoopLibrary,NRotations_DP,NRotations_QP,ImprovePSPoint, - &MLReductionLib(8),IREGIMODE,HelicityFilterLevel,COLLIERMode, - &COLLIERGlobalCache - - real*8 MLStabThres,CTStabThres,ZeroThres,OSThres,COLLIERRequiredAccuracy - - logical UseLoopFilter,LoopInitStartOver,DoubleCheckHelicityFilter, - &COLLIERComputeIRpoles,COLLIERComputeUVpoles,COLLIERCanOutput - logical HelInitStartOver,IREGIRECY,WriteOutFilters - logical UseQPIntegrandForNinja, UseQPIntegrandForCutTools - logical COLLIERUseCacheForPoles,COLLIERUseInternalStabilityTest - - common /MADLOOP/CTModeInit,CTModeRun,NRotations_DP,NRotations_QP, - &COLLIERMode,COLLIERGlobalCache, - &ImprovePSPoint,CheckCycle, MaxAttempts,UseLoopFilter,MLStabThres, - &COLLIERRequiredAccuracy, - &CTStabThres,CTLoopLibrary,LoopInitStartOver, - &COLLIERComputeIRpoles,COLLIERComputeUVpoles,COLLIERCanOutput, - &COLLIERUseCacheForPoles,COLLIERUseInternalStabilityTest, - &DoubleCheckHelicityFilter,ZeroThres,OSThres,HelInitStartOver, - &MLReductionLib,IREGIMODE,HelicityFilterLevel,IREGIRECY, - &WriteOutFilters,UseQPIntegrandForNinja,UseQPIntegrandForCutTools +!==================================================================== +! +! Define common block with all general parameters used by MadLoop +! See their definitions in the file MadLoopParams.dat +! +!==================================================================== +! Eight library entries plus the terminating zero used during fallback. +! + integer CTModeInit,CTModeRun,CheckCycle,MaxAttempts, + &CTLoopLibrary,NRotations_DP,NRotations_QP,ImprovePSPoint, + &MLReductionLib(9),IREGIMODE,HelicityFilterLevel,COLLIERMode, + &COLLIERGlobalCache,LoopPoleMode + + real*8 MLStabThres,CTStabThres,ZeroThres,OSThres,COLLIERRequiredAccuracy + + logical UseLoopFilter,LoopInitStartOver,DoubleCheckHelicityFilter, + &COLLIERComputeIRpoles,COLLIERComputeUVpoles,COLLIERCanOutput + logical HelInitStartOver,IREGIRECY,WriteOutFilters + logical UseQPIntegrandForNinja, UseQPIntegrandForCutTools + logical UseQPIntegrandForNinjaRS + logical COLLIERUseCacheForPoles,COLLIERUseInternalStabilityTest + + common /MADLOOP/CTModeInit,CTModeRun,NRotations_DP,NRotations_QP, + &COLLIERMode,COLLIERGlobalCache,LoopPoleMode, + &ImprovePSPoint,CheckCycle, MaxAttempts,UseLoopFilter,MLStabThres, + &COLLIERRequiredAccuracy, + &CTStabThres,CTLoopLibrary,LoopInitStartOver, + &COLLIERComputeIRpoles,COLLIERComputeUVpoles,COLLIERCanOutput, + &COLLIERUseCacheForPoles,COLLIERUseInternalStabilityTest, + &DoubleCheckHelicityFilter,ZeroThres,OSThres,HelInitStartOver, + &MLReductionLib,IREGIMODE,HelicityFilterLevel,IREGIRECY, + &WriteOutFilters,UseQPIntegrandForNinja,UseQPIntegrandForCutTools, + &UseQPIntegrandForNinjaRS diff --git a/doc/benchmarkfolder/README.md b/doc/benchmarkfolder/README.md new file mode 100644 index 0000000000..8ad4400c50 --- /dev/null +++ b/doc/benchmarkfolder/README.md @@ -0,0 +1,27 @@ +# MadLoop NinjaRS benchmark report + +[Read the final measured report](benchmark.pdf) or its [Typst source](benchmark.typ). + +The final study compares Ninja6 and NinjaRS8 across twelve actual MG7 CLI profiles, including both SM2→4 processes and H/HH/HHH/HHHH. It also reports the separately scoped six-process original-code timing comparison, eight-process normal-rescue correctness, native-DP random stability and installation/precision/software controls. + +[Data, exact scopes and offline reproduction](final-report-v1/README.md) are retained with the report. The two on-shell CLI cases keep NA ratios where timing helicity/filter scope changed; mixed and uncertain results are not described as a blanket speedup. + +The complete scientific evidence, authority readers and prior partial report remain available in the [immutable measurement archive](https://github.com/MadGraphTeam/MadGraph7/tree/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder). This folder retains the requested small PDF, its Typst source, numerical summaries and vector figures. Original evidence paths in its data identify files in that archive, rather than files in the cleaned checkout. + +The seven font binaries and compressed raw CLI materialization are stored in the +[immutable report archive](https://github.com/MadGraphTeam/MadGraph7/tree/cc6f6fe6dd344a0a767dcfe52341c147e39a193a/doc/benchmarkfolder). +They are excluded from new source checkouts. To reproduce the PDF, first fetch +these eight files into ignored local paths (3.51 MB total): + +```sh +python -B doc/benchmarkfolder/fetch_artifacts.py +python -B doc/benchmarkfolder/final-report-v1/reproduce.py --output .benchmark-work/reproduced-benchmark.pdf +``` + +The first command requires network access and verifies every file against the +retained size and SHA256 before installing it atomically. Reruns reuse verified +files and refuse to overwrite modified inputs. The second command is unchanged: +after acquisition it runs entirely offline and requires byte-identical PDF +output using Typst 0.15.1. The CLI materialization supports auditing; it is not a +Typst input. Font licensing remains in `final-report-v1/fonts/OFL.txt`. No +download is required to read the PDF or run the NinjaRS regression suite. diff --git a/doc/benchmarkfolder/benchmark.pdf b/doc/benchmarkfolder/benchmark.pdf new file mode 100644 index 0000000000..462acfeea4 Binary files /dev/null and b/doc/benchmarkfolder/benchmark.pdf differ diff --git a/doc/benchmarkfolder/benchmark.typ b/doc/benchmarkfolder/benchmark.typ new file mode 100644 index 0000000000..8f47277f8e --- /dev/null +++ b/doc/benchmarkfolder/benchmark.typ @@ -0,0 +1,251 @@ +// Final measured report; regenerate offline using final-report-v1/reproduce.py. +#import "final-report-v1/style.typ": * +#show: body => two-tool-style(body) +#let d=json("final-report-v1/report-data.json") +#let correctness=d.correctness +#let labels=( + "qcd-1": $u overline(u) arrow Z$, "ew-1": $u overline(d) arrow W^+$, + "qcd-2": $g g arrow t overline(t)$, "ew-2": $e^+ e^- arrow mu^+ mu^-$, + "qcd-3": $u overline(u) arrow Z g g$, "ew-3": $e^+ e^- arrow t overline(t) gamma$, + "qcd-4": $u overline(u) arrow Z Z g g$, + "ew-4": $e^+ e^- arrow mu^+ mu^- gamma gamma$, + "supplement-gg-h": $g g arrow H$, "supplement-gg-hh": $g g arrow H H$, + "supplement-gg-hhh": $g g arrow H H H$, + "supplement-gg-hhhh": $g g arrow H H H H$, + "control-gg-h": $g g arrow H$, "control-gg-hh": $g g arrow H H$, + "control-gg-hhh": $g g arrow H H H$, + "control-gg-hhhh": $g g arrow H H H H$, + "profile-gg-hhh": $g g arrow H H H$, + "profile-gg-hhhh": $g g arrow H H H H$, +) +#let label(id)=labels.at(id,default:[#id]) +#let us(x)=fmt(x*1000000) +#let panel(body)=block(fill:pale,inset:8pt,radius:4pt,width:100%,body) +#let named-status(s)=( + "complete_comparable":"Matched sessions complete", + "complete_incomparable":"Complete; stage scopes differ", + "failed_attempt":"Attempt failed", + "pending":"Not yet observed", + "comparable":"Matched positive timings", + "nonpositive_samples":"Signed or zero estimate; no ratio", + "incomparable_stage_scope":"Stage scopes differ; no ratio", +).at(s,default:s) +#let ci(x)=[#us(x.at(0))–#us(x.at(1))] + +#align(center)[ + #text(size:25pt,weight:"bold",fill:navy)[MadLoop: Ninja and NinjaRS] + #v(4pt)#text(size:12pt)[Standard Model · reduction, total time and numerical stability] + #v(4pt)#text(size:9pt,fill:luma(100))[#d.date · actual measured components] +] +#v(10pt) +#panel[ + Three measurements answer distinct questions. The stock MG7 CLI reports an estimated reduction stage, a numerator-stage reference, and total time per phase-space point for the current exports. A separate six-process test compares warmed, full-helicity, rescue-enabled MadLoop against original revision #raw(d.light.literal_original_revision.slice(0,12)). Native-DP transformation tests compare Ninja and NinjaRS on identical random proposal streams with rescue disabled. Their samples, timing boundaries and error estimates are kept separate. +] + += Methods and sample scopes + +The main CLI table uses full helicity/color sums. Its *estimated reduction* is FULL−SKIP, including master integrals, callbacks and Laurent assembly. The *numerator stage (SKIP)* also contains non-reduction driver, Born and kinematic work; it is not an instruction-level tensor stopwatch. Adaptive traversal counts and raw floating timing metadata are retained for every stage. Three independent sessions per tool give empirical median-bootstrap intervals, with no small-sample coverage guarantee. All 72 sessions were retained. Ten processes have matching scopes across all six sessions. For the two on-shell SM cases, the selected timing helicity and filter changed after session 0; their per-tool medians remain shown, but the unchanged conservative reader suppresses aggregate ratios as NA. These direct-DP timings supply no timed rescue histogram. Optional polarized rows are shown only for positive saved helicity weight; a zero-weight selected configuration supplies no physical reduction-speed comparison. + +The random-DP panels use 100 declared points for each process and tool. Born processes use full sums; $g g arrow H$ and $g g arrow H H$ use the preregistered all-minus helicity. On-shell $2 arrow 1$ samples vary boosts at one physical invariant. Other cases use 1 TeV and a declared massive-RAMBO proposal with fixed cuts, rather than uniform massive phase-space integration. The empirical tail resolution is 1%; a zero count has an exact one-sided 95% binomial reference upper bound of 2.95%. A missing Ninja tail produces a ratio gap, without adding an epsilon. + +Typography, margins, navy headings, pale panels and logarithmic green–white–red timing cells follow the #link("https://github.com/alphal00p/ninjars/blob/ca1009e89ecb03d3ff477f57b170241f7a9f8669/docs/benchmark/benchmark.typ")[NinjaRS report]. Transformation comparisons follow #link("https://arxiv.org/pdf/1604.01363")[Hirschi–Peraro]; the present finite sample is stated explicitly rather than identified with the paper's larger surveys. + +// The accepted stock-CLI series will be inserted here through the separately +// validated CLI consumer. Its entire section is absent before that series +// exists: no missing values are printed as measurements. +#if d.stock_cli!=none { + pagebreak() + heading(level:1)[MG7 CLI: estimated reduction and total time] + // The final data view supplies only accepted raw-series observations and + // display-only optional-polarized eligibility. It does not alter authority + // statistics. Full-sum tables are the primary comparison. + for group in d.stock_cli.pages { + if group.index>0 {pagebreak()} + heading(level:2)[#group.title] + text(size:10pt)[Large values: *NinjaRS*. The comparison line gives Ninja; all times are in µs per point. Each interval uses the three actual sessions. Gray NA cells retain per-tool values without a cross-session ratio.] + v(6pt) + table(columns:(1.05fr,1.25fr,1.25fr,1.25fr), + inset:(x:5pt,y:9pt),stroke:.3pt+luma(225), + fill:(x,y)=>if y==0 {navy} else if x==0 and calc.rem(y,2)==0 {pale} else {none}, + table.header(text(fill:white)[Process / actual calls],text(fill:white)[Estimated reduction], + text(fill:white)[Numerator stage (SKIP)],text(fill:white)[Total]), + ..group.rows.map(c=>{ + let cells=( + [#set par(justify:false) + #label(c.id)#linebreak()#text(size:10pt)[3 sessions per tool]#linebreak()#text(size:9.5pt)[#c.stage_counts]], + ) + for q in ("reduction_estimate","construction","total") { + let v=c.quantities.at(q); let r=v.ninjars_over_ninja + cells.push(table.cell(fill:if r.ratio==none {pale} else {ratio-fill(r.ratio)},[ + #text(size:18pt,weight:"bold",fill:navy)[#us(v.backend.at("8").median_seconds_per_point) µs] + #linebreak()#text(size:10.5pt)[95% CI #ci(v.backend.at("8").confidence_interval95)] + #linebreak()#text(size:10.5pt)[MAD #us(v.backend.at("8").median_absolute_deviation) µs] + #linebreak()#text(size:10.5pt)[Ninja #us(v.backend.at("6").median_seconds_per_point) µs] + #linebreak()#text(size:10.5pt,weight:"semibold")[#if r.ratio==none {[NA · scopes differ]} else {[×#fixed(r.ratio,3)]}] + #linebreak()#text(size:10pt)[#if r.ratio!=none {[95% CI #fixed(r.confidence_interval95.at(0),3)–#fixed(r.confidence_interval95.at(1),3)]}] + ])) + } + cells + }).flatten(), + ) + v(6pt) + text(size:9.5pt)[N lists the actual unpolarized traversals in sessions 0/1/2. FULL and SKIP use the same N; polarized stages use 2N. Exact per-session phase counts, selected helicities, filter hashes and raw timings remain in JSON.] + } + +} + +#pagebreak() += MG7 profile: process-indexed timings +#image("final-report-v1/timing.svg",width:100%) +#v(5pt) +#text(size:9pt)[Circles denote the estimated reduction stage and squares the total. Open markers are Ninja; filled markers are NinjaRS. Bars give empirical independent-session 95% intervals. No line connects unrelated process families. The ratio panel preserves the large uncertainty of some three-session SM estimates; QCD1/EW1 remain NA because the selected helicity/filter changed between sessions. The numerator stage and exact phase counts are given in the preceding tables.] +#v(7pt) +#table(columns:(.4fr,1.5fr,.4fr,1.5fr),inset:3pt,stroke:.3pt+luma(225), + ..(("qcd-1","ew-1"),("qcd-2","ew-2"),("qcd-3","ew-3"),("qcd-4","ew-4"),("control-gg-h","control-gg-hh"),("profile-gg-hhh","profile-gg-hhhh")).enumerate().map(((i,ids))=>(str(i*2+1),[#label(ids.at(0))],str(i*2+2),[#label(ids.at(1))])).flatten(), +) + +#pagebreak() += Original MadLoop comparison: six warmed processes + +Each row uses the same ten fixed prefix points, seven adjacent alternating pairs, full helicity/color sums, poles and normal rescue. The denominator is original MadLoop with Ninja at #raw(d.light.literal_original_revision.slice(0,12)); the numerator is the installed NinjaRS cohort in the provenance records. A 1.05 ratio is shown as a reference for this sample. The former heavy eight-process runtime requirement was withdrawn when the measurement scope was narrowed. + +#v(7pt) +#table(columns:(1.15fr,1fr,1fr,1.5fr),inset:(x:5pt,y:6pt),stroke:.3pt+luma(225), + fill:(x,y)=>if y==0 {navy} else if calc.rem(y,2)==0 {pale} else {white}, + table.header(text(fill:white)[Process],text(fill:white)[Original Ninja#linebreak()µs / point], + text(fill:white)[NinjaRS#linebreak()µs / point],text(fill:white)[NinjaRS / original Ninja]), + ..d.light.rows.map(c=>{ + let t=c.timing; let r=t.runtime_ratio; let ci=t.ratio_confidence_interval_95 + ([#label(c.id)#linebreak()#text(size:8.5pt)[#c.points points · #c.pairs pairs]], + [#text(size:14pt,weight:"bold",fill:navy)[#us(t.measurements.baseline.median)]#linebreak()#text(size:8.5pt)[MAD #us(t.measurements.baseline.median_absolute_deviation)]], + [#text(size:14pt,weight:"bold",fill:navy)[#us(t.measurements.candidate.median)]#linebreak()#text(size:8.5pt)[MAD #us(t.measurements.candidate.median_absolute_deviation)]], + table.cell(fill:ratio-fill(r),[#text(size:16pt,weight:"bold",fill:navy)[×#fixed(r,3)]#linebreak()#text(size:9pt)[95% CI #fixed(ci.at(0),3)–#fixed(ci.at(1),3)]])) + }).flatten(), +) + +#v(8pt) +The 0.5 s setting is the calibration target used once to select the loop count. Actual warmed commands lasted #fixed(d.light.actual_command_seconds_range.at(0),3)–#fixed(d.light.actual_command_seconds_range.at(1),3) s. Saved status vectors describe the final traversal of each command; they do not form a complete histogram over every adaptive-loop evaluation. All selected final traversals returned normal DP status for both tools. + +#let groups=( + ("On-shell 2→1", "on-shell"), ("Two final-state particles", "two-particle"), + ("Three final-state particles", "three-particle"), ("Loop-induced amplitudes", "loop-induced"), +) +#for group in groups { + pagebreak() + heading(level:1)[Native-DP stability: #group.at(0)] + image("/"+d.stability.assets.at("assets/combined-"+group.at(1)+".svg"),width:100%) + v(4pt) + text(size:9pt)[The combined spread uses the same original, reversed-direction and Lorentz-transformed point. Hollow triangles mark zero-event upper references, not observed failures. All observations in this selected sample were finite. Full direction-only and Lorentz-only vector panels and exact tail counts accompany the report.] +} + +#pagebreak() += Numerical observations and practical limits + +#table(columns:(1.25fr,.8fr,1.15fr,.9fr),inset:(x:4pt,y:5pt),stroke:.3pt+luma(225), + fill:(x,y)=>if y==0 {navy} else if calc.rem(y,2)==0 {pale} else {white}, + table.header(text(fill:white)[Process],text(fill:white)[Finite / N#linebreak()Ninja · NRS], + text(fill:white)[Largest spread#linebreak()Ninja · NRS],text(fill:white)[Saved invalid flags#linebreak()Ninja · NRS]), + ..("qcd-1","ew-1","qcd-2","ew-2","qcd-3","ew-3","supplement-gg-h","supplement-gg-hh").map(id=>{ + let c=d.stability.counts.at(id); let a=c.tools.at("6"); let b=c.tools.at("8") + let ha=d.stability.hardware.at(id).tools.at("6").hardware_exception_observations + let hb=d.stability.hardware.at(id).tools.at("8").hardware_exception_observations + ([#label(id)], [#a.classifications.combined.finite / #c.N#linebreak()#b.classifications.combined.finite / #c.N], + [#a.maximum_spread_display#linebreak()#b.maximum_spread_display], + [#ha.ieee_invalid_seen · #hb.ieee_invalid_seen#linebreak()#text(size:8pt)[300 calls / tool]]) + }).flatten(), +) + +#v(8pt) +Saved hardware IEEE-invalid flags occur on 300 transformed observations for NinjaRS in $g g arrow t overline(t)$, $e^+ e^- arrow mu^+ mu^-$, $u overline(u) arrow Z g g$, $e^+ e^- arrow t overline(t) gamma$ and $g g arrow H H$. Plain-prefix checks reproduce the flags. Saved divide-by-zero/overflow, algorithmic FPE/rejections, nonfinite results and MP/compensated use are zero. Hardware flags are retained separately from numerical rejection by the frozen observer. + +Transformation self-consistency and reference agreement do not provide a scalar finite-part analytic oracle. Analytic pole controls, higher-precision convergence, installation/export checks and software regressions retain their own concrete evidence and scope. + +#pagebreak() += Numerical agreement and normal rescue + +The core comparison includes both $2 arrow 4$ processes. Born, finite, single-pole, double-pole and split-order coefficients passed the retained common-point tolerance. Every case has one fixed 100-point stream, calibration and two repeated observations; the coefficient rows and status histograms repeat exactly. The counts below describe one traversal of each unique stream, rather than treating repeated traversals as additional independent points. + +#v(8pt) +#table(columns:(1.4fr,.65fr,.8fr,.8fr,.85fr),inset:(x:5pt,y:6pt),stroke:.3pt+luma(225), + fill:(x,y)=>if y==0 {navy} else if calc.rem(y,2)==0 {pale} else {white}, + table.header(text(fill:white)[SM process],text(fill:white)[Points],text(fill:white)[NinjaRS DP],text(fill:white)[NinjaRS QP rescue],text(fill:white)[Agreement]), + ..("qcd-1","ew-1","qcd-2","ew-2","qcd-3","ew-3","qcd-4","ew-4").map(id=>{ + let c=correctness.core.at(id) + ([#label(id)],[#c.points_per_unique_stream],[#c.normal_dp],[#c.automatic_qp],[#c.agreement]) + }).flatten(), +) +#v(7pt) +Across these 800 unique points NinjaRS returned DP code 218 for 768 points and genuine automatic QP-rescue code 322 for 32. This normal-controller sample is separate from the rescue-disabled DP figures and from the CLI cache; its rescue frequencies are not inserted into timing cells that did not save full timed-call status histories. + +#v(9pt) +#panel[ + The additional $g g arrow H H H$ and $g g arrow H H H H$ controls passed matched Ninja6/NinjaRS8 full-sum, full-pole, normal-rescue comparisons at two fixed physical points per process, with zero Born terms. Their four native calls succeeded. A versioned, read-only finalizer corrected an analysis-only Python import error after collection; it repeated no native call and preserved the original parent exit 1. This is N=2 correctness evidence, distinct from the requested CLI timing sessions and from random stability. +] + +// Final assembly appends the concrete installation/precision/focused/software +// proof summaries and historical research attribution once their final current +// bound records are selected. No old optimization result is relabelled as a +// timing measurement of the installed final runtime. + +#pagebreak() += Integration, precision and software validation + +NinjaRS is selected with #raw("MLReductionLib=8") through process-prefixed Fortran wrappers and a versioned Rust C ABI. Installation uses #raw("install ninjars"); after updating the checkout, #raw("install ninjars --update") installs its pinned sources and lockfile transactionally. The measured numerical source is #raw("856e76e66961"), with NinjaRS #raw("aa6a6307") and oneloopmaster #raw("8ec256fc"); the final CLI observer is #raw("464b441fe04d"). The later NinjaRS main #raw("ca1009e") contains report-only changes: all 582 non-report source entries match the measured pin. The final watch is dated 22 October 2026. + +#v(7pt) +#table(columns:(1fr,3.3fr),inset:(x:6pt,y:6pt),stroke:.3pt+luma(225), + fill:(x,y)=>if calc.rem(y,2)==0 {pale} else {white}, + [Installation / export], [Actual CLI update and compiled installed smoke; relocated standalone DP/QP/normal-controller returns 110/120/218. FKS/NLO passed 20/20 pole checks at its documented $10^(-5)$ smoke tolerance, plus FKS-export soft/collinear checks with zero failures. This is separate from the stricter coefficient comparisons; no shower validation is claimed.], + [Focused physics], [45 persistent/fresh comparison pairs, 5,400 Born/Laurent/split components, cover complex masses, mixed orders and near-singular automatic rescue. Nine additional fixed two-point controls cover explicit QP direction and reused/finalized state changes; the separate normal-HH anchor supplies the normal-controller comparison.], + [Genuine precision], [The numerator and improved kinematics are recomputed in Fortran binary128. Forty-digit input records recover each original 113-bit value before exact widening; reduction and scalar masters use 256-bit arithmetic. Actual installed-ABI controls contain 64 calls. All 1,392 retained reduction requests converge at 256/384 bits, including complete Laurent, CC and same-basis R1 components; the largest scaled Laurent difference is $2.73 times 10^(-62)$.], + [Software], [The integrated selected-source campaign ran 293 tests: 292 passed and one unchanged conditional skip requiring a generated QCD2 tree. The final observer/resource-path successor passed 95 affected software checks. These overlapping software scopes are not summed as independent tests, and do not replace the physical campaigns.], +) + +#v(8pt) +The standard Rust suite passed 24 checks with 7 ignored. When explicitly enabled, two ignored diagnostics retain the historical bit-identity mismatch and the unresolved exceptional direct-provider case. + +The 256-bit calculation does not make the Fortran numerator 256-bit accurate. Returning through 40-digit output records can round to an adjacent binary128 value: 16 of 22,272 examined fields showed this, with largest Laurent-scaled difference $4.20 times 10^(-36)$. Historical replay is deliberately not labelled bitwise identical: 468 binary128 records changed, and the original bit-identity test exit 101 remains retained. The maximum scaled complete-Laurent difference from historical outputs is $1.48 times 10^(-34)$; a much larger basis-dependent R1 diagnostic change is not a change of that physical Laurent coefficient. + +Direct scalar-provider exceptional-input controls still retain two unsafe successes upstream. The tested full-bridge planar calls were accurate in DP or safely rejected in MP; that bridge behavior does not resolve the direct-provider finding. The retained source-bound receipts distinguish this limitation from accepted MadLoop amplitudes and from the finite-sample stability plots. + += Measured Fortran work and retained research + +The accepted allocation change measured a 3.15% whole-process improvement in the historical QCD3 study (ratio 0.9685, 95% interval 0.9569–0.9936). That study used generated source #raw("f4bffc61") and archive pair #raw("832fc0d1 → 366ae91d"), distinct from the final installed #raw("b0d69deb") archive. Its source-body attribution and exact records accompany the report. Earlier 9.24% DP callback-kernel and 3.19% Ninja6 Fortran-QP prototype results have different boundaries and are not additive. A separate 1,392-request Float256 native/interpreted screen had intervals crossing parity and was not promoted. The actual final timings above, including the slower EW2 ancillary ratio, determine the reported performance rather than these historical experiments. + +#pagebreak() += First-session output, compilation and initialization + +The following captured CLI costs provide preparation context for the per-point timings. Every cell gives *Ninja6 above NinjaRS8*, in seconds, for session 0 of that tool and process. These are direct metadata values, rounded to three significant digits for display; exact values and source hashes are in #raw("final-report-v1/preparation-costs.csv"). They are not three-session statistics. + +#v(8pt) +#table(columns:(1.35fr,1fr,1fr,1fr,1fr,.9fr),inset:(x:5pt,y:6pt),stroke:.3pt+luma(225), + fill:(x,y)=>if y==0 {navy} else if calc.rem(y,2)==0 {pale} else {white}, + table.header(text(fill:white)[Process],text(fill:white)[Output / export],text(fill:white)[HELAS / model compile],text(fill:white)[Initial process compile],text(fill:white)[Initialization],text(fill:white)[Boot]), + ..d.preparation.rows.map(c=>{ + let values=([#label(c.id)],) + for key in d.preparation.fields { + values.push([#c.tools.at("6").at(key).display#linebreak()#c.tools.at("8").at(key).display]) + } + values + }).flatten(), +) +#v(9pt) +#text(size:9.5pt)[The exact captured keys are #raw("Process_output"), #raw("HELAS_MODEL_compilation"), #raw("Process_compilation"), #raw("Initialization") and #raw("Booting_time"), respectively. Output/export is not labelled as standalone symbolic generation. The costs have different boundaries and are not asserted to form an additive total. Additional timed-stage recompilations and complete phase metadata remain in the raw records; boot subtraction and adaptive traversal counts retain their original CLI meanings.] + +#pagebreak() += Provenance and reproduction + +The final profile study contains 72 accepted command records: twelve processes, three sessions and tools 6/8. The first session creates a 20-point CLI DP cache, with zero QP entries; later sessions reuse it. This cache is not a matched-point random-stream authority or a complete timed-call status history. Three earlier Ninja-only pilot attempts failed before a complete profile result; their distinct source/specification, error and cleanup records are retained separately and their partial timing fragments are excluded. + +The full-sum CLI comparison includes both SM $2 arrow 4$ processes and loop-induced H, HH, HHH and HHHH. The separate normal-rescue six-process comparison uses original Ninja revision #raw("27147b3300f5") and final NinjaRS runtime #raw("a7577a9a3329") / archive #raw("b0d69deb8c16"). It passes the agreed 1.05 upper-interval reference in that amended ten-point, seven-pair scope. No canceled heavy eight-process timing requirement is reinstated, and no uniform SM speedup is inferred from the mixed, uncertain CLI estimates. + +#v(7pt) +#panel[ + *Offline PDF reproduction:* from the repository root, run #raw("python -B doc/benchmarkfolder/final-report-v1/reproduce.py --output reproduced.pdf"). It verifies the document's finite data/vector/font/style closure and compiles with Typst 0.15.1, bundled Libertinus fonts, a fixed #raw("SOURCE_DATE_EPOCH") and creation timestamp. No native archive, physics compilation, network or amplitude evaluation is needed. +] + +#v(8pt) +The source and raw custody verification is a separate operation requiring the exact retained installation and the concrete authority readers. Regenerating from pinned sources with a different compiler can produce new executable and measurement identities. The reproduction README links the #link("https://github.com/MadGraphTeam/MadGraph7/tree/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder")[immutable scientific archive at 19d67c860533], including the exact CLI cards, scalar coefficient records, timing metadata and prior partial report. This folder retains the finite offline document closure. + +#v(8pt) +Styling is attributed to #link("https://github.com/alphal00p/ninjars/blob/ca1009e89ecb03d3ff477f57b170241f7a9f8669/docs/benchmark/benchmark.typ")[NinjaRS ca1009e] and the earlier #link("https://github.com/MadGraphTeam/pyamplicol/blob/loop/docs/performance_reports/loop/benchmarks.typ")[pyamplicol report]. Tail and timing comparisons are inspired by #link("https://arxiv.org/pdf/1604.01363")[Hirschi–Peraro, arXiv:1604.01363]. The external optional plotting archive was inspected for methodology; no external plotting code is included. Libertinus 7.051 is distributed unmodified under the bundled SIL Open Font License. diff --git a/doc/benchmarkfolder/fetch_artifacts.py b/doc/benchmarkfolder/fetch_artifacts.py new file mode 100644 index 0000000000..b3e9934f68 --- /dev/null +++ b/doc/benchmarkfolder/fetch_artifacts.py @@ -0,0 +1,82 @@ +"""Fetch the frozen report's optional binary inputs into ignored local paths. + +The published PDF and its numerical summaries remain in the source tree. Run +this once before the separately offline, byte-identical PDF reproduction. +""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import tempfile +import urllib.request + +HERE = Path(__file__).resolve().parent +REVISION = "cc6f6fe6dd344a0a767dcfe52341c147e39a193a" +BASE_URL = ("https://raw.githubusercontent.com/MadGraphTeam/MadGraph7/" + + REVISION + "/doc/benchmarkfolder/") +ARTIFACTS = ( + "final-report-v1/cli-report.json.gz", + "final-report-v1/fonts/LibertinusMath-Regular.otf", + "final-report-v1/fonts/LibertinusMono-Regular.otf", + "final-report-v1/fonts/LibertinusSerif-Bold.otf", + "final-report-v1/fonts/LibertinusSerif-BoldItalic.otf", + "final-report-v1/fonts/LibertinusSerif-Italic.otf", + "final-report-v1/fonts/LibertinusSerif-Regular.otf", + "final-report-v1/fonts/LibertinusSerif-Semibold.otf", +) + + +def matches(data, expected): + return (len(data) == expected["bytes"] + and hashlib.sha256(data).hexdigest() == expected["sha256"]) + + +def fetch_artifacts(output_root, manifest): + """Fetch only missing, hash-verified files; never overwrite changed inputs.""" + root = output_root.resolve() + downloaded = 0 + for name in ARTIFACTS: + expected = manifest["files"][name] + target = (root / name).resolve() + if not target.is_relative_to(root): + raise ValueError("Artifact path escapes output directory: " + name) + if target.exists(): + if not matches(target.read_bytes(), expected): + raise ValueError("Existing artifact differs; move it aside first: " + + str(target)) + continue + # Reading at most the expected size plus one also rejects oversized + # responses. No response is installed before its size and hash agree. + with urllib.request.urlopen(BASE_URL + name, timeout=60) as response: + data = response.read(expected["bytes"] + 1) + if not matches(data, expected): + raise ValueError("Downloaded artifact failed checksum: " + name) + target.parent.mkdir(parents=True, exist_ok=True) + temporary = None + try: + with tempfile.NamedTemporaryFile(dir=target.parent, delete=False) as stream: + temporary = Path(stream.name) + stream.write(data) + stream.flush() + os.fsync(stream.fileno()) + temporary.replace(target) + finally: + if temporary is not None: + temporary.unlink(missing_ok=True) + downloaded += 1 + return {"verified_artifacts": len(ARTIFACTS), "downloaded": downloaded, + "revision": REVISION, "output_root": str(root)} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output-root", type=Path, default=HERE, + help="report root to populate (default: this directory)") + args = parser.parse_args() + manifest = json.loads((HERE / "final-report-v1/manifest.json").read_text()) + print(json.dumps(fetch_artifacts(args.output_root, manifest), sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/doc/benchmarkfolder/final-report-v1/README.md b/doc/benchmarkfolder/final-report-v1/README.md new file mode 100644 index 0000000000..20e9bbdb83 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/README.md @@ -0,0 +1,108 @@ +# Final measured benchmark report + +The published document is [`../benchmark.pdf`](../benchmark.pdf), generated from +[`../benchmark.typ`](../benchmark.typ). It contains actual Ninja6/NinjaRS8 +measurements and the separately scoped correctness/precision evidence. + +* Main MG7 CLI profile: all 12 processes including both SM 2→4 cases and + gg→H/HH/HHH/HHHH, three sessions/tool (72 accepted records). Large table values + are NinjaRS; the comparison line is Ninja. Estimated reduction is FULL−SKIP; + SKIP also contains non-reduction driver/Born/kinematic overhead. Actual phase + counts and signed raw estimates are retained. +* Ten cases have matching scopes across all six sessions. The QCD1/EW1 timing + helicity/filter changes after session 0, so their aggregate ratios remain NA + under the unchanged conservative reader. Every measured median is retained. + All actual selected weights are positive; optional zero-weight polarized + ratios would be suppressed in presentation, without changing raw statistics. +* Ancillary original-code comparison: six cases, ten fixed prefix points and + seven adjacent pairs, full sums/poles/normal rescue. The denominator is literal + original 27147 Ninja. All six upper 95% ratio intervals are below 1.05, including + the slower EW2 median. The 0.5 s setting is a calibration target; actual commands + last 0.326–0.519s. Only final-traversal status vectors were saved. +* Normal correctness: eight SM cases with 100 unique points each, calibration and + two exact repeated observations. NinjaRS returns 768 DP/32 automatic QP outcomes + per 800-point cohort. Extra HHH/HHHH controls use two fixed points each. +* Native-DP random stability: exactly eight affordable cases ×100 points ×2 tools. + Born cases use full sums; H/HH use all-minus. One-point streams have one + constrained on-shell invariant and random boosts. Hardware IEEE-invalid flags + are retained separately from algorithmic rejection; see the report. + +## Offline PDF reproduction + +First run `python -B doc/benchmarkfolder/fetch_artifacts.py` to obtain the +checksum-verified fonts and compressed CLI materialization from the immutable +report archive. These optional binary files are ignored in new checkouts; see +the [acquisition instructions](../README.md). The remaining steps are offline. + +Activate the documented environment or provide **Typst 0.15.1 (9dfd3a08)**, then +run from the repository root: + +```sh +python -B doc/benchmarkfolder/final-report-v1/reproduce.py --output .benchmark-work/reproduced-benchmark.pdf +``` + +The script checks every finite manifest-listed input, uses the bundled +Libertinus 7.051 fonts with system/embedded fonts disabled, sets +`SOURCE_DATE_EPOCH=1792627200` and the same explicit creation timestamp, then +requires byte-identical PDF output. It performs no network, native-library read, +physics compilation or amplitude evaluation. `--verify-only` checks inputs +without invoking Typst. `plot.py` recreates the timing SVG from the copied +validated statistics; it recomputes no timers/bootstrap/scientific acceptance. +The 12 DP SVGs come from the separately audited vector capsule in the immutable +scientific archive below. Its retained `plot.py` and tail arrays document their +construction; the frozen vectors here suffice for offline PDF reproduction. + +`report-data.json` is the compact Typst/data view. `cli-report.json.gz` retains +the exact concrete-consumer materialization (decoded hash in provenance), +including raw session values, intervals, per-stage counts, selected helicities, +runtime metadata and source hashes. `measurements.csv` provides the main full-sum +statistics in a flat format. `preparation-costs.csv` retains the exact captured +first-session output/export, HELAS/model compilation, initial process compilation, +initialization and boot costs, with 24 source-metadata hashes. These are neither +an additive total nor standalone symbolic-generation measurements. `provenance.json` links the concrete authorities. +No failed pilot fragment enters those statistics; all three earlier Ninja-only +failed pilots are retained separately in the archived publication inventory. + +## Scientific/source custody and regeneration + +The [immutable scientific archive](https://github.com/MadGraphTeam/MadGraph7/tree/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder) is commit +`19d67c8605337c176680878a521b3a014176a7fb`. It preserves the full raw observations, +command cards, authority readers, generated-source closure, audits and historical +partial report at their original paths. Those experiment trees are intentionally +absent from this lean report folder. `provenance.json` gives an immutable blob URL +and original byte hash for each concrete authority. Original paths inside the +copied JSON/gzip/CSV are archival identifiers, not current-checkout dependencies. + +For raw scientific revalidation, open the archive's documented campaign recipe +or extract that exact commit into a separate directory; do not run the old raw +paths against the cleaned checkout. With that archive and its retained native +prerequisites restored, the original command was: + +```sh +python -B tools/ninjars_cli_report_v3.py \ + --results docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/result-list.json \ + --expected docs/benchmarkfolder/final-report-v1/expected-cli-pins.json \ + --output revalidated-cli-report.json +``` + +This is an archived-checkout command, not an offline-PDF prerequisite. It used +consumer `6095252a` and concrete reader `b0681842`; native full-custody validation +also needs the exact retained b0d installation. The CLI observer commit 464b +differs from numerical source 856e; the shared Fortran/Rust numerical +implementation remains unchanged. Fresh scientific regeneration uses the +archive's command cards, installation pins, compiler and campaign recipes. +A different compiler can produce fresh executable/measurement identities; +that is distinct from reproducing this PDF from already validated measurements. + +The source-bound numerical proof retains 1392-request 256/384 convergence, the +historical bit-identity failure, adjacent binary128 rounding and the unresolved +direct-provider exceptional cases. The report does not convert those failures +into passes. Standard Rust tests are 24 pass/7 ignored; the two failing diagnostics +are explicit ignored controls, not a failing ordinary suite. + +Styling is attributed to [NinjaRS ca1009e](https://github.com/alphal00p/ninjars/blob/ca1009e89ecb03d3ff477f57b170241f7a9f8669/docs/benchmark/benchmark.typ) +and [pyamplicol](https://github.com/MadGraphTeam/pyamplicol/blob/loop/docs/performance_reports/loop/benchmarks.typ). +Method inspiration is [Hirschi–Peraro](https://arxiv.org/pdf/1604.01363). +Bundled unmodified Libertinus fonts use the included OFL 1.1 license. The +[historical partial report](https://github.com/MadGraphTeam/MadGraph7/tree/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/historical/20261021-partial) +is retained in the immutable scientific archive. diff --git a/doc/benchmarkfolder/final-report-v1/compile-environment.json b/doc/benchmarkfolder/final-report-v1/compile-environment.json new file mode 100644 index 0000000000..59b178beeb --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/compile-environment.json @@ -0,0 +1,7 @@ +{ + "SOURCE_DATE_EPOCH": 1792627200, + "creation_timestamp": 1792627200, + "font_origin": "Libertinus7.051, bundled unmodified underOFL1.1", + "native_revalidation_required_for_offline_compile": false, + "typst": "0.15.1 (9dfd3a08)" +} diff --git a/doc/benchmarkfolder/final-report-v1/expected-cli-pins.json b/doc/benchmarkfolder/final-report-v1/expected-cli-pins.json new file mode 100644 index 0000000000..1083323f62 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/expected-cli-pins.json @@ -0,0 +1,5 @@ +{ + "ninja_archive": "42866021f93004c143e0a49de8c420a6bebbcd4eb26242eef556ad71296e57c0", + "ninjars_archive": "b0d69deb8c16deb13293176296afc5e18dbeeebe778a20fa39b61804fba89d4c", + "process_checks": "59b2051d9ba17408046e9a7df188b70256e4081b71519b441623bc5e33358899" +} diff --git a/doc/benchmarkfolder/final-report-v1/fonts/OFL.txt b/doc/benchmarkfolder/final-report-v1/fonts/OFL.txt new file mode 100644 index 0000000000..e85f1f4c41 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/fonts/OFL.txt @@ -0,0 +1,94 @@ +Copyright © 2012-2024 The Libertinus Project Authors, +with Reserved Font Name "Linux Libertine", "Biolinum", "STIX Fonts". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/doc/benchmarkfolder/final-report-v1/formatter-source.py b/doc/benchmarkfolder/final-report-v1/formatter-source.py new file mode 100644 index 0000000000..0d9d18e6ca --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/formatter-source.py @@ -0,0 +1,94 @@ +"""Offline display view of an already validated CLI-consumer snapshot. + +This formatter does not validate or accept physics. Run the concrete public CLI +consumer first, then bind its materialized JSON by SHA256. Raw statistics remain +unchanged; optional zero-weight polarized comparisons are omitted from display. +""" +import argparse +import copy +import hashlib +import json +import math +from pathlib import Path + +ORDER = ("qcd-1", "ew-1", "qcd-2", "ew-2", "qcd-3", "ew-3", "qcd-4", "ew-4", + "control-gg-h", "control-gg-hh", "profile-gg-hhh", "profile-gg-hhhh") +PAGES = (("SM: one or two final-state particles", ORDER[:4]), + ("SM: three or four final-state particles", ORDER[4:8]), + ("Loop-induced amplitudes: H, HH, HHH and HHHH", ORDER[8:])) + + +def format_snapshot(snapshot): + if snapshot.get("schema") != "ninjars-cli-profile-report-v1" or snapshot.get("requested_tools") != [6, 8]: + raise ValueError("Use the materialized two-tool CLI-consumer snapshot") + if set(snapshot["cases"]) != set(ORDER): + raise ValueError("The final CLI presentation retains all twelve declared processes, including both 2-to-4 cases") + rows, optional, suppressed = {}, [], [] + for cid in ORDER: + case = snapshot["cases"][cid] + complete = case["status"] == "complete_comparable" + observations = case["observations"] + stage_counts = { + backend: {name: [record["stage_point_counts"][name] for record in records] + for name in ("unpolarized_full", "unpolarized_skip", "polarized_full", "polarized_skip")} + for backend, records in observations.items()} + row = {"id": cid, "process": case["process"], "status": case["status"], + "sessions": case["sessions"], "required_sessions_per_backend": case["required_sessions_per_backend"], + "actual_stage_counts": stage_counts, + "quantities": copy.deepcopy(case["timings"]["helicity_sum"]), + "primary_mode": "full-helicity-color-sum", + "failed_attempts": copy.deepcopy(case["failed_attempts"])} + row["stage_counts"] = "; ".join( + name + " FULL/SKIP " + str(stage_counts[backend]["unpolarized_full"]) + "/" + + str(stage_counts[backend]["unpolarized_skip"]) + for backend, name in (("6", "Ninja"), ("8", "NRS"))) + # Do not turn absent/incomparable sessions into a complete final table. + # The source consumer still retains partial actual statistics and errors. + rows[cid] = row + weights = {backend: [record["selected_helicity_weight"] for record in records] + for backend, records in observations.items()} + positive = complete and all(type(w) in (int, float) and math.isfinite(w) and w > 0 + for series in weights.values() for w in series) + if positive: + optional.append({"id": cid, "weights": weights, + "quantities": copy.deepcopy(case["timings"]["single_helicity"]), + "actual_stage_counts": stage_counts, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison"}) + else: + suppressed.append({"id": cid, "weights": weights, + "display": "grey; no optional polarized performance ratio", + "reason": "Zero/nonpositive or unavailable saved weight, or incomplete/incomparable sessions", + "raw_diagnostic_preserved": True}) + return {"pages": [{"index": i, "title": title, "rows": [rows[cid] for cid in ids]} + for i, (title, ids) in enumerate(PAGES)], + "all_twelve_sessions_complete_comparable": snapshot["complete"], + "declared_scope": copy.deepcopy(snapshot["declared_scope"]), + "runtime_pins": copy.deepcopy(snapshot["runtime_pins"]), + "optional_positive_weight_polarized": optional, + "suppressed_optional_polarized": suppressed, + "retained_failed_attempts": snapshot["retained_failed_attempts"], + "attempt_inventory_scope": snapshot["attempt_inventory_scope"], + "timed_status_counts_available": False, + "source_snapshot_preserved": True, + "scope": "Display-only full-sum RED/SKIP/TOTAL view; actual consumer statistics copied unchanged"} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--snapshot", type=Path, required=True) + parser.add_argument("--sha256", required=True, help="Hash of the actual, concrete-consumer materialization") + parser.add_argument("--output", type=Path, required=True) + args = parser.parse_args() + raw = args.snapshot.read_bytes() + if hashlib.sha256(raw).hexdigest() != args.sha256: + raise ValueError("Materialized CLI snapshot changed") + if args.output.exists(): + raise ValueError("Preserve earlier display views") + view = format_snapshot(json.loads(raw)) + view["materialized_snapshot"] = {"path": str(args.snapshot), "sha256": args.sha256} + view["formatter_sha256"] = hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + args.output.write_text(json.dumps(view, indent=2, sort_keys=True, allow_nan=False) + "\n") + + +if __name__ == "__main__": + main() diff --git a/doc/benchmarkfolder/final-report-v1/historical-optimization-facts.json b/doc/benchmarkfolder/final-report-v1/historical-optimization-facts.json new file mode 100644 index 0000000000..c81af91ded --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/historical-optimization-facts.json @@ -0,0 +1,480 @@ +{ + "schema": "private-report-presentation-independent-facts-v1", + "reviewer": "/root/allocation_final", + "created_utc": "2026-10-21T03:01:45.099325+00:00", + "scope": "Read retained records/source only. No physics, engines, compilers, tests, new samples, bootstrap recomputation, production edits, or final acceptance claims.", + "head_during_read": "9d33d4650a2e6079d007c365f1c12bb74a2def3f", + "studies": [ + { + "id": "allocation-qcd-3", + "kind": "full-warmed-MadLoop", + "process": { + "id": "qcd-3", + "model": "loop_sm", + "nfinal": 3, + "process": "u u~ > z g g [virt=QCD]" + }, + "backend": 8, + "precision": "DP with genuine Float256 own rescue from binary128 Fortran inputs", + "cpu": 234, + "pairs": 21, + "points_per_traversal": 100, + "timing_unit": "seconds/point", + "baseline_median": 0.12641518774, + "candidate_median": 0.12243543447, + "ratio_candidate_over_baseline": 0.968518392915057, + "paired_bootstrap_95_CI": [ + 0.9568779827192503, + 0.993639704088713 + ], + "bootstrap": { + "kind": "ratio of medians, paired percentile, linear interpolation", + "resamples": 100000, + "seed": 20261020 + }, + "status_counts_every_arm_traversal": { + "218": 98, + "322": 2 + }, + "exact_component_comparisons": 33600, + "all_raw_values_rows_accuracy_status_exact": true, + "selection": "gain-demonstrated", + "identities": { + "allocation": { + "generated_sources_sha256": "a52d4842c4b93e50b42727b943a9f6845361147ade681aa7eb76f0f6a4ea92e1", + "executable_sha256": "407a2fe6a31e425f14e9fd2636d012f0e42c2e61981af9bbb09ec3689fe53348", + "driver_sha256": "3e56a4efdfe5d8350a80955b60b842f15cac2c1d47c039421e96b675ae5cef76", + "parameter_card_sha256": "8fb107ff7269fd876f0f3aa741eeb830ec6f94a3f8a7bc96b852afcdde698060", + "madloop_card_sha256": "7da30726e90d04d6e48d3fafcb75fe40db8f440a93c70a279f288b35f665ec49", + "points_sha256": "b6121328eaded263e1ed62d04cea99126119b4ca3d7732f1abb3374f6cce1f41", + "generation_revision": "f4bffc61ed67e5d083b80ff9901768d4d5779989", + "generation_tree_state_sha256": "077ad72d1f0888924a37efaf59ce90007bf4221bf096b7faf5b83769307e1b72" + }, + "original": { + "generated_sources_sha256": "a52d4842c4b93e50b42727b943a9f6845361147ade681aa7eb76f0f6a4ea92e1", + "executable_sha256": "00117f28635ba30b366c9a0367afd2763aa51ca083ba345a3351ec70bef57ed3", + "driver_sha256": "3e56a4efdfe5d8350a80955b60b842f15cac2c1d47c039421e96b675ae5cef76", + "parameter_card_sha256": "8fb107ff7269fd876f0f3aa741eeb830ec6f94a3f8a7bc96b852afcdde698060", + "madloop_card_sha256": "7da30726e90d04d6e48d3fafcb75fe40db8f440a93c70a279f288b35f665ec49", + "points_sha256": "b6121328eaded263e1ed62d04cea99126119b4ca3d7732f1abb3374f6cce1f41", + "generation_revision": "f4bffc61ed67e5d083b80ff9901768d4d5779989", + "generation_tree_state_sha256": "077ad72d1f0888924a37efaf59ce90007bf4221bf096b7faf5b83769307e1b72" + } + } + }, + { + "id": "allocation-ew-2", + "kind": "full-warmed-MadLoop", + "process": { + "id": "ew-2", + "model": "loop_qcd_qed_sm_Gmu", + "nfinal": 2, + "process": "e+ e- > mu+ mu- [virt=QED]" + }, + "backend": 8, + "precision": "DP; no rescue observed", + "cpu": 234, + "pairs": 7, + "points_per_traversal": 100, + "timing_unit": "seconds/point", + "baseline_median": 0.0008399354700000001, + "candidate_median": 0.00083795285, + "ratio_candidate_over_baseline": 0.9976395567626164, + "paired_bootstrap_95_CI": [ + 0.9947156585798971, + 0.9993386991979275 + ], + "bootstrap": { + "kind": "ratio of medians, paired percentile, linear interpolation", + "resamples": 100000, + "seed": 20261020 + }, + "status_counts_every_arm_traversal": { + "218": 100 + }, + "exact_component_comparisons": 11200, + "all_raw_values_rows_accuracy_status_exact": true, + "selection": "regression-gate-passed", + "identities": { + "allocation": { + "generated_sources_sha256": "089ff160ec2c531e2b80f164ca31340253dea65e8977d518faa031653861b803", + "executable_sha256": "54fd2fb9a5e59fb03f4771cab00ddf59da5b4656419ce8dc9e356ddc406eb559", + "driver_sha256": "6142db3a8c1bd3faeac1b15d05f4dccf73f85cef24923e7556029bec98a8fbf9", + "parameter_card_sha256": "ed72c21a3b814a5d92d53f72ab3662d0b9f1743f60f755e825ecee1c18a0c715", + "madloop_card_sha256": "7da30726e90d04d6e48d3fafcb75fe40db8f440a93c70a279f288b35f665ec49", + "points_sha256": "ed6f3f83033372061ed6de45c05a366aeeb68a63ddd006998682f406174e7b53", + "generation_revision": "f4bffc61ed67e5d083b80ff9901768d4d5779989", + "generation_tree_state_sha256": "077ad72d1f0888924a37efaf59ce90007bf4221bf096b7faf5b83769307e1b72" + }, + "original": { + "generated_sources_sha256": "089ff160ec2c531e2b80f164ca31340253dea65e8977d518faa031653861b803", + "executable_sha256": "3659432ccb57f76018d4c9c63206a7603e97ecc3e6fd8d96fbbff1eea7b383a3", + "driver_sha256": "6142db3a8c1bd3faeac1b15d05f4dccf73f85cef24923e7556029bec98a8fbf9", + "parameter_card_sha256": "ed72c21a3b814a5d92d53f72ab3662d0b9f1743f60f755e825ecee1c18a0c715", + "madloop_card_sha256": "7da30726e90d04d6e48d3fafcb75fe40db8f440a93c70a279f288b35f665ec49", + "points_sha256": "ed6f3f83033372061ed6de45c05a366aeeb68a63ddd006998682f406174e7b53", + "generation_revision": "f4bffc61ed67e5d083b80ff9901768d4d5779989", + "generation_tree_state_sha256": "077ad72d1f0888924a37efaf59ce90007bf4221bf096b7faf5b83769307e1b72" + } + } + }, + { + "id": "native-NativeDenominators", + "kind": "private-complete-MpState-evaluate-request-screen", + "process": "1392 retained actual MadLoop MP bridge requests covering nine topology/rank shapes; not a generated full-process timing", + "backend": "private policy, same compiled executable for all three arms", + "precision": "113-bit input recovery then exact widening to Float256; same interpreted generic tensor in all arms", + "cpu": 190, + "triplets": 7, + "timing_unit": "seconds/complete 1392-request stream", + "baseline": "Interpreted", + "candidate": "NativeDenominators", + "baseline_median": 19.853261741, + "candidate_median": 20.284039222, + "ratio_candidate_over_baseline": 1.0216980709074308, + "paired_bootstrap_95_CI": [ + 0.973591667127239, + 1.0456657740821684 + ], + "bootstrap": { + "resamples": 100000, + "seed": 20261021, + "unit": "triplet indices", + "percentiles": "linear2.5%97.5%" + }, + "all_statuses_successful": true, + "selection": "No demonstrated gain; not promoted. CI crosses one; does not establish a slowdown.", + "executable_sha256": "26d8648fe69fe4fe38fade56352d950aebd0d7f3e7bce23d94a3387f06e20578", + "input_sha256": "1fafb19d4b534c3e222e5b265dfd8b139f262d3353f847a5c39955c468fa9f4d", + "build_completed_sha256": "689f86c5f4cf106e818ac0618f3fe2ec6916b15f7c332259c53f7d9897ca01d5" + }, + { + "id": "native-FullNative", + "kind": "private-complete-MpState-evaluate-request-screen", + "process": "1392 retained actual MadLoop MP bridge requests covering nine topology/rank shapes; not a generated full-process timing", + "backend": "private policy, same compiled executable for all three arms", + "precision": "113-bit input recovery then exact widening to Float256; same interpreted generic tensor in all arms", + "cpu": 190, + "triplets": 7, + "timing_unit": "seconds/complete 1392-request stream", + "baseline": "Interpreted", + "candidate": "FullNative", + "baseline_median": 19.853261741, + "candidate_median": 19.993630338, + "ratio_candidate_over_baseline": 1.0070703040553843, + "paired_bootstrap_95_CI": [ + 0.9810598340340952, + 1.0401095393062334 + ], + "bootstrap": { + "resamples": 100000, + "seed": 20261021, + "unit": "triplet indices", + "percentiles": "linear2.5%97.5%" + }, + "all_statuses_successful": true, + "selection": "No demonstrated gain; not promoted. CI crosses one; does not establish a slowdown.", + "executable_sha256": "26d8648fe69fe4fe38fade56352d950aebd0d7f3e7bce23d94a3387f06e20578", + "input_sha256": "1fafb19d4b534c3e222e5b265dfd8b139f262d3353f847a5c39955c468fa9f4d", + "build_completed_sha256": "689f86c5f4cf106e818ac0618f3fe2ec6916b15f7c332259c53f7d9897ca01d5" + }, + { + "id": "older-tensor-callback-allocation", + "kind": "pure-generic-tensor-callback-dispatch", + "process": "same1392-record captured input trace, nine topology/rank shapes", + "precision": "Float256 tensor callbacks; preserved exact per-value precision/sign", + "cpu": 234, + "pairs": 21, + "timing_unit": "seconds/sum of1392 per-record callback timer intervals", + "baseline_median": 7.240937685, + "candidate_median": 6.571593567, + "ratio_candidate_over_baseline": 0.9075611271470292, + "paired_bootstrap_95_CI": [ + 0.8982879334364353, + 0.9127498167466004 + ], + "bootstrap": { + "percentile": "linear interpolation at (n-1)*p", + "resampling": "complete adjacent pair indices", + "rng": "Python random.Random", + "samples": 100000, + "seed": 20261020 + }, + "exact_complex_outputs_per_block": 86436, + "all42blocks_exact": true, + "trace_sha256": "7a8cea5904b2bb665be87f5079cbf094713607e4ad25ca7c6fecef6e3c0977a5", + "source_hashes": { + "Cargo.lock": "c7b5be891dcdb75654adaa36dac5f3940c701c18d7d105215c598d7d42a81a25", + "Cargo.toml": "8748a4d8820c1580c9c520eb249abe4bf61d1305f90b802814bfdc5dbf87f427", + "src/allocation.rs": "525d5083904cd0257938c128e0e44f2d202de0e31f82b411f45e2a004ff8e5e1", + "src/capture.rs": "57a79744a889b806713d9a0fb05aaf0a0fbce6c3f576afcb525e7c2ec62c7406", + "src/common.rs": "f2729527b649b98b6272d38a9eeeab7dffaa5f1d507b1667f0cf9ac4a1568d9f", + "src/kernel.rs": "d01da637a77fb79de4616ae5a9f278c1217176540c7e04e56290fc9d9c2b679c", + "src/original.rs": "f5b153e179ac56e4a833f8d83b011a667e61cff1bcb567c2f1508a1d94013e55" + }, + "full_process_claim": false + }, + { + "id": "older-Fortran-QP-sharing", + "kind": "full-warmed-MadLoop-prototype-comparison", + "process": "u u~ > z g g [virt=QCD], loop_sm", + "backend": 6, + "precision": "Ninja6 DP with two own QP rescues; prototype changes QP FFV rank2-4 accumulation only", + "cpu": 208, + "pairs": 21, + "points_per_traversal": 100, + "timing_unit": "seconds/point", + "baseline_median": 0.06857657389999999, + "candidate_median": 0.06638863190000001, + "ratio_candidate_over_baseline": 0.9680949065319231, + "paired_bootstrap_95_CI": [ + 0.9584911267952578, + 0.9821376255819932 + ], + "bootstrap": { + "method": "paired percentile", + "resamples": 10000, + "seed": 410083 + }, + "status_counts_every_arm_traversal": { + "216": 98, + "328": 2 + }, + "printed_binary64_identical_coefficients": 16800, + "identities": { + "generation_revision": "b44d20e725f1ec68589df20284e4ce9116e9e2ab", + "generation_tree_state_sha256": "5778e8f909acaab782c0a35217fc60af3bbe1211fef765dfd1abf6a925e5d58a", + "builds": { + "original": { + "seconds": 4.498756770975888, + "executable_sha256": "ca676400ee141fb863c3e296238810e9473b66135807475e44525c522a75f22d", + "compiled_sources_sha256": "c5b9e82f8e88867ae9e3c90167f3a54864231689ea6d8e8ba7d7fe09b953b210" + }, + "factor": { + "seconds": 17.64875009492971, + "executable_sha256": "94fb71b9c8c9eccf5335003992724af70797e9ce4a6e24803ecb68611b5a044c", + "compiled_sources_sha256": "fda7b253d9f3d4785a966f1d46f6ff75c675545906208dbbd9e43fd64520a8a0" + } + }, + "used_ninja_archive_sha256": "42866021f93004c143e0a49de8c420a6bebbcd4eb26242eef556ad71296e57c0", + "used_scalar_olo_archive_sha256": "8469cc93665ba24c2ca0b848d61fead56a517f78c4a1672a110d64177568aa8d" + }, + "historical_package_acceptance_eligible": false + } + ], + "allocation_identity": { + "baseline_archive_sha256": "832fc0d1198814b9cc80a65e47bc7aa5dc204f7d25701f206c910cd188fbe80b", + "allocation_archive_sha256": "366ae91da891e9d7e5c19cbf4cbcca20a622d32b452305df58146a96c4189357", + "minimal_release_tensor_sha256": "240bbc1f9c8937393227c16a6ce4887ee68524a3f021a8a93656151159445d70", + "original_tensor_sha256": "f5b153e179ac56e4a833f8d83b011a667e61cff1bcb567c2f1508a1d94013e55", + "same_wrapper_sha256": "4831e01d07d83d376c6e9fd1f13543094496ce168308e041eac126bbdc888245", + "same_bridge_lib_rs_sha256": "a4f7215e5812ce337a3fdc083c99ee731f1b6cc3a83e4ff4780ed0e1a4a26128", + "package_record": { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-process-v1/package-exact.json", + "sha256": "4dd11b5760ac187f32a4b8a395ca25d016ee68ecab7e00fa96d15b61a3950dc4", + "bytes": 8861 + }, + "build_parity": "Retained exact installer cargo rustc invocation and complete effective Cargo fingerprint parity; no effective-LTO inference from manifest alone.", + "promotion_gates_passed": true, + "not_current_final_archive": "Timed allocation366ae\u2026 differs from final installed800a941f\u2026; retain exact historical identity.", + "v1_paused_samples": "Historical12 completed pairs plus one arm and interrupted worker excluded; fresh v2fixed21+7 only." + }, + "native_identity": { + "prepared_source_delta_sha256": "11bf858bcf64fb80fa01f31068974c310f5252cadde88477fa4137e8edbfb4a8", + "original_tensor_sha256": "f5b153e179ac56e4a833f8d83b011a667e61cff1bcb567c2f1508a1d94013e55", + "prepared_study_lib_rs_sha256": "11a57c8b2f4a901d326908e50c2bab1b2f6c4abfdf5699cb2413a013f69363d6", + "supplement_source_hashes": { + ".gitignore": "75b7dbb02a9764029bd6e213d34359fa93b3241ba7e74ebf4b9b13dc3fbc27aa", + "Cargo.lock": "c7b5be891dcdb75654adaa36dac5f3940c701c18d7d105215c598d7d42a81a25", + "Cargo.toml": "12d41805a3fd441239cdc91112c7330664b857bc630178a561790f7a1215d919", + "Makefile": "3373a4dea5f02c76b13a86b2d323b0f39d2d080e2acb3e682d692d528836838f", + "UPSTREAM.md": "fed6015ef5ebae4f35cd8c8d83855c9b87a381f60013e62d927e280790b92c54", + "build.rs": "fa389383328261938398f067a18ad860ef21e0bb4bc15c95b24be3e0a6704342", + "examples/replay.rs": "6381e93e652fec4547949a7a2a4c05e7b6955fe817862e97f42e83f2d0182200", + "mninjars.f90": "ebcd440b64a7983d2789670556905531a24a860308687f5f8b2f789ac569ae05", + "ninjars.h": "62e8237316e80b63264de3fc031f118e242e62651f1cec9c6d1c40cca0aace8c", + "smoke.f90": "913e96e53e2ba15a71679559d0a2b79b3a12cc7640286ab1a86d1db260e2919a", + "src/guarded.rs": "0c7ac81fe597083e13b069e74a978161d56a101ca8b58bad4b8adaa04ad0d94c", + "src/guarded_fenv.c": "79e47e68003e6660cfc0d67318b1069e0f2f8958a7a6d642020543670ffbb427", + "src/guarded_tests.rs": "9566681f2b67e82f5fed8f3186c362820b7991624296d04c905491b230f3769d", + "src/lib.rs": "11a57c8b2f4a901d326908e50c2bab1b2f6c4abfdf5699cb2413a013f69363d6", + "src/native_study_tests.rs": "1a10fa9c69fe0517c79f03a7d2fa86c7b39c6efb4df8c9464a14fbe70a7d36a2", + "src/native_supplement_tests.rs": "4b2ba0697cb58374bbc93525afa9de6f94aeab17e9716861afa7635267775a95", + "src/retry_tests.rs": "2492364fb5877d3ea34088b2f33e3a55c27ba77bafe7871c4d91f78aa41fb10e", + "src/tensor.rs": "f5b153e179ac56e4a833f8d83b011a667e61cff1bcb567c2f1508a1d94013e55", + "src/transport_contract_tests.rs": "884307cd6500059cfb28a24748f8219d0d9f3a87ab84dd97bfd9af34a97ac6fb", + "src/transport_replay_tests.rs": "d0a0e3129a9eb43765087d182a204db012cd8bb90ade093c25449e94c6a9a6cf", + "tests/data/cases/madloop-four-photon-top-box-0.json": "9aea91e4e6c70b0f5984b2070e7aef8a77699260dacac1a9b3c9d65f23189796", + "tests/data/cases/madloop-gg-hh-top-box-2.json": "c9271b79b2a4df2155ee8855fda3ffc6090f37261711468efd3126cf6665d5a3", + "tests/data/cases/madloop-gg-hh-top-triangle-0.json": "5178de553b5dcfa0fcca616748943a63f2933399203f7d7040ba9c98aa3b4ea2", + "tests/data/cases/madloop-gg-hhh-top-box-8.json": "3f14438d72237acbd9c74f8ba813fa6fd04c2aa1af2cdde143134146a650a489", + "tests/data/cases/madloop-gg-hhh-top-pentagon-26.json": "af571c4df618dafad08dc0acdb345f39d0446a2ec814f03b7cc2ee5a25d727ca", + "tests/data/cases/madloop-gg-hhh-top-triangle-0.json": "98483fd5759713618d7dfa784d604b83a7f03b241a5402d9a808af3655920353", + "tests/data/cases/madloop-hgg-top-triangle-0.json": "8a70a0fc3569676b2601dbeb36b16cb70817b40df8eb3e762e4ed1899246d590", + "tests/data/compensated/corrected-results.json": "f868eb5d279ef0ef68aefcf34704a094cb4452447aff857c7650358b623dfa94", + "tests/data/compensated/expansion-results.json": "8bdf9a439db23f793ca38f774997d866d6a0fa279e00a086d81cee21a3d67b76", + "tests/data/compensated/inputs.json": "1fb7ea9413efd25053dfdab357baf9ee973d8df3b6452fbaa280b684aea177b9", + "tests/data/convergence.json": "b34d6ef194a5297914050ceb6ffd25f5402c0150898921d2dcaf65471e55ec93", + "tests/data/ninja/madloop-four-photon-top-box-0.json": "dc34ad2683fbe535140c63bba564b8f6e8e74ce3c64eb17ef3cfa96baa5a6dde", + "tests/data/ninja/madloop-gg-hh-top-box-2.json": "d893de26b4e2e4edbeb4d6ba3122a6cd231bd5842719b3b8b2c4a84ee5e67dcc", + "tests/data/ninja/madloop-gg-hh-top-triangle-0.json": "669b92538382201f26487865cd44a1d8eea03b13ed7b99dcdae21bd7662cca95", + "tests/data/ninja/madloop-gg-hhh-top-box-8.json": "c49f6d9db0c09602c6e663e60499a9b5126b9ca66d1738f6b5bac5846afda572", + "tests/data/ninja/madloop-gg-hhh-top-pentagon-26.json": "e4b1522302bab1592924b251a7ee153c94623726d68b2d552e6211a4b0b3ded3", + "tests/data/ninja/madloop-gg-hhh-top-triangle-0.json": "7905a646d4bb23daf1b0506b662913f60796c87dfcbbd556c5bd957f7eba3bd2", + "tests/data/ninja/madloop-hgg-top-triangle-0.json": "a50906866f8e8812c02365cff98cb56a20639537f1804d290edbd8020ed9d30b", + "tests/data/provenance.json": "f77b7cee3079a95f001a3cc7d6a9f0aa1f8a1b51f3668b0d709552c67016d18b", + "tests/fenv_helpers.c": "cdb2df81ddcfc898f00dae4d74a78f0d6436aaa6c9ea3e5991bf11616b8bbd8d", + "tests/replay.py": "9c475d4fa7c17c200eafda7a1e0e6e0bb0f4392de2c89a9e26a302f69089a2b9" + }, + "shared_libraries": { + "/nix/store/m07syxhld8hpprrdmzq565ziia6vlw9l-xgcc-15.3.0-libgcc/lib/libgcc_s.so.1": { + "resolved": "/nix/store/m07syxhld8hpprrdmzq565ziia6vlw9l-xgcc-15.3.0-libgcc/lib/libgcc_s.so.1", + "sha256": "ae2bd6022e9a79c88e58327b50f3f2f78bf70ad26ceedd238b9f3e218379740c" + }, + "/nix/store/lm3pknxi0ipypy3lxh1wmm8wvvavdwrn-glibc-2.42-84/lib/libm.so.6": { + "resolved": "/nix/store/lm3pknxi0ipypy3lxh1wmm8wvvavdwrn-glibc-2.42-84/lib/libm.so.6", + "sha256": "864704dfd98b7025f21dd1dcc8f8f1f6388ecb44aa984b075f0188c253d4ab53" + }, + "/nix/store/lm3pknxi0ipypy3lxh1wmm8wvvavdwrn-glibc-2.42-84/lib/libc.so.6": { + "resolved": "/nix/store/lm3pknxi0ipypy3lxh1wmm8wvvavdwrn-glibc-2.42-84/lib/libc.so.6", + "sha256": "b8cb091b34bdd88f6902eebff8761f9ea306e6789b4ac4d06d4470c0d568c80c" + }, + "/nix/store/lm3pknxi0ipypy3lxh1wmm8wvvavdwrn-glibc-2.42-84/lib/ld-linux-x86-64.so.2": { + "resolved": "/nix/store/lm3pknxi0ipypy3lxh1wmm8wvvavdwrn-glibc-2.42-84/lib/ld-linux-x86-64.so.2", + "sha256": "05657061620b22dbeb881cd13630ef66d39916d3b9c2a8efeb9ec6244367051f" + }, + "/nix/store/lm3pknxi0ipypy3lxh1wmm8wvvavdwrn-glibc-2.42-84/lib64/ld-linux-x86-64.so.2": { + "resolved": "/nix/store/lm3pknxi0ipypy3lxh1wmm8wvvavdwrn-glibc-2.42-84/lib/ld-linux-x86-64.so.2", + "sha256": "05657061620b22dbeb881cd13630ef66d39916d3b9c2a8efeb9ec6244367051f" + } + }, + "thread_environment": { + "OMP_NUM_THREADS": "1", + "OPENBLAS_NUM_THREADS": "1", + "RAYON_NUM_THREADS": "1", + "MKL_NUM_THREADS": "1" + }, + "public_default_retained": "Interpreted", + "private_feature": "ninjars-symbolica native-kernels; never promoted", + "three_git_revisions": { + "ninjars": "0d0d7e7a8033431b60a8580731084742e0655cda", + "oneloopmaster": "09b2c7497743db875ed446da95123175dd00b1c8", + "symbolica": "e679e8c129ce15ec50c46ffb4ff4b59aeb7813b8" + } + }, + "timing_boundaries": { + "allocation_full_process": "Fresh worker for each arm. Initialization and complete100-point warm traversal outside timer. SYSTEM_CLOCK surrounds one100-point RUN, including point copy, scale/coupling update, Fortran numerator and kinematics, reduction, scalar masters, stability/actual rescue, status counting and final timed answer/accuracy/status copies. Formatting/serialization and process start/stop outside. One worker exits0 before next.", + "native_request_screen": "One complete private MpState::evaluate for each1392 ordered requests: recover113bit ASCII, widen256bit, reset/bind tensor, rebuild reduction inputs, reduction/scalar masters, format8ASCII fields. Reused independent state/cache perpolicy. Request objects/result-vector capacity prepared outside; returned output-buffer allocation/push inside. Serialization and returned-buffer release outside. Excludes MadLoop Fortran numerator/kinematics, stability controller, and public manager IPC. No cost subtraction.", + "older_callback": "Sum1392 per-record intervals around shared dispatch plus ordered tensor evaluate/expansion methods writing preallocated outputs. Coefficient binding, parsing, cloning, views/output allocation, comparisons, formatting/serialization outside. No amplitude/cut/geometry/master construction or calls. No-op timing retained, not subtracted.", + "older_Fortran": "Fresh uninstrumented standalone check perarm/repetition; initialization/warm traversal outside timer, separate full-output evidence pass before timing. SYSTEM_CLOCK includes all100 scale/coupling updates and full SLOOPMATRIX_THRES amplitude calls with real rescues and status histogram, excludes serialization. Consequently exact row evidence is from the untimed pass, unlike allocation worker final timed traversal." + }, + "interpretation_limits": [ + "3.15% whole-process allocation,9.24% pure tensor callback and3.19% Ninja6 Fortran prototype are separate comparisons and cannot be added or treated as the same workload.", + "Allocation measured existing NinjaRS original tensor vs allocation tensor, not original MadLoop with Ninja.", + "Native screen rejects promotion under the declared upperCI<1 rule; confidence intervals cross1, so no statistically demonstrated improvement or slowdown.", + "None of these studies closes the final eight-process original-Ninja5% acceptance gate.", + "Older Fortran package honestly remained isolated/not acceptance eligible at capture; later source promotion must use its separate production proof." + ], + "retained_record_bindings": [ + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-process-v2/manifest.json", + "sha256": "3b75bddaa8423b3edc5d7d941e7fc664938adeb0e44df36fc5ecc8c18a0440d8", + "bytes": 149230 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-process-v2/frozen-bindings.json", + "sha256": "64766a546d751705993e4b074f830d9ff32260c89e4ecfd6f6e4aa9114e2871e", + "bytes": 883638 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-process-v2/PLAN.md", + "sha256": "f474fd463f4becc896bfa5d728fa718e28b2a728aaa2c8f38446aff8138341a5", + "bytes": 4056 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-process-v2/timings/attempt-1/result.json", + "sha256": "3102c1a33dce5d26113dc9c098e1100920933d1507fd11aaed0ee91606411191", + "bytes": 29251 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-process-v2/timings/attempt-1/analysis.json", + "sha256": "79e661e62a4ce253181bdff22fa1dd530269ccbe570b61e2e2b9c9712e3f1a4d", + "bytes": 4315 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-process-v2/independent-measurement-audit.json", + "sha256": "c1305a7cca29d9a7fe4c843d95e4dd30f82a61b6bda5bea0ef82d60acefbfe7c", + "bytes": 2183 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-native-float256-v1/manifest.json", + "sha256": "38887d55ab8276fa2ee4cd64905012dcd946e9d18d668d7087cd7e5c15b1b9d5", + "bytes": 30019 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-native-float256-v1/SCREENING-PLAN.md", + "sha256": "f2616a490480d4b6a6e3d7c0f5a39865ad32855d29c8f9104c084baba882eb60", + "bytes": 4021 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-native-float256-v1/screening-analysis.json.gz", + "sha256": "53eb16383f507d7e3c768c0cbab2935bf6c0148aa20f8878872cd77bc2422fd8", + "bytes": 1327 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-native-float256-v1/selection-analysis.json", + "sha256": "0581c1fe7ac1371197610c894a360a8ccd82798a3970a167b9d6fc3002d5044c", + "bytes": 2045 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-native-float256-v1/prepared.json", + "sha256": "c61f2a58b944e2bd7f17bd1c9b66e0104316f2c565d00b4d5aa03f4a991c9e42", + "bytes": 9339 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-native-float256-v1/supplement/run-screening/result.json", + "sha256": "51845fe45a941320a2bb5157789c7ff9e28f4cb0cfe3626b82fd7b75a2121c23", + "bytes": 3678 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-native-float256-v1/supplement/build-completed.json", + "sha256": "689f86c5f4cf106e818ac0618f3fe2ec6916b15f7c332259c53f7d9897ca01d5", + "bytes": 6932 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-performance-v1/manifest.json", + "sha256": "20b091be21e04ae7c7220067337a9dd6ccf61e5915ce511cfc2bdac67ac2be7d", + "bytes": 11319 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-performance-v1/PLAN.md", + "sha256": "e4145bd2b345621488a03249fa2ad29e81b32fa7f11f140602c0d65ad030b006", + "bytes": 6393 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-performance-v1/timings/attempt-1/summary.json", + "sha256": "fe396620f4beae6f8e8f370413fdd933e9894dc489f099e1fbcedf57a76df341", + "bytes": 8402 + }, + { + "path": "docs/benchmarkfolder/experiments/ninjars-mp-tensor-allocation-performance-v1/build-inputs.json", + "sha256": "83be219a494d4709cb9334d890a6212700bfb008d662ec792345c08f04dbc657", + "bytes": 1551 + }, + { + "path": "docs/benchmarkfolder/experiments/symmetric-factorization/confirmatory21/qcd3-factor-confirmatory21-v1/analysis.json", + "sha256": "d2e78e55be1690f79e03c6d5ac26eeb1e4a96b8f03fd17b3a8ebde6c541efb6e", + "bytes": 7869 + }, + { + "path": "docs/benchmarkfolder/experiments/symmetric-factorization/confirmatory21/qcd3-factor-confirmatory21-v1/result.json", + "sha256": "5b094ab736c31c557040c2628467f7596af84f23bdabfefc588d14a5dcb42dbb", + "bytes": 3151077 + }, + { + "path": "docs/benchmarkfolder/experiments/symmetric-factorization/confirmatory21/qcd3-factor-confirmatory21-v1/predeclared-policy.json", + "sha256": "41dc662f45fe3dbb85a7fa8388aaf388e2b4a6e4a755a3c0c82265ea22f1216c", + "bytes": 1053 + } + ] +} diff --git a/doc/benchmarkfolder/final-report-v1/manifest.json b/doc/benchmarkfolder/final-report-v1/manifest.json new file mode 100644 index 0000000000..1042619c0d --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/manifest.json @@ -0,0 +1,168 @@ +{ + "excluded_redundant_materialization": "cli-report.json is preserved as deterministic cli-report.json.gz with exact decoded hash in provenance; the gzip and seven font binaries are acquired from immutable commit cc6f6fe6dd344a0a767dcfe52341c147e39a193a into ignored local paths using fetch_artifacts.py.", + "expected_pdf": { + "bytes": 346438, + "path": "benchmark.pdf", + "sha256": "c87adf29a508a5428bf351067d1a63d0ad23cb0b2632483e9dabd4763f1ad443" + }, + "files": { + "README.md": { + "bytes": 2245, + "sha256": "3b39bbcfb8e4fd8914535f8d932b459e8501f7caad485bb8f42bc350ee6a0309" + }, + "benchmark.typ": { + "bytes": 23441, + "sha256": "c92260703b39819d8566d55d1f8b37c8c76f56fa542e067ab75016a14669f490" + }, + "fetch_artifacts.py": { + "bytes": 3323, + "sha256": "791f951413c8a895e4ddb3b6e6032c5c2a2ed9425b2e8755be391b196b3cf038" + }, + "final-report-v1/README.md": { + "bytes": 7033, + "sha256": "8fcd5039f6d146809a88d1df7b57fa3340edca99430c4baa26bce9155c5d8259" + }, + "final-report-v1/cli-report.json.gz": { + "bytes": 1351700, + "sha256": "8234d9968f652eff6bb9c9dcffc41d967cffb9ec585477ce1ace05e23a948857" + }, + "final-report-v1/compile-environment.json": { + "bytes": 235, + "sha256": "6b6fc4cfff84db6fe8eeb661df3fbd45da22abaae08df70a6d1b5ab2cb64f39d" + }, + "final-report-v1/expected-cli-pins.json": { + "bytes": 267, + "sha256": "e9ccc784d5beeb0ea526ece124fe9f72f6a147b247fce8785dbde2339738a7c1" + }, + "final-report-v1/fonts/LibertinusMath-Regular.otf": { + "bytes": 588848, + "sha256": "ded714b0d3808af527438ed7a85f16933133f66a12104c4a83db4cc248888011" + }, + "final-report-v1/fonts/LibertinusMono-Regular.otf": { + "bytes": 59264, + "sha256": "c1872d14ecedecc5fbf069ebd778a242c5f20f2687c5443f3409ff0a3b945d0d" + }, + "final-report-v1/fonts/LibertinusSerif-Bold.otf": { + "bytes": 293908, + "sha256": "0264914210ed51b3231ebc92ce529e9f2e166ba9eebf0cd4a579558690a27b64" + }, + "final-report-v1/fonts/LibertinusSerif-BoldItalic.otf": { + "bytes": 259176, + "sha256": "47a665259f09f554f5d133d7718cdad43ff462c6a6b2328f38023465e62d57ce" + }, + "final-report-v1/fonts/LibertinusSerif-Italic.otf": { + "bytes": 332312, + "sha256": "9a393d63d6e05f620d3dc0190dfd35a8ede58c0808cf0fc9de7fcb9c723e4c24" + }, + "final-report-v1/fonts/LibertinusSerif-Regular.otf": { + "bytes": 337132, + "sha256": "fcf06307a77367394fcb0ccb241e59eea70dba3d732be309647611224679c733" + }, + "final-report-v1/fonts/LibertinusSerif-Semibold.otf": { + "bytes": 291640, + "sha256": "a4b3f28e85881db34695c1f005e4c79233a6caf3a2bd286c9b418c025fb99308" + }, + "final-report-v1/fonts/OFL.txt": { + "bytes": 4426, + "sha256": "9aeecc8107c489ec1ec0068b0313e531a760edf3493705b32ab8ab8215a8794e" + }, + "final-report-v1/formatter-source.py": { + "bytes": 5393, + "sha256": "f15e07d1092648fd3d40f06c8c0c2469132b904d74e23d722edfae588497b8ad" + }, + "final-report-v1/historical-optimization-facts.json": { + "bytes": 27806, + "sha256": "58c066c29841acba15da4ccfaaa7cc830c01136fbb47f0c997f4520de209ea38" + }, + "final-report-v1/measurements.csv": { + "bytes": 19049, + "sha256": "6f38a85e220728d07e176dd25e02385adcc93af956203f4a386a21ae664454d6" + }, + "final-report-v1/plot.py": { + "bytes": 3751, + "sha256": "9e70db18efeace27059e72bd18a192fc651bed5af4e65c8a5c3c6675cc49d0a4" + }, + "final-report-v1/preparation-costs.csv": { + "bytes": 28083, + "sha256": "ca7901b27d6a51f4ecf1bcabb023ff92313300724a3b23a3464473b594bbf34b" + }, + "final-report-v1/provenance.json": { + "bytes": 24048, + "sha256": "f003ca27f0a58de1704662abc5806ef21eb7e85301fdefee6ab9acf84172a303" + }, + "final-report-v1/report-data.json": { + "bytes": 288111, + "sha256": "bc42cc02076418eeba4b188de167575196f86139bc9c8b463349d2e766011e9c" + }, + "final-report-v1/reproduce.py": { + "bytes": 2402, + "sha256": "d47adcb9306964c788bd63515a756f0844de2c3503003bf4ba00f104c44ae5ea" + }, + "final-report-v1/stability/combined-loop-induced.svg": { + "bytes": 79241, + "sha256": "83751162b57f04707aa3b0bf965ca37865d9aee38302afe313983b937a5da369" + }, + "final-report-v1/stability/combined-on-shell.svg": { + "bytes": 70298, + "sha256": "865e148f64e246115cadc8f48d7e056b34a5764fd52cf4efd15b4e6bb5b6d506" + }, + "final-report-v1/stability/combined-three-particle.svg": { + "bytes": 83380, + "sha256": "dc7ee9c7983ddd35f95c356dc1983fd4f3a616597f0fc93650d359c83144f902" + }, + "final-report-v1/stability/combined-two-particle.svg": { + "bytes": 75197, + "sha256": "bdf406ef339dfdffbd3c1a47b3f585c4c9c6a0166fce4cc9b22f0b4552657382" + }, + "final-report-v1/stability/direction-loop-induced.svg": { + "bytes": 76397, + "sha256": "b69447d7fc57e11e80db18c5ad4d072f88cbebd9987ed0453102bee12449db38" + }, + "final-report-v1/stability/direction-on-shell.svg": { + "bytes": 65884, + "sha256": "3091ca65c8155237898c318580ce2066995b54bac34ed37ffaa27d9bc227b6ce" + }, + "final-report-v1/stability/direction-three-particle.svg": { + "bytes": 82105, + "sha256": "f89f4321768e79caef179ab79e2ec742a0ed459db52d48e4d9c616d0147bff03" + }, + "final-report-v1/stability/direction-two-particle.svg": { + "bytes": 68752, + "sha256": "83007d873524765ae8c8d4a4c93b33e6545be247a884e756ae0d784a81fcfdf5" + }, + "final-report-v1/stability/lorentz-loop-induced.svg": { + "bytes": 75393, + "sha256": "82c60ca00af45bc8f9a48dfc6f299a15aba8c442468ceb0b9751b90460871470" + }, + "final-report-v1/stability/lorentz-on-shell.svg": { + "bytes": 61080, + "sha256": "b77944f57d0a1184d3054708e16f63cf773f2327f264da320a1eeb3ae9fec70d" + }, + "final-report-v1/stability/lorentz-three-particle.svg": { + "bytes": 80779, + "sha256": "c91c65a26599c03574f20d958af5d4e98457189b68299f89ac9a9b5ae5a467ac" + }, + "final-report-v1/stability/lorentz-two-particle.svg": { + "bytes": 67728, + "sha256": "7a09948ca2127df20fddad9f3029296d0ff3ed669fc2f3c68cb4166db1746580" + }, + "final-report-v1/style.typ": { + "bytes": 2733, + "sha256": "6940ffd9613dde9c4f9554255a418024b99d04dfef383818d4c4f8ee368bbf4c" + }, + "final-report-v1/timing.svg": { + "bytes": 136922, + "sha256": "9d313f9efddc72320179532e268d91f564a41fd41260f57e9ec25e04550004ff" + } + }, + "schema": "final-actual-benchmark-document-v1", + "scientific_archive": { + "historical_partial_report_url": "https://github.com/MadGraphTeam/MadGraph7/tree/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/historical/20261021-partial", + "revision": "19d67c8605337c176680878a521b3a014176a7fb", + "scope": "Archived raw scientific evidence and readers; separate from the finite local offline document inputs.", + "tree_url": "https://github.com/MadGraphTeam/MadGraph7/tree/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder" + }, + "scope": "Exact finite offline document closure; no native verification, amplitude evaluation or new statistical inference", + "source_date_epoch": 1792627200, + "typst_version": "typst 0.15.1 (9dfd3a08)" +} diff --git a/doc/benchmarkfolder/final-report-v1/measurements.csv b/doc/benchmarkfolder/final-report-v1/measurements.csv new file mode 100644 index 0000000000..0f74fcfcfc --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/measurements.csv @@ -0,0 +1,73 @@ +case,backend,quantity,sessions,median_seconds_per_point,mad_seconds_per_point,ci95_lower,ci95_upper,observed_seconds_per_point,actual_unpolarized_full_N,ratio_status,nrs_over_ninja,ratio_ci95_lower,ratio_ci95_upper +qcd-1,6,construction,3,1.4483522781843662e-05,2.2162616046944572e-08,1.436423507181661e-05,1.4505685397890606e-05,"[1.436423507181661e-05, 1.4483522781843662e-05, 1.4505685397890606e-05]","[10707, 3818, 4082]",incomparable_stage_scope,,, +qcd-1,8,construction,3,1.4465047246307464e-05,8.960917332077401e-08,1.4369479389222711e-05,1.4554656419628238e-05,"[1.4554656419628238e-05, 1.4369479389222711e-05, 1.4465047246307464e-05]","[16376, 6549, 6443]",incomparable_stage_scope,,, +qcd-1,6,reduction_estimate,3,3.502189032532665e-05,3.996078229642206e-06,5.6215747460226075e-06,3.9017968554968856e-05,"[5.6215747460226075e-06, 3.9017968554968856e-05, 3.502189032532665e-05]","[10707, 3818, 4082]",incomparable_stage_scope,,, +qcd-1,8,reduction_estimate,3,1.6851085873119046e-05,4.500804416473727e-07,1.1245448471688037e-05,1.730116631476642e-05,"[1.1245448471688037e-05, 1.6851085873119046e-05, 1.730116631476642e-05]","[16376, 6549, 6443]",incomparable_stage_scope,,, +qcd-1,6,total,3,4.952757572321726e-05,3.973915613595262e-06,1.9985809817839217e-05,5.350149133681252e-05,"[1.9985809817839217e-05, 5.350149133681252e-05, 4.952757572321726e-05]","[10707, 3818, 4082]",incomparable_stage_scope,,, +qcd-1,8,total,3,3.122056526234176e-05,5.456482987321236e-07,2.5800104891316275e-05,3.176621356107388e-05,"[2.5800104891316275e-05, 3.122056526234176e-05, 3.176621356107388e-05]","[16376, 6549, 6443]",incomparable_stage_scope,,, +ew-1,6,construction,3,7.973156214757943e-05,1.2844411362441345e-06,7.84471210113353e-05,8.336335766910284e-05,"[8.336335766910284e-05, 7.973156214757943e-05, 7.84471210113353e-05]","[7315, 2629, 3186]",incomparable_stage_scope,,, +ew-1,8,construction,3,8.084191990188113e-05,1.9833903780968167e-07,8.064358086407145e-05,8.196831913664937e-05,"[8.084191990188113e-05, 8.196831913664937e-05, 8.064358086407145e-05]","[10544, 4096, 4559]",incomparable_stage_scope,,, +ew-1,6,reduction_estimate,3,6.104702014101749e-05,1.0860732405352066e-05,5.018628773566542e-05,7.713326214383699e-05,"[6.104702014101749e-05, 7.713326214383699e-05, 5.018628773566542e-05]","[7315, 2629, 3186]",incomparable_stage_scope,,, +ew-1,8,reduction_estimate,3,5.9169028887075785e-05,2.398683679916662e-06,5.677034520715912e-05,7.063680095598102e-05,"[5.9169028887075785e-05, 7.063680095598102e-05, 5.677034520715912e-05]","[10544, 4096, 4559]",incomparable_stage_scope,,, +ew-1,6,total,3,0.00014441037781012033,1.2454446481296094e-05,0.00012863340874700072,0.00015686482429141642,"[0.00014441037781012033, 0.00015686482429141642, 0.00012863340874700072]","[7315, 2629, 3186]",incomparable_stage_scope,,, +ew-1,8,total,3,0.00014001094878895692,2.5970227177263435e-06,0.00013741392607123057,0.00015260512009263039,"[0.00014001094878895692, 0.00015260512009263039, 0.00013741392607123057]","[10544, 4096, 4559]",incomparable_stage_scope,,, +qcd-2,6,construction,3,0.0008779834048161369,6.242075266910379e-06,0.0008717413295492265,0.0008889798090400041,"[0.0008717413295492265, 0.0008779834048161369, 0.0008889798090400041]","[5581, 3361, 3378]",comparable,1.0007260868944257,0.9820413367207111,1.0162294228103148 +qcd-2,8,construction,3,0.0008786208970598971,5.605977072528894e-06,0.0008730149199873682,0.0008858891881677068,"[0.0008786208970598971, 0.0008858891881677068, 0.0008730149199873682]","[6936, 4810, 4477]",comparable,1.0007260868944257,0.9820413367207111,1.0162294228103148 +qcd-2,6,reduction_estimate,3,0.00026398058343380564,8.262163088513814e-06,0.00024882154820443886,0.00027224274652231945,"[0.00027224274652231945, 0.00026398058343380564, 0.00024882154820443886]","[5581, 3361, 3378]",comparable,0.9719891927698252,0.8239053894379758,1.073408755239663 +qcd-2,8,reduction_estimate,3,0.00025658627419873224,1.0500954136200263e-05,0.00022430226609513573,0.0002670872283349325,"[0.00025658627419873224, 0.00022430226609513573, 0.0002670872283349325]","[6936, 4810, 4477]",comparable,0.9719891927698252,0.8239053894379758,1.073408755239663 +qcd-2,6,total,3,0.0011419639882499426,2.020087821603435e-06,0.001137801357244443,0.001143984076071546,"[0.001143984076071546, 0.0011419639882499426, 0.001137801357244443]","[5581, 3361, 3378]",comparable,0.9940831610621381,0.9704605837480293,1.0020221377512062 +qcd-2,8,total,3,0.0011352071712586293,4.8949770636713685e-06,0.0011101914542628426,0.0011401021483223007,"[0.0011352071712586293, 0.0011101914542628426, 0.0011401021483223007]","[6936, 4810, 4477]",comparable,0.9940831610621381,0.9704605837480293,1.0020221377512062 +ew-2,6,construction,3,0.0005344452617837371,1.2504124575613267e-06,0.0005331948493261758,0.0005464012039100302,"[0.0005464012039100302, 0.0005331948493261758, 0.0005344452617837371]","[4889, 2544, 2641]",comparable,0.9972822735238682,0.9719962221324951,1.0033778286740282 +ew-2,8,construction,3,0.0005329927857457442,1.892879776547703e-06,0.0005310999059691965,0.0005349958901770739,"[0.0005329927857457442, 0.0005349958901770739, 0.0005310999059691965]","[5759, 3158, 3213]",comparable,0.9972822735238682,0.9719962221324951,1.0033778286740282 +ew-2,6,reduction_estimate,3,0.00019328836576415368,6.583778531904093e-06,0.00018670458723224958,0.00021706334075088018,"[0.00019328836576415368, 0.00021706334075088018, 0.00018670458723224958]","[4889, 2544, 2641]",comparable,1.027623103529237,0.8838837627518636,1.11836789677179 +ew-2,8,reduction_estimate,3,0.00019862759030265392,6.7688279242759984e-06,0.00019185876237837792,0.00020880441654057616,"[0.00020880441654057616, 0.00019862759030265392, 0.00019185876237837792]","[5759, 3158, 3213]",comparable,1.027623103529237,0.8838837627518636,1.11836789677179 +ew-2,6,total,3,0.0007396895696741839,1.0568620402872059e-05,0.0007211498490159867,0.0007502581900770559,"[0.0007396895696741839, 0.0007502581900770559, 0.0007211498490159867]","[4889, 2544, 2641]",comparable,0.9917991419060728,0.9636131639873499,1.0286311552287049 +ew-2,8,total,3,0.0007336234804797278,8.173721806592569e-06,0.0007229586683475744,0.0007417972022863204,"[0.0007417972022863204, 0.0007336234804797278, 0.0007229586683475744]","[5759, 3158, 3213]",comparable,0.9917991419060728,0.9636131639873499,1.0286311552287049 +qcd-3,6,construction,3,0.039493254859084836,0.00022723717477409616,0.03496303051973866,0.03972049203385893,"[0.03496303051973866, 0.03972049203385893, 0.039493254859084836]","[565, 623, 618]",comparable,0.9879991078598808,0.8871777484535064,1.121366779874911 +qcd-3,8,construction,3,0.03901930056725872,0.00018708038132885657,0.035239136690064406,0.039206380948587576,"[0.035239136690064406, 0.039206380948587576, 0.03901930056725872]","[658, 639, 663]",comparable,0.9879991078598808,0.8871777484535064,1.121366779874911 +qcd-3,6,reduction_estimate,3,0.003735171938405453,0.0010823232339280744,0.0026528487044773785,0.006155917496807807,"[0.006155917496807807, 0.0026528487044773785, 0.003735171938405453]","[565, 623, 618]",comparable,0.7671780789017703,0.45452562356661863,1.1527925888887862 +qcd-3,8,reduction_estimate,3,0.0028655420320736966,6.751979321246993e-05,0.0027980222388612266,0.00305818432596474,"[0.0028655420320736966, 0.0027980222388612266, 0.00305818432596474]","[658, 639, 663]",comparable,0.7671780789017703,0.45452562356661863,1.1527925888887862 +qcd-3,6,total,3,0.04237334073833631,0.0008550860591539783,0.04111894801654647,0.04322842679749029,"[0.04111894801654647, 0.04237334073833631, 0.04322842679749029]","[565, 623, 618]",comparable,0.9912931681935165,0.8814727147172134,1.0233113180884703 +qcd-3,8,total,3,0.0420044031874488,7.308170577465661e-05,0.0381046787221381,0.04207748489322346,"[0.0381046787221381, 0.0420044031874488, 0.04207748489322346]","[658, 639, 663]",comparable,0.9912931681935165,0.8814727147172134,1.0233113180884703 +ew-3,6,construction,3,0.03232616421661841,0.00016877315076177513,0.03215739106585663,0.03345578088672883,"[0.03215739106585663, 0.03345578088672883, 0.03232616421661841]","[611, 654, 658]",comparable,0.9809852525851996,0.9188593794699533,1.0337862097728783 +ew-3,8,construction,3,0.03171149036915005,0.0009703323038876797,0.030741158065262373,0.03324386742615615,"[0.030741158065262373, 0.03171149036915005, 0.03324386742615615]","[429, 699, 562]",comparable,0.9809852525851996,0.9188593794699533,1.0337862097728783 +ew-3,6,reduction_estimate,3,0.0020032799185395467,0.0004897083689110529,0.0015135715496284938,0.006314177281226067,"[0.0020032799185395467, 0.0015135715496284938, 0.006314177281226067]","[611, 654, 658]",comparable,1.3910462968442947,0.007135960170992981,3.2790228048185863 +ew-3,8,reduction_estimate,3,0.0027866551122269767,0.002176380515729461,4.505771759141797e-05,0.004963035627956438,"[0.004963035627956438, 0.0027866551122269767, 4.505771759141797e-05]","[429, 699, 562]",comparable,1.3910462968442947,0.007135960170992981,3.2790228048185863 +ew-3,6,total,3,0.03496935243635732,0.0008086814519611407,0.03416067098439618,0.038640341497844476,"[0.03416067098439618, 0.03496935243635732, 0.038640341497844476]","[611, 654, 658]",comparable,0.9865251449583499,0.8615070119296064,1.0451842034814738 +ew-3,8,total,3,0.03449814548137703,0.0012060482118417815,0.033288925143747566,0.03570419369321881,"[0.03570419369321881, 0.03449814548137703, 0.033288925143747566]","[429, 699, 562]",comparable,0.9865251449583499,0.8615070119296064,1.0451842034814738 +qcd-4,6,construction,3,1.0666636514663697,7.277965545648968e-05,1.0419695043563844,1.0667364311218261,"[1.0667364311218261, 1.0419695043563844, 1.0666636514663697]","[50, 50, 50]",comparable,0.9864344794544688,0.9810199768411763,1.014799188728898 +qcd-4,8,construction,3,1.0521938037872314,0.005196003913879421,1.0464897489547729,1.0573898077011108,"[1.0573898077011108, 1.0521938037872314, 1.0464897489547729]","[50, 50, 50]",comparable,0.9864344794544688,0.9810199768411763,1.014799188728898 +qcd-4,6,reduction_estimate,3,0.060235223770141566,0.013052258491516033,0.03457710742950448,0.0732874822616576,"[0.03457710742950448, 0.060235223770141566, 0.0732874822616576]","[50, 50, 50]",comparable,0.8666036480301776,0.6861148824694943,1.9021744241930238 +qcd-4,8,reduction_estimate,3,0.05220006465911875,0.0019164323806764028,0.05028363227844235,0.06577168941497802,"[0.05220006465911875, 0.05028363227844235, 0.06577168941497802]","[50, 50, 50]",comparable,0.8666036480301776,0.6861148824694943,1.9021744241930238 +qcd-4,6,total,3,1.102204728126526,0.0008911895751952947,1.1013135385513306,1.1399511337280273,"[1.1013135385513306, 1.102204728126526, 1.1399511337280273]","[50, 50, 50]",comparable,1.006700338009125,0.9671269262746361,1.0099407656722545 +qcd-4,8,total,3,1.1095898723602295,0.0026715660095213423,1.1024774360656737,1.1122614383697509,"[1.1095898723602295, 1.1024774360656737, 1.1122614383697509]","[50, 50, 50]",comparable,1.006700338009125,0.9671269262746361,1.0099407656722545 +ew-4,6,construction,3,0.31012227211469484,0.00038503121626159986,0.3096710157394409,0.31050730333095644,"[0.3096710157394409, 0.31050730333095644, 0.31012227211469484]","[50, 82, 81]",comparable,0.9982603947812936,0.988703046533998,1.0055421763292667 +ew-4,8,construction,3,0.309582781791687,0.0018044853210449352,0.30699951677437287,0.31138726711273196,"[0.31138726711273196, 0.309582781791687, 0.30699951677437287]","[50, 80, 83]",comparable,0.9982603947812936,0.988703046533998,1.0055421763292667 +ew-4,6,reduction_estimate,3,0.02436900727542829,0.002417817420178381,0.02195118985524991,0.032214889526367196,"[0.032214889526367196, 0.02195118985524991, 0.02436900727542829]","[50, 82, 81]",comparable,1.2124709675323126,0.8248662623713129,1.3544738894287607 +ew-4,8,reduction_estimate,3,0.029546713829040505,0.00018559967178899406,0.026572975516319264,0.0297323135008295,"[0.029546713829040505, 0.026572975516319264, 0.0297323135008295]","[50, 80, 83]",comparable,1.2124709675323126,0.8248662623713129,1.3544738894287607 +ew-4,6,total,3,0.33449127939012313,0.002032786203916781,0.33245849318620635,0.3418859052658081,"[0.3418859052658081, 0.33245849318620635, 0.33449127939012313]","[50, 82, 81]",comparable,1.0066983835547654,0.9832395899639479,1.025493371140376 +ew-4,8,total,3,0.33673183027520237,0.000576072967196084,0.3361557573080063,0.34093398094177246,"[0.34093398094177246, 0.3361557573080063, 0.33673183027520237]","[50, 80, 83]",comparable,1.0066983835547654,0.9832395899639479,1.025493371140376 +control-gg-h,6,construction,3,3.409247176769452e-05,2.1135761268274093e-08,3.407133600642625e-05,3.423006106645633e-05,"[3.409247176769452e-05, 3.407133600642625e-05, 3.423006106645633e-05]","[9984, 3790, 3900]",comparable,1.017049128437462,0.9947981302621614,1.0233327133836556 +control-gg-h,8,construction,3,3.4673718697612496e-05,1.925940264499242e-07,3.4052000747670364e-05,3.486631272406242e-05,"[3.486631272406242e-05, 3.4673718697612496e-05, 3.4052000747670364e-05]","[14105, 6084, 5924]",comparable,1.017049128437462,0.9947981302621614,1.0233327133836556 +control-gg-h,6,reduction_estimate,3,7.417489320803912e-05,1.329188336862138e-06,5.0618599813718065e-05,7.550408154490126e-05,"[5.0618599813718065e-05, 7.550408154490126e-05, 7.417489320803912e-05]","[9984, 3790, 3900]",comparable,0.49402130779226877,0.44940994996807365,0.7967639623427715 +control-gg-h,8,reduction_estimate,3,3.664397774798736e-05,2.7116922385079316e-06,3.393228550947943e-05,4.033107615582108e-05,"[4.033107615582108e-05, 3.393228550947943e-05, 3.664397774798736e-05]","[14105, 6084, 5924]",comparable,0.49402130779226877,0.44940994996807365,0.7967639623427715 +control-gg-h,6,total,3,0.00010840495427449544,1.1704632768320619e-06,8.471107158141259e-05,0.0001095754175513275,"[8.471107158141259e-05, 0.0001095754175513275, 0.00010840495427449544]","[9984, 3790, 3900]",comparable,0.6521471178950577,0.6261076228612624,0.8876925704760346 +control-gg-h,8,total,3,7.069597849565772e-05,2.0899742885657996e-06,6.860600420709192e-05,7.51973888798835e-05,"[7.51973888798835e-05, 6.860600420709192e-05, 7.069597849565772e-05]","[14105, 6084, 5924]",comparable,0.6521471178950577,0.6261076228612624,0.8876925704760346 +control-gg-hh,6,construction,3,0.00026869458178102894,7.259333138101651e-07,0.00026796864846721877,0.0002701450662035358,"[0.0002701450662035358, 0.00026869458178102894, 0.00026796864846721877]","[5416, 3172, 3171]",comparable,1.0014432652588523,0.995289781891016,1.0073037777590097 +control-gg-hh,8,construction,3,0.00026908237933615534,2.097553155041361e-07,0.0002688726240206512,0.00026992583192200553,"[0.0002688726240206512, 0.00026908237933615534, 0.00026992583192200553]","[7404, 4797, 4616]",comparable,1.0014432652588523,0.995289781891016,1.0073037777590097 +control-gg-hh,6,reduction_estimate,3,0.0011368171414090286,3.1256604287148437e-06,0.0011336914809803138,0.0012057775655630373,"[0.0011336914809803138, 0.0011368171414090286, 0.0012057775655630373]","[5416, 3172, 3171]",comparable,0.8144158662309191,0.7625510788784925,0.827967706484704 +control-gg-hh,8,reduction_estimate,3,0.0009258419169667913,6.3749334592150524e-06,0.0009194669835075762,0.0009386599353685178,"[0.0009386599353685178, 0.0009258419169667913, 0.0009194669835075762]","[7404, 4797, 4616]",comparable,0.8144158662309191,0.7625510788784925,0.827967706484704 +control-gg-hh,6,total,3,0.0014055117231900574,1.6751760062078992e-06,0.0014038365471838495,0.001473746214030256,"[0.0014038365471838495, 0.0014055117231900574, 0.001473746214030256]","[5416, 3172, 3171]",comparable,0.8501702807507393,0.8070540260639228,0.8601660654949652 +control-gg-hh,8,total,3,0.0011949242963029466,5.531480873364808e-06,0.0011893928154295818,0.001207532559389169,"[0.001207532559389169, 0.0011949242963029466, 0.0011893928154295818]","[7404, 4797, 4616]",comparable,0.8501702807507393,0.8070540260639228,0.8601660654949652 +profile-gg-hhh,6,construction,3,0.005786511501241714,2.2660589035899785e-05,0.005542752609713225,0.005809172090277614,"[0.005786511501241714, 0.005542752609713225, 0.005809172090277614]","[703, 663, 664]",comparable,0.9651645409048947,0.8949000269593178,1.0277686501041325 +profile-gg-hhh,8,construction,3,0.005584935716536852,0.00011173165100926766,0.005198628260200754,0.005696667367546119,"[0.005696667367546119, 0.005584935716536852, 0.005198628260200754]","[804, 807, 813]",comparable,0.9651645409048947,0.8949000269593178,1.0277686501041325 +profile-gg-hhh,6,reduction_estimate,3,0.030429097142514423,0.0002492249590406066,0.030157157455582215,0.03067832210155503,"[0.03067832210155503, 0.030429097142514423, 0.030157157455582215]","[703, 663, 664]",comparable,0.8727385013999835,0.8417519643751077,0.8922994378144098 +profile-gg-hhh,8,reduction_estimate,3,0.02655664463911256,0.00035257000458408655,0.025823537892716228,0.026909214643696645,"[0.026909214643696645, 0.025823537892716228, 0.02655664463911256]","[804, 807, 813]",comparable,0.8727385013999835,0.8417519643751077,0.8922994378144098 +profile-gg-hhh,6,total,3,0.03597184975222765,5.520206367820579e-06,0.03596632954585983,0.036464833602796745,"[0.036464833602796745, 0.03597184975222765, 0.03596632954585983]","[703, 663, 664]",comparable,0.8827812058051528,0.8613359915851677,0.9065668480201119 +profile-gg-hhh,8,total,3,0.03175527289931331,0.0003467992900602346,0.03140847360925308,0.032605882011242766,"[0.032605882011242766, 0.03140847360925308, 0.03175527289931331]","[804, 807, 813]",comparable,0.8827812058051528,0.8613359915851677,0.9065668480201119 +profile-gg-hhhh,6,construction,3,0.07961652755737304,0.000855350494384774,0.07861759662628173,0.08047187805175782,"[0.08047187805175782, 0.07961652755737304, 0.07861759662628173]","[50, 50, 50]",comparable,1.0043866872806921,0.9834530006042794,1.0266303994812083 +profile-gg-hhhh,8,construction,3,0.07996578036614184,0.0007454342645502599,0.07914030993426288,0.0807112146306921,"[0.07996578036614184, 0.0807112146306921, 0.07914030993426288]","[53, 54, 54]",comparable,1.0043866872806921,0.9834530006042794,1.0266303994812083 +profile-gg-hhhh,6,reduction_estimate,3,0.49105167865753174,0.00010891437530513581,0.4909427642822266,0.49287658214569086,"[0.49105167865753174, 0.4909427642822266, 0.49287658214569086]","[50, 50, 50]",comparable,0.8525166731518793,0.8490559970675174,0.8530452729352701 +profile-gg-hhhh,8,reduction_estimate,3,0.41862974343476467,0.00014992554982495854,0.4184798178849397,0.41879640435272797,"[0.41879640435272797, 0.4184798178849397, 0.41862974343476467]","[53, 54, 54]",comparable,0.8525166731518793,0.8490559970675174,0.8530452729352701 +profile-gg-hhhh,6,total,3,0.5714941787719726,2.937793731694338e-05,0.5705592918395996,0.5715235567092896,"[0.5715235567092896, 0.5705592918395996, 0.5714941787719726]","[50, 50, 50]",comparable,0.872733622222733,0.870952819924136,0.8749152623667524 +profile-gg-hhhh,8,total,3,0.4987621847188698,0.0004288477967619997,0.4977700533690276,0.4991910325156318,"[0.4987621847188698, 0.4991910325156318, 0.4977700533690276]","[53, 54, 54]",comparable,0.872733622222733,0.870952819924136,0.8749152623667524 diff --git a/doc/benchmarkfolder/final-report-v1/plot.py b/doc/benchmarkfolder/final-report-v1/plot.py new file mode 100644 index 0000000000..1f340a62d0 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/plot.py @@ -0,0 +1,70 @@ +"""Recreate the final timing vector figure from copied, validated summaries.""" +import argparse +import json +import os +from pathlib import Path + +os.environ.setdefault("MPLCONFIGDIR", str(Path(__file__).resolve().parents[3] / ".benchmark-work/final-report-plot-cache-v1")) +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +from matplotlib import font_manager + +HERE = Path(__file__).resolve().parent + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output", type=Path, default=HERE / "timing.svg") + args = parser.parse_args() + for font in (HERE / "fonts").glob("*.otf"): + font_manager.fontManager.addfont(str(font)) + plt.rcParams.update({"font.family": "Libertinus Serif", "font.size": 10, + "svg.hashsalt": "madloop-final-20261022", "axes.labelsize": 11, + "axes.spines.top": False, "axes.spines.right": False, + "xtick.labelsize": 10, "ytick.labelsize": 9.5}) + data = json.loads((HERE / "report-data.json").read_text()) + rows = [row for page in data["stock_cli"]["pages"] for row in page["rows"]] + fig, (ax, ratio) = plt.subplots(2, 1, figsize=(7.0, 7.1), sharex=True, + gridspec_kw={"height_ratios": [1.4, 1], "hspace": .16}) + navy, green = "#1f3b63", "#3a944a" + for i, row in enumerate(rows, 1): + for quantity, marker, shift in (("reduction_estimate", "o", -.11), ("total", "s", .11)): + q = row["quantities"][quantity] + for backend, color, offset, filled in (("6", navy, -.035, False), ("8", green, .035, True)): + values = q["backend"][backend] + y = values["median_seconds_per_point"] * 1000 + lo, hi = [v * 1000 for v in values["confidence_interval95"]] + ax.errorbar(i + shift + offset, y, yerr=[[max(0, y-lo)], [max(0, hi-y)]], + marker=marker, markersize=5, linestyle="none", color=color, + markerfacecolor=color if filled else "white", capsize=2, linewidth=.9, + label=("Ninja" if backend == "6" else "NinjaRS") + + (" · reduction estimate" if quantity == "reduction_estimate" else " · total") if i == 1 else None) + r = q["ninjars_over_ninja"] + if r["ratio"] is not None: + lo, hi = r["confidence_interval95"]; y = r["ratio"] + ratio.errorbar(i + shift, y, yerr=[[max(0, y-lo)], [max(0, hi-y)]], + marker=marker, markersize=5, linestyle="none", color=navy if marker == "o" else green, + capsize=2, linewidth=.9) + if row["quantities"]["total"]["ninjars_over_ninja"]["ratio"] is None: + ratio.text(i, .014, "NA", ha="center", va="bottom", fontsize=9, color="#707070") + ax.set_yscale("symlog", linthresh=.001) + ax.set_ylabel("Wall time per point [ms]") + ax.grid(axis="y", color="#e2e8ef", linewidth=.6) + ax.legend(loc="upper left", frameon=False, fontsize=9, ncol=2) + ratio.set_yscale("log"); ratio.set_ylim(.004, 5) + ratio.axhline(1, color="#666666", linestyle="--", linewidth=.8) + ratio.set_ylabel("NinjaRS / Ninja") + ratio.set_xlabel("Process index (mapping below)") + ratio.set_xticks(range(1, 13)); ratio.set_xlim(.5, 12.5) + ratio.grid(axis="y", color="#e2e8ef", linewidth=.6) + ratio.plot([], [], "o", color=navy, label="Estimated reduction") + ratio.plot([], [], "s", color=green, label="Total") + ratio.legend(loc="lower right", frameon=False, fontsize=9) + fig.subplots_adjust(left=.12, right=.985, top=.97, bottom=.09) + fig.savefig(args.output, metadata={"Date": None, "Creator": "Matplotlib final report source"}) + plt.close(fig) + + +if __name__ == "__main__": + main() diff --git a/doc/benchmarkfolder/final-report-v1/preparation-costs.csv b/doc/benchmarkfolder/final-report-v1/preparation-costs.csv new file mode 100644 index 0000000000..04f2b25c0f --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/preparation-costs.csv @@ -0,0 +1,121 @@ +case,backend,session,cli_field,seconds,metadata_path,metadata_sha256 +qcd-1,6,0,Process_output,0.8491826057434082,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/6/0/timing-metadata.json,8d4b90c81f496886612bea64e07cf86729660167cf25a381369e7038b3453955 +qcd-1,6,0,HELAS_MODEL_compilation,2.64616060256958,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/6/0/timing-metadata.json,8d4b90c81f496886612bea64e07cf86729660167cf25a381369e7038b3453955 +qcd-1,6,0,Process_compilation,6.203837156295776,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/6/0/timing-metadata.json,8d4b90c81f496886612bea64e07cf86729660167cf25a381369e7038b3453955 +qcd-1,6,0,Initialization,0.022416114807128906,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/6/0/timing-metadata.json,8d4b90c81f496886612bea64e07cf86729660167cf25a381369e7038b3453955 +qcd-1,6,0,Booting_time,0.009557723999023438,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/6/0/timing-metadata.json,8d4b90c81f496886612bea64e07cf86729660167cf25a381369e7038b3453955 +qcd-1,8,0,Process_output,0.7954418659210205,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/8/0/timing-metadata.json,d2ef427c7bdbf9c01d5fd65a0982f022cec39461323987f9b259697db067a5f4 +qcd-1,8,0,HELAS_MODEL_compilation,2.5631794929504395,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/8/0/timing-metadata.json,d2ef427c7bdbf9c01d5fd65a0982f022cec39461323987f9b259697db067a5f4 +qcd-1,8,0,Process_compilation,6.371279239654541,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/8/0/timing-metadata.json,d2ef427c7bdbf9c01d5fd65a0982f022cec39461323987f9b259697db067a5f4 +qcd-1,8,0,Initialization,0.01465606689453125,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/8/0/timing-metadata.json,d2ef427c7bdbf9c01d5fd65a0982f022cec39461323987f9b259697db067a5f4 +qcd-1,8,0,Booting_time,0.00926661491394043,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/8/0/timing-metadata.json,d2ef427c7bdbf9c01d5fd65a0982f022cec39461323987f9b259697db067a5f4 +ew-1,6,0,Process_output,1.6317667961120605,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/6/0/timing-metadata.json,757ac0b39cc99c78bf47dcfc2ccc9485ee439ea45df90cd63089db1d4b39ee1a +ew-1,6,0,HELAS_MODEL_compilation,16.705623149871826,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/6/0/timing-metadata.json,757ac0b39cc99c78bf47dcfc2ccc9485ee439ea45df90cd63089db1d4b39ee1a +ew-1,6,0,Process_compilation,7.051156282424927,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/6/0/timing-metadata.json,757ac0b39cc99c78bf47dcfc2ccc9485ee439ea45df90cd63089db1d4b39ee1a +ew-1,6,0,Initialization,0.03281259536743164,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/6/0/timing-metadata.json,757ac0b39cc99c78bf47dcfc2ccc9485ee439ea45df90cd63089db1d4b39ee1a +ew-1,6,0,Booting_time,0.017609357833862305,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/6/0/timing-metadata.json,757ac0b39cc99c78bf47dcfc2ccc9485ee439ea45df90cd63089db1d4b39ee1a +ew-1,8,0,Process_output,1.59907865524292,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/8/0/timing-metadata.json,e433c93501898eff78359383aec5af7d6d88ddd1fb0a7ecd1b7b5b932276a7c2 +ew-1,8,0,HELAS_MODEL_compilation,17.25681233406067,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/8/0/timing-metadata.json,e433c93501898eff78359383aec5af7d6d88ddd1fb0a7ecd1b7b5b932276a7c2 +ew-1,8,0,Process_compilation,6.215627193450928,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/8/0/timing-metadata.json,e433c93501898eff78359383aec5af7d6d88ddd1fb0a7ecd1b7b5b932276a7c2 +ew-1,8,0,Initialization,0.022763490676879883,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/8/0/timing-metadata.json,e433c93501898eff78359383aec5af7d6d88ddd1fb0a7ecd1b7b5b932276a7c2 +ew-1,8,0,Booting_time,0.015154123306274414,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/8/0/timing-metadata.json,e433c93501898eff78359383aec5af7d6d88ddd1fb0a7ecd1b7b5b932276a7c2 +qcd-2,6,0,Process_output,2.036442518234253,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/6/0/timing-metadata.json,c6d46c96ca15b7b86ff83456eff66bb1e19cfebf65d3d155988d9d89f5340cbc +qcd-2,6,0,HELAS_MODEL_compilation,4.251473665237427,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/6/0/timing-metadata.json,c6d46c96ca15b7b86ff83456eff66bb1e19cfebf65d3d155988d9d89f5340cbc +qcd-2,6,0,Process_compilation,13.910211086273193,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/6/0/timing-metadata.json,c6d46c96ca15b7b86ff83456eff66bb1e19cfebf65d3d155988d9d89f5340cbc +qcd-2,6,0,Initialization,0.04300832748413086,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/6/0/timing-metadata.json,c6d46c96ca15b7b86ff83456eff66bb1e19cfebf65d3d155988d9d89f5340cbc +qcd-2,6,0,Booting_time,0.009781122207641602,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/6/0/timing-metadata.json,c6d46c96ca15b7b86ff83456eff66bb1e19cfebf65d3d155988d9d89f5340cbc +qcd-2,8,0,Process_output,1.5206308364868164,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/8/0/timing-metadata.json,97479542b9e6f4cad089d0c26275223e37d2e9da62e5995d871be1cba56de7e3 +qcd-2,8,0,HELAS_MODEL_compilation,4.559494495391846,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/8/0/timing-metadata.json,97479542b9e6f4cad089d0c26275223e37d2e9da62e5995d871be1cba56de7e3 +qcd-2,8,0,Process_compilation,14.023098945617676,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/8/0/timing-metadata.json,97479542b9e6f4cad089d0c26275223e37d2e9da62e5995d871be1cba56de7e3 +qcd-2,8,0,Initialization,0.03460526466369629,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/8/0/timing-metadata.json,97479542b9e6f4cad089d0c26275223e37d2e9da62e5995d871be1cba56de7e3 +qcd-2,8,0,Booting_time,0.010094881057739258,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/8/0/timing-metadata.json,97479542b9e6f4cad089d0c26275223e37d2e9da62e5995d871be1cba56de7e3 +ew-2,6,0,Process_output,3.5179073810577393,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/6/0/timing-metadata.json,d487051050435d655c2bbddd607f8ca7ce85d0b6d728cc393ba91d192d536d6c +ew-2,6,0,HELAS_MODEL_compilation,36.00076460838318,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/6/0/timing-metadata.json,d487051050435d655c2bbddd607f8ca7ce85d0b6d728cc393ba91d192d536d6c +ew-2,6,0,Process_compilation,7.607125759124756,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/6/0/timing-metadata.json,d487051050435d655c2bbddd607f8ca7ce85d0b6d728cc393ba91d192d536d6c +ew-2,6,0,Initialization,0.04909658432006836,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/6/0/timing-metadata.json,d487051050435d655c2bbddd607f8ca7ce85d0b6d728cc393ba91d192d536d6c +ew-2,6,0,Booting_time,0.01892709732055664,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/6/0/timing-metadata.json,d487051050435d655c2bbddd607f8ca7ce85d0b6d728cc393ba91d192d536d6c +ew-2,8,0,Process_output,3.4315192699432373,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/8/0/timing-metadata.json,45f5e7aab113fbb600d1c1e6e64423af8a06731830c167206726859565bbec66 +ew-2,8,0,HELAS_MODEL_compilation,35.90091347694397,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/8/0/timing-metadata.json,45f5e7aab113fbb600d1c1e6e64423af8a06731830c167206726859565bbec66 +ew-2,8,0,Process_compilation,7.368338108062744,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/8/0/timing-metadata.json,45f5e7aab113fbb600d1c1e6e64423af8a06731830c167206726859565bbec66 +ew-2,8,0,Initialization,0.041678428649902344,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/8/0/timing-metadata.json,45f5e7aab113fbb600d1c1e6e64423af8a06731830c167206726859565bbec66 +ew-2,8,0,Booting_time,0.01841259002685547,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/8/0/timing-metadata.json,45f5e7aab113fbb600d1c1e6e64423af8a06731830c167206726859565bbec66 +qcd-3,6,0,Process_output,2.882514715194702,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/6/0/timing-metadata.json,e1ef775598b7ffaef564a459c9d120dd24921bfbb614ab59c8d79b2b9ccefd95 +qcd-3,6,0,HELAS_MODEL_compilation,7.888396739959717,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/6/0/timing-metadata.json,e1ef775598b7ffaef564a459c9d120dd24921bfbb614ab59c8d79b2b9ccefd95 +qcd-3,6,0,Process_compilation,16.833760261535645,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/6/0/timing-metadata.json,e1ef775598b7ffaef564a459c9d120dd24921bfbb614ab59c8d79b2b9ccefd95 +qcd-3,6,0,Initialization,0.4253578186035156,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/6/0/timing-metadata.json,e1ef775598b7ffaef564a459c9d120dd24921bfbb614ab59c8d79b2b9ccefd95 +qcd-3,6,0,Booting_time,0.01082158088684082,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/6/0/timing-metadata.json,e1ef775598b7ffaef564a459c9d120dd24921bfbb614ab59c8d79b2b9ccefd95 +qcd-3,8,0,Process_output,2.4739251136779785,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/8/0/timing-metadata.json,5285e8cdd39be1afe59476042f117cbb2ce8b8b7210ba01d3b7e87882289d08f +qcd-3,8,0,HELAS_MODEL_compilation,8.59476923942566,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/8/0/timing-metadata.json,5285e8cdd39be1afe59476042f117cbb2ce8b8b7210ba01d3b7e87882289d08f +qcd-3,8,0,Process_compilation,16.25465178489685,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/8/0/timing-metadata.json,5285e8cdd39be1afe59476042f117cbb2ce8b8b7210ba01d3b7e87882289d08f +qcd-3,8,0,Initialization,0.3647949695587158,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/8/0/timing-metadata.json,5285e8cdd39be1afe59476042f117cbb2ce8b8b7210ba01d3b7e87882289d08f +qcd-3,8,0,Booting_time,0.010278701782226562,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/8/0/timing-metadata.json,5285e8cdd39be1afe59476042f117cbb2ce8b8b7210ba01d3b7e87882289d08f +ew-3,6,0,Process_output,6.785901308059692,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/6/0/timing-metadata.json,96cbd2b192367d668fa8112ed633c464efbd012524809e55794afaca3ca92130 +ew-3,6,0,HELAS_MODEL_compilation,79.07075715065002,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/6/0/timing-metadata.json,96cbd2b192367d668fa8112ed633c464efbd012524809e55794afaca3ca92130 +ew-3,6,0,Process_compilation,15.725582838058472,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/6/0/timing-metadata.json,96cbd2b192367d668fa8112ed633c464efbd012524809e55794afaca3ca92130 +ew-3,6,0,Initialization,0.39325547218322754,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/6/0/timing-metadata.json,96cbd2b192367d668fa8112ed633c464efbd012524809e55794afaca3ca92130 +ew-3,6,0,Booting_time,0.02692437171936035,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/6/0/timing-metadata.json,96cbd2b192367d668fa8112ed633c464efbd012524809e55794afaca3ca92130 +ew-3,8,0,Process_output,6.63463830947876,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/8/0/timing-metadata.json,8cc7c12301b32ebc4a88ba0764ba5bf0d4149c195eb23ce1b74a9b63ed3e0c2c +ew-3,8,0,HELAS_MODEL_compilation,76.81632804870605,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/8/0/timing-metadata.json,8cc7c12301b32ebc4a88ba0764ba5bf0d4149c195eb23ce1b74a9b63ed3e0c2c +ew-3,8,0,Process_compilation,16.30589199066162,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/8/0/timing-metadata.json,8cc7c12301b32ebc4a88ba0764ba5bf0d4149c195eb23ce1b74a9b63ed3e0c2c +ew-3,8,0,Initialization,0.560570478439331,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/8/0/timing-metadata.json,8cc7c12301b32ebc4a88ba0764ba5bf0d4149c195eb23ce1b74a9b63ed3e0c2c +ew-3,8,0,Booting_time,0.029071807861328125,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/8/0/timing-metadata.json,8cc7c12301b32ebc4a88ba0764ba5bf0d4149c195eb23ce1b74a9b63ed3e0c2c +qcd-4,6,0,Process_output,6.75002908706665,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/6/0/timing-metadata.json,5c563d78372ea3a5092ff5610041dc4c23b24c974d0dcdd57ecddf24fa3309d5 +qcd-4,6,0,HELAS_MODEL_compilation,8.85440993309021,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/6/0/timing-metadata.json,5c563d78372ea3a5092ff5610041dc4c23b24c974d0dcdd57ecddf24fa3309d5 +qcd-4,6,0,Process_compilation,24.647397994995117,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/6/0/timing-metadata.json,5c563d78372ea3a5092ff5610041dc4c23b24c974d0dcdd57ecddf24fa3309d5 +qcd-4,6,0,Initialization,14.255916118621826,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/6/0/timing-metadata.json,5c563d78372ea3a5092ff5610041dc4c23b24c974d0dcdd57ecddf24fa3309d5 +qcd-4,6,0,Booting_time,0.02290797233581543,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/6/0/timing-metadata.json,5c563d78372ea3a5092ff5610041dc4c23b24c974d0dcdd57ecddf24fa3309d5 +qcd-4,8,0,Process_output,6.7650041580200195,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/8/0/timing-metadata.json,cd1466cb4a041cf0e734e3e77cdb3a372b3fdfbc382ac4def3d4b4a3f9379116 +qcd-4,8,0,HELAS_MODEL_compilation,9.312835931777954,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/8/0/timing-metadata.json,cd1466cb4a041cf0e734e3e77cdb3a372b3fdfbc382ac4def3d4b4a3f9379116 +qcd-4,8,0,Process_compilation,24.10556173324585,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/8/0/timing-metadata.json,cd1466cb4a041cf0e734e3e77cdb3a372b3fdfbc382ac4def3d4b4a3f9379116 +qcd-4,8,0,Initialization,13.757172346115112,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/8/0/timing-metadata.json,cd1466cb4a041cf0e734e3e77cdb3a372b3fdfbc382ac4def3d4b4a3f9379116 +qcd-4,8,0,Booting_time,0.0246734619140625,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/8/0/timing-metadata.json,cd1466cb4a041cf0e734e3e77cdb3a372b3fdfbc382ac4def3d4b4a3f9379116 +ew-4,6,0,Process_output,19.99200463294983,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/6/0/timing-metadata.json,9f504d7a7a83cda03625c64b07b51fdd43f4c3f9965ad72f13e6585207900cc5 +ew-4,6,0,HELAS_MODEL_compilation,42.394105434417725,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/6/0/timing-metadata.json,9f504d7a7a83cda03625c64b07b51fdd43f4c3f9965ad72f13e6585207900cc5 +ew-4,6,0,Process_compilation,31.543988466262817,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/6/0/timing-metadata.json,9f504d7a7a83cda03625c64b07b51fdd43f4c3f9965ad72f13e6585207900cc5 +ew-4,6,0,Initialization,6.3058412075042725,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/6/0/timing-metadata.json,9f504d7a7a83cda03625c64b07b51fdd43f4c3f9965ad72f13e6585207900cc5 +ew-4,6,0,Booting_time,0.07288312911987305,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/6/0/timing-metadata.json,9f504d7a7a83cda03625c64b07b51fdd43f4c3f9965ad72f13e6585207900cc5 +ew-4,8,0,Process_output,20.393913745880127,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/8/0/timing-metadata.json,4c846e6820034910bae9b0ef7ed6b8cad8a79bdde00f9ba2176fb2029e347dd7 +ew-4,8,0,HELAS_MODEL_compilation,43.70957827568054,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/8/0/timing-metadata.json,4c846e6820034910bae9b0ef7ed6b8cad8a79bdde00f9ba2176fb2029e347dd7 +ew-4,8,0,Process_compilation,31.43924307823181,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/8/0/timing-metadata.json,4c846e6820034910bae9b0ef7ed6b8cad8a79bdde00f9ba2176fb2029e347dd7 +ew-4,8,0,Initialization,7.301720380783081,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/8/0/timing-metadata.json,4c846e6820034910bae9b0ef7ed6b8cad8a79bdde00f9ba2176fb2029e347dd7 +ew-4,8,0,Booting_time,0.07377195358276367,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/8/0/timing-metadata.json,4c846e6820034910bae9b0ef7ed6b8cad8a79bdde00f9ba2176fb2029e347dd7 +control-gg-h,6,0,Process_output,0.7136421203613281,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/6/0/timing-metadata.json,220ca0315d096b69832c9af7403dfa5d522e0365820d250f089a5e34bed5cd67 +control-gg-h,6,0,HELAS_MODEL_compilation,2.0487117767333984,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/6/0/timing-metadata.json,220ca0315d096b69832c9af7403dfa5d522e0365820d250f089a5e34bed5cd67 +control-gg-h,6,0,Process_compilation,10.917911291122437,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/6/0/timing-metadata.json,220ca0315d096b69832c9af7403dfa5d522e0365820d250f089a5e34bed5cd67 +control-gg-h,6,0,Initialization,0.02404046058654785,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/6/0/timing-metadata.json,220ca0315d096b69832c9af7403dfa5d522e0365820d250f089a5e34bed5cd67 +control-gg-h,6,0,Booting_time,0.009894847869873047,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/6/0/timing-metadata.json,220ca0315d096b69832c9af7403dfa5d522e0365820d250f089a5e34bed5cd67 +control-gg-h,8,0,Process_output,0.8637597560882568,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/8/0/timing-metadata.json,ee7287945c09cfeba0f3a0938e955c2af567d8bec4c2fc1059d2891d533acd28 +control-gg-h,8,0,HELAS_MODEL_compilation,2.2035534381866455,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/8/0/timing-metadata.json,ee7287945c09cfeba0f3a0938e955c2af567d8bec4c2fc1059d2891d533acd28 +control-gg-h,8,0,Process_compilation,11.439311027526855,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/8/0/timing-metadata.json,ee7287945c09cfeba0f3a0938e955c2af567d8bec4c2fc1059d2891d533acd28 +control-gg-h,8,0,Initialization,0.01701641082763672,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/8/0/timing-metadata.json,ee7287945c09cfeba0f3a0938e955c2af567d8bec4c2fc1059d2891d533acd28 +control-gg-h,8,0,Booting_time,0.009107112884521484,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/8/0/timing-metadata.json,ee7287945c09cfeba0f3a0938e955c2af567d8bec4c2fc1059d2891d533acd28 +control-gg-hh,6,0,Process_output,0.8600406646728516,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/6/0/timing-metadata.json,95671f0d09e252306cc3b42f41707c3209f06409c66a89fe0bd45573b227c704 +control-gg-hh,6,0,HELAS_MODEL_compilation,2.1690361499786377,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/6/0/timing-metadata.json,95671f0d09e252306cc3b42f41707c3209f06409c66a89fe0bd45573b227c704 +control-gg-hh,6,0,Process_compilation,13.797868013381958,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/6/0/timing-metadata.json,95671f0d09e252306cc3b42f41707c3209f06409c66a89fe0bd45573b227c704 +control-gg-hh,6,0,Initialization,0.04431414604187012,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/6/0/timing-metadata.json,95671f0d09e252306cc3b42f41707c3209f06409c66a89fe0bd45573b227c704 +control-gg-hh,6,0,Booting_time,0.010015726089477539,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/6/0/timing-metadata.json,95671f0d09e252306cc3b42f41707c3209f06409c66a89fe0bd45573b227c704 +control-gg-hh,8,0,Process_output,1.0508224964141846,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/8/0/timing-metadata.json,552dd9364bc54e060ffa5b31779e94308af8e938cc4af0ba8f1eef3c0d51ad54 +control-gg-hh,8,0,HELAS_MODEL_compilation,2.348954677581787,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/8/0/timing-metadata.json,552dd9364bc54e060ffa5b31779e94308af8e938cc4af0ba8f1eef3c0d51ad54 +control-gg-hh,8,0,Process_compilation,13.68647313117981,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/8/0/timing-metadata.json,552dd9364bc54e060ffa5b31779e94308af8e938cc4af0ba8f1eef3c0d51ad54 +control-gg-hh,8,0,Initialization,0.03241562843322754,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/8/0/timing-metadata.json,552dd9364bc54e060ffa5b31779e94308af8e938cc4af0ba8f1eef3c0d51ad54 +control-gg-hh,8,0,Booting_time,0.010501384735107422,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/8/0/timing-metadata.json,552dd9364bc54e060ffa5b31779e94308af8e938cc4af0ba8f1eef3c0d51ad54 +profile-gg-hhh,6,0,Process_output,1.3587110042572021,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/6/0/timing-metadata.json,b53b618214427b01de481c4f7db32cbf0106a6a3f2858d32415341d2d9404e7e +profile-gg-hhh,6,0,HELAS_MODEL_compilation,2.828005075454712,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/6/0/timing-metadata.json,b53b618214427b01de481c4f7db32cbf0106a6a3f2858d32415341d2d9404e7e +profile-gg-hhh,6,0,Process_compilation,18.974144458770752,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/6/0/timing-metadata.json,b53b618214427b01de481c4f7db32cbf0106a6a3f2858d32415341d2d9404e7e +profile-gg-hhh,6,0,Initialization,0.3418705463409424,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/6/0/timing-metadata.json,b53b618214427b01de481c4f7db32cbf0106a6a3f2858d32415341d2d9404e7e +profile-gg-hhh,6,0,Booting_time,0.012513160705566406,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/6/0/timing-metadata.json,b53b618214427b01de481c4f7db32cbf0106a6a3f2858d32415341d2d9404e7e +profile-gg-hhh,8,0,Process_output,2.13539719581604,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/8/0/timing-metadata.json,5b8aeb3da39a72c5a7ef6fea803cde9f3b7dcd2808ae7154e30888aae4d7f14f +profile-gg-hhh,8,0,HELAS_MODEL_compilation,2.7774994373321533,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/8/0/timing-metadata.json,5b8aeb3da39a72c5a7ef6fea803cde9f3b7dcd2808ae7154e30888aae4d7f14f +profile-gg-hhh,8,0,Process_compilation,16.986674785614014,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/8/0/timing-metadata.json,5b8aeb3da39a72c5a7ef6fea803cde9f3b7dcd2808ae7154e30888aae4d7f14f +profile-gg-hhh,8,0,Initialization,0.29871225357055664,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/8/0/timing-metadata.json,5b8aeb3da39a72c5a7ef6fea803cde9f3b7dcd2808ae7154e30888aae4d7f14f +profile-gg-hhh,8,0,Booting_time,0.012935876846313477,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/8/0/timing-metadata.json,5b8aeb3da39a72c5a7ef6fea803cde9f3b7dcd2808ae7154e30888aae4d7f14f +profile-gg-hhhh,6,0,Process_output,5.346100807189941,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/6/0/timing-metadata.json,768ce44881536b7ed7e6f1ff8c9a4caac45d01313a9f22bf09ab46188f629c90 +profile-gg-hhhh,6,0,HELAS_MODEL_compilation,2.309084415435791,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/6/0/timing-metadata.json,768ce44881536b7ed7e6f1ff8c9a4caac45d01313a9f22bf09ab46188f629c90 +profile-gg-hhhh,6,0,Process_compilation,22.67106533050537,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/6/0/timing-metadata.json,768ce44881536b7ed7e6f1ff8c9a4caac45d01313a9f22bf09ab46188f629c90 +profile-gg-hhhh,6,0,Initialization,5.220057725906372,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/6/0/timing-metadata.json,768ce44881536b7ed7e6f1ff8c9a4caac45d01313a9f22bf09ab46188f629c90 +profile-gg-hhhh,6,0,Booting_time,0.17943763732910156,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/6/0/timing-metadata.json,768ce44881536b7ed7e6f1ff8c9a4caac45d01313a9f22bf09ab46188f629c90 +profile-gg-hhhh,8,0,Process_output,5.5279295444488525,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/8/0/timing-metadata.json,a876a9444cf96ab90481daec60e88bd372f7d8729400246528d84d71ea7881cc +profile-gg-hhhh,8,0,HELAS_MODEL_compilation,2.4736132621765137,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/8/0/timing-metadata.json,a876a9444cf96ab90481daec60e88bd372f7d8729400246528d84d71ea7881cc +profile-gg-hhhh,8,0,Process_compilation,23.578145027160645,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/8/0/timing-metadata.json,a876a9444cf96ab90481daec60e88bd372f7d8729400246528d84d71ea7881cc +profile-gg-hhhh,8,0,Initialization,4.593463897705078,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/8/0/timing-metadata.json,a876a9444cf96ab90481daec60e88bd372f7d8729400246528d84d71ea7881cc +profile-gg-hhhh,8,0,Booting_time,0.18143463134765625,docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/8/0/timing-metadata.json,a876a9444cf96ab90481daec60e88bd372f7d8729400246528d84d71ea7881cc diff --git a/doc/benchmarkfolder/final-report-v1/provenance.json b/doc/benchmarkfolder/final-report-v1/provenance.json new file mode 100644 index 0000000000..f17e61e4d8 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/provenance.json @@ -0,0 +1,280 @@ +{ + "archive_sha256": "b0d69deb8c16deb13293176296afc5e18dbeeebe778a20fa39b61804fba89d4c", + "authorities": [ + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/dependencies/pins.json", + "bytes": 1761, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/dependencies/pins.json", + "role": "dependency_pins", + "scope": "Pinned build sources; numerical runtime is aa6a/8ec, later ca1009 report-only equivalence separate", + "sha256": "a330299c567e9d2956f77537f19a875dce2bceac26df683012feb2d2c0a7d930" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/dependencies/upstream-watch-ca1009e-v1/manifest.json", + "bytes": 732, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/dependencies/upstream-watch-ca1009e-v1/manifest.json", + "role": "upstream_equivalence", + "scope": "582 non-report tree entries equal; no new binary identity or numerical replay claimed", + "sha256": "59ee4a920f1f921dd216ae739f67a5663192e4084cd4fb0dcfde5cf69d6c9ffc" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/install-export/installation.json", + "bytes": 16025, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/install-export/installation.json", + "role": "installation", + "scope": "Actual install ninjars --update; archive and ABI3 metadata authority", + "sha256": "df329e3b705d6793753531fab84671056f654849a3d033325882539da55abd5b" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/install-export/manifest.json", + "bytes": 11775, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/install-export/manifest.json", + "role": "installation_manifest", + "scope": "Concrete owner verifier and retained raw install/export evidence", + "sha256": "dd5cbbefc2158c66c4b8b383465fd6cf7988d1722453ffc51c6241334e4e2841" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/install-export/runtime-results.json", + "bytes": 2089, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/install-export/runtime-results.json", + "role": "relocated_exports", + "scope": "SA110/120/218; NLO20/20 poles at1e-5 plus soft/collinear; no shower", + "sha256": "9c11ff64f4e0dd34818bb30a660f065a90ca231372f85e31e71122e59d761b90" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/main-install-publication/transition.json", + "bytes": 8781, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/main-install-publication/transition.json", + "role": "main_install_publication", + "scope": "Exact main installation transition; native artifact remains custody prerequisite", + "sha256": "7f318d8b798ba60959df93b235b48df33da006c481cf9f9f62c251170281c95a" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/numerical-controls-v1/manifest-v2.json", + "bytes": 67601, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/numerical-controls-v1/manifest-v2.json", + "role": "numerical_manifest", + "scope": "45 source images, ordinary unit proof and complete1392x256/384 replay; metadata relocation verified", + "sha256": "909d76260e4658181be09e9c7916b9896dd56eccc2b385b31e502d549f3bf987" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/numerical-controls-v1/verification-v2.json", + "bytes": 7822, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/numerical-controls-v1/verification-v2.json", + "role": "numerical_recomputation", + "scope": "Historical bit changes/exit101 and direct-provider unsafe successes retained separately from full bridge convergence", + "sha256": "7f19cf47f11d7607450b4f51e31a67d40b710e23a2cfbc3bb71a97cce02d1caf" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/installed-precision/run-v1/result-portable.json", + "bytes": 26806, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/installed-precision/run-v1/result-portable.json", + "role": "installed64", + "scope": "Actual final installed64 ABI calls, not private-build-only proof", + "sha256": "3fe9ea08112d4ad7238155f9d7db07d3e3533467c58c3046b9a73e885bea0657" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/dataset-correctness-only-public-v2.json", + "bytes": 100483, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/dataset-correctness-only-public-v2.json", + "role": "core_correctness", + "scope": "Eight cases, two100-point normal-rescue records/case; old performance/final flags unchanged", + "sha256": "82ec747c1dc1b4e2624a4d7c2b90e7d69b72e589027dbb8e84951057d21b6e7d" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/focused-execution-ninja-nrs-v1/physical-comparison.json", + "bytes": 10081, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/focused-execution-ninja-nrs-v1/physical-comparison.json", + "role": "focused_ninja_nrs", + "scope": "45 physical comparison pairs/5400 components; persistent and fresh complex/mixed/near-singular scope", + "sha256": "4f79d0c82e312efa76f9a3a5e854ad3ae6c3fc8e04f53c704712d5d7df9a7042" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/focused-light-controls-v2/actual-control-summary.json", + "bytes": 8866, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/focused-light-controls-v2/actual-control-summary.json", + "role": "custom_two_point_controls", + "scope": "Exactly9fixed-two-point QP direction/state/complex/rotation controls; direct120/accuracy-1 not stability", + "sha256": "b0be98b39365f3479e82bf890bead61e74c84cab6bede8357b178263f55330ec" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/focused-light-hh-normal-anchor-v1/comparison.json", + "bytes": 6264, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/focused-light-hh-normal-anchor-v1/comparison.json", + "role": "normal_hh_anchor", + "scope": "Read-only first2 normalHH versus explicitQP forward/reverse;96 components; not HH100", + "sha256": "4873f62e81c63d68a1d3b62f3beea24f4f83f5df1d850a350b73727acf934464" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/higher-higgs-controls/run-v1/result-finalized-v1.json", + "bytes": 4733, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/higher-higgs-controls/run-v1/result-finalized-v1.json", + "role": "higher_higgs", + "scope": "HHH/HHHH2points/tool; original Python parent exit1 and versioned pure-comparator correction retained", + "sha256": "6a61ff18068ce87dfd06c4ee6f56f7580329f6bd24f22a98fa64c9a6da6649a6" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/higher-higgs-controls/independent-review-v1/receipt.json", + "bytes": 22606, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/higher-higgs-controls/independent-review-v1/receipt.json", + "role": "higher_higgs_independent", + "scope": "Independent numerical/source/custody review; normal fullsum/poles/rescue; no timing inference", + "sha256": "37ca4cd94b4d52e08bec8bd4496c7b1d15b6a4450834e42266ab71a6b2693283" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/integrated-software-293-v1/manifest.json", + "bytes": 15199, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/integrated-software-293-v1/manifest.json", + "role": "software293", + "scope": "293software tests292pass1conditional skip; exact observed source snapshot, later pathfix tests separate", + "sha256": "2ffaf7c06ff0f824d300fde6e103f2140b3f813ff8cde53e0525f5327bfb224b" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/light-timing/runs/run-v1/result.json", + "bytes": 123422, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/light-timing/runs/run-v1/result.json", + "role": "light_timing", + "scope": "6cases10fixed-prefix points7adjacent pairs; original27147 Ninja6/finalNRS8 fullsum rescue-on", + "sha256": "ab7f9b9dc0e870e1ba62aa534615250ddaaa8eed6d7dffa6b37846266aaf46ae" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/light-timing/terminal-summary-v1.json", + "bytes": 8645, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/light-timing/terminal-summary-v1.json", + "role": "light_timing_duration", + "scope": "Actual.326-.519s commands; .5s calibration target; last-traversal status vectors only", + "sha256": "367eebf8c156a43a5ce37e318c3e21f0c840ff596662bf3c9e5cf5873c84a911" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/paper-comparison/lightweight-stability-figures-v1/manifest.json", + "bytes": 5295, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/paper-comparison/lightweight-stability-figures-v1/manifest.json", + "role": "dp_vectors", + "scope": "12audited actual SVGs and complete offline vector recreation closure; selected8N100", + "sha256": "a19f26913c7b78ae576e11196c2644ad660bedd7e8650f4853c5743f4e9a2479" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/paper-comparison/lightweight-final-science-v1/data/0001-summary.json", + "bytes": 7332985, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/paper-comparison/lightweight-final-science-v1/data/0001-summary.json", + "role": "dp_observations", + "scope": "Exactc463 qualified summary; original embedded native custody paths preserved", + "sha256": "c46368e08f039d39d4acb6369f067407785315cf5a591099db97f1e9adb6b12e" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/paper-comparison/lightweight-final-science-v1/data/1174-light-eight-final-independent-composite-audit-v1.json", + "bytes": 5232, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/paper-comparison/lightweight-final-science-v1/data/1174-light-eight-final-independent-composite-audit-v1.json", + "role": "dp_composite_audit", + "scope": "Selected8 arithmetic+source/runtime/raw-custody independent gate; hardware invalid retained", + "sha256": "64ac6c50cb1712272e11dbca41e797e7389d893df88ca67c1189e8f1bdf14e33" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/final-validation-v1/publication-result.json", + "bytes": 26489, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/final-validation-v1/publication-result.json", + "role": "profile-cli-expanded-v4/run-v1/final-validation-v1/publication-result.json", + "sha256": "1bb293b575590aec3bdd801f80f579a0fd7ba212363c37f92bf4eb74ca1f996d" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/result-list.json", + "bytes": 8247, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/result-list.json", + "role": "profile-cli-expanded-v4/run-v1/result-list.json", + "sha256": "ea1d1ad683d15a1c4d07314410e381390764451696f27858276eb5555b66eb31" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/continuation-launch-v1/terminal-cleanup.json", + "bytes": 21829, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/continuation-launch-v1/terminal-cleanup.json", + "role": "profile-cli-expanded-v4/run-v1/continuation-launch-v1/terminal-cleanup.json", + "sha256": "1f61210a1acee6fcd3aa367b68aa1f2877cda492e1f5e8fe83b4531aca26190e" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/generated-source-closure-v1/closure.json", + "bytes": 1253728, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/generated-source-closure-v1/closure.json", + "role": "profile-cli-expanded-v4/run-v1/generated-source-closure-v1/closure.json", + "sha256": "a160171b0af9247bcdd8c283704a70e4966c8b7a0828a1955c139641a1b46971" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/dependencies/upstream-watch-final-20261022.json", + "bytes": 1025, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/dependencies/upstream-watch-final-20261022.json", + "role": "dependencies/upstream-watch-final-20261022.json", + "sha256": "2be01f7bf06f6941bc594646c9dbc3f64bcaa279bd06a5fc7d18b02196500217" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-observer-contract-software-v1/live-result.json", + "bytes": 2550, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-observer-contract-software-v1/live-result.json", + "role": "profile-cli-observer-contract-software-v1/live-result.json", + "sha256": "df4a3a8a91129e77e06f98b346c68742f294ece744efe4d8696947a1f2a5601d" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/final-release-audits-v1/installer-export-closure.json", + "bytes": 4334, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/final-release-audits-v1/installer-export-closure.json", + "role": "final-release-audits-v1/installer-export-closure.json", + "sha256": "28d883477a9c41eaa59cf1c15539d072d78bbf3d3a607c9d00e0339fe2ecca1d" + }, + { + "archive_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/final-release-audits-v1/scientific-claims-review.json", + "bytes": 14805, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/final-release-audits-v1/scientific-claims-review.json", + "role": "final-release-audits-v1/scientific-claims-review.json", + "sha256": "58644f5045a1a2b0ea3cf059365d97388d5aec847b7b5991d4e8820a07ea3d7f" + } + ], + "cli_observer_revision": "464b441fe04d3cb5b3da7708897fa831e32c55eb", + "compressed_cli_report_sha256": "8234d9968f652eff6bb9c9dcffc41d967cffb9ec585477ce1ace05e23a948857", + "consumer_sha256": "6095252a4a0e1570b2cf90213962c6bc34286fe5020933d7241bb8471747a4c0", + "decoded_cli_report_bytes": 10672582, + "decoded_cli_report_sha256": "8a1da525d23d21bd19b5c47b96aa1be479aa412bc13f3e0aebaf485dd55ac334", + "figures": "Original plotting source from validated statistics; no external plotting code copied", + "font_license_source": "https://raw.githubusercontent.com/alerque/libertinus/v7.051/OFL.txt", + "ninjars_pin": "aa6a6307dd081dc3714f9accebc0df9e5561ae73", + "numerical_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "oneloopmaster_pin": "8ec256fc26cb361b20e10f59c19beb35717ef32c", + "preparation_cost_scope": "Captured r0 timing_result, exact five CLI fields; no sum or symbolic-generation inference", + "preparation_metadata_archive_base_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/", + "preparation_metadata_sha256": { + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/6/0/timing-metadata.json": "220ca0315d096b69832c9af7403dfa5d522e0365820d250f089a5e34bed5cd67", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/8/0/timing-metadata.json": "ee7287945c09cfeba0f3a0938e955c2af567d8bec4c2fc1059d2891d533acd28", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/6/0/timing-metadata.json": "95671f0d09e252306cc3b42f41707c3209f06409c66a89fe0bd45573b227c704", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/8/0/timing-metadata.json": "552dd9364bc54e060ffa5b31779e94308af8e938cc4af0ba8f1eef3c0d51ad54", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/6/0/timing-metadata.json": "757ac0b39cc99c78bf47dcfc2ccc9485ee439ea45df90cd63089db1d4b39ee1a", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/8/0/timing-metadata.json": "e433c93501898eff78359383aec5af7d6d88ddd1fb0a7ecd1b7b5b932276a7c2", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/6/0/timing-metadata.json": "d487051050435d655c2bbddd607f8ca7ce85d0b6d728cc393ba91d192d536d6c", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/8/0/timing-metadata.json": "45f5e7aab113fbb600d1c1e6e64423af8a06731830c167206726859565bbec66", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/6/0/timing-metadata.json": "96cbd2b192367d668fa8112ed633c464efbd012524809e55794afaca3ca92130", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/8/0/timing-metadata.json": "8cc7c12301b32ebc4a88ba0764ba5bf0d4149c195eb23ce1b74a9b63ed3e0c2c", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/6/0/timing-metadata.json": "9f504d7a7a83cda03625c64b07b51fdd43f4c3f9965ad72f13e6585207900cc5", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/8/0/timing-metadata.json": "4c846e6820034910bae9b0ef7ed6b8cad8a79bdde00f9ba2176fb2029e347dd7", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/6/0/timing-metadata.json": "b53b618214427b01de481c4f7db32cbf0106a6a3f2858d32415341d2d9404e7e", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/8/0/timing-metadata.json": "5b8aeb3da39a72c5a7ef6fea803cde9f3b7dcd2808ae7154e30888aae4d7f14f", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/6/0/timing-metadata.json": "768ce44881536b7ed7e6f1ff8c9a4caac45d01313a9f22bf09ab46188f629c90", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/8/0/timing-metadata.json": "a876a9444cf96ab90481daec60e88bd372f7d8729400246528d84d71ea7881cc", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/6/0/timing-metadata.json": "8d4b90c81f496886612bea64e07cf86729660167cf25a381369e7038b3453955", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/8/0/timing-metadata.json": "d2ef427c7bdbf9c01d5fd65a0982f022cec39461323987f9b259697db067a5f4", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/6/0/timing-metadata.json": "c6d46c96ca15b7b86ff83456eff66bb1e19cfebf65d3d155988d9d89f5340cbc", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/8/0/timing-metadata.json": "97479542b9e6f4cad089d0c26275223e37d2e9da62e5995d871be1cba56de7e3", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/6/0/timing-metadata.json": "e1ef775598b7ffaef564a459c9d120dd24921bfbb614ab59c8d79b2b9ccefd95", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/8/0/timing-metadata.json": "5285e8cdd39be1afe59476042f117cbb2ce8b8b7210ba01d3b7e87882289d08f", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/6/0/timing-metadata.json": "5c563d78372ea3a5092ff5610041dc4c23b24c974d0dcdd57ecddf24fa3309d5", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/8/0/timing-metadata.json": "cd1466cb4a041cf0e734e3e77cdb3a372b3fdfbc382ac4def3d4b4a3f9379116" + }, + "reader_sha256": "b0681842604b651eac164448f0ca5b19cc61ae02c16704ceb4e9e926516c8ff7", + "runtime_identity_sha256": "a7577a9a33292ffb5d675ccf1b9c3667db3ab3613d77ccd270f1efc9e9802008", + "scientific_statistics_recomputed_by_document_formatter": false, + "scope": "Final actual document input provenance; finite offline assets are local, complete scientific authorities are preserved at source_archive revision", + "source_archive": { + "download_url": "https://github.com/MadGraphTeam/MadGraph7/archive/19d67c8605337c176680878a521b3a014176a7fb.tar.gz", + "native_prerequisites": "Full source/runtime custody verification still requires the exact retained native installation; the archive contains no claimed replacement native library.", + "path_semantics": "Original path fields and nested raw input paths identify immutable files at this revision; they are not current-checkout dependencies.", + "repository": "https://github.com/MadGraphTeam/MadGraph7", + "revision": "19d67c8605337c176680878a521b3a014176a7fb", + "source_archive_base_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/", + "tree_url": "https://github.com/MadGraphTeam/MadGraph7/tree/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder" + } +} diff --git a/doc/benchmarkfolder/final-report-v1/report-data.json b/doc/benchmarkfolder/final-report-v1/report-data.json new file mode 100644 index 0000000000..00c9322466 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/report-data.json @@ -0,0 +1,8209 @@ +{ + "core_correctness": { + "cases": { + "ew-1": { + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 3, + "passed": true + }, + { + "failures": [], + "pairs": 3, + "passed": true + } + ], + "passed": true, + "status": "passed" + }, + "calibration_reference_timing_repetitions": 0, + "nrs_numerical_observations": 2, + "performance": { + "passed": false, + "status": "pending" + }, + "timing_agreement": { + "comparisons": [], + "passed": false, + "status": "pending" + } + }, + "ew-2": { + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 3, + "passed": true + }, + { + "failures": [], + "pairs": 3, + "passed": true + } + ], + "passed": true, + "status": "passed" + }, + "calibration_reference_timing_repetitions": 0, + "nrs_numerical_observations": 2, + "performance": { + "passed": false, + "status": "pending" + }, + "timing_agreement": { + "comparisons": [], + "passed": false, + "status": "pending" + } + }, + "ew-3": { + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 3, + "passed": true + }, + { + "failures": [], + "pairs": 3, + "passed": true + } + ], + "passed": true, + "status": "passed" + }, + "calibration_reference_timing_repetitions": 0, + "nrs_numerical_observations": 2, + "performance": { + "passed": false, + "status": "pending" + }, + "timing_agreement": { + "comparisons": [], + "passed": false, + "status": "pending" + } + }, + "ew-4": { + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 3, + "passed": true + }, + { + "failures": [], + "pairs": 3, + "passed": true + } + ], + "passed": true, + "status": "passed" + }, + "calibration_reference_timing_repetitions": 0, + "nrs_numerical_observations": 2, + "performance": { + "passed": false, + "status": "pending" + }, + "timing_agreement": { + "comparisons": [], + "passed": false, + "status": "pending" + } + }, + "qcd-1": { + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 3, + "passed": true + }, + { + "failures": [], + "pairs": 3, + "passed": true + } + ], + "passed": true, + "status": "passed" + }, + "calibration_reference_timing_repetitions": 0, + "nrs_numerical_observations": 2, + "performance": { + "passed": false, + "status": "pending" + }, + "timing_agreement": { + "comparisons": [], + "passed": false, + "status": "pending" + } + }, + "qcd-2": { + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 3, + "passed": true + }, + { + "failures": [], + "pairs": 3, + "passed": true + } + ], + "passed": true, + "status": "passed" + }, + "calibration_reference_timing_repetitions": 0, + "nrs_numerical_observations": 2, + "performance": { + "passed": false, + "status": "pending" + }, + "timing_agreement": { + "comparisons": [], + "passed": false, + "status": "pending" + } + }, + "qcd-3": { + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 3, + "passed": true + }, + { + "failures": [], + "pairs": 3, + "passed": true + } + ], + "passed": true, + "status": "passed" + }, + "calibration_reference_timing_repetitions": 0, + "nrs_numerical_observations": 2, + "performance": { + "passed": false, + "status": "pending" + }, + "timing_agreement": { + "comparisons": [], + "passed": false, + "status": "pending" + } + }, + "qcd-4": { + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 3, + "passed": true + }, + { + "failures": [], + "pairs": 3, + "passed": true + } + ], + "passed": true, + "status": "passed" + }, + "calibration_reference_timing_repetitions": 0, + "nrs_numerical_observations": 2, + "performance": { + "passed": false, + "status": "pending" + }, + "timing_agreement": { + "comparisons": [], + "passed": false, + "status": "pending" + } + } + }, + "nrs_correctness_passed": true, + "scope": "Eight SM processes, two 100-point normal-rescue observations each; retained calibration separate. Its historical timing/final flags are left unchanged.", + "source": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/dataset-correctness-only-public-v2.json" + }, + "correctness": { + "core": { + "ew-1": { + "agreement": "passed", + "automatic_qp": 0, + "calibration_and_two_repetitions_identical": true, + "normal_dp": 100, + "points_per_unique_stream": 100, + "records": [ + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-1-candidate-8-calibration.json", + "sha256": "26c5a8033aa7107c552abb51b00c3408475da4d08888a422268403a4ed637900" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-1-candidate-8-0.json", + "sha256": "794bccddbaea596b6a92fbf9a3d694977706e9e2669a9fedf108441be5ac328c" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-1-candidate-8-1.json", + "sha256": "3a656ee8fb44cc0ff36364afc7bfe4530a3deb041ed5320521d8169eb3407fd8" + } + ], + "return_codes": { + "218": 100 + } + }, + "ew-2": { + "agreement": "passed", + "automatic_qp": 0, + "calibration_and_two_repetitions_identical": true, + "normal_dp": 100, + "points_per_unique_stream": 100, + "records": [ + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-2-candidate-8-calibration.json", + "sha256": "74312451d36b595796baa40c83f30445b8b97b5e7306005f962d296bca11f5e9" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-2-candidate-8-0.json", + "sha256": "b7a16fbf7713e47ab783013a8897ca59e1949e20ec81d51feb8f18ed093065ec" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-2-candidate-8-1.json", + "sha256": "082756cc83f9c1dfb7a62154c7a9cc8c648bb6f5cb238b7870fa5cb0b67eb7e8" + } + ], + "return_codes": { + "218": 100 + } + }, + "ew-3": { + "agreement": "passed", + "automatic_qp": 2, + "calibration_and_two_repetitions_identical": true, + "normal_dp": 98, + "points_per_unique_stream": 100, + "records": [ + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-3-candidate-8-calibration.json", + "sha256": "fddee67c20461950fcd57b25b9573621470fbbaaefdcb0237815c256384ed2c2" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-3-candidate-8-0.json", + "sha256": "13e92e8cecd7ebed3e90799a1efd82de7896388d4d0f37c851269a004b42eb32" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-3-candidate-8-1.json", + "sha256": "94ce9f342b26a2b60df45c2935b784162af22528f0c96963e1e0a3731cb2069f" + } + ], + "return_codes": { + "218": 98, + "322": 2 + } + }, + "ew-4": { + "agreement": "passed", + "automatic_qp": 4, + "calibration_and_two_repetitions_identical": true, + "normal_dp": 96, + "points_per_unique_stream": 100, + "records": [ + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-4-candidate-8-calibration.json", + "sha256": "bb664010d8372b66ce425cfe3b7f8b91e8a4b501bab9d36fd79f90402a6b6065" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-4-candidate-8-0.json", + "sha256": "5583a39164dc2a9c628c3492e3e47002308d358fa467f061b04227224151d33e" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/ew-4-candidate-8-1.json", + "sha256": "6e743aab64c2f570d381ceb5dc5fdddaa6717ca689c7f1606b6abf638bce24bb" + } + ], + "return_codes": { + "218": 96, + "322": 4 + } + }, + "qcd-1": { + "agreement": "passed", + "automatic_qp": 0, + "calibration_and_two_repetitions_identical": true, + "normal_dp": 100, + "points_per_unique_stream": 100, + "records": [ + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-1-candidate-8-calibration.json", + "sha256": "82884a0401c8fd4f8a07df46cc778fdf3fd582235773df7486fcf78912959323" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-1-candidate-8-0.json", + "sha256": "e33c48023376453dc6be24e53a3e183237d3963b68f2e214dc948c14e8a3ef9c" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-1-candidate-8-1.json", + "sha256": "d0db53d285c76769cf83005396c11ef79ceb1b5c36395894269e78aaa6a034a2" + } + ], + "return_codes": { + "218": 100 + } + }, + "qcd-2": { + "agreement": "passed", + "automatic_qp": 0, + "calibration_and_two_repetitions_identical": true, + "normal_dp": 100, + "points_per_unique_stream": 100, + "records": [ + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-2-candidate-8-calibration.json", + "sha256": "4ff3517fb3053598b619f758ea4ecf9680dc012a3ea5239932f3ba0d6a264501" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-2-candidate-8-0.json", + "sha256": "7cc2fc6725b76e303c67a0eaf77a7e65272e6e9c54d5f437ab1c3ae238107c76" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-2-candidate-8-1.json", + "sha256": "f01354785e43b4f5bbf4cfb8481791bda6487a1eaf56b73f77a1f3cfcd1559d1" + } + ], + "return_codes": { + "218": 100 + } + }, + "qcd-3": { + "agreement": "passed", + "automatic_qp": 2, + "calibration_and_two_repetitions_identical": true, + "normal_dp": 98, + "points_per_unique_stream": 100, + "records": [ + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-3-candidate-8-calibration.json", + "sha256": "f73b1e9d68ef26b67f349ac91022c8035b3355ac4b80e1fb4421a4620441ade8" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-3-candidate-8-0.json", + "sha256": "0e0e23cb913751bda924d8b518bad4aaef8d5e8040f846e0c1f76ea8c9ad9e3b" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-3-candidate-8-1.json", + "sha256": "470315e7a242dc3d221361bd515671ef11fae691328dc52f91607a55da59af1c" + } + ], + "return_codes": { + "218": 98, + "322": 2 + } + }, + "qcd-4": { + "agreement": "passed", + "automatic_qp": 24, + "calibration_and_two_repetitions_identical": true, + "normal_dp": 76, + "points_per_unique_stream": 100, + "records": [ + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-4-candidate-8-calibration.json", + "sha256": "f70bf152007737bc0e255bdceaffa1f2a29db92a0ca7a51890f68c3dc864be2d" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-4-candidate-8-0.json", + "sha256": "b51ba99e833bb889e6dd37f9b765e99d4f39649331b4a8566313e63f4fe68dbd" + }, + { + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/run-v1/data/qcd-4-candidate-8-1.json", + "sha256": "db6d70a296dbe2cb98b457dfccbe941756ecb6e8f3a3358cc7a360038033ac67" + } + ], + "return_codes": { + "218": 76, + "322": 24 + } + } + }, + "core_automatic_qp": 32, + "core_normal_dp": 768, + "core_unique_points": 800, + "count_scope": "One100-point stream per process; identical calibration/two repeats are not additional independent points", + "higher_higgs": { + "profile-gg-hhh": { + "agreement_passed": true, + "correctness_only": true, + "points_per_tool": 2, + "raw_records": { + "6": { + "bytes": 175928, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/higher-higgs-controls/run-v1/data/candidate-profile-gg-hhh-6-0.json", + "sha256": "bd2a828b95a66abbed2d250edb79731cb7eafc6709a2cbfeeb38c1ca17e0ce8e" + }, + "8": { + "bytes": 175925, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/higher-higgs-controls/run-v1/data/candidate-profile-gg-hhh-8-0.json", + "sha256": "86675883dd66c3f9134fef0be71dcfb584ebf6d97c998570bb03357f343096ce" + } + } + }, + "profile-gg-hhhh": { + "agreement_passed": true, + "correctness_only": true, + "points_per_tool": 2, + "raw_records": { + "6": { + "bytes": 175931, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/higher-higgs-controls/run-v1/data/candidate-profile-gg-hhhh-6-0.json", + "sha256": "17567b7173822a0c0dc8a8e93c7c048feceb081030543a4db27788f95d8b35a3" + }, + "8": { + "bytes": 175942, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/higher-higgs-controls/run-v1/data/candidate-profile-gg-hhhh-8-0.json", + "sha256": "b57f02e207674c3de4574912948a20db75b19b085a9db6c6e0d12dc041662dca" + } + } + } + }, + "higher_higgs_native_calls_repeated_by_finalizer": 0, + "higher_higgs_original_parent_exit_code": 1, + "native_evaluations": 0, + "purpose": "Display-only materialization of already reviewed actual terminal receipts", + "scientific_validation_recomputed": false, + "source_bindings": [ + { + "bytes": 25023, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/terminal-correctness-v1.json", + "sha256": "1aa2d578516706e227de99c012a9152f2fee81377f054720af6e81f688abf102" + }, + { + "bytes": 4733, + "path": "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/higher-higgs-controls/run-v1/result-finalized-v1.json", + "sha256": "6a61ff18068ce87dfd06c4ee6f56f7580329f6bd24f22a98fa64c9a6da6649a6" + } + ] + }, + "date": "2026-10-22", + "document_scope": "Final actual report components: all 72 CLI sessions retained, ten comparable cases and two with NA ratios under the unchanged conservative reader; original-code timing, normal correctness, native-DP stability and other qualifications retain their separate scopes.", + "input_sha256": { + ".benchmark-work/light-final-report-assembly-v1/light6-validated.json": "ab7f9b9dc0e870e1ba62aa534615250ddaaa8eed6d7dffa6b37846266aaf46ae", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/core-correctness/dataset-correctness-only-public-v2.json": "82ec747c1dc1b4e2624a4d7c2b90e7d69b72e589027dbb8e84951057d21b6e7d", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/light-timing/terminal-summary-v1.json": "367eebf8c156a43a5ce37e318c3e21f0c840ff596662bf3c9e5cf5873c84a911", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/paper-comparison/lightweight-stability-figures-v1/manifest.json": "a19f26913c7b78ae576e11196c2644ad660bedd7e8650f4853c5743f4e9a2479" + }, + "light": { + "actual_command_seconds_range": [ + 0.326159496, + 0.51864067 + ], + "calibration_target_seconds": 0.5, + "candidate_cohort": { + "archive_sha256": "b0d69deb8c16deb13293176296afc5e18dbeeebe778a20fa39b61804fba89d4c", + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "generator_identity_sha256": "77b16df0251af4104a2c541bab913c11f4e67496a290495ce1a1c5fc526dfe3c", + "numerical_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "runtime_identity_sha256": "a7577a9a33292ffb5d675ccf1b9c3667db3ab3613d77ccd270f1efc9e9802008" + }, + "completion_scope": "Ancillary six-case fixed-prefix comparison; the withdrawn eight-case runtime gate is not reinstated", + "literal_original_revision": "27147b3300f556a75661a886e92bdbe00558ee25", + "rows": [ + { + "actual_command_seconds_range": [ + 0.326159496, + 0.331853435 + ], + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + } + ], + "passed": true + }, + "final_traversal_status_counts": { + "baseline/6": [ + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + } + ], + "candidate/8": [ + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + } + ] + }, + "id": "qcd-1", + "pairs": 7, + "points": 10, + "timing": { + "bootstrap": { + "method": "paired percentile", + "resamples": 10000, + "seed": 410083 + }, + "maximum_ratio": 1.05, + "measurements": { + "baseline": { + "maximum": 4.2328244260204076e-05, + "median": 4.2057178571428566e-05, + "median_absolute_deviation": 7.108035714286211e-08, + "minimum": 4.197760663265306e-05, + "samples": [ + 4.229729630102041e-05, + 4.197760663265306e-05, + 4.2023266198979595e-05, + 4.2328244260204076e-05, + 4.212825892857143e-05, + 4.204343482142857e-05, + 4.2057178571428566e-05 + ], + "stdev": 1.3800757161447678e-07 + }, + "candidate": { + "maximum": 3.8879644917257684e-05, + "median": 3.868681808510639e-05, + "median_absolute_deviation": 5.300591016548547e-08, + "minimum": 3.8553131914893615e-05, + "samples": [ + 3.8553131914893615e-05, + 3.8698209219858155e-05, + 3.873982399527187e-05, + 3.8643003427895984e-05, + 3.8879644917257684e-05, + 3.868681808510639e-05, + 3.856504113475177e-05 + ], + "stdev": 1.1142281810566743e-07 + } + }, + "passed": true, + "ratio_confidence_interval_95": [ + 0.9117613773772438, + 0.9218660875106502 + ], + "runtime_ratio": 0.9198624206186806, + "status": "passed" + } + }, + { + "actual_command_seconds_range": [ + 0.41919182, + 0.437495408 + ], + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + } + ], + "passed": true + }, + "final_traversal_status_counts": { + "baseline/6": [ + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + } + ], + "candidate/8": [ + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + } + ] + }, + "id": "ew-1", + "pairs": 7, + "points": 10, + "timing": { + "bootstrap": { + "method": "paired percentile", + "resamples": 10000, + "seed": 410083 + }, + "maximum_ratio": 1.05, + "measurements": { + "baseline": { + "maximum": 0.00020443710654205607, + "median": 0.00020300465841121496, + "median_absolute_deviation": 1.6365373831778423e-07, + "minimum": 0.00020263712897196262, + "samples": [ + 0.00020263712897196262, + 0.00020300465841121496, + 0.00020443710654205607, + 0.0002031050238317757, + 0.00020291570514018693, + 0.00020284100467289718, + 0.00020385560140186916 + ], + "stdev": 6.469829222406037e-07 + }, + "candidate": { + "maximum": 0.0001912774545045045, + "median": 0.00018966102072072072, + "median_absolute_deviation": 1.4522522522524917e-07, + "minimum": 0.00018882514414414415, + "samples": [ + 0.00018882514414414415, + 0.00019101182207207205, + 0.00018976277792792794, + 0.00018966102072072072, + 0.0001912774545045045, + 0.00018951579549549548, + 0.00018963730045045045 + ], + "stdev": 8.717352530166398e-07 + } + }, + "passed": true, + "ratio_confidence_interval_95": [ + 0.930253076915019, + 0.9413358218877591 + ], + "runtime_ratio": 0.9342693030055261, + "status": "passed" + } + }, + { + "actual_command_seconds_range": [ + 0.488465174, + 0.503909683 + ], + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + } + ], + "passed": true + }, + "final_traversal_status_counts": { + "baseline/6": [ + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + } + ], + "candidate/8": [ + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + } + ] + }, + "id": "qcd-2", + "pairs": 7, + "points": 10, + "timing": { + "bootstrap": { + "method": "paired percentile", + "resamples": 10000, + "seed": 410083 + }, + "maximum_ratio": 1.05, + "measurements": { + "baseline": { + "maximum": 0.0013997491194444446, + "median": 0.0013853607027777778, + "median_absolute_deviation": 3.2421138888890765e-06, + "minimum": 0.0013804526333333334, + "samples": [ + 0.0013853607027777778, + 0.0013804526333333334, + 0.0013865009611111112, + 0.0013812362222222223, + 0.0013882327472222223, + 0.0013821185888888887, + 0.0013997491194444446 + ], + "stdev": 6.618483312448996e-06 + }, + "candidate": { + "maximum": 0.00122851888, + "median": 0.00122329059, + "median_absolute_deviation": 1.8635250000000221e-06, + "minimum": 0.001221162935, + "samples": [ + 0.001225154115, + 0.001221384875, + 0.0012231038375, + 0.0012251132425, + 0.00122851888, + 0.00122329059, + 0.001221162935 + ], + "stdev": 2.555230610759819e-06 + } + }, + "passed": true, + "ratio_confidence_interval_95": [ + 0.8798127529003507, + 0.8869686609644211 + ], + "runtime_ratio": 0.8830123357384022, + "status": "passed" + } + }, + { + "actual_command_seconds_range": [ + 0.477356602, + 0.48890689 + ], + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + } + ], + "passed": true + }, + "final_traversal_status_counts": { + "baseline/6": [ + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + } + ], + "candidate/8": [ + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + } + ] + }, + "id": "ew-2", + "pairs": 7, + "points": 10, + "timing": { + "bootstrap": { + "method": "paired percentile", + "resamples": 10000, + "seed": 410083 + }, + "maximum_ratio": 1.05, + "measurements": { + "baseline": { + "maximum": 0.000813094345, + "median": 0.000799413015, + "median_absolute_deviation": 2.0968399999999384e-06, + "minimum": 0.0007955943366666667, + "samples": [ + 0.0007967102716666667, + 0.0007998227316666667, + 0.0007955943366666667, + 0.000797316175, + 0.000799413015, + 0.000813094345, + 0.00080019807 + ], + "stdev": 5.897068021061537e-06 + }, + "candidate": { + "maximum": 0.0008286557457627119, + "median": 0.0008259859389830508, + "median_absolute_deviation": 1.7490898305084828e-06, + "minimum": 0.0008241615593220339, + "samples": [ + 0.0008254766813559322, + 0.0008241615593220339, + 0.0008259859389830508, + 0.0008286557457627119, + 0.0008242368491525423, + 0.0008274533355932203, + 0.0008286264254237289 + ], + "stdev": 1.9088724036644503e-06 + } + }, + "passed": true, + "ratio_confidence_interval_95": [ + 1.0305244106215907, + 1.0392695537924197 + ], + "runtime_ratio": 1.0332405446051574, + "status": "passed" + } + }, + { + "actual_command_seconds_range": [ + 0.393712416, + 0.470025293 + ], + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + } + ], + "passed": true + }, + "final_traversal_status_counts": { + "baseline/6": [ + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + } + ], + "candidate/8": [ + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + } + ] + }, + "id": "supplement-gg-h", + "pairs": 7, + "points": 10, + "timing": { + "bootstrap": { + "method": "paired percentile", + "resamples": 10000, + "seed": 410083 + }, + "maximum_ratio": 1.05, + "measurements": { + "baseline": { + "maximum": 0.00016434450804195806, + "median": 0.00015775330489510488, + "median_absolute_deviation": 2.7774283216783137e-06, + "minimum": 0.00015484856503496504, + "samples": [ + 0.00016434450804195806, + 0.00016101573496503496, + 0.0001582328237762238, + 0.00015775330489510488, + 0.00015582233006993006, + 0.00015497587657342657, + 0.00015484856503496504 + ], + "stdev": 3.4914350297922965e-06 + }, + "candidate": { + "maximum": 0.0001281472827044025, + "median": 0.00012403076603773587, + "median_absolute_deviation": 1.7483647798743679e-07, + "minimum": 0.0001238089358490566, + "samples": [ + 0.0001281472827044025, + 0.00012661572421383648, + 0.00012406431666666667, + 0.00012403076603773587, + 0.00012388006792452832, + 0.0001238089358490566, + 0.00012385592955974843 + ], + "stdev": 1.7445982399114363e-06 + } + }, + "passed": true, + "ratio_confidence_interval_95": [ + 0.784061825516816, + 0.7991948959944504 + ], + "runtime_ratio": 0.7862324413438299, + "status": "passed" + } + }, + { + "actual_command_seconds_range": [ + 0.492066581, + 0.51864067 + ], + "agreement": { + "comparisons": [ + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + }, + { + "failures": [], + "pairs": 1, + "passed": true + } + ], + "passed": true + }, + "final_traversal_status_counts": { + "baseline/6": [ + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + }, + { + "216": 10 + } + ], + "candidate/8": [ + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + }, + { + "218": 10 + } + ] + }, + "id": "supplement-gg-hh", + "pairs": 7, + "points": 10, + "timing": { + "bootstrap": { + "method": "paired percentile", + "resamples": 10000, + "seed": 410083 + }, + "maximum_ratio": 1.05, + "measurements": { + "baseline": { + "maximum": 0.0028813370555555557, + "median": 0.0028037529555555558, + "median_absolute_deviation": 6.270800000000333e-06, + "minimum": 0.0027971351055555557, + "samples": [ + 0.0027974821555555554, + 0.0027971351055555557, + 0.0028037529555555558, + 0.0028008202833333337, + 0.002806665527777778, + 0.00286588695, + 0.0028813370555555557 + ], + "stdev": 3.578383800937897e-05 + }, + "candidate": { + "maximum": 0.0022807332863636364, + "median": 0.002263450690909091, + "median_absolute_deviation": 1.3476318181818246e-05, + "minimum": 0.0022366662772727273, + "samples": [ + 0.0022366662772727273, + 0.0022807332863636364, + 0.002279462827272727, + 0.0022499743727272727, + 0.0022662753363636365, + 0.002263450690909091, + 0.0022633641954545457 + ], + "stdev": 1.559660836399435e-05 + } + }, + "passed": true, + "ratio_confidence_interval_95": [ + 0.7897604598306105, + 0.8148265835211542 + ], + "runtime_ratio": 0.8072931983626191, + "status": "passed" + } + } + ], + "status_scope": "Saved status vectors cover the final traversal of each timed command, not every adaptive-loop evaluation" + }, + "materialization_source_sha256": "3e3f37840d3cb83dcd02d4af6b41ee6d34f46e95bc9ddc258b7dd4b5f4c05ebb", + "preparation": { + "fields": [ + "Process_output", + "HELAS_MODEL_compilation", + "Process_compilation", + "Initialization", + "Booting_time" + ], + "metadata_sha256": { + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/6/0/timing-metadata.json": "220ca0315d096b69832c9af7403dfa5d522e0365820d250f089a5e34bed5cd67", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-h/8/0/timing-metadata.json": "ee7287945c09cfeba0f3a0938e955c2af567d8bec4c2fc1059d2891d533acd28", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/6/0/timing-metadata.json": "95671f0d09e252306cc3b42f41707c3209f06409c66a89fe0bd45573b227c704", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/control-gg-hh/8/0/timing-metadata.json": "552dd9364bc54e060ffa5b31779e94308af8e938cc4af0ba8f1eef3c0d51ad54", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/6/0/timing-metadata.json": "757ac0b39cc99c78bf47dcfc2ccc9485ee439ea45df90cd63089db1d4b39ee1a", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-1/8/0/timing-metadata.json": "e433c93501898eff78359383aec5af7d6d88ddd1fb0a7ecd1b7b5b932276a7c2", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/6/0/timing-metadata.json": "d487051050435d655c2bbddd607f8ca7ce85d0b6d728cc393ba91d192d536d6c", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-2/8/0/timing-metadata.json": "45f5e7aab113fbb600d1c1e6e64423af8a06731830c167206726859565bbec66", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/6/0/timing-metadata.json": "96cbd2b192367d668fa8112ed633c464efbd012524809e55794afaca3ca92130", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-3/8/0/timing-metadata.json": "8cc7c12301b32ebc4a88ba0764ba5bf0d4149c195eb23ce1b74a9b63ed3e0c2c", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/6/0/timing-metadata.json": "9f504d7a7a83cda03625c64b07b51fdd43f4c3f9965ad72f13e6585207900cc5", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/ew-4/8/0/timing-metadata.json": "4c846e6820034910bae9b0ef7ed6b8cad8a79bdde00f9ba2176fb2029e347dd7", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/6/0/timing-metadata.json": "b53b618214427b01de481c4f7db32cbf0106a6a3f2858d32415341d2d9404e7e", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhh/8/0/timing-metadata.json": "5b8aeb3da39a72c5a7ef6fea803cde9f3b7dcd2808ae7154e30888aae4d7f14f", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/6/0/timing-metadata.json": "768ce44881536b7ed7e6f1ff8c9a4caac45d01313a9f22bf09ab46188f629c90", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/profile-gg-hhhh/8/0/timing-metadata.json": "a876a9444cf96ab90481daec60e88bd372f7d8729400246528d84d71ea7881cc", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/6/0/timing-metadata.json": "8d4b90c81f496886612bea64e07cf86729660167cf25a381369e7038b3453955", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-1/8/0/timing-metadata.json": "d2ef427c7bdbf9c01d5fd65a0982f022cec39461323987f9b259697db067a5f4", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/6/0/timing-metadata.json": "c6d46c96ca15b7b86ff83456eff66bb1e19cfebf65d3d155988d9d89f5340cbc", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-2/8/0/timing-metadata.json": "97479542b9e6f4cad089d0c26275223e37d2e9da62e5995d871be1cba56de7e3", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/6/0/timing-metadata.json": "e1ef775598b7ffaef564a459c9d120dd24921bfbb614ab59c8d79b2b9ccefd95", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-3/8/0/timing-metadata.json": "5285e8cdd39be1afe59476042f117cbb2ce8b8b7210ba01d3b7e87882289d08f", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/6/0/timing-metadata.json": "5c563d78372ea3a5092ff5610041dc4c23b24c974d0dcdd57ecddf24fa3309d5", + "docs/benchmarkfolder/policy-v3/final-pins-20261021-v1/profile-cli-expanded-v4/run-v1/qcd-4/8/0/timing-metadata.json": "cd1466cb4a041cf0e734e3e77cdb3a372b3fdfbc382ac4def3d4b4a3f9379116" + }, + "rows": [ + { + "id": "qcd-1", + "tools": { + "6": { + "Booting_time": { + "display": "0.00956", + "seconds": 0.009557723999023438 + }, + "HELAS_MODEL_compilation": { + "display": "2.65", + "seconds": 2.64616060256958 + }, + "Initialization": { + "display": "0.0224", + "seconds": 0.022416114807128906 + }, + "Process_compilation": { + "display": "6.2", + "seconds": 6.203837156295776 + }, + "Process_output": { + "display": "0.849", + "seconds": 0.8491826057434082 + } + }, + "8": { + "Booting_time": { + "display": "0.00927", + "seconds": 0.00926661491394043 + }, + "HELAS_MODEL_compilation": { + "display": "2.56", + "seconds": 2.5631794929504395 + }, + "Initialization": { + "display": "0.0147", + "seconds": 0.01465606689453125 + }, + "Process_compilation": { + "display": "6.37", + "seconds": 6.371279239654541 + }, + "Process_output": { + "display": "0.795", + "seconds": 0.7954418659210205 + } + } + } + }, + { + "id": "ew-1", + "tools": { + "6": { + "Booting_time": { + "display": "0.0176", + "seconds": 0.017609357833862305 + }, + "HELAS_MODEL_compilation": { + "display": "16.7", + "seconds": 16.705623149871826 + }, + "Initialization": { + "display": "0.0328", + "seconds": 0.03281259536743164 + }, + "Process_compilation": { + "display": "7.05", + "seconds": 7.051156282424927 + }, + "Process_output": { + "display": "1.63", + "seconds": 1.6317667961120605 + } + }, + "8": { + "Booting_time": { + "display": "0.0152", + "seconds": 0.015154123306274414 + }, + "HELAS_MODEL_compilation": { + "display": "17.3", + "seconds": 17.25681233406067 + }, + "Initialization": { + "display": "0.0228", + "seconds": 0.022763490676879883 + }, + "Process_compilation": { + "display": "6.22", + "seconds": 6.215627193450928 + }, + "Process_output": { + "display": "1.6", + "seconds": 1.59907865524292 + } + } + } + }, + { + "id": "qcd-2", + "tools": { + "6": { + "Booting_time": { + "display": "0.00978", + "seconds": 0.009781122207641602 + }, + "HELAS_MODEL_compilation": { + "display": "4.25", + "seconds": 4.251473665237427 + }, + "Initialization": { + "display": "0.043", + "seconds": 0.04300832748413086 + }, + "Process_compilation": { + "display": "13.9", + "seconds": 13.910211086273193 + }, + "Process_output": { + "display": "2.04", + "seconds": 2.036442518234253 + } + }, + "8": { + "Booting_time": { + "display": "0.0101", + "seconds": 0.010094881057739258 + }, + "HELAS_MODEL_compilation": { + "display": "4.56", + "seconds": 4.559494495391846 + }, + "Initialization": { + "display": "0.0346", + "seconds": 0.03460526466369629 + }, + "Process_compilation": { + "display": "14", + "seconds": 14.023098945617676 + }, + "Process_output": { + "display": "1.52", + "seconds": 1.5206308364868164 + } + } + } + }, + { + "id": "ew-2", + "tools": { + "6": { + "Booting_time": { + "display": "0.0189", + "seconds": 0.01892709732055664 + }, + "HELAS_MODEL_compilation": { + "display": "36", + "seconds": 36.00076460838318 + }, + "Initialization": { + "display": "0.0491", + "seconds": 0.04909658432006836 + }, + "Process_compilation": { + "display": "7.61", + "seconds": 7.607125759124756 + }, + "Process_output": { + "display": "3.52", + "seconds": 3.5179073810577393 + } + }, + "8": { + "Booting_time": { + "display": "0.0184", + "seconds": 0.01841259002685547 + }, + "HELAS_MODEL_compilation": { + "display": "35.9", + "seconds": 35.90091347694397 + }, + "Initialization": { + "display": "0.0417", + "seconds": 0.041678428649902344 + }, + "Process_compilation": { + "display": "7.37", + "seconds": 7.368338108062744 + }, + "Process_output": { + "display": "3.43", + "seconds": 3.4315192699432373 + } + } + } + }, + { + "id": "qcd-3", + "tools": { + "6": { + "Booting_time": { + "display": "0.0108", + "seconds": 0.01082158088684082 + }, + "HELAS_MODEL_compilation": { + "display": "7.89", + "seconds": 7.888396739959717 + }, + "Initialization": { + "display": "0.425", + "seconds": 0.4253578186035156 + }, + "Process_compilation": { + "display": "16.8", + "seconds": 16.833760261535645 + }, + "Process_output": { + "display": "2.88", + "seconds": 2.882514715194702 + } + }, + "8": { + "Booting_time": { + "display": "0.0103", + "seconds": 0.010278701782226562 + }, + "HELAS_MODEL_compilation": { + "display": "8.59", + "seconds": 8.59476923942566 + }, + "Initialization": { + "display": "0.365", + "seconds": 0.3647949695587158 + }, + "Process_compilation": { + "display": "16.3", + "seconds": 16.25465178489685 + }, + "Process_output": { + "display": "2.47", + "seconds": 2.4739251136779785 + } + } + } + }, + { + "id": "ew-3", + "tools": { + "6": { + "Booting_time": { + "display": "0.0269", + "seconds": 0.02692437171936035 + }, + "HELAS_MODEL_compilation": { + "display": "79.1", + "seconds": 79.07075715065002 + }, + "Initialization": { + "display": "0.393", + "seconds": 0.39325547218322754 + }, + "Process_compilation": { + "display": "15.7", + "seconds": 15.725582838058472 + }, + "Process_output": { + "display": "6.79", + "seconds": 6.785901308059692 + } + }, + "8": { + "Booting_time": { + "display": "0.0291", + "seconds": 0.029071807861328125 + }, + "HELAS_MODEL_compilation": { + "display": "76.8", + "seconds": 76.81632804870605 + }, + "Initialization": { + "display": "0.561", + "seconds": 0.560570478439331 + }, + "Process_compilation": { + "display": "16.3", + "seconds": 16.30589199066162 + }, + "Process_output": { + "display": "6.63", + "seconds": 6.63463830947876 + } + } + } + }, + { + "id": "qcd-4", + "tools": { + "6": { + "Booting_time": { + "display": "0.0229", + "seconds": 0.02290797233581543 + }, + "HELAS_MODEL_compilation": { + "display": "8.85", + "seconds": 8.85440993309021 + }, + "Initialization": { + "display": "14.3", + "seconds": 14.255916118621826 + }, + "Process_compilation": { + "display": "24.6", + "seconds": 24.647397994995117 + }, + "Process_output": { + "display": "6.75", + "seconds": 6.75002908706665 + } + }, + "8": { + "Booting_time": { + "display": "0.0247", + "seconds": 0.0246734619140625 + }, + "HELAS_MODEL_compilation": { + "display": "9.31", + "seconds": 9.312835931777954 + }, + "Initialization": { + "display": "13.8", + "seconds": 13.757172346115112 + }, + "Process_compilation": { + "display": "24.1", + "seconds": 24.10556173324585 + }, + "Process_output": { + "display": "6.77", + "seconds": 6.7650041580200195 + } + } + } + }, + { + "id": "ew-4", + "tools": { + "6": { + "Booting_time": { + "display": "0.0729", + "seconds": 0.07288312911987305 + }, + "HELAS_MODEL_compilation": { + "display": "42.4", + "seconds": 42.394105434417725 + }, + "Initialization": { + "display": "6.31", + "seconds": 6.3058412075042725 + }, + "Process_compilation": { + "display": "31.5", + "seconds": 31.543988466262817 + }, + "Process_output": { + "display": "20", + "seconds": 19.99200463294983 + } + }, + "8": { + "Booting_time": { + "display": "0.0738", + "seconds": 0.07377195358276367 + }, + "HELAS_MODEL_compilation": { + "display": "43.7", + "seconds": 43.70957827568054 + }, + "Initialization": { + "display": "7.3", + "seconds": 7.301720380783081 + }, + "Process_compilation": { + "display": "31.4", + "seconds": 31.43924307823181 + }, + "Process_output": { + "display": "20.4", + "seconds": 20.393913745880127 + } + } + } + }, + { + "id": "control-gg-h", + "tools": { + "6": { + "Booting_time": { + "display": "0.00989", + "seconds": 0.009894847869873047 + }, + "HELAS_MODEL_compilation": { + "display": "2.05", + "seconds": 2.0487117767333984 + }, + "Initialization": { + "display": "0.024", + "seconds": 0.02404046058654785 + }, + "Process_compilation": { + "display": "10.9", + "seconds": 10.917911291122437 + }, + "Process_output": { + "display": "0.714", + "seconds": 0.7136421203613281 + } + }, + "8": { + "Booting_time": { + "display": "0.00911", + "seconds": 0.009107112884521484 + }, + "HELAS_MODEL_compilation": { + "display": "2.2", + "seconds": 2.2035534381866455 + }, + "Initialization": { + "display": "0.017", + "seconds": 0.01701641082763672 + }, + "Process_compilation": { + "display": "11.4", + "seconds": 11.439311027526855 + }, + "Process_output": { + "display": "0.864", + "seconds": 0.8637597560882568 + } + } + } + }, + { + "id": "control-gg-hh", + "tools": { + "6": { + "Booting_time": { + "display": "0.01", + "seconds": 0.010015726089477539 + }, + "HELAS_MODEL_compilation": { + "display": "2.17", + "seconds": 2.1690361499786377 + }, + "Initialization": { + "display": "0.0443", + "seconds": 0.04431414604187012 + }, + "Process_compilation": { + "display": "13.8", + "seconds": 13.797868013381958 + }, + "Process_output": { + "display": "0.86", + "seconds": 0.8600406646728516 + } + }, + "8": { + "Booting_time": { + "display": "0.0105", + "seconds": 0.010501384735107422 + }, + "HELAS_MODEL_compilation": { + "display": "2.35", + "seconds": 2.348954677581787 + }, + "Initialization": { + "display": "0.0324", + "seconds": 0.03241562843322754 + }, + "Process_compilation": { + "display": "13.7", + "seconds": 13.68647313117981 + }, + "Process_output": { + "display": "1.05", + "seconds": 1.0508224964141846 + } + } + } + }, + { + "id": "profile-gg-hhh", + "tools": { + "6": { + "Booting_time": { + "display": "0.0125", + "seconds": 0.012513160705566406 + }, + "HELAS_MODEL_compilation": { + "display": "2.83", + "seconds": 2.828005075454712 + }, + "Initialization": { + "display": "0.342", + "seconds": 0.3418705463409424 + }, + "Process_compilation": { + "display": "19", + "seconds": 18.974144458770752 + }, + "Process_output": { + "display": "1.36", + "seconds": 1.3587110042572021 + } + }, + "8": { + "Booting_time": { + "display": "0.0129", + "seconds": 0.012935876846313477 + }, + "HELAS_MODEL_compilation": { + "display": "2.78", + "seconds": 2.7774994373321533 + }, + "Initialization": { + "display": "0.299", + "seconds": 0.29871225357055664 + }, + "Process_compilation": { + "display": "17", + "seconds": 16.986674785614014 + }, + "Process_output": { + "display": "2.14", + "seconds": 2.13539719581604 + } + } + } + }, + { + "id": "profile-gg-hhhh", + "tools": { + "6": { + "Booting_time": { + "display": "0.179", + "seconds": 0.17943763732910156 + }, + "HELAS_MODEL_compilation": { + "display": "2.31", + "seconds": 2.309084415435791 + }, + "Initialization": { + "display": "5.22", + "seconds": 5.220057725906372 + }, + "Process_compilation": { + "display": "22.7", + "seconds": 22.67106533050537 + }, + "Process_output": { + "display": "5.35", + "seconds": 5.346100807189941 + } + }, + "8": { + "Booting_time": { + "display": "0.181", + "seconds": 0.18143463134765625 + }, + "HELAS_MODEL_compilation": { + "display": "2.47", + "seconds": 2.4736132621765137 + }, + "Initialization": { + "display": "4.59", + "seconds": 4.593463897705078 + }, + "Process_compilation": { + "display": "23.6", + "seconds": 23.578145027160645 + }, + "Process_output": { + "display": "5.53", + "seconds": 5.5279295444488525 + } + } + } + } + ], + "scope": "Exact captured first CLI timing_result values, not summed or relabelled as symbolic generation", + "session": 0, + "units": "seconds" + }, + "profile_matched_cases": 10, + "profile_measurements": 72, + "profile_unmatched_cases": [ + "qcd-1", + "ew-1" + ], + "schema": "private-light-final-document-components-v1", + "software_fixture": false, + "stability": { + "assets": { + "assets/combined-loop-induced.svg": "final-report-v1/stability/combined-loop-induced.svg", + "assets/combined-on-shell.svg": "final-report-v1/stability/combined-on-shell.svg", + "assets/combined-three-particle.svg": "final-report-v1/stability/combined-three-particle.svg", + "assets/combined-two-particle.svg": "final-report-v1/stability/combined-two-particle.svg", + "assets/direction-loop-induced.svg": "final-report-v1/stability/direction-loop-induced.svg", + "assets/direction-on-shell.svg": "final-report-v1/stability/direction-on-shell.svg", + "assets/direction-three-particle.svg": "final-report-v1/stability/direction-three-particle.svg", + "assets/direction-two-particle.svg": "final-report-v1/stability/direction-two-particle.svg", + "assets/lorentz-loop-induced.svg": "final-report-v1/stability/lorentz-loop-induced.svg", + "assets/lorentz-on-shell.svg": "final-report-v1/stability/lorentz-on-shell.svg", + "assets/lorentz-three-particle.svg": "final-report-v1/stability/lorentz-three-particle.svg", + "assets/lorentz-two-particle.svg": "final-report-v1/stability/lorentz-two-particle.svg" + }, + "counts": { + "ew-1": { + "N": 100, + "center_of_mass_energy_gev": 80.419, + "helicity_selection": { + "argument": -1, + "one_based_index": null, + "physical_tuple": null, + "policy": "full-helicity-color-sum", + "table": { + "bytes": 88, + "path": ".benchmark-work/policy-v3/final-pins-20261021-v1/generation/outputs/candidate/ew-1/SubProcesses/MadLoop5_resources/ML5_0_HelConfigs.dat", + "sha256": "4598f48b6b2ac00343f20c274f536e95cd7ccbd56b035f7292a9387e40b0f035" + } + }, + "sample_kind": "random-boosted-on-shell-descriptive", + "tools": { + "6": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 6.005196340198675e-13, + "maximum_spread_display": "6.01e-13", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + }, + "8": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 5.99409410995242e-13, + "maximum_spread_display": "5.99e-13", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + } + } + }, + "ew-2": { + "N": 100, + "center_of_mass_energy_gev": 1000.0, + "helicity_selection": { + "argument": -1, + "one_based_index": null, + "physical_tuple": null, + "policy": "full-helicity-color-sum", + "table": { + "bytes": 160, + "path": ".benchmark-work/policy-v3/final-pins-20261021-v1/generation/outputs/candidate/ew-2/SubProcesses/MadLoop5_resources/ML5_0_HelConfigs.dat", + "sha256": "d78a7b145b2fb57b58555e7d56cd6be7a461c1924690fa882e876251c8a02bb5" + } + }, + "sample_kind": "preregistered-random-SM-DP", + "tools": { + "6": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 6.550315845288647e-14, + "maximum_spread_display": "6.55e-14", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + }, + "8": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 8.326672684689007e-14, + "maximum_spread_display": "8.33e-14", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + } + } + }, + "ew-3": { + "N": 100, + "center_of_mass_energy_gev": 1000.0, + "helicity_selection": { + "argument": -1, + "one_based_index": null, + "physical_tuple": null, + "policy": "full-helicity-color-sum", + "table": { + "bytes": 400, + "path": ".benchmark-work/policy-v3/final-pins-20261021-v1/generation/outputs/candidate/ew-3/SubProcesses/MadLoop5_resources/ML5_0_HelConfigs.dat", + "sha256": "0754c409fe7f8c86e09071dd6a8afc5969e97266773b8c6d6ed5f79f9c0c7425" + } + }, + "sample_kind": "preregistered-random-SM-DP", + "tools": { + "6": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 1.0816458839783286e-11, + "maximum_spread_display": "1.08e-11", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + }, + "8": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 4.1589842681596496e-11, + "maximum_spread_display": "4.16e-11", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + } + } + }, + "qcd-1": { + "N": 100, + "center_of_mass_energy_gev": 91.188, + "helicity_selection": { + "argument": -1, + "one_based_index": null, + "physical_tuple": null, + "policy": "full-helicity-color-sum", + "table": { + "bytes": 88, + "path": ".benchmark-work/policy-v3/final-pins-20261021-v1/generation/outputs/candidate/qcd-1/SubProcesses/MadLoop5_resources/ML5_0_HelConfigs.dat", + "sha256": "4598f48b6b2ac00343f20c274f536e95cd7ccbd56b035f7292a9387e40b0f035" + } + }, + "sample_kind": "random-boosted-on-shell-descriptive", + "tools": { + "6": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 5.0182080713058754e-14, + "maximum_spread_display": "5.02e-14", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + }, + "8": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 5.062616992290884e-14, + "maximum_spread_display": "5.06e-14", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + } + } + }, + "qcd-2": { + "N": 100, + "center_of_mass_energy_gev": 1000.0, + "helicity_selection": { + "argument": -1, + "one_based_index": null, + "physical_tuple": null, + "policy": "full-helicity-color-sum", + "table": { + "bytes": 160, + "path": ".benchmark-work/policy-v3/final-pins-20261021-v1/generation/outputs/candidate/qcd-2/SubProcesses/MadLoop5_resources/ML5_0_HelConfigs.dat", + "sha256": "0ed2daffdd393c7f7c4ab782461fb6a76a1e30fb235ae5ba2a5cb12aff88886a" + } + }, + "sample_kind": "preregistered-random-SM-DP", + "tools": { + "6": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 3.99347221957761e-13, + "maximum_spread_display": "3.99e-13", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + }, + "8": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 5.823119764160211e-13, + "maximum_spread_display": "5.82e-13", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + } + } + }, + "qcd-3": { + "N": 100, + "center_of_mass_energy_gev": 1000.0, + "helicity_selection": { + "argument": -1, + "one_based_index": null, + "physical_tuple": null, + "policy": "full-helicity-color-sum", + "table": { + "bytes": 592, + "path": ".benchmark-work/policy-v3/final-pins-20261021-v1/generation/outputs/candidate/qcd-3/SubProcesses/MadLoop5_resources/ML5_0_HelConfigs.dat", + "sha256": "669402f3985e86bddb24d97f397ab43c031109cd78fd8b6d47ea86f828aba3bc" + } + }, + "sample_kind": "preregistered-random-SM-DP", + "tools": { + "6": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 3.1098179651481984e-09, + "maximum_spread_display": "3.11e-09", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + }, + "8": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 7.66307129095677e-10, + "maximum_spread_display": "7.66e-10", + "origin_card_policy": { + "exporter": null, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_template", + "overrides": {}, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + } + } + }, + "supplement-gg-h": { + "N": 100, + "center_of_mass_energy_gev": 125.0, + "helicity_selection": { + "argument": 1, + "one_based_index": 1, + "physical_tuple": [ + -1, + -1, + 0 + ], + "policy": "loop-induced-all-minus", + "table": { + "bytes": 28, + "path": ".benchmark-work/policy-v3/final-pins-20261021-v1/controls-generation/outputs/candidate/control-gg-h/SubProcesses/MadLoop5_resources/ML5_0_HelConfigs.dat", + "sha256": "710526b7a98cd34d2c3020551f8297016e0476a76d97c4c26dfdd9b68f4921db" + } + }, + "sample_kind": "random-boosted-on-shell-descriptive", + "tools": { + "6": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 4.606315329171157e-13, + "maximum_spread_display": "4.61e-13", + "origin_card_policy": { + "exporter": { + "git_path": "madgraph/loop/loop_exporters.py", + "sha256": "4d69dd051947c41987f8af18e0e20e18ef177e681ff94320cd6ec0a6e03fe7bd" + }, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_loop_induced_exporter", + "overrides": { + "COLLIERComputeIRpoles": false, + "COLLIERComputeUVpoles": false, + "MLReductionLib": "7|6|1" + }, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + }, + "8": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 3.3251179587527134e-13, + "maximum_spread_display": "3.33e-13", + "origin_card_policy": { + "exporter": { + "git_path": "madgraph/loop/loop_exporters.py", + "sha256": "4d69dd051947c41987f8af18e0e20e18ef177e681ff94320cd6ec0a6e03fe7bd" + }, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_loop_induced_exporter", + "overrides": { + "COLLIERComputeIRpoles": false, + "COLLIERComputeUVpoles": false, + "MLReductionLib": "7|6|1" + }, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + } + } + }, + "supplement-gg-hh": { + "N": 100, + "center_of_mass_energy_gev": 1000.0, + "helicity_selection": { + "argument": 1, + "one_based_index": 1, + "physical_tuple": [ + -1, + -1, + 0, + 0 + ], + "policy": "loop-induced-all-minus", + "table": { + "bytes": 36, + "path": ".benchmark-work/policy-v3/final-pins-20261021-v1/controls-generation/outputs/candidate/control-gg-hh/SubProcesses/MadLoop5_resources/ML5_0_HelConfigs.dat", + "sha256": "63c09e295349032b7cc4bfbff5541477904b8e4a9eacc84c90b4a25952ea2c54" + } + }, + "sample_kind": "preregistered-random-SM-DP", + "tools": { + "6": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 4.4131365228860736e-13, + "maximum_spread_display": "4.41e-13", + "origin_card_policy": { + "exporter": { + "git_path": "madgraph/loop/loop_exporters.py", + "sha256": "4d69dd051947c41987f8af18e0e20e18ef177e681ff94320cd6ec0a6e03fe7bd" + }, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_loop_induced_exporter", + "overrides": { + "COLLIERComputeIRpoles": false, + "COLLIERComputeUVpoles": false, + "MLReductionLib": "7|6|1" + }, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + }, + "8": { + "classifications": { + "combined": { + "finite": 100 + }, + "direction": { + "finite": 100 + }, + "lorentz": { + "finite": 100 + } + }, + "maximum_combined_spread": 4.144462550926657e-13, + "maximum_spread_display": "4.14e-13", + "origin_card_policy": { + "exporter": { + "git_path": "madgraph/loop/loop_exporters.py", + "sha256": "4d69dd051947c41987f8af18e0e20e18ef177e681ff94320cd6ec0a6e03fe7bd" + }, + "generation_revision": "856e76e669618ec8d0f799b9c8e6f86819dcd986", + "kind": "committed_loop_induced_exporter", + "overrides": { + "COLLIERComputeIRpoles": false, + "COLLIERComputeUVpoles": false, + "MLReductionLib": "7|6|1" + }, + "template": { + "git_path": "Template/loop_material/StandAlone/Cards/MadLoopParams.dat", + "sha256": "b643cd5f0b8dd11533c02430daa906473f6183cb38b99a12244425ff0ff9ef25" + } + } + } + } + } + }, + "finite_resolution": 0.01, + "hardware": { + "ew-1": { + "N": 100, + "tools": { + "6": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + }, + "8": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + } + }, + "transformed_observations_per_tool": 300 + }, + "ew-2": { + "N": 100, + "tools": { + "6": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + }, + "8": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 300, + "ieee_overflow_seen": 0 + } + } + }, + "transformed_observations_per_tool": 300 + }, + "ew-3": { + "N": 100, + "tools": { + "6": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + }, + "8": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 300, + "ieee_overflow_seen": 0 + } + } + }, + "transformed_observations_per_tool": 300 + }, + "qcd-1": { + "N": 100, + "tools": { + "6": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + }, + "8": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + } + }, + "transformed_observations_per_tool": 300 + }, + "qcd-2": { + "N": 100, + "tools": { + "6": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + }, + "8": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 300, + "ieee_overflow_seen": 0 + } + } + }, + "transformed_observations_per_tool": 300 + }, + "qcd-3": { + "N": 100, + "tools": { + "6": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + }, + "8": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 300, + "ieee_overflow_seen": 0 + } + } + }, + "transformed_observations_per_tool": 300 + }, + "supplement-gg-h": { + "N": 100, + "tools": { + "6": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + }, + "8": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + } + }, + "transformed_observations_per_tool": 300 + }, + "supplement-gg-hh": { + "N": 100, + "tools": { + "6": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 0, + "ieee_overflow_seen": 0 + } + }, + "8": { + "algorithmic_failure_categories": {}, + "classification_counts": { + "finite": 100 + }, + "hardware_exception_observations": { + "ieee_divzero_seen": 0, + "ieee_invalid_seen": 300, + "ieee_overflow_seen": 0 + } + } + }, + "transformed_observations_per_tool": 300 + } + }, + "sample_size": 100, + "zero_event_upper95": 0.029513049607039932 + }, + "stock_cli": { + "all_twelve_sessions_complete_comparable": false, + "attempt_inventory_scope": "Selected retained success/failure descriptors; final assembly must also review the controller launch ledger for attempts that produced no result file", + "declared_scope": { + "initial_stability_points": 20, + "repetitions": 3 + }, + "optional_positive_weight_polarized": [ + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 11162, + 6722, + 6756 + ], + "polarized_skip": [ + 11162, + 6722, + 6756 + ], + "unpolarized_full": [ + 5581, + 3361, + 3378 + ], + "unpolarized_skip": [ + 5581, + 3361, + 3378 + ] + }, + "8": { + "polarized_full": [ + 13872, + 9620, + 8954 + ], + "polarized_skip": [ + 13872, + 9620, + 8954 + ], + "unpolarized_full": [ + 6936, + 4810, + 4477 + ], + "unpolarized_skip": [ + 6936, + 4810, + 4477 + ] + } + }, + "id": "qcd-2", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0001955525974628426, + 0.00019879555354619161 + ], + "maximum_seconds_per_point": 0.00019879555354619161, + "median_absolute_deviation": 1.5276372589809368e-06, + "median_seconds_per_point": 0.00019708023472182352, + "minimum_seconds_per_point": 0.0001955525974628426, + "observed_seconds_per_point": [ + 0.0001955525974628426, + 0.00019879555354619161, + 0.00019708023472182352 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0001955627995674861, + 0.00019684861894297352 + ], + "maximum_seconds_per_point": 0.00019684861894297352, + "median_absolute_deviation": 2.45897620145593e-08, + "median_seconds_per_point": 0.00019682402918095896, + "minimum_seconds_per_point": 0.0001955627995674861, + "observed_seconds_per_point": [ + 0.00019684861894297352, + 0.00019682402918095896, + 0.0001955627995674861 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9837382983621192, + 1.0066274828202024 + ], + "ratio": 0.9986999937298319, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0001861130825929151, + 0.0001953529704598155 + ], + "maximum_seconds_per_point": 0.0001953529704598155, + "median_absolute_deviation": 3.5842052879695374e-06, + "median_seconds_per_point": 0.00019176876517184595, + "minimum_seconds_per_point": 0.0001861130825929151, + "observed_seconds_per_point": [ + 0.00019176876517184595, + 0.0001861130825929151, + 0.0001953529704598155 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0001750326314736953, + 0.00017760786345991425 + ], + "maximum_seconds_per_point": 0.00017760786345991425, + "median_absolute_deviation": 4.888684872869284e-07, + "median_seconds_per_point": 0.00017552149996098222, + "minimum_seconds_per_point": 0.0001750326314736953, + "observed_seconds_per_point": [ + 0.0001750326314736953, + 0.00017760786345991425, + 0.00017552149996098222 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8959814179518701, + 0.9543007991995689 + ], + "ratio": 0.9152767907938272, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0003849086361391067, + 0.000392433205181639 + ], + "maximum_seconds_per_point": 0.000392433205181639, + "median_absolute_deviation": 2.4127264955818226e-06, + "median_seconds_per_point": 0.00038732136263468854, + "minimum_seconds_per_point": 0.0003849086361391067, + "observed_seconds_per_point": [ + 0.00038732136263468854, + 0.0003849086361391067, + 0.000392433205181639 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0003710842995284683, + 0.0003744318926408732 + ], + "maximum_seconds_per_point": 0.0003744318926408732, + "median_absolute_deviation": 7.969508882004926e-07, + "median_seconds_per_point": 0.0003718812504166688, + "minimum_seconds_per_point": 0.0003710842995284683, + "observed_seconds_per_point": [ + 0.0003718812504166688, + 0.0003744318926408732, + 0.0003710842995284683 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9455986257755908, + 0.9727812199712579 + ], + "ratio": 0.9601361719038914, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 2, + 2, + 2 + ], + "8": [ + 2, + 2, + 2 + ] + } + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 9778, + 5088, + 5282 + ], + "polarized_skip": [ + 9778, + 5088, + 5282 + ], + "unpolarized_full": [ + 4889, + 2544, + 2641 + ], + "unpolarized_skip": [ + 4889, + 2544, + 2641 + ] + }, + "8": { + "polarized_full": [ + 11518, + 6316, + 6426 + ], + "polarized_skip": [ + 11518, + 6316, + 6426 + ], + "unpolarized_full": [ + 5759, + 3158, + 3213 + ], + "unpolarized_skip": [ + 5759, + 3158, + 3213 + ] + } + }, + "id": "ew-2", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.000258088653532676, + 0.0002586842314746878 + ], + "maximum_seconds_per_point": 0.0002586842314746878, + "median_absolute_deviation": 2.6763802501723454e-07, + "median_seconds_per_point": 0.00025841659344967056, + "minimum_seconds_per_point": 0.000258088653532676, + "observed_seconds_per_point": [ + 0.0002586842314746878, + 0.00025841659344967056, + 0.000258088653532676 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00025798997662351613, + 0.0002623660466306262 + ], + "maximum_seconds_per_point": 0.0002623660466306262, + "median_absolute_deviation": 1.0232532078407151e-07, + "median_seconds_per_point": 0.0002580923019443002, + "minimum_seconds_per_point": 0.00025798997662351613, + "observed_seconds_per_point": [ + 0.0002623660466306262, + 0.0002580923019443002, + 0.00025798997662351613 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9973162073033447, + 1.0165733481088841 + ], + "ratio": 0.9987450825001548, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0001364587518763515, + 0.00014025612973708463 + ], + "maximum_seconds_per_point": 0.00014025612973708463, + "median_absolute_deviation": 1.58161263937159e-06, + "median_seconds_per_point": 0.00013867451709771304, + "minimum_seconds_per_point": 0.0001364587518763515, + "observed_seconds_per_point": [ + 0.00014025612973708463, + 0.00013867451709771304, + 0.0001364587518763515 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00015768101903004952, + 0.0001626849702976413 + ], + "maximum_seconds_per_point": 0.0001626849702976413, + "median_absolute_deviation": 1.7221540289625529e-06, + "median_seconds_per_point": 0.00016096281626867874, + "minimum_seconds_per_point": 0.00015768101903004952, + "observed_seconds_per_point": [ + 0.00015768101903004952, + 0.0001626849702976413, + 0.00016096281626867874 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.1242362050459291, + 1.1921915455085945 + ], + "ratio": 1.160723827545481, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0003945474054090275, + 0.00039894036121177243 + ], + "maximum_seconds_per_point": 0.00039894036121177243, + "median_absolute_deviation": 1.8492506643888245e-06, + "median_seconds_per_point": 0.0003970911105473836, + "minimum_seconds_per_point": 0.0003945474054090275, + "observed_seconds_per_point": [ + 0.00039894036121177243, + 0.0003970911105473836, + 0.0003945474054090275 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0004189527928921949, + 0.0004207772722419415 + ], + "maximum_seconds_per_point": 0.0004207772722419415, + "median_absolute_deviation": 7.30206581265767e-07, + "median_seconds_per_point": 0.00042004706566067573, + "minimum_seconds_per_point": 0.0004189527928921949, + "observed_seconds_per_point": [ + 0.00042004706566067573, + 0.0004207772722419415, + 0.0004189527928921949 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.0501639684178234, + 1.0664809005795424 + ], + "ratio": 1.0578102971926209, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 2, + 2, + 2 + ], + "8": [ + 2, + 2, + 2 + ] + } + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 1130, + 1246, + 1236 + ], + "polarized_skip": [ + 1130, + 1246, + 1236 + ], + "unpolarized_full": [ + 565, + 623, + 618 + ], + "unpolarized_skip": [ + 565, + 623, + 618 + ] + }, + "8": { + "polarized_full": [ + 1316, + 1278, + 1326 + ], + "polarized_skip": [ + 1316, + 1278, + 1326 + ], + "unpolarized_full": [ + 658, + 639, + 663 + ], + "unpolarized_skip": [ + 658, + 639, + 663 + ] + } + }, + "id": "qcd-3", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0014491781724237762, + 0.0014808141297892846 + ], + "maximum_seconds_per_point": 0.0014808141297892846, + "median_absolute_deviation": 6.727737232027154e-06, + "median_seconds_per_point": 0.0014740863925572574, + "minimum_seconds_per_point": 0.0014491781724237762, + "observed_seconds_per_point": [ + 0.0014491781724237762, + 0.0014740863925572574, + 0.0014808141297892846 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.001334761594928869, + 0.0013699790471279783 + ], + "maximum_seconds_per_point": 0.0013699790471279783, + "median_absolute_deviation": 9.917399642516474e-07, + "median_seconds_per_point": 0.0013357533348931207, + "minimum_seconds_per_point": 0.001334761594928869, + "observed_seconds_per_point": [ + 0.001334761594928869, + 0.0013357533348931207, + 0.0013699790471279783 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9013701099129853, + 0.9453489385895621 + ], + "ratio": 0.9061567501317508, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0016027408363544838, + 0.0017055617480943902 + ], + "maximum_seconds_per_point": 0.0017055617480943902, + "median_absolute_deviation": 1.3947247892122025e-06, + "median_seconds_per_point": 0.001604135561143696, + "minimum_seconds_per_point": 0.0016027408363544838, + "observed_seconds_per_point": [ + 0.0016027408363544838, + 0.0017055617480943902, + 0.001604135561143696 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0011156427824026184, + 0.0013544367326070816 + ], + "maximum_seconds_per_point": 0.0013544367326070816, + "median_absolute_deviation": 8.201373565561512e-08, + "median_seconds_per_point": 0.001354354718871426, + "minimum_seconds_per_point": 0.0011156427824026184, + "observed_seconds_per_point": [ + 0.0011156427824026184, + 0.0013544367326070816, + 0.001354354718871426 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.6541204290311486, + 0.8450753246468827 + ], + "ratio": 0.8442894426614517, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00305191900877826, + 0.0031796481406516476 + ], + "maximum_seconds_per_point": 0.0031796481406516476, + "median_absolute_deviation": 3.3030682154720596e-05, + "median_seconds_per_point": 0.0030849496909329806, + "minimum_seconds_per_point": 0.00305191900877826, + "observed_seconds_per_point": [ + 0.00305191900877826, + 0.0031796481406516476, + 0.0030849496909329806 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0024504043773314874, + 0.0027243337659994043 + ], + "maximum_seconds_per_point": 0.0027243337659994043, + "median_absolute_deviation": 3.414369849920199e-05, + "median_seconds_per_point": 0.0026901900675002023, + "minimum_seconds_per_point": 0.0024504043773314874, + "observed_seconds_per_point": [ + 0.0024504043773314874, + 0.0026901900675002023, + 0.0027243337659994043 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.7706526851204654, + 0.8926625372964946 + ], + "ratio": 0.8720369331814318, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 1, + 1, + 1 + ], + "8": [ + 1, + 1, + 1 + ] + } + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 1222, + 1308, + 1316 + ], + "polarized_skip": [ + 1222, + 1308, + 1316 + ], + "unpolarized_full": [ + 611, + 654, + 658 + ], + "unpolarized_skip": [ + 611, + 654, + 658 + ] + }, + "8": { + "polarized_full": [ + 858, + 1398, + 1124 + ], + "polarized_skip": [ + 858, + 1398, + 1124 + ], + "unpolarized_full": [ + 429, + 699, + 562 + ], + "unpolarized_skip": [ + 429, + 699, + 562 + ] + } + }, + "id": "ew-3", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.002372420946236718, + 0.0026721307571898117 + ], + "maximum_seconds_per_point": 0.0026721307571898117, + "median_absolute_deviation": 8.968624686115159e-05, + "median_seconds_per_point": 0.00258244451032866, + "minimum_seconds_per_point": 0.002372420946236718, + "observed_seconds_per_point": [ + 0.002372420946236718, + 0.00258244451032866, + 0.0026721307571898117 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.002328268297902354, + 0.002721547057188632 + ], + "maximum_seconds_per_point": 0.002721547057188632, + "median_absolute_deviation": 9.044870701669077e-05, + "median_seconds_per_point": 0.002631098350171941, + "minimum_seconds_per_point": 0.002328268297902354, + "observed_seconds_per_point": [ + 0.002328268297902354, + 0.002721547057188632, + 0.002631098350171941 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8713152571736099, + 1.1471602716649925 + ], + "ratio": 1.0188402266335972, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0026578669490060543, + 0.0029266198606225746 + ], + "maximum_seconds_per_point": 0.0029266198606225746, + "median_absolute_deviation": 0.00013189655119590343, + "median_seconds_per_point": 0.0027897635002019578, + "minimum_seconds_per_point": 0.0026578669490060543, + "observed_seconds_per_point": [ + 0.0029266198606225746, + 0.0027897635002019578, + 0.0026578669490060543 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.002441120592308489, + 0.002886861861178462 + ], + "maximum_seconds_per_point": 0.002886861861178462, + "median_absolute_deviation": 7.586778419510151e-05, + "median_seconds_per_point": 0.0028109940769833605, + "minimum_seconds_per_point": 0.002441120592308489, + "observed_seconds_per_point": [ + 0.002441120592308489, + 0.002886861861178462, + 0.0028109940769833605 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8341092142350164, + 1.0861574023703644 + ], + "ratio": 1.0076101708190912, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.005299040806859293, + 0.005372208010530618 + ], + "maximum_seconds_per_point": 0.005372208010530618, + "median_absolute_deviation": 3.095689933657348e-05, + "median_seconds_per_point": 0.005329997706195866, + "minimum_seconds_per_point": 0.005299040806859293, + "observed_seconds_per_point": [ + 0.005299040806859293, + 0.005372208010530618, + 0.005329997706195866 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.004769388890210843, + 0.005608408918367094 + ], + "maximum_seconds_per_point": 0.005608408918367094, + "median_absolute_deviation": 0.00016631649121179228, + "median_seconds_per_point": 0.0054420924271553015, + "minimum_seconds_per_point": 0.004769388890210843, + "observed_seconds_per_point": [ + 0.004769388890210843, + 0.005608408918367094, + 0.0054420924271553015 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8877893188167458, + 1.0583819077421224 + ], + "ratio": 1.0210309135460098, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 1, + 1, + 1 + ], + "8": [ + 1, + 1, + 1 + ] + } + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 100, + 100, + 100 + ], + "polarized_skip": [ + 100, + 100, + 100 + ], + "unpolarized_full": [ + 50, + 50, + 50 + ], + "unpolarized_skip": [ + 50, + 50, + 50 + ] + }, + "8": { + "polarized_full": [ + 100, + 100, + 100 + ], + "polarized_skip": [ + 100, + 100, + 100 + ], + "unpolarized_full": [ + 50, + 50, + 50 + ], + "unpolarized_skip": [ + 50, + 50, + 50 + ] + } + }, + "id": "qcd-4", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.01718167543411255, + 0.01742210626602173 + ], + "maximum_seconds_per_point": 0.01742210626602173, + "median_absolute_deviation": 4.0256977081300216e-05, + "median_seconds_per_point": 0.01738184928894043, + "minimum_seconds_per_point": 0.01718167543411255, + "observed_seconds_per_point": [ + 0.01738184928894043, + 0.01718167543411255, + 0.01742210626602173 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.016849405765533447, + 0.016935803890228272 + ], + "maximum_seconds_per_point": 0.016935803890228272, + "median_absolute_deviation": 2.1884441375734365e-05, + "median_seconds_per_point": 0.016913919448852538, + "minimum_seconds_per_point": 0.016849405765533447, + "observed_seconds_per_point": [ + 0.016849405765533447, + 0.016935803890228272, + 0.016913919448852538 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9671279412636108, + 0.9856898970751058 + ], + "ratio": 0.9730793983822181, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.02107569932937622, + 0.021936900615692142 + ], + "maximum_seconds_per_point": 0.021936900615692142, + "median_absolute_deviation": 4.6472549438479616e-05, + "median_seconds_per_point": 0.021890428066253662, + "minimum_seconds_per_point": 0.02107569932937622, + "observed_seconds_per_point": [ + 0.021936900615692142, + 0.02107569932937622, + 0.021890428066253662 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.01529351949691772, + 0.01636775493621826 + ], + "maximum_seconds_per_point": 0.01636775493621826, + "median_absolute_deviation": 0.00030124664306640375, + "median_seconds_per_point": 0.016066508293151857, + "minimum_seconds_per_point": 0.01529351949691772, + "observed_seconds_per_point": [ + 0.016066508293151857, + 0.01529351949691772, + 0.01636775493621826 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.6971595379329838, + 0.7766174056869457 + ], + "ratio": 0.7339513071432361, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03825737476348877, + 0.03931874990463257 + ], + "maximum_seconds_per_point": 0.03931874990463257, + "median_absolute_deviation": 6.2155723571794e-06, + "median_seconds_per_point": 0.03931253433227539, + "minimum_seconds_per_point": 0.03825737476348877, + "observed_seconds_per_point": [ + 0.03931874990463257, + 0.03825737476348877, + 0.03931253433227539 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03222932338714599, + 0.0332816743850708 + ], + "maximum_seconds_per_point": 0.0332816743850708, + "median_absolute_deviation": 0.0003657603263854947, + "median_seconds_per_point": 0.032915914058685304, + "minimum_seconds_per_point": 0.03222932338714599, + "observed_seconds_per_point": [ + 0.032915914058685304, + 0.03222932338714599, + 0.0332816743850708 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8196934914085025, + 0.8699414058288555 + ], + "ratio": 0.8372880206723662, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 1, + 1, + 1 + ], + "8": [ + 1, + 1, + 1 + ] + } + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 100, + 164, + 162 + ], + "polarized_skip": [ + 100, + 164, + 162 + ], + "unpolarized_full": [ + 50, + 82, + 81 + ], + "unpolarized_skip": [ + 50, + 82, + 81 + ] + }, + "8": { + "polarized_full": [ + 100, + 160, + 166 + ], + "polarized_skip": [ + 100, + 160, + 166 + ], + "unpolarized_full": [ + 50, + 80, + 83 + ], + "unpolarized_skip": [ + 50, + 80, + 83 + ] + } + }, + "id": "ew-4", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.021193087836842477, + 0.021914072036743164 + ], + "maximum_seconds_per_point": 0.021914072036743164, + "median_absolute_deviation": 8.466031241941702e-06, + "median_seconds_per_point": 0.02120155386808442, + "minimum_seconds_per_point": 0.021193087836842477, + "observed_seconds_per_point": [ + 0.021914072036743164, + 0.02120155386808442, + 0.021193087836842477 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.021710433155657297, + 0.022542470693588258 + ], + "maximum_seconds_per_point": 0.022542470693588258, + "median_absolute_deviation": 0.0002079971727118428, + "median_seconds_per_point": 0.02191843032836914, + "minimum_seconds_per_point": 0.021710433155657297, + "observed_seconds_per_point": [ + 0.02191843032836914, + 0.022542470693588258, + 0.021710433155657297 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9907073920016131, + 1.063670894356413 + ], + "ratio": 1.033812449066003, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.016267460069538636, + 0.01733585596084595 + ], + "maximum_seconds_per_point": 0.01733585596084595, + "median_absolute_deviation": 0.00019025606981281154, + "median_seconds_per_point": 0.016457716139351448, + "minimum_seconds_per_point": 0.016267460069538636, + "observed_seconds_per_point": [ + 0.01733585596084595, + 0.016457716139351448, + 0.016267460069538636 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.01691122502088547, + 0.018137898445129398 + ], + "maximum_seconds_per_point": 0.018137898445129398, + "median_absolute_deviation": 0.0005421089264283745, + "median_seconds_per_point": 0.017595789518701024, + "minimum_seconds_per_point": 0.01691122502088547, + "observed_seconds_per_point": [ + 0.018137898445129398, + 0.01691122502088547, + 0.017595789518701024 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9755056259743082, + 1.1149803575724289 + ], + "ratio": 1.0691513554926597, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03746054790638111, + 0.03924992799758911 + ], + "maximum_seconds_per_point": 0.03924992799758911, + "median_absolute_deviation": 0.00019872210105475324, + "median_seconds_per_point": 0.037659270007435866, + "minimum_seconds_per_point": 0.03746054790638111, + "observed_seconds_per_point": [ + 0.03924992799758911, + 0.037659270007435866, + 0.03746054790638111 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03930622267435832, + 0.04005632877349854 + ], + "maximum_seconds_per_point": 0.04005632877349854, + "median_absolute_deviation": 0.00014747304011540618, + "median_seconds_per_point": 0.03945369571447373, + "minimum_seconds_per_point": 0.03930622267435832, + "observed_seconds_per_point": [ + 0.04005632877349854, + 0.03945369571447373, + 0.03930622267435832 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.001434261911835, + 1.0692937239894256 + ], + "ratio": 1.0476489774412396, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 1, + 1, + 1 + ], + "8": [ + 1, + 1, + 1 + ] + } + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 19968, + 7580, + 7800 + ], + "polarized_skip": [ + 19968, + 7580, + 7800 + ], + "unpolarized_full": [ + 9984, + 3790, + 3900 + ], + "unpolarized_skip": [ + 9984, + 3790, + 3900 + ] + }, + "8": { + "polarized_full": [ + 28210, + 12168, + 11848 + ], + "polarized_skip": [ + 28210, + 12168, + 11848 + ], + "unpolarized_full": [ + 14105, + 6084, + 5924 + ], + "unpolarized_skip": [ + 14105, + 6084, + 5924 + ] + } + }, + "id": "control-gg-h", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 3.380976754945941e-05, + 3.516712249853672e-05 + ], + "maximum_seconds_per_point": 3.516712249853672e-05, + "median_absolute_deviation": 6.006749716205753e-08, + "median_seconds_per_point": 3.386983504662147e-05, + "minimum_seconds_per_point": 3.380976754945941e-05, + "observed_seconds_per_point": [ + 3.516712249853672e-05, + 3.380976754945941e-05, + 3.386983504662147e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 3.4048590242588024e-05, + 3.505340929802588e-05 + ], + "maximum_seconds_per_point": 3.505340929802588e-05, + "median_absolute_deviation": 1.7919265677559626e-08, + "median_seconds_per_point": 3.4066509508265584e-05, + "minimum_seconds_per_point": 3.4048590242588024e-05, + "observed_seconds_per_point": [ + 3.4048590242588024e-05, + 3.505340929802588e-05, + 3.4066509508265584e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9681938078386926, + 1.036783504848035 + ], + "ratio": 1.0058067735308835, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 4.3381781627734504e-05, + 4.548350969950358e-05 + ], + "maximum_seconds_per_point": 4.548350969950358e-05, + "median_absolute_deviation": 2.43647222258905e-07, + "median_seconds_per_point": 4.523986247724468e-05, + "minimum_seconds_per_point": 4.3381781627734504e-05, + "observed_seconds_per_point": [ + 4.3381781627734504e-05, + 4.523986247724468e-05, + 4.548350969950358e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 3.159769188017535e-05, + 3.378512809439176e-05 + ], + "maximum_seconds_per_point": 3.378512809439176e-05, + "median_absolute_deviation": 7.683754331352943e-08, + "median_seconds_per_point": 3.1674529423488876e-05, + "minimum_seconds_per_point": 3.159769188017535e-05, + "observed_seconds_per_point": [ + 3.1674529423488876e-05, + 3.159769188017535e-05, + 3.378512809439176e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.6947065450518699, + 0.7787860900759436 + ], + "ratio": 0.7001464568867983, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 7.854890412627123e-05, + 7.935334474612505e-05 + ], + "maximum_seconds_per_point": 7.935334474612505e-05, + "median_absolute_deviation": 3.0371471942096254e-07, + "median_seconds_per_point": 7.904963002670409e-05, + "minimum_seconds_per_point": 7.854890412627123e-05, + "observed_seconds_per_point": [ + 7.854890412627123e-05, + 7.904963002670409e-05, + 7.935334474612505e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 6.57231196660769e-05, + 6.785163760265734e-05 + ], + "maximum_seconds_per_point": 6.785163760265734e-05, + "median_absolute_deviation": 9.279815121243293e-07, + "median_seconds_per_point": 6.665110117820123e-05, + "minimum_seconds_per_point": 6.57231196660769e-05, + "observed_seconds_per_point": [ + 6.57231196660769e-05, + 6.665110117820123e-05, + 6.785163760265734e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8282337672891383, + 0.8638139304092963 + ], + "ratio": 0.8431551312218102, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 2, + 2, + 2 + ], + "8": [ + 2, + 2, + 2 + ] + } + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 10832, + 6344, + 6342 + ], + "polarized_skip": [ + 10832, + 6344, + 6342 + ], + "unpolarized_full": [ + 5416, + 3172, + 3171 + ], + "unpolarized_skip": [ + 5416, + 3172, + 3171 + ] + }, + "8": { + "polarized_full": [ + 14808, + 9594, + 9232 + ], + "polarized_skip": [ + 14808, + 9594, + 9232 + ], + "unpolarized_full": [ + 7404, + 4797, + 4616 + ], + "unpolarized_skip": [ + 7404, + 4797, + 4616 + ] + } + }, + "id": "control-gg-hh", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00015053117821100368, + 0.00015311570469794008 + ], + "maximum_seconds_per_point": 0.00015311570469794008, + "median_absolute_deviation": 1.118947831755721e-07, + "median_seconds_per_point": 0.00015064307299417925, + "minimum_seconds_per_point": 0.00015053117821100368, + "observed_seconds_per_point": [ + 0.00015053117821100368, + 0.00015064307299417925, + 0.00015311570469794008 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00015204564616012653, + 0.00015261903585966167 + ], + "maximum_seconds_per_point": 0.00015261903585966167, + "median_absolute_deviation": 7.0527316675369e-08, + "median_seconds_per_point": 0.0001521161734768019, + "minimum_seconds_per_point": 0.00015204564616012653, + "observed_seconds_per_point": [ + 0.0001521161734768019, + 0.00015204564616012653, + 0.00015261903585966167 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9930114383764583, + 1.0138699349428555 + ], + "ratio": 1.0097787468971744, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0006207797070319235, + 0.0006313669980892931 + ], + "maximum_seconds_per_point": 0.0006313669980892931, + "median_absolute_deviation": 3.4881132916840356e-07, + "median_seconds_per_point": 0.0006211285183610919, + "minimum_seconds_per_point": 0.0006207797070319235, + "observed_seconds_per_point": [ + 0.0006313669980892931, + 0.0006207797070319235, + 0.0006211285183610919 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00044116070301850334, + 0.0004527863781237074 + ], + "maximum_seconds_per_point": 0.0004527863781237074, + "median_absolute_deviation": 3.554606322870397e-07, + "median_seconds_per_point": 0.0004415161636507904, + "minimum_seconds_per_point": 0.00044116070301850334, + "observed_seconds_per_point": [ + 0.0004527863781237074, + 0.00044116070301850334, + 0.0004415161636507904 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.6987389337003496, + 0.7293833432290707 + ], + "ratio": 0.7108290001170351, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0007714227800261028, + 0.0007818981763002968 + ], + "maximum_seconds_per_point": 0.0007818981763002968, + "median_absolute_deviation": 2.8214430329292096e-06, + "median_seconds_per_point": 0.000774244223059032, + "minimum_seconds_per_point": 0.0007714227800261028, + "observed_seconds_per_point": [ + 0.0007818981763002968, + 0.0007714227800261028, + 0.000774244223059032 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0005932063491786299, + 0.0006049025516005093 + ], + "maximum_seconds_per_point": 0.0006049025516005093, + "median_absolute_deviation": 9.288503318221827e-07, + "median_seconds_per_point": 0.0005941351995104521, + "minimum_seconds_per_point": 0.0005932063491786299, + "observed_seconds_per_point": [ + 0.0006049025516005093, + 0.0005932063491786299, + 0.0005941351995104521 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.7586746806157051, + 0.7841388240830031 + ], + "ratio": 0.7673744043746678, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 2, + 2, + 2 + ], + "8": [ + 2, + 2, + 2 + ] + } + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 1406, + 1326, + 1328 + ], + "polarized_skip": [ + 1406, + 1326, + 1328 + ], + "unpolarized_full": [ + 703, + 663, + 664 + ], + "unpolarized_skip": [ + 703, + 663, + 664 + ] + }, + "8": { + "polarized_full": [ + 1608, + 1614, + 1626 + ], + "polarized_skip": [ + 1608, + 1614, + 1626 + ], + "unpolarized_full": [ + 804, + 807, + 813 + ], + "unpolarized_skip": [ + 804, + 807, + 813 + ] + } + }, + "id": "profile-gg-hhh", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0015894411915567666, + 0.0016257543879819203 + ], + "maximum_seconds_per_point": 0.0016257543879819203, + "median_absolute_deviation": 2.171514101650604e-06, + "median_seconds_per_point": 0.0016235828738802697, + "minimum_seconds_per_point": 0.0015894411915567666, + "observed_seconds_per_point": [ + 0.0016235828738802697, + 0.0015894411915567666, + 0.0016257543879819203 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0015606386448020367, + 0.0016052120237102295 + ], + "maximum_seconds_per_point": 0.0016052120237102295, + "median_absolute_deviation": 4.382586060231635e-06, + "median_seconds_per_point": 0.0016008294376499978, + "minimum_seconds_per_point": 0.0015606386448020367, + "observed_seconds_per_point": [ + 0.0015606386448020367, + 0.0016052120237102295, + 0.0016008294376499978 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9599473674121753, + 1.009922249553641 + ], + "ratio": 0.9859856638079136, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.008423748419115806, + 0.00864246864915742 + ], + "maximum_seconds_per_point": 0.00864246864915742, + "median_absolute_deviation": 2.272435638944227e-05, + "median_seconds_per_point": 0.008446472775505249, + "minimum_seconds_per_point": 0.008423748419115806, + "observed_seconds_per_point": [ + 0.00864246864915742, + 0.008423748419115806, + 0.008446472775505249 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.006252920202370206, + 0.006421289930296181 + ], + "maximum_seconds_per_point": 0.006421289930296181, + "median_absolute_deviation": 3.9051719255131165e-05, + "median_seconds_per_point": 0.006291971921625337, + "minimum_seconds_per_point": 0.006252920202370206, + "observed_seconds_per_point": [ + 0.006421289930296181, + 0.006291971921625337, + 0.006252920202370206 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.7235108921083355, + 0.7622841531834575 + ], + "ratio": 0.7449230097410651, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.010013189610672572, + 0.01026605152303769 + ], + "maximum_seconds_per_point": 0.01026605152303769, + "median_absolute_deviation": 5.903755281459755e-05, + "median_seconds_per_point": 0.01007222716348717, + "minimum_seconds_per_point": 0.010013189610672572, + "observed_seconds_per_point": [ + 0.01026605152303769, + 0.010013189610672572, + 0.01007222716348717 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.007853749640020204, + 0.007981928575098218 + ], + "maximum_seconds_per_point": 0.007981928575098218, + "median_absolute_deviation": 4.343430531536345e-05, + "median_seconds_per_point": 0.007897183945335567, + "minimum_seconds_per_point": 0.007853749640020204, + "observed_seconds_per_point": [ + 0.007981928575098218, + 0.007897183945335567, + 0.007853749640020204 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.7650214517622357, + 0.7971414589603565 + ], + "ratio": 0.784055384886835, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 1, + 1, + 1 + ], + "8": [ + 1, + 1, + 1 + ] + } + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 100, + 100, + 100 + ], + "polarized_skip": [ + 100, + 100, + 100 + ], + "unpolarized_full": [ + 50, + 50, + 50 + ], + "unpolarized_skip": [ + 50, + 50, + 50 + ] + }, + "8": { + "polarized_full": [ + 106, + 108, + 108 + ], + "polarized_skip": [ + 106, + 108, + 108 + ], + "unpolarized_full": [ + 53, + 54, + 54 + ], + "unpolarized_skip": [ + 53, + 54, + 54 + ] + } + }, + "id": "profile-gg-hhhh", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.022547681331634522, + 0.022733473777770997 + ], + "maximum_seconds_per_point": 0.022733473777770997, + "median_absolute_deviation": 9.027481079101549e-05, + "median_seconds_per_point": 0.022637956142425537, + "minimum_seconds_per_point": 0.022547681331634522, + "observed_seconds_per_point": [ + 0.022637956142425537, + 0.022733473777770997, + 0.022547681331634522 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.022406262380105478, + 0.022900871510775585 + ], + "maximum_seconds_per_point": 0.022900871510775585, + "median_absolute_deviation": 0.0002451504468084821, + "median_seconds_per_point": 0.022655721063967103, + "minimum_seconds_per_point": 0.022406262380105478, + "observed_seconds_per_point": [ + 0.022900871510775585, + 0.022655721063967103, + 0.022406262380105478 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9856066256805209, + 1.0156641463016214 + ], + "ratio": 1.0007847405229429, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.12868302106857302, + 0.12883022546768189 + ], + "maximum_seconds_per_point": 0.12883022546768189, + "median_absolute_deviation": 6.235599517820378e-05, + "median_seconds_per_point": 0.12874537706375122, + "minimum_seconds_per_point": 0.12868302106857302, + "observed_seconds_per_point": [ + 0.12883022546768189, + 0.12874537706375122, + 0.12868302106857302 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.09973917592246578, + 0.10009852824387727 + ], + "maximum_seconds_per_point": 0.10009852824387727, + "median_absolute_deviation": 0.0001583257227990298, + "median_seconds_per_point": 0.09989750164526481, + "minimum_seconds_per_point": 0.09973917592246578, + "observed_seconds_per_point": [ + 0.09973917592246578, + 0.09989750164526481, + 0.10009852824387727 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.7741908046841552, + 0.7778689636959677 + ], + "ratio": 0.7759307862044498, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.15123070240020753, + 0.1514788508415222 + ], + "maximum_seconds_per_point": 0.1514788508415222, + "median_absolute_deviation": 1.0669231414794922e-05, + "median_seconds_per_point": 0.15146818161010742, + "minimum_seconds_per_point": 0.15123070240020753, + "observed_seconds_per_point": [ + 0.15146818161010742, + 0.1514788508415222, + 0.15123070240020753 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.12250479062398274, + 0.12264004743324136 + ], + "maximum_seconds_per_point": 0.12264004743324136, + "median_absolute_deviation": 4.8432085249169865e-05, + "median_seconds_per_point": 0.12255322270923191, + "minimum_seconds_per_point": 0.12250479062398274, + "observed_seconds_per_point": [ + 0.12264004743324136, + 0.12255322270923191, + 0.12250479062398274 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8087253761394569, + 0.8109467554325996 + ], + "ratio": 0.8091020926407819, + "status": "comparable" + } + } + }, + "scope": "Optional positive-weight selected-helicity diagnostic; not the full-sum primary comparison", + "weights": { + "6": [ + 1, + 1, + 1 + ], + "8": [ + 1, + 1, + 1 + ] + } + } + ], + "pages": [ + { + "index": 0, + "rows": [ + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 21414, + 7636, + 8164 + ], + "polarized_skip": [ + 21414, + 7636, + 8164 + ], + "unpolarized_full": [ + 10707, + 3818, + 4082 + ], + "unpolarized_skip": [ + 10707, + 3818, + 4082 + ] + }, + "8": { + "polarized_full": [ + 32752, + 13098, + 12886 + ], + "polarized_skip": [ + 32752, + 13098, + 12886 + ], + "unpolarized_full": [ + 16376, + 6549, + 6443 + ], + "unpolarized_skip": [ + 16376, + 6549, + 6443 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "qcd-1", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "u u~ > z [virt=QCD]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.436423507181661e-05, + 1.4505685397890606e-05 + ], + "maximum_seconds_per_point": 1.4505685397890606e-05, + "median_absolute_deviation": 2.2162616046944572e-08, + "median_seconds_per_point": 1.4483522781843662e-05, + "minimum_seconds_per_point": 1.436423507181661e-05, + "observed_seconds_per_point": [ + 1.436423507181661e-05, + 1.4483522781843662e-05, + 1.4505685397890606e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.4369479389222711e-05, + 1.4554656419628238e-05 + ], + "maximum_seconds_per_point": 1.4554656419628238e-05, + "median_absolute_deviation": 8.960917332077401e-08, + "median_seconds_per_point": 1.4465047246307464e-05, + "minimum_seconds_per_point": 1.4369479389222711e-05, + "observed_seconds_per_point": [ + 1.4554656419628238e-05, + 1.4369479389222711e-05, + 1.4465047246307464e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "confidence_interval95": null, + "ratio": null, + "status": "incomparable_stage_scope" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 5.6215747460226075e-06, + 3.9017968554968856e-05 + ], + "maximum_seconds_per_point": 3.9017968554968856e-05, + "median_absolute_deviation": 3.996078229642206e-06, + "median_seconds_per_point": 3.502189032532665e-05, + "minimum_seconds_per_point": 5.6215747460226075e-06, + "observed_seconds_per_point": [ + 5.6215747460226075e-06, + 3.9017968554968856e-05, + 3.502189032532665e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.1245448471688037e-05, + 1.730116631476642e-05 + ], + "maximum_seconds_per_point": 1.730116631476642e-05, + "median_absolute_deviation": 4.500804416473727e-07, + "median_seconds_per_point": 1.6851085873119046e-05, + "minimum_seconds_per_point": 1.1245448471688037e-05, + "observed_seconds_per_point": [ + 1.1245448471688037e-05, + 1.6851085873119046e-05, + 1.730116631476642e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "confidence_interval95": null, + "ratio": null, + "status": "incomparable_stage_scope" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.9985809817839217e-05, + 5.350149133681252e-05 + ], + "maximum_seconds_per_point": 5.350149133681252e-05, + "median_absolute_deviation": 3.973915613595262e-06, + "median_seconds_per_point": 4.952757572321726e-05, + "minimum_seconds_per_point": 1.9985809817839217e-05, + "observed_seconds_per_point": [ + 1.9985809817839217e-05, + 5.350149133681252e-05, + 4.952757572321726e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 2.5800104891316275e-05, + 3.176621356107388e-05 + ], + "maximum_seconds_per_point": 3.176621356107388e-05, + "median_absolute_deviation": 5.456482987321236e-07, + "median_seconds_per_point": 3.122056526234176e-05, + "minimum_seconds_per_point": 2.5800104891316275e-05, + "observed_seconds_per_point": [ + 2.5800104891316275e-05, + 3.122056526234176e-05, + 3.176621356107388e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "confidence_interval95": null, + "ratio": null, + "status": "incomparable_stage_scope" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [10707, 3818, 4082]; NRS N [16376, 6549, 6443]", + "status": "complete_incomparable" + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 14630, + 5258, + 6372 + ], + "polarized_skip": [ + 14630, + 5258, + 6372 + ], + "unpolarized_full": [ + 7315, + 2629, + 3186 + ], + "unpolarized_skip": [ + 7315, + 2629, + 3186 + ] + }, + "8": { + "polarized_full": [ + 21088, + 8192, + 9118 + ], + "polarized_skip": [ + 21088, + 8192, + 9118 + ], + "unpolarized_full": [ + 10544, + 4096, + 4559 + ], + "unpolarized_skip": [ + 10544, + 4096, + 4559 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "ew-1", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "u d~ > w+ [virt=QED]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 7.84471210113353e-05, + 8.336335766910284e-05 + ], + "maximum_seconds_per_point": 8.336335766910284e-05, + "median_absolute_deviation": 1.2844411362441345e-06, + "median_seconds_per_point": 7.973156214757943e-05, + "minimum_seconds_per_point": 7.84471210113353e-05, + "observed_seconds_per_point": [ + 8.336335766910284e-05, + 7.973156214757943e-05, + 7.84471210113353e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 8.064358086407145e-05, + 8.196831913664937e-05 + ], + "maximum_seconds_per_point": 8.196831913664937e-05, + "median_absolute_deviation": 1.9833903780968167e-07, + "median_seconds_per_point": 8.084191990188113e-05, + "minimum_seconds_per_point": 8.064358086407145e-05, + "observed_seconds_per_point": [ + 8.084191990188113e-05, + 8.196831913664937e-05, + 8.064358086407145e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "confidence_interval95": null, + "ratio": null, + "status": "incomparable_stage_scope" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 5.018628773566542e-05, + 7.713326214383699e-05 + ], + "maximum_seconds_per_point": 7.713326214383699e-05, + "median_absolute_deviation": 1.0860732405352066e-05, + "median_seconds_per_point": 6.104702014101749e-05, + "minimum_seconds_per_point": 5.018628773566542e-05, + "observed_seconds_per_point": [ + 6.104702014101749e-05, + 7.713326214383699e-05, + 5.018628773566542e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 5.677034520715912e-05, + 7.063680095598102e-05 + ], + "maximum_seconds_per_point": 7.063680095598102e-05, + "median_absolute_deviation": 2.398683679916662e-06, + "median_seconds_per_point": 5.9169028887075785e-05, + "minimum_seconds_per_point": 5.677034520715912e-05, + "observed_seconds_per_point": [ + 5.9169028887075785e-05, + 7.063680095598102e-05, + 5.677034520715912e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "confidence_interval95": null, + "ratio": null, + "status": "incomparable_stage_scope" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00012863340874700072, + 0.00015686482429141642 + ], + "maximum_seconds_per_point": 0.00015686482429141642, + "median_absolute_deviation": 1.2454446481296094e-05, + "median_seconds_per_point": 0.00014441037781012033, + "minimum_seconds_per_point": 0.00012863340874700072, + "observed_seconds_per_point": [ + 0.00014441037781012033, + 0.00015686482429141642, + 0.00012863340874700072 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00013741392607123057, + 0.00015260512009263039 + ], + "maximum_seconds_per_point": 0.00015260512009263039, + "median_absolute_deviation": 2.5970227177263435e-06, + "median_seconds_per_point": 0.00014001094878895692, + "minimum_seconds_per_point": 0.00013741392607123057, + "observed_seconds_per_point": [ + 0.00014001094878895692, + 0.00015260512009263039, + 0.00013741392607123057 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "confidence_interval95": null, + "ratio": null, + "status": "incomparable_stage_scope" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [7315, 2629, 3186]; NRS N [10544, 4096, 4559]", + "status": "complete_incomparable" + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 11162, + 6722, + 6756 + ], + "polarized_skip": [ + 11162, + 6722, + 6756 + ], + "unpolarized_full": [ + 5581, + 3361, + 3378 + ], + "unpolarized_skip": [ + 5581, + 3361, + 3378 + ] + }, + "8": { + "polarized_full": [ + 13872, + 9620, + 8954 + ], + "polarized_skip": [ + 13872, + 9620, + 8954 + ], + "unpolarized_full": [ + 6936, + 4810, + 4477 + ], + "unpolarized_skip": [ + 6936, + 4810, + 4477 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "qcd-2", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "g g > t t~ [virt=QCD]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0008717413295492265, + 0.0008889798090400041 + ], + "maximum_seconds_per_point": 0.0008889798090400041, + "median_absolute_deviation": 6.242075266910379e-06, + "median_seconds_per_point": 0.0008779834048161369, + "minimum_seconds_per_point": 0.0008717413295492265, + "observed_seconds_per_point": [ + 0.0008717413295492265, + 0.0008779834048161369, + 0.0008889798090400041 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0008730149199873682, + 0.0008858891881677068 + ], + "maximum_seconds_per_point": 0.0008858891881677068, + "median_absolute_deviation": 5.605977072528894e-06, + "median_seconds_per_point": 0.0008786208970598971, + "minimum_seconds_per_point": 0.0008730149199873682, + "observed_seconds_per_point": [ + 0.0008786208970598971, + 0.0008858891881677068, + 0.0008730149199873682 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9820413367207111, + 1.0162294228103148 + ], + "ratio": 1.0007260868944257, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00024882154820443886, + 0.00027224274652231945 + ], + "maximum_seconds_per_point": 0.00027224274652231945, + "median_absolute_deviation": 8.262163088513814e-06, + "median_seconds_per_point": 0.00026398058343380564, + "minimum_seconds_per_point": 0.00024882154820443886, + "observed_seconds_per_point": [ + 0.00027224274652231945, + 0.00026398058343380564, + 0.00024882154820443886 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00022430226609513573, + 0.0002670872283349325 + ], + "maximum_seconds_per_point": 0.0002670872283349325, + "median_absolute_deviation": 1.0500954136200263e-05, + "median_seconds_per_point": 0.00025658627419873224, + "minimum_seconds_per_point": 0.00022430226609513573, + "observed_seconds_per_point": [ + 0.00025658627419873224, + 0.00022430226609513573, + 0.0002670872283349325 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8239053894379758, + 1.073408755239663 + ], + "ratio": 0.9719891927698252, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.001137801357244443, + 0.001143984076071546 + ], + "maximum_seconds_per_point": 0.001143984076071546, + "median_absolute_deviation": 2.020087821603435e-06, + "median_seconds_per_point": 0.0011419639882499426, + "minimum_seconds_per_point": 0.001137801357244443, + "observed_seconds_per_point": [ + 0.001143984076071546, + 0.0011419639882499426, + 0.001137801357244443 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0011101914542628426, + 0.0011401021483223007 + ], + "maximum_seconds_per_point": 0.0011401021483223007, + "median_absolute_deviation": 4.8949770636713685e-06, + "median_seconds_per_point": 0.0011352071712586293, + "minimum_seconds_per_point": 0.0011101914542628426, + "observed_seconds_per_point": [ + 0.0011352071712586293, + 0.0011101914542628426, + 0.0011401021483223007 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9704605837480293, + 1.0020221377512062 + ], + "ratio": 0.9940831610621381, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [5581, 3361, 3378]; NRS N [6936, 4810, 4477]", + "status": "complete_comparable" + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 9778, + 5088, + 5282 + ], + "polarized_skip": [ + 9778, + 5088, + 5282 + ], + "unpolarized_full": [ + 4889, + 2544, + 2641 + ], + "unpolarized_skip": [ + 4889, + 2544, + 2641 + ] + }, + "8": { + "polarized_full": [ + 11518, + 6316, + 6426 + ], + "polarized_skip": [ + 11518, + 6316, + 6426 + ], + "unpolarized_full": [ + 5759, + 3158, + 3213 + ], + "unpolarized_skip": [ + 5759, + 3158, + 3213 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "ew-2", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "e+ e- > mu+ mu- [virt=QED]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0005331948493261758, + 0.0005464012039100302 + ], + "maximum_seconds_per_point": 0.0005464012039100302, + "median_absolute_deviation": 1.2504124575613267e-06, + "median_seconds_per_point": 0.0005344452617837371, + "minimum_seconds_per_point": 0.0005331948493261758, + "observed_seconds_per_point": [ + 0.0005464012039100302, + 0.0005331948493261758, + 0.0005344452617837371 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0005310999059691965, + 0.0005349958901770739 + ], + "maximum_seconds_per_point": 0.0005349958901770739, + "median_absolute_deviation": 1.892879776547703e-06, + "median_seconds_per_point": 0.0005329927857457442, + "minimum_seconds_per_point": 0.0005310999059691965, + "observed_seconds_per_point": [ + 0.0005329927857457442, + 0.0005349958901770739, + 0.0005310999059691965 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9719962221324951, + 1.0033778286740282 + ], + "ratio": 0.9972822735238682, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00018670458723224958, + 0.00021706334075088018 + ], + "maximum_seconds_per_point": 0.00021706334075088018, + "median_absolute_deviation": 6.583778531904093e-06, + "median_seconds_per_point": 0.00019328836576415368, + "minimum_seconds_per_point": 0.00018670458723224958, + "observed_seconds_per_point": [ + 0.00019328836576415368, + 0.00021706334075088018, + 0.00018670458723224958 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00019185876237837792, + 0.00020880441654057616 + ], + "maximum_seconds_per_point": 0.00020880441654057616, + "median_absolute_deviation": 6.7688279242759984e-06, + "median_seconds_per_point": 0.00019862759030265392, + "minimum_seconds_per_point": 0.00019185876237837792, + "observed_seconds_per_point": [ + 0.00020880441654057616, + 0.00019862759030265392, + 0.00019185876237837792 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8838837627518636, + 1.11836789677179 + ], + "ratio": 1.027623103529237, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0007211498490159867, + 0.0007502581900770559 + ], + "maximum_seconds_per_point": 0.0007502581900770559, + "median_absolute_deviation": 1.0568620402872059e-05, + "median_seconds_per_point": 0.0007396895696741839, + "minimum_seconds_per_point": 0.0007211498490159867, + "observed_seconds_per_point": [ + 0.0007396895696741839, + 0.0007502581900770559, + 0.0007211498490159867 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0007229586683475744, + 0.0007417972022863204 + ], + "maximum_seconds_per_point": 0.0007417972022863204, + "median_absolute_deviation": 8.173721806592569e-06, + "median_seconds_per_point": 0.0007336234804797278, + "minimum_seconds_per_point": 0.0007229586683475744, + "observed_seconds_per_point": [ + 0.0007417972022863204, + 0.0007336234804797278, + 0.0007229586683475744 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9636131639873499, + 1.0286311552287049 + ], + "ratio": 0.9917991419060728, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [4889, 2544, 2641]; NRS N [5759, 3158, 3213]", + "status": "complete_comparable" + } + ], + "title": "SM: one or two final-state particles" + }, + { + "index": 1, + "rows": [ + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 1130, + 1246, + 1236 + ], + "polarized_skip": [ + 1130, + 1246, + 1236 + ], + "unpolarized_full": [ + 565, + 623, + 618 + ], + "unpolarized_skip": [ + 565, + 623, + 618 + ] + }, + "8": { + "polarized_full": [ + 1316, + 1278, + 1326 + ], + "polarized_skip": [ + 1316, + 1278, + 1326 + ], + "unpolarized_full": [ + 658, + 639, + 663 + ], + "unpolarized_skip": [ + 658, + 639, + 663 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "qcd-3", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "u u~ > z g g [virt=QCD]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03496303051973866, + 0.03972049203385893 + ], + "maximum_seconds_per_point": 0.03972049203385893, + "median_absolute_deviation": 0.00022723717477409616, + "median_seconds_per_point": 0.039493254859084836, + "minimum_seconds_per_point": 0.03496303051973866, + "observed_seconds_per_point": [ + 0.03496303051973866, + 0.03972049203385893, + 0.039493254859084836 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.035239136690064406, + 0.039206380948587576 + ], + "maximum_seconds_per_point": 0.039206380948587576, + "median_absolute_deviation": 0.00018708038132885657, + "median_seconds_per_point": 0.03901930056725872, + "minimum_seconds_per_point": 0.035239136690064406, + "observed_seconds_per_point": [ + 0.035239136690064406, + 0.039206380948587576, + 0.03901930056725872 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8871777484535064, + 1.121366779874911 + ], + "ratio": 0.9879991078598808, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0026528487044773785, + 0.006155917496807807 + ], + "maximum_seconds_per_point": 0.006155917496807807, + "median_absolute_deviation": 0.0010823232339280744, + "median_seconds_per_point": 0.003735171938405453, + "minimum_seconds_per_point": 0.0026528487044773785, + "observed_seconds_per_point": [ + 0.006155917496807807, + 0.0026528487044773785, + 0.003735171938405453 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0027980222388612266, + 0.00305818432596474 + ], + "maximum_seconds_per_point": 0.00305818432596474, + "median_absolute_deviation": 6.751979321246993e-05, + "median_seconds_per_point": 0.0028655420320736966, + "minimum_seconds_per_point": 0.0027980222388612266, + "observed_seconds_per_point": [ + 0.0028655420320736966, + 0.0027980222388612266, + 0.00305818432596474 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.45452562356661863, + 1.1527925888887862 + ], + "ratio": 0.7671780789017703, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.04111894801654647, + 0.04322842679749029 + ], + "maximum_seconds_per_point": 0.04322842679749029, + "median_absolute_deviation": 0.0008550860591539783, + "median_seconds_per_point": 0.04237334073833631, + "minimum_seconds_per_point": 0.04111894801654647, + "observed_seconds_per_point": [ + 0.04111894801654647, + 0.04237334073833631, + 0.04322842679749029 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0381046787221381, + 0.04207748489322346 + ], + "maximum_seconds_per_point": 0.04207748489322346, + "median_absolute_deviation": 7.308170577465661e-05, + "median_seconds_per_point": 0.0420044031874488, + "minimum_seconds_per_point": 0.0381046787221381, + "observed_seconds_per_point": [ + 0.0381046787221381, + 0.0420044031874488, + 0.04207748489322346 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8814727147172134, + 1.0233113180884703 + ], + "ratio": 0.9912931681935165, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [565, 623, 618]; NRS N [658, 639, 663]", + "status": "complete_comparable" + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 1222, + 1308, + 1316 + ], + "polarized_skip": [ + 1222, + 1308, + 1316 + ], + "unpolarized_full": [ + 611, + 654, + 658 + ], + "unpolarized_skip": [ + 611, + 654, + 658 + ] + }, + "8": { + "polarized_full": [ + 858, + 1398, + 1124 + ], + "polarized_skip": [ + 858, + 1398, + 1124 + ], + "unpolarized_full": [ + 429, + 699, + 562 + ], + "unpolarized_skip": [ + 429, + 699, + 562 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "ew-3", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "e+ e- > t t~ a [virt=QED]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03215739106585663, + 0.03345578088672883 + ], + "maximum_seconds_per_point": 0.03345578088672883, + "median_absolute_deviation": 0.00016877315076177513, + "median_seconds_per_point": 0.03232616421661841, + "minimum_seconds_per_point": 0.03215739106585663, + "observed_seconds_per_point": [ + 0.03215739106585663, + 0.03345578088672883, + 0.03232616421661841 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.030741158065262373, + 0.03324386742615615 + ], + "maximum_seconds_per_point": 0.03324386742615615, + "median_absolute_deviation": 0.0009703323038876797, + "median_seconds_per_point": 0.03171149036915005, + "minimum_seconds_per_point": 0.030741158065262373, + "observed_seconds_per_point": [ + 0.030741158065262373, + 0.03171149036915005, + 0.03324386742615615 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9188593794699533, + 1.0337862097728783 + ], + "ratio": 0.9809852525851996, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0015135715496284938, + 0.006314177281226067 + ], + "maximum_seconds_per_point": 0.006314177281226067, + "median_absolute_deviation": 0.0004897083689110529, + "median_seconds_per_point": 0.0020032799185395467, + "minimum_seconds_per_point": 0.0015135715496284938, + "observed_seconds_per_point": [ + 0.0020032799185395467, + 0.0015135715496284938, + 0.006314177281226067 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 4.505771759141797e-05, + 0.004963035627956438 + ], + "maximum_seconds_per_point": 0.004963035627956438, + "median_absolute_deviation": 0.002176380515729461, + "median_seconds_per_point": 0.0027866551122269767, + "minimum_seconds_per_point": 4.505771759141797e-05, + "observed_seconds_per_point": [ + 0.004963035627956438, + 0.0027866551122269767, + 4.505771759141797e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.007135960170992981, + 3.2790228048185863 + ], + "ratio": 1.3910462968442947, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03416067098439618, + 0.038640341497844476 + ], + "maximum_seconds_per_point": 0.038640341497844476, + "median_absolute_deviation": 0.0008086814519611407, + "median_seconds_per_point": 0.03496935243635732, + "minimum_seconds_per_point": 0.03416067098439618, + "observed_seconds_per_point": [ + 0.03416067098439618, + 0.03496935243635732, + 0.038640341497844476 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.033288925143747566, + 0.03570419369321881 + ], + "maximum_seconds_per_point": 0.03570419369321881, + "median_absolute_deviation": 0.0012060482118417815, + "median_seconds_per_point": 0.03449814548137703, + "minimum_seconds_per_point": 0.033288925143747566, + "observed_seconds_per_point": [ + 0.03570419369321881, + 0.03449814548137703, + 0.033288925143747566 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8615070119296064, + 1.0451842034814738 + ], + "ratio": 0.9865251449583499, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [611, 654, 658]; NRS N [429, 699, 562]", + "status": "complete_comparable" + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 100, + 100, + 100 + ], + "polarized_skip": [ + 100, + 100, + 100 + ], + "unpolarized_full": [ + 50, + 50, + 50 + ], + "unpolarized_skip": [ + 50, + 50, + 50 + ] + }, + "8": { + "polarized_full": [ + 100, + 100, + 100 + ], + "polarized_skip": [ + 100, + 100, + 100 + ], + "unpolarized_full": [ + 50, + 50, + 50 + ], + "unpolarized_skip": [ + 50, + 50, + 50 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "qcd-4", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "u u~ > z z g g [virt=QCD]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.0419695043563844, + 1.0667364311218261 + ], + "maximum_seconds_per_point": 1.0667364311218261, + "median_absolute_deviation": 7.277965545648968e-05, + "median_seconds_per_point": 1.0666636514663697, + "minimum_seconds_per_point": 1.0419695043563844, + "observed_seconds_per_point": [ + 1.0667364311218261, + 1.0419695043563844, + 1.0666636514663697 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.0464897489547729, + 1.0573898077011108 + ], + "maximum_seconds_per_point": 1.0573898077011108, + "median_absolute_deviation": 0.005196003913879421, + "median_seconds_per_point": 1.0521938037872314, + "minimum_seconds_per_point": 1.0464897489547729, + "observed_seconds_per_point": [ + 1.0573898077011108, + 1.0521938037872314, + 1.0464897489547729 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9810199768411763, + 1.014799188728898 + ], + "ratio": 0.9864344794544688, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03457710742950448, + 0.0732874822616576 + ], + "maximum_seconds_per_point": 0.0732874822616576, + "median_absolute_deviation": 0.013052258491516033, + "median_seconds_per_point": 0.060235223770141566, + "minimum_seconds_per_point": 0.03457710742950448, + "observed_seconds_per_point": [ + 0.03457710742950448, + 0.060235223770141566, + 0.0732874822616576 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.05028363227844235, + 0.06577168941497802 + ], + "maximum_seconds_per_point": 0.06577168941497802, + "median_absolute_deviation": 0.0019164323806764028, + "median_seconds_per_point": 0.05220006465911875, + "minimum_seconds_per_point": 0.05028363227844235, + "observed_seconds_per_point": [ + 0.05220006465911875, + 0.05028363227844235, + 0.06577168941497802 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.6861148824694943, + 1.9021744241930238 + ], + "ratio": 0.8666036480301776, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.1013135385513306, + 1.1399511337280273 + ], + "maximum_seconds_per_point": 1.1399511337280273, + "median_absolute_deviation": 0.0008911895751952947, + "median_seconds_per_point": 1.102204728126526, + "minimum_seconds_per_point": 1.1013135385513306, + "observed_seconds_per_point": [ + 1.1013135385513306, + 1.102204728126526, + 1.1399511337280273 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 1.1024774360656737, + 1.1122614383697509 + ], + "maximum_seconds_per_point": 1.1122614383697509, + "median_absolute_deviation": 0.0026715660095213423, + "median_seconds_per_point": 1.1095898723602295, + "minimum_seconds_per_point": 1.1024774360656737, + "observed_seconds_per_point": [ + 1.1095898723602295, + 1.1024774360656737, + 1.1122614383697509 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9671269262746361, + 1.0099407656722545 + ], + "ratio": 1.006700338009125, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [50, 50, 50]; NRS N [50, 50, 50]", + "status": "complete_comparable" + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 100, + 164, + 162 + ], + "polarized_skip": [ + 100, + 164, + 162 + ], + "unpolarized_full": [ + 50, + 82, + 81 + ], + "unpolarized_skip": [ + 50, + 82, + 81 + ] + }, + "8": { + "polarized_full": [ + 100, + 160, + 166 + ], + "polarized_skip": [ + 100, + 160, + 166 + ], + "unpolarized_full": [ + 50, + 80, + 83 + ], + "unpolarized_skip": [ + 50, + 80, + 83 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "ew-4", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "e+ e- > mu+ mu- a a [virt=QED]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.3096710157394409, + 0.31050730333095644 + ], + "maximum_seconds_per_point": 0.31050730333095644, + "median_absolute_deviation": 0.00038503121626159986, + "median_seconds_per_point": 0.31012227211469484, + "minimum_seconds_per_point": 0.3096710157394409, + "observed_seconds_per_point": [ + 0.3096710157394409, + 0.31050730333095644, + 0.31012227211469484 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.30699951677437287, + 0.31138726711273196 + ], + "maximum_seconds_per_point": 0.31138726711273196, + "median_absolute_deviation": 0.0018044853210449352, + "median_seconds_per_point": 0.309582781791687, + "minimum_seconds_per_point": 0.30699951677437287, + "observed_seconds_per_point": [ + 0.31138726711273196, + 0.309582781791687, + 0.30699951677437287 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.988703046533998, + 1.0055421763292667 + ], + "ratio": 0.9982603947812936, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.02195118985524991, + 0.032214889526367196 + ], + "maximum_seconds_per_point": 0.032214889526367196, + "median_absolute_deviation": 0.002417817420178381, + "median_seconds_per_point": 0.02436900727542829, + "minimum_seconds_per_point": 0.02195118985524991, + "observed_seconds_per_point": [ + 0.032214889526367196, + 0.02195118985524991, + 0.02436900727542829 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.026572975516319264, + 0.0297323135008295 + ], + "maximum_seconds_per_point": 0.0297323135008295, + "median_absolute_deviation": 0.00018559967178899406, + "median_seconds_per_point": 0.029546713829040505, + "minimum_seconds_per_point": 0.026572975516319264, + "observed_seconds_per_point": [ + 0.029546713829040505, + 0.026572975516319264, + 0.0297323135008295 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8248662623713129, + 1.3544738894287607 + ], + "ratio": 1.2124709675323126, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.33245849318620635, + 0.3418859052658081 + ], + "maximum_seconds_per_point": 0.3418859052658081, + "median_absolute_deviation": 0.002032786203916781, + "median_seconds_per_point": 0.33449127939012313, + "minimum_seconds_per_point": 0.33245849318620635, + "observed_seconds_per_point": [ + 0.3418859052658081, + 0.33245849318620635, + 0.33449127939012313 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.3361557573080063, + 0.34093398094177246 + ], + "maximum_seconds_per_point": 0.34093398094177246, + "median_absolute_deviation": 0.000576072967196084, + "median_seconds_per_point": 0.33673183027520237, + "minimum_seconds_per_point": 0.3361557573080063, + "observed_seconds_per_point": [ + 0.34093398094177246, + 0.3361557573080063, + 0.33673183027520237 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9832395899639479, + 1.025493371140376 + ], + "ratio": 1.0066983835547654, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [50, 82, 81]; NRS N [50, 80, 83]", + "status": "complete_comparable" + } + ], + "title": "SM: three or four final-state particles" + }, + { + "index": 2, + "rows": [ + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 19968, + 7580, + 7800 + ], + "polarized_skip": [ + 19968, + 7580, + 7800 + ], + "unpolarized_full": [ + 9984, + 3790, + 3900 + ], + "unpolarized_skip": [ + 9984, + 3790, + 3900 + ] + }, + "8": { + "polarized_full": [ + 28210, + 12168, + 11848 + ], + "polarized_skip": [ + 28210, + 12168, + 11848 + ], + "unpolarized_full": [ + 14105, + 6084, + 5924 + ], + "unpolarized_skip": [ + 14105, + 6084, + 5924 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "control-gg-h", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "g g > h [sqrvirt=QCD]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 3.407133600642625e-05, + 3.423006106645633e-05 + ], + "maximum_seconds_per_point": 3.423006106645633e-05, + "median_absolute_deviation": 2.1135761268274093e-08, + "median_seconds_per_point": 3.409247176769452e-05, + "minimum_seconds_per_point": 3.407133600642625e-05, + "observed_seconds_per_point": [ + 3.409247176769452e-05, + 3.407133600642625e-05, + 3.423006106645633e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 3.4052000747670364e-05, + 3.486631272406242e-05 + ], + "maximum_seconds_per_point": 3.486631272406242e-05, + "median_absolute_deviation": 1.925940264499242e-07, + "median_seconds_per_point": 3.4673718697612496e-05, + "minimum_seconds_per_point": 3.4052000747670364e-05, + "observed_seconds_per_point": [ + 3.486631272406242e-05, + 3.4673718697612496e-05, + 3.4052000747670364e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9947981302621614, + 1.0233327133836556 + ], + "ratio": 1.017049128437462, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 5.0618599813718065e-05, + 7.550408154490126e-05 + ], + "maximum_seconds_per_point": 7.550408154490126e-05, + "median_absolute_deviation": 1.329188336862138e-06, + "median_seconds_per_point": 7.417489320803912e-05, + "minimum_seconds_per_point": 5.0618599813718065e-05, + "observed_seconds_per_point": [ + 5.0618599813718065e-05, + 7.550408154490126e-05, + 7.417489320803912e-05 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 3.393228550947943e-05, + 4.033107615582108e-05 + ], + "maximum_seconds_per_point": 4.033107615582108e-05, + "median_absolute_deviation": 2.7116922385079316e-06, + "median_seconds_per_point": 3.664397774798736e-05, + "minimum_seconds_per_point": 3.393228550947943e-05, + "observed_seconds_per_point": [ + 4.033107615582108e-05, + 3.393228550947943e-05, + 3.664397774798736e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.44940994996807365, + 0.7967639623427715 + ], + "ratio": 0.49402130779226877, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 8.471107158141259e-05, + 0.0001095754175513275 + ], + "maximum_seconds_per_point": 0.0001095754175513275, + "median_absolute_deviation": 1.1704632768320619e-06, + "median_seconds_per_point": 0.00010840495427449544, + "minimum_seconds_per_point": 8.471107158141259e-05, + "observed_seconds_per_point": [ + 8.471107158141259e-05, + 0.0001095754175513275, + 0.00010840495427449544 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 6.860600420709192e-05, + 7.51973888798835e-05 + ], + "maximum_seconds_per_point": 7.51973888798835e-05, + "median_absolute_deviation": 2.0899742885657996e-06, + "median_seconds_per_point": 7.069597849565772e-05, + "minimum_seconds_per_point": 6.860600420709192e-05, + "observed_seconds_per_point": [ + 7.51973888798835e-05, + 6.860600420709192e-05, + 7.069597849565772e-05 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.6261076228612624, + 0.8876925704760346 + ], + "ratio": 0.6521471178950577, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [9984, 3790, 3900]; NRS N [14105, 6084, 5924]", + "status": "complete_comparable" + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 10832, + 6344, + 6342 + ], + "polarized_skip": [ + 10832, + 6344, + 6342 + ], + "unpolarized_full": [ + 5416, + 3172, + 3171 + ], + "unpolarized_skip": [ + 5416, + 3172, + 3171 + ] + }, + "8": { + "polarized_full": [ + 14808, + 9594, + 9232 + ], + "polarized_skip": [ + 14808, + 9594, + 9232 + ], + "unpolarized_full": [ + 7404, + 4797, + 4616 + ], + "unpolarized_skip": [ + 7404, + 4797, + 4616 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "control-gg-hh", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "g g > h h [sqrvirt=QCD]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.00026796864846721877, + 0.0002701450662035358 + ], + "maximum_seconds_per_point": 0.0002701450662035358, + "median_absolute_deviation": 7.259333138101651e-07, + "median_seconds_per_point": 0.00026869458178102894, + "minimum_seconds_per_point": 0.00026796864846721877, + "observed_seconds_per_point": [ + 0.0002701450662035358, + 0.00026869458178102894, + 0.00026796864846721877 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0002688726240206512, + 0.00026992583192200553 + ], + "maximum_seconds_per_point": 0.00026992583192200553, + "median_absolute_deviation": 2.097553155041361e-07, + "median_seconds_per_point": 0.00026908237933615534, + "minimum_seconds_per_point": 0.0002688726240206512, + "observed_seconds_per_point": [ + 0.0002688726240206512, + 0.00026908237933615534, + 0.00026992583192200553 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.995289781891016, + 1.0073037777590097 + ], + "ratio": 1.0014432652588523, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0011336914809803138, + 0.0012057775655630373 + ], + "maximum_seconds_per_point": 0.0012057775655630373, + "median_absolute_deviation": 3.1256604287148437e-06, + "median_seconds_per_point": 0.0011368171414090286, + "minimum_seconds_per_point": 0.0011336914809803138, + "observed_seconds_per_point": [ + 0.0011336914809803138, + 0.0011368171414090286, + 0.0012057775655630373 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0009194669835075762, + 0.0009386599353685178 + ], + "maximum_seconds_per_point": 0.0009386599353685178, + "median_absolute_deviation": 6.3749334592150524e-06, + "median_seconds_per_point": 0.0009258419169667913, + "minimum_seconds_per_point": 0.0009194669835075762, + "observed_seconds_per_point": [ + 0.0009386599353685178, + 0.0009258419169667913, + 0.0009194669835075762 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.7625510788784925, + 0.827967706484704 + ], + "ratio": 0.8144158662309191, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0014038365471838495, + 0.001473746214030256 + ], + "maximum_seconds_per_point": 0.001473746214030256, + "median_absolute_deviation": 1.6751760062078992e-06, + "median_seconds_per_point": 0.0014055117231900574, + "minimum_seconds_per_point": 0.0014038365471838495, + "observed_seconds_per_point": [ + 0.0014038365471838495, + 0.0014055117231900574, + 0.001473746214030256 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.0011893928154295818, + 0.001207532559389169 + ], + "maximum_seconds_per_point": 0.001207532559389169, + "median_absolute_deviation": 5.531480873364808e-06, + "median_seconds_per_point": 0.0011949242963029466, + "minimum_seconds_per_point": 0.0011893928154295818, + "observed_seconds_per_point": [ + 0.001207532559389169, + 0.0011949242963029466, + 0.0011893928154295818 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8070540260639228, + 0.8601660654949652 + ], + "ratio": 0.8501702807507393, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [5416, 3172, 3171]; NRS N [7404, 4797, 4616]", + "status": "complete_comparable" + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 1406, + 1326, + 1328 + ], + "polarized_skip": [ + 1406, + 1326, + 1328 + ], + "unpolarized_full": [ + 703, + 663, + 664 + ], + "unpolarized_skip": [ + 703, + 663, + 664 + ] + }, + "8": { + "polarized_full": [ + 1608, + 1614, + 1626 + ], + "polarized_skip": [ + 1608, + 1614, + 1626 + ], + "unpolarized_full": [ + 804, + 807, + 813 + ], + "unpolarized_skip": [ + 804, + 807, + 813 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "profile-gg-hhh", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "g g > h h h [sqrvirt=QCD]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.005542752609713225, + 0.005809172090277614 + ], + "maximum_seconds_per_point": 0.005809172090277614, + "median_absolute_deviation": 2.2660589035899785e-05, + "median_seconds_per_point": 0.005786511501241714, + "minimum_seconds_per_point": 0.005542752609713225, + "observed_seconds_per_point": [ + 0.005786511501241714, + 0.005542752609713225, + 0.005809172090277614 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.005198628260200754, + 0.005696667367546119 + ], + "maximum_seconds_per_point": 0.005696667367546119, + "median_absolute_deviation": 0.00011173165100926766, + "median_seconds_per_point": 0.005584935716536852, + "minimum_seconds_per_point": 0.005198628260200754, + "observed_seconds_per_point": [ + 0.005696667367546119, + 0.005584935716536852, + 0.005198628260200754 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8949000269593178, + 1.0277686501041325 + ], + "ratio": 0.9651645409048947, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.030157157455582215, + 0.03067832210155503 + ], + "maximum_seconds_per_point": 0.03067832210155503, + "median_absolute_deviation": 0.0002492249590406066, + "median_seconds_per_point": 0.030429097142514423, + "minimum_seconds_per_point": 0.030157157455582215, + "observed_seconds_per_point": [ + 0.03067832210155503, + 0.030429097142514423, + 0.030157157455582215 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.025823537892716228, + 0.026909214643696645 + ], + "maximum_seconds_per_point": 0.026909214643696645, + "median_absolute_deviation": 0.00035257000458408655, + "median_seconds_per_point": 0.02655664463911256, + "minimum_seconds_per_point": 0.025823537892716228, + "observed_seconds_per_point": [ + 0.026909214643696645, + 0.025823537892716228, + 0.02655664463911256 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8417519643751077, + 0.8922994378144098 + ], + "ratio": 0.8727385013999835, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03596632954585983, + 0.036464833602796745 + ], + "maximum_seconds_per_point": 0.036464833602796745, + "median_absolute_deviation": 5.520206367820579e-06, + "median_seconds_per_point": 0.03597184975222765, + "minimum_seconds_per_point": 0.03596632954585983, + "observed_seconds_per_point": [ + 0.036464833602796745, + 0.03597184975222765, + 0.03596632954585983 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.03140847360925308, + 0.032605882011242766 + ], + "maximum_seconds_per_point": 0.032605882011242766, + "median_absolute_deviation": 0.0003467992900602346, + "median_seconds_per_point": 0.03175527289931331, + "minimum_seconds_per_point": 0.03140847360925308, + "observed_seconds_per_point": [ + 0.032605882011242766, + 0.03140847360925308, + 0.03175527289931331 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8613359915851677, + 0.9065668480201119 + ], + "ratio": 0.8827812058051528, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [703, 663, 664]; NRS N [804, 807, 813]", + "status": "complete_comparable" + }, + { + "actual_stage_counts": { + "6": { + "polarized_full": [ + 100, + 100, + 100 + ], + "polarized_skip": [ + 100, + 100, + 100 + ], + "unpolarized_full": [ + 50, + 50, + 50 + ], + "unpolarized_skip": [ + 50, + 50, + 50 + ] + }, + "8": { + "polarized_full": [ + 106, + 108, + 108 + ], + "polarized_skip": [ + 106, + 108, + 108 + ], + "unpolarized_full": [ + 53, + 54, + 54 + ], + "unpolarized_skip": [ + 53, + 54, + 54 + ] + } + }, + "failed_attempts": { + "6": [], + "8": [] + }, + "id": "profile-gg-hhhh", + "phase_count_scope": "For each session unpolarized FULL and SKIP use this N; polarized stages use2N. Complete stage arrays retained unchanged.", + "primary_mode": "full-helicity-color-sum", + "process": "g g > h h h h [sqrvirt=QCD]", + "quantities": { + "construction": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.07861759662628173, + 0.08047187805175782 + ], + "maximum_seconds_per_point": 0.08047187805175782, + "median_absolute_deviation": 0.000855350494384774, + "median_seconds_per_point": 0.07961652755737304, + "minimum_seconds_per_point": 0.07861759662628173, + "observed_seconds_per_point": [ + 0.08047187805175782, + 0.07961652755737304, + 0.07861759662628173 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.07914030993426288, + 0.0807112146306921 + ], + "maximum_seconds_per_point": 0.0807112146306921, + "median_absolute_deviation": 0.0007454342645502599, + "median_seconds_per_point": 0.07996578036614184, + "minimum_seconds_per_point": 0.07914030993426288, + "observed_seconds_per_point": [ + 0.07996578036614184, + 0.0807112146306921, + 0.07914030993426288 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.9834530006042794, + 1.0266303994812083 + ], + "ratio": 1.0043866872806921, + "status": "comparable" + } + }, + "reduction_estimate": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.4909427642822266, + 0.49287658214569086 + ], + "maximum_seconds_per_point": 0.49287658214569086, + "median_absolute_deviation": 0.00010891437530513581, + "median_seconds_per_point": 0.49105167865753174, + "minimum_seconds_per_point": 0.4909427642822266, + "observed_seconds_per_point": [ + 0.49105167865753174, + 0.4909427642822266, + 0.49287658214569086 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.4184798178849397, + 0.41879640435272797 + ], + "maximum_seconds_per_point": 0.41879640435272797, + "median_absolute_deviation": 0.00014992554982495854, + "median_seconds_per_point": 0.41862974343476467, + "minimum_seconds_per_point": 0.4184798178849397, + "observed_seconds_per_point": [ + 0.41879640435272797, + 0.4184798178849397, + 0.41862974343476467 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.8490559970675174, + 0.8530452729352701 + ], + "ratio": 0.8525166731518793, + "status": "comparable" + } + }, + "total": { + "backend": { + "6": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.5705592918395996, + 0.5715235567092896 + ], + "maximum_seconds_per_point": 0.5715235567092896, + "median_absolute_deviation": 2.937793731694338e-05, + "median_seconds_per_point": 0.5714941787719726, + "minimum_seconds_per_point": 0.5705592918395996, + "observed_seconds_per_point": [ + 0.5715235567092896, + 0.5705592918395996, + 0.5714941787719726 + ], + "sessions": 3 + }, + "8": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile median bootstrap; linear quantiles", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.4977700533690276, + 0.4991910325156318 + ], + "maximum_seconds_per_point": 0.4991910325156318, + "median_absolute_deviation": 0.0004288477967619997, + "median_seconds_per_point": 0.4987621847188698, + "minimum_seconds_per_point": 0.4977700533690276, + "observed_seconds_per_point": [ + 0.4987621847188698, + 0.4991910325156318, + 0.4977700533690276 + ], + "sessions": 3 + } + }, + "ninjars_over_ninja": { + "bootstrap": { + "draws": 10000, + "method": "independent-session percentile ratio of medians; no paired-point claim", + "seed": 20261021 + }, + "confidence_interval95": [ + 0.870952819924136, + 0.8749152623667524 + ], + "ratio": 0.872733622222733, + "status": "comparable" + } + } + }, + "required_sessions_per_backend": 3, + "sessions": { + "6": 3, + "8": 3 + }, + "stage_counts": "Ninja N [50, 50, 50]; NRS N [53, 54, 54]", + "status": "complete_comparable" + } + ], + "title": "Loop-induced amplitudes: H, HH, HHH and HHHH" + } + ], + "retained_failed_attempts": 0, + "runtime_pins": { + "ninja_archive": "42866021f93004c143e0a49de8c420a6bebbcd4eb26242eef556ad71296e57c0", + "ninjars_archive": "b0d69deb8c16deb13293176296afc5e18dbeeebe778a20fa39b61804fba89d4c", + "process_checks": "59b2051d9ba17408046e9a7df188b70256e4081b71519b441623bc5e33358899" + }, + "scope": "Display-only full-sum RED/SKIP/TOTAL view; actual consumer statistics copied unchanged", + "source_snapshot_preserved": true, + "suppressed_optional_polarized": [ + { + "display": "grey; no optional polarized performance ratio", + "id": "qcd-1", + "raw_diagnostic_preserved": true, + "reason": "Zero/nonpositive or unavailable saved weight, or incomplete/incomparable sessions", + "weights": { + "6": [ + 1, + 1, + 1 + ], + "8": [ + 1, + 1, + 1 + ] + } + }, + { + "display": "grey; no optional polarized performance ratio", + "id": "ew-1", + "raw_diagnostic_preserved": true, + "reason": "Zero/nonpositive or unavailable saved weight, or incomplete/incomparable sessions", + "weights": { + "6": [ + 1, + 1, + 1 + ], + "8": [ + 1, + 1, + 1 + ] + } + } + ], + "timed_status_counts_available": false + } +} diff --git a/doc/benchmarkfolder/final-report-v1/reproduce.py b/doc/benchmarkfolder/final-report-v1/reproduce.py new file mode 100644 index 0000000000..da5b971c31 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/reproduce.py @@ -0,0 +1,53 @@ +"""Verify the finite offline document closure and reproduce the final PDF.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import shutil +import subprocess + +HERE = Path(__file__).resolve().parent +ROOT = HERE.parent + + +def digest(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output", type=Path, default=Path("reproduced.pdf")) + parser.add_argument("--verify-only", action="store_true") + args = parser.parse_args() + manifest = json.loads((HERE / "manifest.json").read_text()) + for name, expected in manifest["files"].items(): + filename = (ROOT / name).resolve() + if not filename.is_relative_to(ROOT.resolve()) or digest(filename) != expected["sha256"] or filename.stat().st_size != expected["bytes"]: + raise ValueError("Changed offline report input: " + name) + if args.verify_only: + print(json.dumps({"verified_inputs": len(manifest["files"]), "native_reads": 0}, sort_keys=True)) + return + typst = shutil.which("typst") + if typst is None: + raise RuntimeError("Install Typst0.15.1 or activate the recorded dev environment") + version = subprocess.check_output([typst, "--version"], text=True).strip() + if version != manifest["typst_version"]: + raise RuntimeError("Expected " + manifest["typst_version"] + "; observed " + version) + output = args.output.resolve() + output.parent.mkdir(parents=True, exist_ok=True) + env = dict(os.environ, SOURCE_DATE_EPOCH=str(manifest["source_date_epoch"]), + TYPST_FONT_PATHS="", RAYON_NUM_THREADS="1") + command = [typst, "compile", "--root", str(ROOT), "--ignore-system-fonts", "--ignore-embedded-fonts", + "--font-path", str(HERE / "fonts"), "--creation-timestamp", str(manifest["source_date_epoch"]), + str(ROOT / "benchmark.typ"), str(output)] + subprocess.run(command, env=env, check=True) + actual = digest(output) + if actual != manifest["expected_pdf"]["sha256"]: + raise ValueError("PDF bytes differ from the retained final build: " + actual) + print(json.dumps({"verified_inputs": len(manifest["files"]), "output": str(output), + "sha256": actual, "byte_identical": True, "native_reads": 0}, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/doc/benchmarkfolder/final-report-v1/reproduction.json b/doc/benchmarkfolder/final-report-v1/reproduction.json new file mode 100644 index 0000000000..5ba1264ccc --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/reproduction.json @@ -0,0 +1,59 @@ +{ + "amplitude_calls": 0, + "artifact_acquisition_20261029": { + "binary_artifacts": 8, + "binary_bytes": 3513980, + "byte_identical_pdf": true, + "command": "python -B doc/benchmarkfolder/fetch_artifacts.py", + "current_manifest_sha256": "694f53830829c679a02bfb6ab7c489858153a96fd4aaf7eafe1457da79f2d62d", + "native_reads": 0, + "observed_utc": "2026-10-29T20:35:49.978632+00:00", + "offline_reproduced_pdf_sha256": "c87adf29a508a5428bf351067d1a63d0ad23cb0b2632483e9dabd4763f1ad443", + "revision": "cc6f6fe6dd344a0a767dcfe52341c147e39a193a", + "scope": "Optional binary inputs removed from new source checkouts; original offline reproduction command and PDF/source/scientific values unchanged.", + "verification": "Fresh download from immutable GitHub commit into an isolated report copy; unchanged reproduction script using Typst 0.15.1 (9dfd3a08).", + "verified_input_files": 37 + }, + "byte_identical_pdf": true, + "command": [ + "python", + "-B", + "doc/benchmarkfolder/final-report-v1/reproduce.py", + "--output", + "reproduced.pdf" + ], + "creation_timestamp": 1792627200, + "fonts": "Bundled unmodified Libertinus7.051/OFL1.1; system and embedded fonts disabled", + "gzip_decoded_materialization_sha256": "8a1da525d23d21bd19b5c47b96aa1be479aa412bc13f3e0aebaf485dd55ac334", + "isolated_reproduced_pdf_sha256": "c87adf29a508a5428bf351067d1a63d0ad23cb0b2632483e9dabd4763f1ad443", + "isolated_tree_files": 37, + "main_pdf_sha256": "c87adf29a508a5428bf351067d1a63d0ad23cb0b2632483e9dabd4763f1ad443", + "main_typst_sha256": "c92260703b39819d8566d55d1f8b37c8c76f56fa542e067ab75016a14669f490", + "manifest_sha256": "70e31a6b28f2ca1c9d6f510ab5a375e750a253f68b4fd1cec721747c74bcc56c", + "native_reads": 0, + "observed_utc": "2026-10-22T18:28:42.647221+00:00", + "pages": 15, + "physics_compiler_calls": 0, + "relocation": { + "archive_authority_git_objects_verified": 29, + "archive_preparation_metadata_git_objects_verified": 24, + "archive_revision": "19d67c8605337c176680878a521b3a014176a7fb", + "changed_pdf_text_pages": [ + 15 + ], + "new_report_root": "doc/benchmarkfolder", + "old_report_root": "docs/benchmarkfolder", + "original_pdf_sha256": "076b136ae99083f8111e7d35489d45b7b00ad2383b44e3177b30c14c31ad3869", + "prior_reproduction_url": "https://github.com/MadGraphTeam/MadGraph7/blob/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/final-report-v1/reproduction.json", + "scientific_data_and_figure_bytes_unchanged": true + }, + "report_data_sha256": "bc42cc02076418eeba4b188de167575196f86139bc9c8b463349d2e766011e9c", + "reproduced_pdf_sha256": "c87adf29a508a5428bf351067d1a63d0ad23cb0b2632483e9dabd4763f1ad443", + "schema": "final-benchmark-offline-reproduction-v1", + "scope": "Report relocation and document reproduction only; no new scientific measurement, statistical inference, native custody verification or physics compilation", + "source_date_epoch": 1792627200, + "standalone_svg_byte_identity_claimed": false, + "typst_version": "typst 0.15.1 (9dfd3a08)", + "verified_input_files": 36, + "visual_review": "Changed page15 inspected: reproduction/archive wording is readable, no clipping or overlap; text on pages1\u201314 is unchanged from the approved prior report." +} diff --git a/doc/benchmarkfolder/final-report-v1/stability/combined-loop-induced.svg b/doc/benchmarkfolder/final-report-v1/stability/combined-loop-induced.svg new file mode 100644 index 0000000000..3b682e2a27 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/combined-loop-induced.svg @@ -0,0 +1,2401 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + g + g + H + → +   + ( + l + o + o + p +   + i + n + d + u + c + e + d + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + on-shell boosted frames; one physical + invariant; Ecm=125 GeV; seed=20261029 + no final-state cuts + single all-minus helicity; tuple (-1, -1, + 0); index 1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + g + g + H + H + → +   + ( + l + o + o + p +   + i + n + d + u + c + e + d + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261030 + cuts: ΔR > 0.5 + single all-minus helicity; tuple (-1, -1, + 0, 0); index 1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · direction + Lorentz transformation + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/combined-on-shell.svg b/doc/benchmarkfolder/final-report-v1/stability/combined-on-shell.svg new file mode 100644 index 0000000000..60141888c4 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/combined-on-shell.svg @@ -0,0 +1,2094 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + u + u + Z + ̄ + → +   + ( + Q + C + D + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + on-shell boosted frames; one physical + invariant; Ecm=91.188 GeV; seed=20261021 + no final-state cuts + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + u + d + W + ̄ + → + + +   + ( + E + W + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + on-shell boosted frames; one physical + invariant; Ecm=80.419 GeV; seed=20261022 + no final-state cuts + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · direction + Lorentz transformation + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/combined-three-particle.svg b/doc/benchmarkfolder/final-report-v1/stability/combined-three-particle.svg new file mode 100644 index 0000000000..451075b3c6 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/combined-three-particle.svg @@ -0,0 +1,2615 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + u + u + Z + g + g + ̄ + → +   + ( + Q + C + D + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261025 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + e + e + t + t + γ + + + − + → + ̄ +   + ( + E + W + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261026 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · direction + Lorentz transformation + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/combined-two-particle.svg b/doc/benchmarkfolder/final-report-v1/stability/combined-two-particle.svg new file mode 100644 index 0000000000..c21a43d3a5 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/combined-two-particle.svg @@ -0,0 +1,2285 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + g + g + t + t + → + ̄ +   + ( + Q + C + D + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261023 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + e + e + μ + μ + + + − + + + − + → +   + ( + E + W + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261024 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · direction + Lorentz transformation + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/direction-loop-induced.svg b/doc/benchmarkfolder/final-report-v1/stability/direction-loop-induced.svg new file mode 100644 index 0000000000..2faae34725 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/direction-loop-induced.svg @@ -0,0 +1,2279 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + g + g + H + → +   + ( + l + o + o + p +   + i + n + d + u + c + e + d + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 5 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + on-shell boosted frames; one physical + invariant; Ecm=125 GeV; seed=20261029 + no final-state cuts + single all-minus helicity; tuple (-1, -1, + 0); index 1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + g + g + H + H + → +   + ( + l + o + o + p +   + i + n + d + u + c + e + d + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261030 + cuts: ΔR > 0.5 + single all-minus helicity; tuple (-1, -1, + 0, 0); index 1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · loop-direction reversal + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/direction-on-shell.svg b/doc/benchmarkfolder/final-report-v1/stability/direction-on-shell.svg new file mode 100644 index 0000000000..18c6511502 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/direction-on-shell.svg @@ -0,0 +1,1910 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + u + u + Z + ̄ + → +   + ( + Q + C + D + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + on-shell boosted frames; one physical + invariant; Ecm=91.188 GeV; seed=20261021 + no final-state cuts + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + u + d + W + ̄ + → + + +   + ( + E + W + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + on-shell boosted frames; one physical + invariant; Ecm=80.419 GeV; seed=20261022 + no final-state cuts + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · loop-direction reversal + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/direction-three-particle.svg b/doc/benchmarkfolder/final-report-v1/stability/direction-three-particle.svg new file mode 100644 index 0000000000..21f79650f2 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/direction-three-particle.svg @@ -0,0 +1,2564 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + u + u + Z + g + g + ̄ + → +   + ( + Q + C + D + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261025 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + e + e + t + t + γ + + + − + → + ̄ +   + ( + E + W + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261026 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · loop-direction reversal + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/direction-two-particle.svg b/doc/benchmarkfolder/final-report-v1/stability/direction-two-particle.svg new file mode 100644 index 0000000000..1c4cb25e04 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/direction-two-particle.svg @@ -0,0 +1,2016 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + g + g + t + t + → + ̄ +   + ( + Q + C + D + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261023 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + e + e + μ + μ + + + − + + + − + → +   + ( + E + W + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261024 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · loop-direction reversal + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/lorentz-loop-induced.svg b/doc/benchmarkfolder/final-report-v1/stability/lorentz-loop-induced.svg new file mode 100644 index 0000000000..0361f098ee --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/lorentz-loop-induced.svg @@ -0,0 +1,2237 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + g + g + H + → +   + ( + l + o + o + p +   + i + n + d + u + c + e + d + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + on-shell boosted frames; one physical + invariant; Ecm=125 GeV; seed=20261029 + no final-state cuts + single all-minus helicity; tuple (-1, -1, + 0); index 1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + g + g + H + H + → +   + ( + l + o + o + p +   + i + n + d + u + c + e + d + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261030 + cuts: ΔR > 0.5 + single all-minus helicity; tuple (-1, -1, + 0, 0); index 1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · Lorentz transformation + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/lorentz-on-shell.svg b/doc/benchmarkfolder/final-report-v1/stability/lorentz-on-shell.svg new file mode 100644 index 0000000000..ccf925c418 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/lorentz-on-shell.svg @@ -0,0 +1,1710 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + u + u + Z + ̄ + → +   + ( + Q + C + D + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + on-shell boosted frames; one physical + invariant; Ecm=91.188 GeV; seed=20261021 + no final-state cuts + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + u + d + W + ̄ + → + + +   + ( + E + W + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + on-shell boosted frames; one physical + invariant; Ecm=80.419 GeV; seed=20261022 + no final-state cuts + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · Lorentz transformation + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/lorentz-three-particle.svg b/doc/benchmarkfolder/final-report-v1/stability/lorentz-three-particle.svg new file mode 100644 index 0000000000..3ee04f3f5e --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/lorentz-three-particle.svg @@ -0,0 +1,2514 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + u + u + Z + g + g + ̄ + → +   + ( + Q + C + D + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261025 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + e + e + t + t + γ + + + − + → + ̄ +   + ( + E + W + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261026 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · Lorentz transformation + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/stability/lorentz-two-particle.svg b/doc/benchmarkfolder/final-report-v1/stability/lorentz-two-particle.svg new file mode 100644 index 0000000000..d9d0e11607 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/stability/lorentz-two-particle.svg @@ -0,0 +1,1972 @@ + + + + + + + + image/svg+xml + + + MadLoop NinjaRS actual lightweight DP study + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + g + g + t + t + → + ̄ +   + ( + Q + C + D + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 2 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261023 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fraction with spread > Δ + + + + + + + + + + + + + + + + + + + + + + e + e + μ + μ + + + − + + + − + → +   + ( + E + W + ) + + + + + + + + + + + + + + + Ninja + + + + + + NinjaRS + + + + + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 5 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 1 + 2 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 9 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 6 + + + + + + + + + + + + + + + + + + 1 + 0 + − + 3 + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + + + + + + relative spread threshold Δ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + 1 + + + + NRS / Ninja + + + + + + + + + + + + + + + + + + + + + massive RAMBO proposal, not uniform massive + phase space; Ecm=1000 GeV; seed=20261024 + cuts: pT > 50 GeV; ΔR > 0.5 + full helicity/color sum; selector -1 + Ninja: N=100; 0 failed/unbounded + NinjaRS: N=100; 0 failed/unbounded + + + + Unrecovered native double precision · Lorentz transformation + + + All N=100 observations; resolution 1%. Hollow triangles: zero events, one-sided 95% upper reference 2.95%. + Ninja-zero tail ratios are undefined/unbounded gaps; no epsilon or smoothing. + Self-consistency estimates do not measure error against a finite-part oracle. + + + + + + + + + + + + + + + + + diff --git a/doc/benchmarkfolder/final-report-v1/style.typ b/doc/benchmarkfolder/final-report-v1/style.typ new file mode 100644 index 0000000000..785cea41f8 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/style.typ @@ -0,0 +1,85 @@ +// Style adapted from NinjaRS ca1009e; all data/claims below are ours. +#let data=json("report-data.json") +#let two-tool-style(body)={ +set document(title: "MadLoop: Ninja and NinjaRS", author: "MadLoop–NinjaRS development") +set page( + paper: "a4", + margin: (x: 1.6cm, y: 1.8cm), + numbering: "1", + header: context { + if counter(page).get().first() > 1 [ + #set text(8pt, fill: luma(110)) + MadLoop Ninja / NinjaRS #h(1fr) #data.date + ] + }, +) +set text(font: "Libertinus Serif", size: 10.5pt, lang: "en") +show math.equation: set text(font: "Libertinus Math") +set par(justify: true, leading: 0.62em) +set heading(numbering: "1.1") +show heading.where(level: 1): it => { + v(0.6em) + block(text(14pt, fill: rgb("#1f3b63"), it)) + v(0.2em) +} +show heading.where(level: 2): it => block(text(11.5pt, fill: rgb("#1f3b63"), it)) +show raw: set text(font: "Libertinus Mono", size: 8.5pt) +show link: set text(fill: rgb("#1f5fa8")) +show figure.where(kind: table): set block(breakable: true) +show figure.where(kind: table): set figure.caption(position: top) + + +body +} +// ---------------------------------------------------------------- helpers -- + +#let navy = rgb("#1f3b63") +#let pale = rgb("#eef3f9") +#let is-num(x) = type(x) == int or type(x) == float + +// Fixed-decimal formatting (keeps trailing zeros: 0.30, 1.05). +#let fixed(x, d) = { + let s = str(calc.round(x, digits: d)) + if d == 0 { return s } + let parts = s.split(".") + let frac = if parts.len() > 1 { parts.at(1) } else { "" } + parts.at(0) + "." + frac + "0" * (d - frac.len()) +} + +// Significant-figure formatting suited to timings. +#let fmt(x) = { + if not is-num(x) { return [—] } + let a = calc.abs(x) + let d = if a >= 100 { 0 } else if a >= 10 { 1 } else if a >= 1 { 2 } else { 3 } + let s = fixed(x, d) + if a >= 10000 { + // thin-space thousands separator + let int-part = str(int(calc.round(x))) + let groups = () + let rest = int-part + while rest.len() > 3 { + groups.insert(0, rest.slice(rest.len() - 3)) + rest = rest.slice(0, rest.len() - 3) + } + groups.insert(0, rest) + s = groups.join(sym.space.thin) + } + s +} + +#let ratio(a, b) = if is-num(a) and is-num(b) and b != 0 { a / b } else { none } + +// Diverging palette: green (NinjaRS faster) — white (parity) — red (slower). +#let palette = gradient.linear( + rgb("#5aae61"), rgb("#d9f0d3"), rgb("#ffffff"), rgb("#fddbc7"), rgb("#d6604d"), +) +#let ratio-fill(r) = { + if r == none { return none } + // log2 scale: ×1/4 → 0 %, ×1 → 50 %, ×4 → 100 % + let t = calc.clamp(0.5 + calc.log(r, base: 2) / 4, 0, 1) + palette.sample(t * 100%) +} +#let ratio-cell(r) = table.cell( + fill: ratio-fill(r), + if r == none { [—] } else { text(weight: "semibold")[×#fmt(r)] }, +) diff --git a/doc/benchmarkfolder/final-report-v1/timing.svg b/doc/benchmarkfolder/final-report-v1/timing.svg new file mode 100644 index 0000000000..3e0cb68135 --- /dev/null +++ b/doc/benchmarkfolder/final-report-v1/timing.svg @@ -0,0 +1,4434 @@ + + + + + + + + image/svg+xml + + + Matplotlib final report source + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/loop-pole-selection.md b/doc/loop-pole-selection.md new file mode 100644 index 0000000000..15ae915bb8 --- /dev/null +++ b/doc/loop-pole-selection.md @@ -0,0 +1,145 @@ +# Selecting UV and IR poles in MadLoop + +`LoopPoleMode` selects the ultraviolet (UV) and infrared (IR) poles of the +bare loop contribution computed by NinjaRS or COLLIER. It leaves finite +coefficients, rational terms, and model counterterms unchanged. + +After pulling this MadGraph version, update an existing NinjaRS installation +from the MG7 prompt: + +```text +install ninjars --update +``` + +The selector requires bridge ABI 4. Older ABI-3 installations are rejected +before export/linking, with instructions to update. Generate a new process +output to obtain the corresponding Fortran interface and card option. + +## Parameter card + +For UV poles with NinjaRS followed by COLLIER as a rescue backend, set these +entries in the generated process's `Cards/MadLoopParams.dat`: + +```text +#MLReductionLib +8|7 + +#LoopPoleMode +1 +``` + +| `LoopPoleMode` | Loop poles returned | +| --- | --- | +| `-1` (default) | Existing backend behavior: combined poles for NinjaRS; the two legacy COLLIER switches for COLLIER. | +| `0` | Both UV and IR poles. | +| `1` | UV poles only. | +| `2` | IR poles only, including the double pole. | +| `3` | No poles; finite coefficients are still returned. | + +An explicit mode (`0`–`3`) overrides `COLLIERComputeUVpoles` and +`COLLIERComputeIRpoles`. Modes `1`–`3` require every entry in `MLReductionLib`, +including rescue backends, to be NinjaRS (`8`) or COLLIER (`7`). For example, +`8|6|7|1` is rejected in these modes because Ninja and CutTools cannot preserve +the selected pole origin during rescue. Use `8`, `7`, or an ordered combination +of the two available backends. + +## Calling from Fortran + +Generated optimized processes also expose the process-prefixed +`SET_LOOP_POLE_MODE(MODE)` routine. If the matrix routine is named +`ML5_0_SLOOPMATRIX`, the setter is: + +```fortran + CALL ML5_0_SET_LOOP_POLE_MODE(1) +``` + +Call it before evaluating the desired sample. It accepts the same five card +values and preserves the requested choice through MadLoop initialization. +Use the prefix of an actual generated subprocess. The choice is global within +a shared MadLoop library: the most recent setter call applies to every +subprocess, including when another subprocess performs the first evaluation. +Call it with `0` to restore combined poles or `-1` to restore the legacy backend +policy. The reduction and rescue list must still satisfy the selected mode's +requirements. + +## Interpretation and cost + +The selector acts on loop-integral poles before the reduced coefficients are +contracted. In particular, a scaleless bubble has cancelling UV and IR +single-pole residues that must be retained separately. MadLoop forwards the +selection through NinjaRS's public master-provider API to oneloopmaster, +which computes the selected residues. The MadLoop bridge contains no separate +UV/IR residue formulas. +UV-only and IR-only evaluations use the generic NinjaRS engine in double +precision and in higher-precision rescue so that scaleless-bubble coefficients +are retained. These modes share the Symbolica worker and licensing requirements +of higher-precision rescue. A UV-only or IR-only retry through the compensated-DP entry also +uses this generic DP engine; the fast-engine compensated numerator callback +does not apply. Higher-precision rescue remains available. Combined and +no-pole double-precision evaluations retain the fast reduction engine. + +All explicit modes (`0`–`3`) bypass MadLoop's helicity and loop-filter decisions, +including previously learned filters. This prevents filters trained on +combined poles from discarding contributions whose separate UV and IR poles +are nonzero. The default `-1` retains the usual filtering policy. These +diagnostic choices can therefore increase numerator and reduction costs, +including for explicit mode `0` compared with the default combined-pole run. + +For the bare loop amplitude's pole residues, UV plus IR reconstructs the +combined single pole; the double pole is IR. This statement concerns the pole +coefficients, not a sum of the finite coefficients, which each mode retains. +Standard MadLoop outputs can additionally contain model counterterms; this +option does not split their UV and IR origins or remove them. + +Loop-induced outputs involve squaring the loop amplitude. Squaring introduces +interference between its components, so UV-only and IR-only **squared outputs +are not generally additive**. Check pole reconstruction at amplitude level, +and compare NinjaRS and COLLIER using identical modes, inputs, and stability +settings. + +## Validation + +The independent [COLLIER comparison](../vendor/ninjars/tests/poles/README.md) +covers 455 tensor components through rank four, including scaleless bubbles, +complex masses, and UV-divergent tensor triangles and boxes. All UV-only and IR-only DP +results and all higher-precision modes agree with COLLIER at the documented +tolerance. Repeated mode changes reproduce fresh results. Ordinary fast-DP +diagnostics are recorded separately and reproduce the pre-feature library. + +The following processes were also generated with the actual MadGraph CLI and +compared at three fixed points each, including all returned split-order rows: + +| Process | Model | Precision checks | +| --- | --- | --- | +| `u u~ > z [virt=QCD]` | `loop_sm` | Forced DP/QP and automatic stability checks | +| `g g > t t~ [virt=QCD]` | `loop_sm` | Forced DP/QP and automatic stability checks | +| `e+ e- > mu+ mu- [virt=QED]` | `loop_qcd_qed_sm_Gmu` | Forced DP/QP | +| `g g > h [sqrvirt=QCD]` | `loop_sm` | Forced DP/QP | + +All four selectors agree with COLLIER. The automatic QCD runs accept these +points in DP; forced QP runs exercise the higher-precision path. These comparisons isolate the bare loop +by clearing UFO UV/R2 counterterm slots only in disposable generated validation +copies. They leave the production numerator and reduction code intact. Tests +also cycle the selector after loading learned filters. The loop-induced check +compares each mode between backends; it does not assume additivity of squared +outputs. The [retained receipt](../vendor/ninjars/tests/poles/madloop-validation.json) +records the precise run matrix, inputs and tolerances. + +The unchanged Python/Fortran layer passed 107 regression tests. Against the +updated dependency pins, the bridge passed 31 ordinary Rust tests. Seven +pre-existing opt-in Rust diagnostics remain excluded. The real CLI `install ninjars --update` passed its compiled DP/QP +smoke check, including a binary128 perturbation below DP resolution. Its +production archive contains no test-only floating-point mutators. +A compiled two-subprocess regression checks that the latest global selector +survives the first card read and subsequent runtime changes. The unchanged +Fortran/export layer was additionally qualified before this dependency update +with nine export IO tests and a generated shared library containing both +`u u~ > z` and `d d~ > z`: 40 amplitude evaluations passed with NinjaRS and +COLLIER. The [upstream migration receipt](../vendor/ninjars/tests/poles/upstream-migration-validation.json) +records the published revisions and the new native qualification separately. +The Python/Fortran regression modules can be run with: + +```sh +python3 -B -m unittest discover -s tests/unit_tests -p 'test_ninjars*.py' +python3 -B -m unittest tests.unit_tests.loop.test_loop_poles +``` diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 462acbdf6a..f45ebd630c 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -13,3 +13,80 @@ Python 3.12 or higher and a C++ compiler are required. The ``madspace`` library installed automatically the first time you launch a run. To build it yourself instead, run ``install madspace`` from the MadGraph7 prompt, or see the :doc:`MadSpace installation instructions `. + +NinjaRS for MadLoop +------------------ + +The optional NinjaRS reduction backend uses oneloopmaster for scalar integrals. +From the MadGraph7 prompt, run:: + + install ninjars + +The installer builds the pinned sources in ``vendor/ninjars/Cargo.lock``, tests +the installed Fortran interface in double and quadruple precision, and saves the +``ninjars`` library path. It requires Rust/Cargo 1.96 or later, GNU make, C/C++ +compilers, GNU Fortran on Linux, and the GMP/MPFR numerical build dependencies. +The Fortran compiler must support ``REAL(16)``. The repository's pinned Nix +development shell provides these tools. + +Select NinjaRS in the generated ``Cards/MadLoopParams.dat``:: + + #MLReductionLib + 8 + +The existing default reduction order is retained. A chain such as ``8|6|1`` +also permits Ninja and CutTools fallback. ``UseQPIntegrandForNinjaRS`` controls +whether the NinjaRS high-precision rescue receives a numerator recomputed in +quadruple precision. The CLI checks accept ``--reduction=8``. + +High-precision rescue uses Symbolica and follows its licensing requirements. +Symbolica's restricted mode permits one active Symbolica thread per user across +all processes. NinjaRS shares one rescue worker among its contexts within each +process and retains it until MadLoop exits. Concurrent MadGraph processes that +use rescue therefore require a Symbolica license covering their active workers, +or must run sequentially. Upstream license/permit failures can terminate a +process before MadLoop can try another backend. If ``SYMBOLICA_LOCK_DIR`` is set, +use the same directory for all processes belonging to the user. + +For local development, supply source checkouts explicitly:: + + install ninjars --source=/path/to/ninjars --oneloop-source=/path/to/oneloopmaster --jobs=4 --force + +These sources are copied into an isolated build directory; the original +checkouts are left untouched. ``--force`` replaces an existing installation +only after the new one passes both precision checks. The default destination is +``HEPTools/ninjars``; ``--prefix`` or ``heptools_install_dir`` selects another +HEPTools prefix. Build failures retain their log in the reported staging +directory. A successful installation retains its build log and exact Cargo +manifest and lockfile. Cargo target and intermediate build caches are kept +under the installation prefix; explicit ``CARGO_TARGET_DIR`` and +``CARGO_BUILD_BUILD_DIR`` settings are respected. +The installation includes ``include/mninjars.f90`` and ``include/ninjars.h`` +alongside the compiled Fortran module in ``lib``. + +Both standalone Fortran and aMC@NLO exports support NinjaRS. With +``set output_dependencies internal``, the exporter copies its archive, Fortran +module, available interface sources and link metadata into the output directory. +The generated makefiles still require the target platform's native +compiler/runtime libraries. + +The linker must resolve GNU Fortran's arithmetic helpers before loading the +Rust static archive. Otherwise Rust's compiler builtins can replace the +``REAL(16)`` helpers and change directed IEEE rounding. Generated standalone +and aMC@NLO makefiles enforce this ordering using ``ninjars-config.json``. +The installer also checks directed quadruple-precision rounding. An older +installation without this link-order metadata must be rebuilt with +``install ninjars --force``, followed by regeneration or relinking of its +generated processes. + +For a manual Fortran link, use both installed flag files in this order:: + + gfortran caller.f90 -I"$PREFIX/lib" \ + $(cat "$PREFIX/lib/ninjars-link-before.txt") \ + "$PREFIX/lib/libninjars.a" \ + $(cat "$PREFIX/lib/ninjars-native-libs.txt") -o caller + +Here ``PREFIX`` is the NinjaRS installation directory, usually +``HEPTools/ninjars``. The current validated compiler-runtime policy is +GNU Fortran on Linux and places ``-lgcc_s`` before the archive. Additional +platforms require validation of their compiler-runtime resolution. diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000000..0e65db32a5 --- /dev/null +++ b/flake.lock @@ -0,0 +1,50 @@ +{ + "nodes": { + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": [] + }, + "locked": { + "lastModified": 1789298866, + "narHash": "sha256-6eaV5+MdWy1tAlN4HAFr64pTnYc9jiKGXBsu18cyVjE=", + "owner": "nix-community", + "repo": "fenix", + "rev": "1fc6f36a23fa16e3740987957266f6e4b915c3cd", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "rev": "1fc6f36a23fa16e3740987957266f6e4b915c3cd", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1789264731, + "narHash": "sha256-llGJbC0CcU8DfROr6mZjRJgMLQd/SKwfpzxJH/2lHO4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "02f5696b0e6097e589076d886b317b83ff0437d7", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "02f5696b0e6097e589076d886b317b83ff0437d7", + "type": "github" + } + }, + "root": { + "inputs": { + "fenix": "fenix", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000000..005044b4e7 --- /dev/null +++ b/flake.nix @@ -0,0 +1,34 @@ +{ + description = "MadLoop NinjaRS integration and reproducible benchmarks"; + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/02f5696b0e6097e589076d886b317b83ff0437d7"; + fenix.url = "github:nix-community/fenix/1fc6f36a23fa16e3740987957266f6e4b915c3cd"; + fenix.inputs.nixpkgs.follows = "nixpkgs"; + fenix.inputs.rust-analyzer-src.follows = ""; + }; + outputs = { nixpkgs, fenix, ... }: let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + rust = fenix.packages.${system}.stable.withComponents [ + "cargo" "rustc" "rust-std" "rustfmt" "clippy" + ]; + in { + devShells.${system}.default = pkgs.mkShell { + packages = [ rust ] ++ (with pkgs; [ + gcc gfortran gnumake cmake pkg-config gmp mpfr libmpc + autoconf automake libtool perl m4 git gh curl wget + typst poppler-utils libertinus dejavu_fonts util-linux + (python3.withPackages (ps: with ps; [ + six numpy scipy matplotlib pytest psutil + ])) + ]); + RUST_BACKTRACE = "1"; + RUST_MIN_STACK = "134217728"; + OMP_NUM_THREADS = "1"; + OPENBLAS_NUM_THREADS = "1"; + shellHook = '' + export TYPST_FONT_PATHS="${pkgs.libertinus}/share/fonts:${pkgs.dejavu_fonts}/share/fonts" + ''; + }; + }; +} diff --git a/input/.mg7_configuration_default.txt b/input/.mg7_configuration_default.txt index 2e2696e4cd..cd792ea1fb 100644 --- a/input/.mg7_configuration_default.txt +++ b/input/.mg7_configuration_default.txt @@ -236,6 +236,11 @@ #! if ninja=/PATH/TO/ninja/lib: use that specific installation path for ninja # ninja = ./HEPTools/lib +#! NinjaRS reduction library (MLReductionLib = 8). +#! Install with 'install ninjars'; set to None to disable. +#! The directory must contain libninjars.a and ninjars-config.json. +# ninjars = None + #! Set the COLLIER directory containing COLLIER's library #! if '' or None: disabling COLLIER #! if ninja=/PATH/TO/ninja/lib: use that specific installation path for COLLIER diff --git a/madgraph/interface/amcatnlo_run_interface.py b/madgraph/interface/amcatnlo_run_interface.py index 34d85162b8..0f6b87851f 100755 --- a/madgraph/interface/amcatnlo_run_interface.py +++ b/madgraph/interface/amcatnlo_run_interface.py @@ -3509,23 +3509,18 @@ def safe_float(str_float): r"Unknown return code \(100\)\:\s+(?P\d+).*"+\ r"Unknown return code \(10\)\:\s+(?P\d+).*",re.DOTALL) - unit_code_meaning = { 0 : 'Not identified (CTModeRun != -1)', - 1 : 'CutTools (double precision)', - 2 : 'PJFry++', - 3 : 'IREGI', - 4 : 'Golem95', - 5 : 'Samurai', - 6 : 'Ninja (double precision)', - 7 : 'COLLIER', - 8 : 'Ninja (quadruple precision)', - 9 : 'CutTools (quadruple precision)'} RetUnit_finder =re.compile( r"#Unit\s*(?P\d+)\s*=\s*(?P\d+)") + ninjars_finder = re.compile(r"#NinjaRS\s+(DP|QP)\s*=\s*(\d+)") + ninjars_usage = {'DP': 0, 'QP': 0} #Unit for gv_log in log_GV_files: channel_name = '/'.join(gv_log.split('/')[-5:-1]) - log=open(gv_log,'r').read() + with open(gv_log, 'r') as stream: + log = stream.read() + for precision, count in ninjars_finder.findall(log): + ninjars_usage[precision] += int(count) UPS_stats = re.search(UPS_stat_finder,log) for retunit_stats in re.finditer(RetUnit_finder, log): if channel_name not in list(stats['UPS'].keys()): @@ -3565,6 +3560,8 @@ def safe_float(str_float): nTot10 = sum([chan[9] for chan in stats['UPS'].values()],0) nTot1 = [sum([chan[10][i] for chan in stats['UPS'].values()],0) \ for i in range(10)] + backend_usage = sum_html.decode_madloop_backend_usage( + nTot1, ninjars_usage['DP'], ninjars_usage['QP']) UPSfracs = [(chan[0] , 0.0 if chan[1][0]==0 else \ safe_float(chan[1][4]*100)/chan[1][0]) for chan in stats['UPS'].items()] maxUPS = max(UPSfracs, key = lambda w: w[1]) @@ -3579,19 +3576,15 @@ def safe_float(str_float): tmpStr += '\n Quadruple precision used: %d'%nTotqdp tmpStr += '\n Initialization phase-space points: %d'%nTotini tmpStr += '\n Reduction methods used:' - red_methods = [(unit_code_meaning[i],nTot1[i]) for i in \ - unit_code_meaning.keys() if nTot1[i]>0] + red_methods = [(sum_html.MADLOOP_BACKEND_LABELS[backend], count) + for backend, count in backend_usage.items() + if count > 0] for method, n in sorted(red_methods, key= lambda l: l[1], reverse=True): tmpStr += '\n > %s%s%s'%(method,' '*(33-len(method)),n) if nTot100 != 0: debug_msg += '\n Unknown return code (100): %d'%nTot100 if nTot10 != 0: debug_msg += '\n Unknown return code (10): %d'%nTot10 - nUnknownUnit = sum(nTot1[u] for u in range(10) if u \ - not in list(unit_code_meaning.keys())) - if nUnknownUnit != 0: - debug_msg += '\n Unknown return code (1): %d'\ - %nUnknownUnit if maxUPS[1]>0.001: message += tmpStr diff --git a/madgraph/interface/loop_interface.py b/madgraph/interface/loop_interface.py index 0f4870789d..158667e226 100755 --- a/madgraph/interface/loop_interface.py +++ b/madgraph/interface/loop_interface.py @@ -555,7 +555,10 @@ def install_reduction_library(self, force=False): opt = self.options # Check if first time: - if not force and ((opt['ninja'] is None) or (os.path.isfile(pjoin(MG5DIR, opt['ninja'],'libninja.a')))): + ninjars_ready = isinstance(opt.get('ninjars'), str) and os.path.isfile( + pjoin(MG5DIR, opt['ninjars'], 'libninjars.a')) + if not force and ((opt['ninja'] is None) or ninjars_ready or + os.path.isfile(pjoin(MG5DIR, opt['ninja'], 'libninja.a'))): return # do not trigger the question for tests @@ -982,7 +985,7 @@ class AskLoopInstaller(cmd.OneLinePathCompletion): local_installer = ['ninja', 'collier'] required = ['cuttools', 'iregi'] - order = ['cuttools', 'iregi', 'ninja', 'collier', 'golem'] + order = ['cuttools', 'iregi', 'ninja', 'collier', 'golem', 'ninjars'] bypassed = ['pjfry'] @property @@ -1002,6 +1005,7 @@ def __init__(self, question, *args, **opts): self.code = {'ninja': 'install', 'collier': 'install', + 'ninjars': 'off', 'golem': 'off', 'cuttools': 'required', 'iregi': 'required'} @@ -1031,6 +1035,8 @@ def __init__(self, question, *args, **opts): self.code['golem'] = pjoin(install_dir2, 'golem95') if os.path.exists(pjoin(install_dir1, 'ninja')): self.code['ninja'] = pjoin(install_dir2, 'ninja','lib') + if os.path.isfile(pjoin(install_dir1, 'ninjars', 'lib', 'libninjars.a')): + self.code['ninjars'] = pjoin(install_dir1, 'ninjars', 'lib') # 1. create the question question, allowed_answer = self.create_question(first=True) @@ -1052,6 +1058,7 @@ def create_question(self, first = False): descript = {'cuttools': ['cuttools','(OPP)','[0711.3596]'], 'iregi': ['iregi','(TIR)','[1405.0301]'], 'ninja': ['ninja','(OPP)','[1403.1229]'], + 'ninjars': ['ninjars','(OPP)','[NinjaRS]'], 'golem': ['golem','(TIR)','[0807.0605]'], 'collier': ['collier','(TIR)','[1604.06792]']} @@ -1169,6 +1176,7 @@ def apply_name(self, name, line): do_ninja = lambda self,line : self.apply_name('ninja', line) + do_ninjars = lambda self,line : self.apply_name('ninjars', line) do_collier = lambda self,line : self.apply_name('collier', line) do_golem = lambda self,line : self.apply_name('golem', line) do_cuttools = lambda self,line : self.apply_name('cuttools', line) @@ -1189,6 +1197,7 @@ def complete_prog(self, text, line, begidx, endidx, formatting=True): return self.list_completion(text, ['install', 'noinstall', 'local'], line) complete_ninja = complete_prog + complete_ninjars = complete_prog complete_collier = complete_prog complete_golem = complete_prog complete_cuttools = complete_prog diff --git a/madgraph/interface/madevent_interface.py b/madgraph/interface/madevent_interface.py index 3d119549aa..95aa8dfa71 100755 --- a/madgraph/interface/madevent_interface.py +++ b/madgraph/interface/madevent_interface.py @@ -3512,7 +3512,7 @@ def do_treatcards(self, line, mode=None, opt=None): # when running in multi-core with a central disk. So it is turned # off here. If these filters were not initialized then they will # have to be re-computed at the beginning of each run. - if 'WriteOutFilters' in self.MadLoopparam.user_set and \ + if 'writeoutfilters' in self.MadLoopparam.user_set and \ self.MadLoopparam.get('WriteOutFilters'): logger.info( """You chose to have MadLoop writing out filters. @@ -3558,18 +3558,16 @@ def do_treatcards(self, line, mode=None, opt=None): else: run_card = self.run_card if run_card['nhel'] == 0: - if 'MLReductionLib' in self.MadLoopparam.user_set and \ - (self.MadLoopparam.get('MLReductionLib').startswith('1') or - self.MadLoopparam.get('MLReductionLib').startswith('6')): + if 'mlreductionlib' in self.MadLoopparam.user_set and \ + self.MadLoopparam.get('MLReductionLib').startswith(('1', '6', '8')): logger.warning( """You chose to set the preferred reduction technique in MadLoop to be OPP (see parameter MLReductionLib). Beware that this can bring significant slowdown; the optimal choice --when not MC over helicity-- being to first start with TIR reduction.""") # We do not include GOLEM for now since it cannot recycle TIR coefs yet. self.MadLoopparam.set('MLReductionLib','7|6|1', changeifuserset=False) else: - if 'MLReductionLib' in self.MadLoopparam.user_set and \ - not (self.MadLoopparam.get('MLReductionLib').startswith('1') or - self.MadLoopparam.get('MLReductionLib').startswith('6')): + if 'mlreductionlib' in self.MadLoopparam.user_set and \ + not self.MadLoopparam.get('MLReductionLib').startswith(('1', '6', '8')): logger.warning( """You chose to set the preferred reduction technique in MadLoop to be different than OPP (see parameter MLReductionLib). Beware that this can bring significant slowdown; the optimal choice --when MC over helicity-- being to first start with OPP reduction.""") @@ -3580,9 +3578,9 @@ def do_treatcards(self, line, mode=None, opt=None): # to zero when not MC-ing over helicities, unless the parameter # Force_ML_Helicity_Sum is set to True in the matrix.f codes. if run_card['nhel'] == 0: - if ('NRotations_DP' in self.MadLoopparam.user_set and \ + if ('nrotations_dp' in self.MadLoopparam.user_set and \ self.MadLoopparam.get('NRotations_DP')!=0) or \ - ('NRotations_QP' in self.MadLoopparam.user_set and \ + ('nrotations_qp' in self.MadLoopparam.user_set and \ self.MadLoopparam.get('NRotations_QP')!=0): logger.warning( """You chose to also use a lorentz rotation for stability tests (see parameter NRotations_[DP|QP]). @@ -3611,7 +3609,7 @@ def do_treatcards(self, line, mode=None, opt=None): # This is important for getting g g > z z [QCD] working with a # ptheavy cut as low as 1 GeV. if self.proc_characteristics['nexternal']<=4: - if ('MLStabThres' in self.MadLoopparam.user_set and \ + if ('mlstabthres' in self.MadLoopparam.user_set and \ self.MadLoopparam.get('MLStabThres')>1.0e-7): logger.warning( """You chose to increase the default value of the MadLoop parameter 'MLStabThres' above 1.0e-7. diff --git a/madgraph/interface/madgraph_interface.py b/madgraph/interface/madgraph_interface.py index a67e23d574..ed403530b9 100755 --- a/madgraph/interface/madgraph_interface.py +++ b/madgraph/interface/madgraph_interface.py @@ -623,6 +623,17 @@ def help_install(self): logger.info(" --no-debug Optimized build, no debug symbols, Release (source build, default).") logger.info(" --cuda-arch=ARCHS Semicolon-separated CUDA compute capabilities, e.g. 75;80;86.") logger.info(" --hip-arch=ARCHS Semicolon-separated HIP architectures, e.g. gfx900;gfx906.") + logger.info(" ") + logger.info(" \"install ninjars [options]\"",'$MG:BOLD') + logger.info(" Build the pinned NinjaRS/oneloopmaster Fortran interface (MLReductionLib=8).") + logger.info(" Requires Cargo/Rust >= 1.96, GNU make and a Fortran compiler with REAL(16).") + logger.info(" --source=DIR Use a local NinjaRS checkout (copied before building).") + logger.info(" --oneloop-source=DIR Use a local oneloopmaster checkout.") + logger.info(" --prefix=DIR Override the HEPTools installation prefix.") + logger.info(" -j N/--jobs=N Parallel compilation jobs (default: nb_core).") + logger.info(" --update Rebuild with this checkout's committed dependency pins (after git pull).") + logger.info(" Replace the installation after DP and QP smoke tests pass.") + logger.info(" --force Equivalent backward-compatible alias for --update.") def help_display(self): logger.info("syntax: display " + "|".join(self._display_opts),'$MG:color:BLUE') @@ -3804,7 +3815,7 @@ def _tutorial_opts(self): _install_opts = ['Delphes', 'ExRootAnalysis', 'update', 'Golem95', 'QCDLoop', 'maddm', 'maddump', 'looptools', 'cuttools_iregi', 'MadSTR', 'RunningCoupling', - 'madspace'] + 'madspace', 'ninjars'] # The targets below are installed using the HEPToolsInstaller.py script _advanced_install_opts = ['pythia8','zlib','boost','lhapdf6','lhapdf5','collier', @@ -3886,6 +3897,7 @@ def _tutorial_opts(self): 'golem':'auto', 'samurai':None, 'ninja':'./HEPTools/lib', + 'ninjars':None, 'collier':'./HEPTools/lib', 'dmtcp': None, 'lhapdf':'lhapdf-config', @@ -5310,6 +5322,8 @@ def create_lambda_values_list(lower_bound, N): self.set_color_basis_mode() args = self.split_arg(line) + automatic_reduction = (args and args[0] in ('timing', 'profile') and + not any(arg.startswith('--reduction=') for arg in args)) # Check args validity param_card = self.check_check(args) @@ -5721,6 +5735,11 @@ def create_lambda_values_list(lower_bound, N): language_result = [] precision_result = [] + if automatic_reduction and myprocdef and myprocdef.get('has_born'): + from madgraph.various import ninjars_install + MLoptions['MLReductionLib'] = ninjars_install.default_reduction_library( + myprocdef.get('has_born'), self.options.get('ninjars')) + if "_cuttools_dir" in dir(self): CT_dir = self._cuttools_dir else: @@ -5775,6 +5794,18 @@ def create_lambda_values_list(lower_bound, N): if 6 in MLoptions["MLReductionLib"]: logger_check.warning('Ninja not available on your system; it will be skipped.') MLoptions["MLReductionLib"].remove(6) + + if isinstance(self.options.get('ninjars'), str): + from madgraph.various import ninjars_install + TIR_dir['ninjars_dir'] = self.options['ninjars'] + if 8 in MLoptions.get('MLReductionLib', []) and not ninjars_install.is_available( + self.options['ninjars']): + raise self.InvalidCmd("NinjaRS is unavailable or unusable at %s. " + "Run 'install ninjars --update'." % + self.options['ninjars']) + elif 8 in MLoptions.get('MLReductionLib', []): + raise self.InvalidCmd("NinjaRS is disabled. Run 'install ninjars' " + "or set ninjars to its library directory.") if args[0] in ['timing']: timings = process_checks.check_timing(myprocdef, @@ -8568,6 +8599,22 @@ def do_install(self, line, paths=None, additional_options=[]): elif args[0] == 'looptools': self.install_reduction_library(force=True) return + elif args[0] == 'ninjars': + from madgraph.various import ninjars_install + prefix, config_file = self.heptools_install_target( + self.options['heptools_install_dir']) + libdir = ninjars_install.install( + MG5DIR, prefix, + arguments=install_options['options_for_HEPToolsInstaller'] + add_options, + fortran_compiler=self.options['fortran_compiler'], + jobs=self.options['nb_core']) + if libdir is not None: + self.options['ninjars'] = libdir + _, config_file = self.heptools_install_target( + os.path.dirname(os.path.dirname(libdir))) + self.exec_cmd('save options %s ninjars' % config_file, + printcmd=False, log=False) + return elif args[0] == 'cuttools_iregi': self.install_cuttools_iregi() return @@ -11513,12 +11560,12 @@ def set2_fastjet(self, args, log=True): def setup_path_for_options(self,name, args, log=True): - """Set the path for golem/samurai/ninja/collier options. + """Set the path for golem/samurai/ninja/ninjars/collier options. Example: set golem /PATH/TO/golem/lib or: set golem None """ args = [name] + args[:] - if not (args[0] in ['ninja','collier'] and args[1]=='./HEPTools/lib'): + if not (args[0] in ['ninja','ninjars','collier'] and args[1]=='./HEPTools/lib'): if args[1] in ['None',"''",'""']: self.options[args[0]] = None else: @@ -11541,6 +11588,7 @@ def setup_path_for_options(self,name, args, log=True): set2_golem = lambda self, *args, **opts : self.setup_path_for_options('golem' , *args, **opts) set2_samurai = lambda self, *args, **opts : self.setup_path_for_options('samurai' , *args, **opts) set2_ninja = lambda self, *args, **opts : self.setup_path_for_options('ninja' , *args, **opts) + set2_ninjars = lambda self, *args, **opts : self.setup_path_for_options('ninjars', *args, **opts) set2_collier = lambda self,*args, **opts : self.setup_path_for_options('collier' , *args, **opts) def set2_lhapdf(self, args, log=True): @@ -12285,7 +12333,7 @@ def do_set(self, line, log=True, model_reload=True): elif args[0] == 'fastjet': raise Exception('This option is now handled by a dedicated function.') # set_fastjet(args[1:], log=log) - elif args[0] in ['golem','samurai','ninja','collier']: + elif args[0] in ['golem','samurai','ninja','ninjars','collier']: raise Exception('This option is now handled by a dedicated function.') # setup_path_for_options(args, log=log) elif args[0].startswith('lhapdf'): diff --git a/madgraph/iolibs/export_fks.py b/madgraph/iolibs/export_fks.py index c06cd2c0fb..b92555d2a9 100755 --- a/madgraph/iolibs/export_fks.py +++ b/madgraph/iolibs/export_fks.py @@ -85,7 +85,7 @@ def make_jpeg_async(args): devnull = os.open(os.devnull, os.O_RDWR) os.chdir(Pdir) - subprocess.call([os.path.join(old_pos, dir_path, 'bin', 'internal', 'gen_jpeg-pl')], + subprocess.call(['perl', '-w', os.path.join(old_pos, dir_path, 'bin', 'internal', 'gen_jpeg-pl')], stdout = devnull) os.chdir(os.path.pardir) @@ -208,6 +208,9 @@ def copy_fkstemplate(self, model): if os.path.exists(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')): self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')) + if self.set_default_reduction_library(self.MadLoopparam): + self.MadLoopparam.write(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')) + self.MadLoopparam.write(pjoin(self.dir_path, 'Cards', 'MadLoopParams_default.dat')) # write the output file self.MadLoopparam.write(pjoin(self.dir_path,"SubProcesses", "MadLoopParams.dat")) @@ -971,14 +974,14 @@ def finalize(self, matrix_elements, history, mg5options, flaglist): logger.info("Generate jpeg diagrams") for Pdir in P_dir_list: os.chdir(Pdir) - subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_jpeg-pl')], + subprocess.call(['perl', '-w', os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_jpeg-pl')], stdout = devnull) os.chdir(os.path.pardir) # logger.info("Generate web pages") # Create the WebPage using perl script - subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')], \ + subprocess.call(['perl', '-w', os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')], \ stdout = devnull) os.chdir(os.path.pardir) @@ -1007,7 +1010,7 @@ def finalize(self, matrix_elements, history, mg5options, flaglist): logger.warning("Failed to copy " + card + ".dat to default") - subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')], + subprocess.call(['perl', '-w', os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')], stdout = devnull) # Run "make" to generate madevent.tar.gz file @@ -1017,7 +1020,7 @@ def finalize(self, matrix_elements, history, mg5options, flaglist): subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'make_amcatnlo_tar')], stdout = devnull) # - subprocess.call([os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')], + subprocess.call(['perl', '-w', os.path.join(old_pos, self.dir_path, 'bin', 'internal', 'gen_cardhtml-pl')], stdout = devnull) #return to the initial dir @@ -5205,11 +5208,23 @@ def copy_fkstemplate(self, model): libpath,"lib%s.a"%tir,tir_name=tir) setattr(self,tir_dir,libpath) if libpath != "": - if tir in ['pjfry','ninja','golem', 'samurai','collier']: + if tir in ['pjfry','ninja','golem', 'samurai','collier','ninjars']: # We should link dynamically when possible, so we use the original # location of these libraries. - link_tir_libs.append('-L%s/ -l%s'%(libpath,tir)) - tir_libs.append('%s/lib%s.$(libext)'%(libpath,tir)) + copied_ninjars = tir == 'ninjars' and self.dependencies == 'internal' + if tir == 'ninjars': + from madgraph.various import ninjars_install + link_tir_libs.extend(ninjars_install.pre_link_flags(libpath)) + if copied_ninjars: + link_tir_libs.append('-L$(LIBDIR) -lninjars') + tir_libs.append('$(LIBDIR)libninjars.a') + else: + link_tir_libs.append('-L%s/ -l%s'%(libpath,tir)) + tir_libs.append('%s/lib%s.%s' % ( + libpath, tir, 'a' if tir == 'ninjars' else '$(libext)')) + if tir == 'ninjars': + from madgraph.various import ninjars_install + link_tir_libs.extend(ninjars_install.native_link_flags(libpath)) # For Ninja, we must also link against OneLoop. if tir in ['ninja']: if not any(os.path.isfile(pjoin(libpath,'libavh_olo.%s'%ext)) @@ -5219,7 +5234,7 @@ def copy_fkstemplate(self, model): link_tir_libs.append('-L%s/ -l%s'%(libpath,'avh_olo')) tir_libs.append('%s/lib%s.$(libext)'%(libpath,'avh_olo')) # We must add the corresponding includes for these TIR - if tir in ['golem','samurai','ninja','collier']: + if tir in ['golem','samurai','ninja','collier','ninjars']: trg_path = pjoin(os.path.dirname(libpath),'include') trg_path2 = pjoin(trg_path,tir) to_include = None @@ -5229,6 +5244,9 @@ def copy_fkstemplate(self, model): if to_include is None and os.path.isdir(trg_path2): to_include = misc.find_includes_path(trg_path2, self.include_names[tir]) + if to_include is None and tir == 'ninjars': + to_include = misc.find_includes_path( + libpath, self.include_names[tir]) # Special possible location for collier if to_include is None and tir=='collier': to_include = misc.find_includes_path( @@ -5238,7 +5256,8 @@ def copy_fkstemplate(self, model): 'Could not find the include directory for %s, looking in %s and %s.\n' % (tir ,str(trg_path), str(trg_path2))+ 'Generation carries on but you will need to edit the include path by hand in the makefiles.') to_include = '' - tir_include.append('-I %s'%to_include) + tir_include.append('-I %s' % ( + '$(LIBDIR)' if copied_ninjars else to_include)) else: link_tir_libs.append('-l%s'%tir) tir_libs.append('$(LIBDIR)lib%s.$(libext)'%tir) @@ -5296,6 +5315,9 @@ def copy_fkstemplate(self, model): if os.path.exists(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')): self.MadLoopparam = banner_mod.MadLoopParam(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')) + if self.set_default_reduction_library(self.MadLoopparam): + self.MadLoopparam.write(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')) + self.MadLoopparam.write(pjoin(self.dir_path, 'Cards', 'MadLoopParams_default.dat')) # write the output file self.MadLoopparam.write(pjoin(self.dir_path,"SubProcesses", "MadLoopParams.dat")) diff --git a/madgraph/iolibs/export_v4.py b/madgraph/iolibs/export_v4.py index 90443a2e99..073f1f192e 100755 --- a/madgraph/iolibs/export_v4.py +++ b/madgraph/iolibs/export_v4.py @@ -13143,7 +13143,7 @@ def create_model_functions_def(self): if(condition)then mp_recms=expr else - mp_recms=cmplx(real(expr),kind=16) + mp_recms=cmplx(real(expr,kind=16),kind=16) endif end @@ -13151,15 +13151,15 @@ def create_model_functions_def(self): %(complex_mp_format)s function mp_reglog(arg_in) implicit none %(complex_mp_format)s TWOPII - parameter (TWOPII=2.0e0_16*3.14169258478796109557151794433593750e0_16*(0.0e0_16,1.0e0_16)) + parameter (TWOPII=2.0e0_16*3.141592653589793238462643383279502884197e0_16*(0.0e0_16,1.0e0_16)) %(complex_mp_format)s arg_in %(complex_mp_format)s arg arg=arg_in if(abs(imagpart(arg)).eq.0.0e0_16)then - arg=cmplx(real(arg,kind=16),0.0e0_16) + arg=cmplx(real(arg,kind=16),0.0e0_16,kind=16) endif if(abs(real(arg,kind=16)).eq.0.0e0_16)then - arg=cmplx(0.0e0_16,imagpart(arg)) + arg=cmplx(0.0e0_16,imagpart(arg),kind=16) endif if(arg.eq.(0.0e0_16,0.0e0_16)) then mp_reglog=(0.0e0_16,0.0e0_16) @@ -13171,15 +13171,15 @@ def create_model_functions_def(self): %(complex_mp_format)s function mp_reglogp(arg_in) implicit none %(complex_mp_format)s TWOPII - parameter (TWOPII=2.0e0_16*3.14169258478796109557151794433593750e0_16*(0.0e0_16,1.0e0_16)) + parameter (TWOPII=2.0e0_16*3.141592653589793238462643383279502884197e0_16*(0.0e0_16,1.0e0_16)) %(complex_mp_format)s arg_in %(complex_mp_format)s arg arg=arg_in if(abs(imagpart(arg)).eq.0.0e0_16)then - arg=cmplx(real(arg,kind=16),0.0e0_16) + arg=cmplx(real(arg,kind=16),0.0e0_16,kind=16) endif if(abs(real(arg,kind=16)).eq.0.0e0_16)then - arg=cmplx(0.0e0_16,imagpart(arg)) + arg=cmplx(0.0e0_16,imagpart(arg),kind=16) endif if(arg.eq.(0.0e0_16,0.0e0_16))then mp_reglogp=(0.0e0_16,0.0e0_16) @@ -13195,15 +13195,15 @@ def create_model_functions_def(self): %(complex_mp_format)s function mp_reglogm(arg_in) implicit none %(complex_mp_format)s TWOPII - parameter (TWOPII=2.0e0_16*3.14169258478796109557151794433593750e0_16*(0.0e0_16,1.0e0_16)) + parameter (TWOPII=2.0e0_16*3.141592653589793238462643383279502884197e0_16*(0.0e0_16,1.0e0_16)) %(complex_mp_format)s arg_in %(complex_mp_format)s arg arg=arg_in if(abs(imagpart(arg)).eq.0.0e0_16)then - arg=cmplx(real(arg,kind=16),0.0e0_16) + arg=cmplx(real(arg,kind=16),0.0e0_16,kind=16) endif if(abs(real(arg,kind=16)).eq.0.0e0_16)then - arg=cmplx(0.0e0_16,imagpart(arg)) + arg=cmplx(0.0e0_16,imagpart(arg),kind=16) endif if(arg.eq.(0.0e0_16,0.0e0_16))then mp_reglogm=(0.0e0_16,0.0e0_16) @@ -13222,10 +13222,10 @@ def create_model_functions_def(self): %(complex_mp_format)s arg arg=arg_in if(abs(imagpart(arg)).eq.0.0e0_16)then - arg=cmplx(real(arg,kind=16),0.0e0_16) + arg=cmplx(real(arg,kind=16),0.0e0_16,kind=16) endif if(abs(real(arg,kind=16)).eq.0.0e0_16)then - arg=cmplx(0.0e0_16,imagpart(arg)) + arg=cmplx(0.0e0_16,imagpart(arg),kind=16) endif mp_regsqrt=sqrt(arg) end @@ -13233,7 +13233,7 @@ def create_model_functions_def(self): %(complex_mp_format)s function mp_grreglog(logsw,expr1_in,expr2_in) implicit none %(complex_mp_format)s TWOPII - parameter (TWOPII=2.0e0_16*3.14169258478796109557151794433593750e0_16*(0.0e0_16,1.0e0_16)) + parameter (TWOPII=2.0e0_16*3.141592653589793238462643383279502884197e0_16*(0.0e0_16,1.0e0_16)) %(complex_mp_format)s expr1_in,expr2_in %(complex_mp_format)s expr1,expr2 %(real_mp_format)s logsw @@ -13242,16 +13242,16 @@ def create_model_functions_def(self): expr1=expr1_in expr2=expr2_in if(abs(imagpart(expr1)).eq.0.0e0_16)then - expr1=cmplx(real(expr1,kind=16),0.0e0_16) + expr1=cmplx(real(expr1,kind=16),0.0e0_16,kind=16) endif if(abs(real(expr1,kind=16)).eq.0.0e0_16)then - expr1=cmplx(0.0e0_16,imagpart(expr1)) + expr1=cmplx(0.0e0_16,imagpart(expr1),kind=16) endif if(abs(imagpart(expr2)).eq.0.0e0_16)then - expr2=cmplx(real(expr2,kind=16),0.0e0_16) + expr2=cmplx(real(expr2,kind=16),0.0e0_16,kind=16) endif if(abs(real(expr2,kind=16)).eq.0.0e0_16)then - expr2=cmplx(0.0e0_16,imagpart(expr2)) + expr2=cmplx(0.0e0_16,imagpart(expr2),kind=16) endif if(expr1.eq.(0.0e0_16,0.0e0_16))then mp_grreglog=(0.0e0_16,0.0e0_16) @@ -13380,7 +13380,7 @@ def create_model_functions_def(self): %(complex_mp_format)s p2,m12,m22 %(complex_mp_format)s zero,TWOPII parameter (zero=(0.0e0_16,0.0e0_16)) - parameter (TWOPII=2.0e0_16*3.14169258478796109557151794433593750e0_16*(0.0e0_16,1.0e0_16)) + parameter (TWOPII=2.0e0_16*3.141592653589793238462643383279502884197e0_16*(0.0e0_16,1.0e0_16)) %(real_mp_format)s M,M2,Ga,Ga2 %(real_mp_format)s tiny parameter (tiny=-1.0e-14_16) @@ -13479,7 +13479,7 @@ def create_model_functions_def(self): Ga=-imagpart(p2)/M ENDIF gamma0=one+m12/p2-m22/p2 - gamma1=m12/p2-cmplx(0.0e0_16,1.0e0_16)*abs(tiny)/p2 + gamma1=m12/p2-cmplx(0.0e0_16,1.0e0_16,kind=16)*abs(tiny)/p2 IF(abs(Ga).EQ.0.0e0_16)THEN mp_sqrt_trajectory=sqrt(gamma0**2-4.0e0_16*gamma1) RETURN @@ -13488,15 +13488,15 @@ def create_model_functions_def(self): dGa=(Ga-Ga_start)/n_seg prefactor=1.0e0_16 Gai=Ga_start - p2i=cmplx(M**2,-Gai*M) + p2i=cmplx(M**2,-Gai*M,kind=16) gamma0i=one+m12/p2i-m22/p2i - gamma1i=m12/p2i-cmplx(0.0e0_16,1.0e0_16)*abs(tiny)/p2i + gamma1i=m12/p2i-cmplx(0.0e0_16,1.0e0_16,kind=16)*abs(tiny)/p2i argim1=gamma0i**2-4.0e0_16*gamma1i DO i=1,n_seg Gai=dGa*i+Ga_start - p2i=cmplx(M**2,-Gai*M) + p2i=cmplx(M**2,-Gai*M,kind=16) gamma0i=one+m12/p2i-m22/p2i - gamma1i=m12/p2i-cmplx(0.0e0_16,1.0e0_16)*abs(tiny)/p2i + gamma1i=m12/p2i-cmplx(0.0e0_16,1.0e0_16,kind=16)*abs(tiny)/p2i argi=gamma0i**2-4.0e0_16*gamma1i IF(imagpart(argi)*imagpart(argim1).LT.0.0e0_16)THEN intersection=imagpart(argim1)*(real(argi,kind=16)-real(argim1,kind=16)) @@ -13519,7 +13519,7 @@ def create_model_functions_def(self): %(complex_mp_format)s zero,one,half,TWOPII parameter (zero=(0.0e0_16,0.0e0_16),one=(1.0e0_16,0.0e0_16)) parameter (half=(0.5e0_16,0.0e0_16)) - parameter (TWOPII=2.0e0_16*3.14169258478796109557151794433593750e0_16*(0.0e0_16,1.0e0_16)) + parameter (TWOPII=2.0e0_16*3.141592653589793238462643383279502884197e0_16*(0.0e0_16,1.0e0_16)) %(complex_mp_format)s gamma0,gammap,gammam,sqrtterm %(real_mp_format)s M,Ga,dGa,Ga_start %(real_mp_format)s Gai,intersection @@ -13553,7 +13553,7 @@ def create_model_functions_def(self): dGa=(Ga-Ga_start)/n_seg addfactor(1:4)=zero Gai=Ga_start - p2i=cmplx(M**2,-Gai*M) + p2i=cmplx(M**2,-Gai*M,kind=16) sqrttermi=mp_sqrt_trajectory(n_seg,p2i,m12,m22) gamma0i=one+m12/p2i-m22/p2i gammapi=half*(gamma0i+sqrttermi) @@ -13564,7 +13564,7 @@ def create_model_functions_def(self): argim1(4)=(gammami-one)/gammami DO i=1,n_seg Gai=dGa*i+Ga_start - p2i=cmplx(M**2,-Gai*M) + p2i=cmplx(M**2,-Gai*M,kind=16) sqrttermi=mp_sqrt_trajectory(n_seg,p2i,m12,m22) gamma0i=one+m12/p2i-m22/p2i gammapi=half*(gamma0i+sqrttermi) @@ -14116,6 +14116,7 @@ def ExportV4Factory(cmd, noclean, output_type='default', group_subprocesses=True 'golem_dir':cmd.options['golem'], 'samurai_dir':cmd.options['samurai'], 'ninja_dir':cmd.options['ninja'], + 'ninjars_dir':cmd.options.get('ninjars'), 'collier_dir':cmd.options['collier'], 'fortran_compiler':cmd.options['fortran_compiler'], 'f2py_compiler':cmd.options['f2py_compiler'], diff --git a/madgraph/iolibs/helas_call_writers.py b/madgraph/iolibs/helas_call_writers.py index aedc9a8911..3ad8a25178 100755 --- a/madgraph/iolibs/helas_call_writers.py +++ b/madgraph/iolibs/helas_call_writers.py @@ -1796,8 +1796,64 @@ def format_helas_object(self, prefix, number): else: return '%s%s)'%(prefix, number) + @staticmethod + def get_terminal_wavefunctions(matrix_element): + """Prove private diagonal-only roots in the complete optimized graph. + + Unknown graph members or aliases disable the optimization. The emitted + calls and their generated COMMON consumers are checked separately. + """ + try: + producers, consumed, roots = {}, set(), set() + for diagram in matrix_element.get_loop_diagrams(): + for wf in diagram.get('loop_wavefunctions'): + number = wf.get('number') + mother = wf.get_loop_mother() + if (number <= 0 or number != wf.get('me_id') or + number in producers or not wf.get('is_loop') or + mother is None): + return {} + origin = mother.get('number') + if (origin != mother.get('me_id') or origin == number or + (origin not in producers and origin not in (-1, 0))): + return {} + info = wf.get_helas_call_dict(OptimizedOutput=True) + required = ('loop_mother_number', 'loop_mother_rank', + 'vertex_rank', 'lcut_size', 'in_size', 'out_size', 'out') + if any(key not in info for key in required): + return {} + if info['out'] != number or info['loop_mother_number'] != origin: + return {} + producers[number] = {key: info[key] for key in required} + consumed.add(origin) + for amplitude in diagram.get_loop_amplitudes(): + root = amplitude.get_final_loop_wavefunction() + if (root.get('number') != root.get('me_id') or + root.get('number') not in producers): + return {} + roots.add(root.get('number')) + for wf in matrix_element.get_all_wavefunctions(): + if not wf.get('is_loop') and any(m.get('is_loop') for m in wf.get('mothers')): + return {} + result = {} + for number in roots - consumed: + info = producers[number] + left, right = info['loop_mother_rank'], info['vertex_rank'] + # The measured compact path is vertex-first. Other effective + # theory kernels retain the full updater. + if (min(left, right) < 0 or + (left < right and left != 0 and right != 0) or + not 0 < info['lcut_size'] <= info['out_size'] <= 16 or + not 0 < info['in_size'] <= 16): + continue + result[number] = info + return result + except (KeyError, ValueError, TypeError, AttributeError, MadGraph5Error): + return {} + def get_coef_construction_calls(self, matrix_element, group_loops=True, - squared_orders=[], split_orders=[]): + squared_orders=[], split_orders=[], + terminal_wavefunctions=None): """ Return the calls to the helas routines to construct the coefficients of the polynomial representation of the loop numerator (i.e. Pozzorini method). Group the coefficients of the loop with same denominator @@ -1811,12 +1867,40 @@ def get_coef_construction_calls(self, matrix_element, group_loops=True, res = [] sqso_max_lamp = [sqso[1][2] for sqso in squared_orders] + # Validate all generated updater statements before redirecting any. + # This leaves the generic cached wavefunction call functions untouched. + terminal_calls = {} + if terminal_wavefunctions: + for diagram in matrix_element.get_loop_diagrams(): + for wf in diagram.get('loop_wavefunctions'): + number = wf.get('number') + if number not in terminal_wavefunctions: + continue + info = terminal_wavefunctions[number] + expected = ('CALL %(proc_prefix)sUPDATE_WL_{loop_mother_rank}_{vertex_rank}' + '(WL(1,0,1,{loop_mother_number}),{lcut_size},COEFS,' + '{in_size},{out_size},WL(1,0,1,{out}))').format(**info) + call = self.get_wavefunction_call(wf) + if call.splitlines().count(expected) != 1: + terminal_calls = {} + break + terminal_calls[number] = (expected, expected.replace( + 'UPDATE_WL_', 'TERMINAL_WL_', 1)[:-1]+',WL_ENTRY_INEXACT)') + else: + continue + break + if set(terminal_calls) != set(terminal_wavefunctions): + terminal_calls = {} i=0 for ldiag in matrix_element.get_loop_diagrams(): res.append("# Coefficient construction for loop diagram with ID %d"\ %ldiag.get('number')) for lwf in ldiag.get('loop_wavefunctions'): - res.append(self.get_wavefunction_call(lwf)) + call = self.get_wavefunction_call(lwf) + if lwf.get('number') in terminal_calls: + before, after = terminal_calls[lwf.get('number')] + call = call.replace(before, after, 1) + res.append(call) for lamp in ldiag.get_loop_amplitudes(): # If the loop grouping is not desired, then make sure it is # turned off here. It is of course not to be included for diff --git a/madgraph/iolibs/template_files/loop/loop_matrix_standalone.inc b/madgraph/iolibs/template_files/loop/loop_matrix_standalone.inc index 6a90abe709..70c2765e24 100644 --- a/madgraph/iolibs/template_files/loop/loop_matrix_standalone.inc +++ b/madgraph/iolibs/template_files/loop/loop_matrix_standalone.inc @@ -400,6 +400,12 @@ C For now only CutTools is interfaced in the default mode. Samurai could follow. STOP 1 ENDIF ENDIF +C The non-optimized output uses CutTools regardless of the requested chain. +IF(LoopPoleMode.GT.0) THEN + WRITE(*,*) 'LoopPoleMode=1, 2 or 3 requires optimized MadLoop output with NinjaRS or COLLIER.' + WRITE(*,*) 'Regenerate with loop_optimized_output enabled and MLReductionLib=8 or 7.' + STOP 1 +ENDIF IF (LOCAL_ML_INIT) THEN C Setup the file paths CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) diff --git a/madgraph/iolibs/template_files/loop_optimized/COLLIER_interface.inc b/madgraph/iolibs/template_files/loop_optimized/COLLIER_interface.inc index 805c3106ec..bfc592172c 100644 --- a/madgraph/iolibs/template_files/loop_optimized/COLLIER_interface.inc +++ b/madgraph/iolibs/template_files/loop_optimized/COLLIER_interface.inc @@ -44,6 +44,10 @@ C INTEGER CURR_RANK, SGN INTEGER CURR_INDEX INTEGER CURR_MAXCOEF + INTEGER LAST_POLE_MODE + LOGICAL COMPUTE_UV,COMPUTE_IR,LAST_UV,LAST_IR + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV,LAST_IR/.TRUE.,.TRUE./ %(real_dp_format)s RBUFF(0:3) INTEGER COEFMAP_ZERO(0:LOOPMAXCOEFS-1) @@ -127,6 +131,29 @@ C Initialize COLLIER if needed CALL cite('Denner:2016kdg','one-loop reduction with COLLIER') ENDIF +C Pole selection is part of the tensor-cache key. Preserve the legacy +C booleans, so returning to mode -1 restores the caller's old choices. + CALL ML_LOOP_POLE_FLAGS(COMPUTE_UV,COMPUTE_IR) + IF(LAST_POLE_MODE.NE.LoopPoleMode.OR.(LAST_UV.NEQV.COMPUTE_UV).OR.(LAST_IR.NEQV.COMPUTE_IR)) THEN + IF(LAST_POLE_MODE.NE.-2) THEN + CALL %(proc_prefix)sCLEAR_COLLIER_CACHE() + IF(COLLIERGlobalCache.NE.0) THEN + IF(COLLIERGlobalCache.EQ.-1) THEN + CALL INITCACHESYSTEM_CLL(N_CACHES*NPROCS,MAXNEXTERNAL) + ELSE + CALL INITCACHESYSTEM_CLL(N_CACHES*NPROCS,COLLIERGlobalCache) + ENDIF + CALL SwitchOffCacheSystem_cll() + NCALLS_IN_CACHE=-1 + NCOLLIERCALLS=0 + IF(COLLIER_CACHE_ACTIVE.EQ.1) CALL SwitchOnCache_cll((unique_id-1)*N_CACHES+1) + ENDIF + ENDIF + LAST_POLE_MODE=LoopPoleMode + LAST_UV=COMPUTE_UV + LAST_IR=COMPUTE_IR + ENDIF + C Initialize the event if it is the first time collier is called on this PS point IF(MUST_INIT_EVENT) THEN MUST_INIT_EVENT = .False. @@ -163,11 +190,11 @@ C No need to check the other caches since we already had to reset he ENDDO CALL InitEvent_cll((UNIQUE_ID-1)*N_CACHES+1) NCOLLIERCALLS(1) = 0 - IF(COLLIERComputeUVpoles.and.COLLIERUseCacheForPoles) THEN + IF(COMPUTE_UV.and.COLLIERUseCacheForPoles) THEN CALL InitEvent_cll((UNIQUE_ID-1)*N_CACHES+2) NCOLLIERCALLS(2) = 0 ENDIF - IF(COLLIERComputeIRpoles.and.COLLIERUseCacheForPoles) THEN + IF(COMPUTE_IR.and.COLLIERUseCacheForPoles) THEN CALL InitEvent_cll((UNIQUE_ID-1)*N_CACHES+3) NCOLLIERCALLS(3) = 0 CALL InitEvent_cll((UNIQUE_ID-1)*N_CACHES+4) @@ -299,7 +326,7 @@ C We can now call COLLIER ENDIF C Now compute the UV poles if asked for - IF (COLLIERComputeUVpoles) THEN + IF (COMPUTE_UV) THEN IF(COLLIER_CACHE_ACTIVE.eq.1) THEN CALL SwitchOffCache_cll((unique_id-1)*N_CACHES+1) IF(COLLIERUseCacheForPoles) THEN @@ -325,7 +352,7 @@ C Now compute the UV poles if asked for ENDIF C Now compute the IR poles if asked for - IF (COLLIERComputeIRpoles) THEN + IF (COMPUTE_IR) THEN IF(COLLIER_CACHE_ACTIVE.eq.1) THEN CALL SwitchOffCache_cll((unique_id-1)*N_CACHES+1) IF(COLLIERUseCacheForPoles) THEN @@ -376,12 +403,12 @@ C Because we must set q -> -q, we apply a minus sign to coefs of odd rank SGN = 1 ENDIF TIRCOEFS(I,1) = SGN*TNten(C0,C1,C2,C3) - IF (COLLIERComputeUVpoles) THEN + IF (COMPUTE_UV) THEN TIRCOEFS(I,2) = SGN*( TNten_UV(C0,C1,C2,C3)-TNten(C0,C1,C2,C3) ) ELSE TIRCOEFS(I,2) = DCMPLX(0.0d0,0.0d0) ENDIF - IF (COLLIERComputeIRpoles) THEN + IF (COMPUTE_IR) THEN TIRCOEFS(I,2) = TIRCOEFS(I,2) + SGN*( TNten_IR1(C0,C1,C2,C3)-TNten(C0,C1,C2,C3) ) TIRCOEFS(I,3) = SGN*( TNten_IR2(C0,C1,C2,C3)-TNten(C0,C1,C2,C3) ) ELSE diff --git a/madgraph/iolibs/template_files/loop_optimized/NINJARS_interface.inc b/madgraph/iolibs/template_files/loop_optimized/NINJARS_interface.inc new file mode 100644 index 0000000000..a478e516e2 --- /dev/null +++ b/madgraph/iolibs/template_files/loop_optimized/NINJARS_interface.inc @@ -0,0 +1,281 @@ +## if(ninjars_available){ +C NinjaRS tensor reduction using oneloopmaster scalar integrals. + SUBROUTINE %(proc_prefix)sNINJARS_LOOP(NLOOPLINE,PL,M2L,RANK,RES,STABLE) + USE MNINJARS + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE + USE %(proc_prefix)sPOLYNOMIAL_CONSTANTS, ONLY: NCOEF_R,COEFTORANK_MAP + IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/%(proc_prefix)sNRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/%(proc_prefix)sNRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/%(proc_prefix)sNRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + INTEGER NLOOPGROUPS,NSQUAREDSO + PARAMETER (NLOOPGROUPS=%(nloop_groups)d,NSQUAREDSO=%(nSquaredSO)d) + INCLUDE 'loop_max_coefs.inc' + INTEGER NLOOPLINE,RANK + %(real_dp_format)s PL(0:3,NLOOPLINE) + %(mass_dp_format)s M2L(NLOOPLINE) + %(complex_dp_format)s RES(3) + LOGICAL STABLE + %(real_dp_format)s NORMALIZATION + PARAMETER (NORMALIZATION=1.D0/(16.D0*3.14159265358979323846D0**2)) + %(real_dp_format)s P_TMP(0:3,0:NLOOPLINE-1),ABSP_TMP(0:3),REF_P + %(real_dp_format)s P_NRS(0:3,NLOOPLINE),P_S_MAT(NLOOPLINE,0:3) + %(real_dp_format)s PDEN_DUMMY(0:3,NLOOPLINE-1),REAL_S_MAT(NLOOPLINE,NLOOPLINE) + %(real_dp_format)s NRS_SCALE + %(complex_dp_format)s MASSES(NLOOPLINE),S_MAT(NLOOPLINE,NLOOPLINE) + %(complex_dp_format)s TENSORCOEFS(0:LOOPMAXCOEFS-1),NRS_RES(0:2),R1 + INTEGER I,J,K,CURR_MAXCOEF,NRS_STATUS + %(include_vector)s + INCLUDE 'coupl.inc' + INCLUDE 'MadLoopParams.inc' + %(real_dp_format)s LSCALE + INTEGER CTMODE + COMMON/%(proc_prefix)sCT/LSCALE,CTMODE +## if(not AmplitudeReduction){ + INTEGER ID,SQSOINDEX,R + COMMON/%(proc_prefix)sLOOP/ID,SQSOINDEX,R + %(complex_dp_format)s LOOPCOEFS(0:LOOPMAXCOEFS-1,NSQUAREDSO,NLOOPGROUPS) +## }else{ + INTEGER ID,R + COMMON/%(proc_prefix)sLOOP/ID,R + %(complex_dp_format)s LOOPCOEFS(0:LOOPMAXCOEFS-1,NLOOPGROUPS) +## } + COMMON/%(proc_prefix)sLCOEFS/LOOPCOEFS + LOGICAL FPE_IN_DP_REDUCTION,FPE_IN_QP_REDUCTION + COMMON/%(proc_prefix)sFPE_IN_REDUCTION/FPE_IN_DP_REDUCTION,FPE_IN_QP_REDUCTION + + STABLE=.FALSE. + RES=(0.D0,0.D0) + PDEN_DUMMY=0 + MASSES=CMPLX(M2L,KIND=KI_NRS) +C Preserve MadLoop's loop-direction stability test and mass ordering. + CALL %(proc_prefix)sSWITCH_ORDER(CTMODE,NLOOPLINE,PL,PDEN_DUMMY,M2L) + MASSES=M2L +C Match the existing Ninja loop momentum convention, including its +C accumulation order and the residual momentum on the first line. + P_TMP=0 + ABSP_TMP=0 + DO I=0,3 + DO J=1,NLOOPLINE + P_TMP(I,0)=P_TMP(I,0)+PL(I,J) + ABSP_TMP(I)=ABSP_TMP(I)+ABS(PL(I,J)) + ENDDO + ENDDO + REF_P=MAXVAL(ABSP_TMP) + IF (REF_P.GT.1.D-8) THEN + DO I=0,3 + IF (ABS(P_TMP(I,0))/MAX(REF_P*1.D-6,ABSP_TMP(I)).GT.1.D-6) THEN + FPE_IN_DP_REDUCTION=.TRUE. + RETURN + ENDIF + ENDDO + ENDIF + DO I=0,3 + DO J=1,NLOOPLINE-1 + DO K=1,J + P_TMP(I,J)=P_TMP(I,J)+PL(I,K) + ENDDO + ENDDO + ENDDO + DO J=1,NLOOPLINE + DO I=0,3 + P_NRS(I,J)=P_TMP(I,J-1) + P_S_MAT(J,I)=P_NRS(I,J) + ENDDO + ENDDO +C Use MadLoop's thresholded invariants, including complex on-shell masses. + CALL %(proc_prefix)sBUILD_KINEMATIC_MATRIX(NLOOPLINE,P_S_MAT,MASSES,S_MAT) + DO J=1,NLOOPLINE + DO I=1,NLOOPLINE + REAL_S_MAT(I,J)=REAL(S_MAT(I,J)+MASSES(I)+MASSES(J),KIND=KI_NRS) + ENDDO + ENDDO + CURR_MAXCOEF=NCOEF_R(RANK) + DO I=0,CURR_MAXCOEF-1 +## if(not AmplitudeReduction){ + TENSORCOEFS(I)=LOOPCOEFS(I,SQSOINDEX,ID) +## }else{ + TENSORCOEFS(I)=LOOPCOEFS(I,ID) +## } +C q_loop -> -q_loop in NinjaRS's denominator convention. + IF (MOD(COEFTORANK_MAP(I),2).EQ.1) TENSORCOEFS(I)=-TENSORCOEFS(I) + ENDDO + NRS_SCALE=REAL(MU_R**2,KIND=KI_NRS) + IF(NRS_RETRY_MODE) THEN + CALL NINJARS_TENSOR_EVALUATE_COMPENSATED(TENSORCOEFS(0:CURR_MAXCOEF-1),NLOOPLINE,RANK,REAL_S_MAT,P_NRS,MASSES,NRS_SCALE,NRS_RES,R1,NRS_STATUS,MAX(0,LoopPoleMode)) + ELSE + CALL NINJARS_TENSOR_EVALUATE(TENSORCOEFS(0:CURR_MAXCOEF-1),NLOOPLINE,RANK,REAL_S_MAT,P_NRS,MASSES,NRS_SCALE,NRS_RES,R1,NRS_STATUS,MAX(0,LoopPoleMode)) + ENDIF + STABLE=NRS_STATUS.EQ.NINJARS_SUCCESS + DO I=0,2 + STABLE=STABLE.AND.IEEE_IS_FINITE(REAL(NRS_RES(I),KIND=KI_NRS)) + STABLE=STABLE.AND.IEEE_IS_FINITE(AIMAG(NRS_RES(I))) + ENDDO + IF (.NOT.STABLE) THEN + FPE_IN_DP_REDUCTION=.TRUE. + RETURN + ENDIF + DO I=0,2 +## if(AmplitudeReduction){ + RES(I+1)=NORMALIZATION*CMPLX(NRS_RES(I),KIND=KI_NRS) +## }else{ + RES(I+1)=NORMALIZATION*2.D0*DBLE(NRS_RES(I)) +## } + ENDDO + DO I=1,3 + STABLE=STABLE.AND.IEEE_IS_FINITE(DBLE(RES(I))) + STABLE=STABLE.AND.IEEE_IS_FINITE(AIMAG(RES(I))) + ENDDO + IF (.NOT.STABLE) THEN + FPE_IN_DP_REDUCTION=.TRUE. + RES=(0.D0,0.D0) + ENDIF + END +C Initialize retry state even when a caller invokes NINJARS_LOOP directly. + BLOCK DATA %(proc_prefix)sNINJARS_RETRY_INIT + IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/%(proc_prefix)sNRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/%(proc_prefix)sNRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/%(proc_prefix)sNRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + DATA NRS_RETRY_MODE,NRS_RETRY_USED/.FALSE.,.FALSE./ + DATA NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL, + $ NRS_RETRY_HARD_SKIP/0,0,0,0/ + DATA NRS_NATIVE_ACC,NRS_COMP_ACC/-1D0,-1D0/ + END +## if(ninjars_supports_quad_prec){ + SUBROUTINE %(proc_prefix)sMP_NINJARS_LOOP(NLOOPLINE,PL,M2L,RANK,RES,STABLE) + USE MNINJARS + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE + USE %(proc_prefix)sPOLYNOMIAL_CONSTANTS, ONLY: NCOEF_R,COEFTORANK_MAP + IMPLICIT NONE + INTEGER NLOOPGROUPS,NSQUAREDSO + PARAMETER (NLOOPGROUPS=%(nloop_groups)d,NSQUAREDSO=%(nSquaredSO)d) + INCLUDE 'loop_max_coefs.inc' + INTEGER NLOOPLINE,RANK + %(real_mp_format)s PL(0:3,NLOOPLINE) + %(mass_dp_format)s M2L(NLOOPLINE) + %(complex_dp_format)s RES(3) + LOGICAL STABLE + %(real_dp_format)s NORMALIZATION + PARAMETER (NORMALIZATION=1.D0/(16.D0*3.14159265358979323846D0**2)) + %(real_mp_format)s P_TMP(0:3,0:NLOOPLINE-1),ABSP_TMP(0:3),REF_P + %(real_mp_format)s P_NRS(0:3,NLOOPLINE),P_S_MAT(NLOOPLINE,0:3) + %(real_mp_format)s PDEN_DUMMY(0:3,NLOOPLINE-1),REAL_S_MAT(NLOOPLINE,NLOOPLINE) + %(real_mp_format)s NRS_SCALE + %(complex_mp_format)s MASSES(NLOOPLINE),S_MAT(NLOOPLINE,NLOOPLINE) + %(complex_mp_format)s TENSORCOEFS(0:LOOPMAXCOEFS-1),NRS_RES(0:2),R1 + INTEGER I,J,K,CURR_MAXCOEF,NRS_STATUS + %(include_vector)s + INCLUDE 'coupl.inc' + INCLUDE 'MadLoopParams.inc' + %(real_dp_format)s LSCALE + INTEGER CTMODE + COMMON/%(proc_prefix)sCT/LSCALE,CTMODE +## if(not AmplitudeReduction){ + INTEGER ID,SQSOINDEX,R + COMMON/%(proc_prefix)sLOOP/ID,SQSOINDEX,R + %(complex_mp_format)s LOOPCOEFS(0:LOOPMAXCOEFS-1,NSQUAREDSO,NLOOPGROUPS) +## }else{ + INTEGER ID,R + COMMON/%(proc_prefix)sLOOP/ID,R + %(complex_mp_format)s LOOPCOEFS(0:LOOPMAXCOEFS-1,NLOOPGROUPS) +## } + COMMON/%(proc_prefix)sMP_LCOEFS/LOOPCOEFS + LOGICAL FPE_IN_DP_REDUCTION,FPE_IN_QP_REDUCTION + COMMON/%(proc_prefix)sFPE_IN_REDUCTION/FPE_IN_DP_REDUCTION,FPE_IN_QP_REDUCTION + + STABLE=.FALSE. + RES=(0.D0,0.D0) + PDEN_DUMMY=0 + MASSES=CMPLX(M2L,KIND=KI_QNRS) +C Preserve MadLoop's loop-direction stability test and mass ordering. + CALL %(proc_prefix)sMP_SWITCH_ORDER(CTMODE,NLOOPLINE,PL,PDEN_DUMMY,MASSES) + +C Match the existing Ninja loop momentum convention, including its +C accumulation order and the residual momentum on the first line. + P_TMP=0 + ABSP_TMP=0 + DO I=0,3 + DO J=1,NLOOPLINE + P_TMP(I,0)=P_TMP(I,0)+PL(I,J) + ABSP_TMP(I)=ABSP_TMP(I)+ABS(PL(I,J)) + ENDDO + ENDDO + REF_P=MAXVAL(ABSP_TMP) + IF (REF_P.GT.1.D-8) THEN + DO I=0,3 + IF (ABS(P_TMP(I,0))/MAX(REF_P*1.D-6,ABSP_TMP(I)).GT.1.D-6) THEN + FPE_IN_QP_REDUCTION=.TRUE. + RETURN + ENDIF + ENDDO + ENDIF + DO I=0,3 + DO J=1,NLOOPLINE-1 + DO K=1,J + P_TMP(I,J)=P_TMP(I,J)+PL(I,K) + ENDDO + ENDDO + ENDDO + DO J=1,NLOOPLINE + DO I=0,3 + P_NRS(I,J)=P_TMP(I,J-1) + P_S_MAT(J,I)=P_NRS(I,J) + ENDDO + ENDDO +C Use MadLoop's thresholded invariants, including complex on-shell masses. + CALL %(proc_prefix)sMP_BUILD_KINEMATIC_MATRIX(NLOOPLINE,P_S_MAT,MASSES,S_MAT) + DO J=1,NLOOPLINE + DO I=1,NLOOPLINE + REAL_S_MAT(I,J)=REAL(S_MAT(I,J)+MASSES(I)+MASSES(J),KIND=KI_QNRS) + ENDDO + ENDDO + CURR_MAXCOEF=NCOEF_R(RANK) + DO I=0,CURR_MAXCOEF-1 +## if(not AmplitudeReduction){ + TENSORCOEFS(I)=LOOPCOEFS(I,SQSOINDEX,ID) +## }else{ + TENSORCOEFS(I)=LOOPCOEFS(I,ID) +## } +C q_loop -> -q_loop in NinjaRS's denominator convention. + IF (MOD(COEFTORANK_MAP(I),2).EQ.1) TENSORCOEFS(I)=-TENSORCOEFS(I) + ENDDO + NRS_SCALE=REAL(MU_R**2,KIND=KI_QNRS) + CALL NINJARS_TENSOR_EVALUATE(TENSORCOEFS(0:CURR_MAXCOEF-1),NLOOPLINE,RANK,REAL_S_MAT,P_NRS,MASSES,NRS_SCALE,NRS_RES,R1,NRS_STATUS,MAX(0,LoopPoleMode)) + STABLE=NRS_STATUS.EQ.NINJARS_SUCCESS + DO I=0,2 + STABLE=STABLE.AND.IEEE_IS_FINITE(REAL(NRS_RES(I),KIND=KI_QNRS)) + STABLE=STABLE.AND.IEEE_IS_FINITE(AIMAG(NRS_RES(I))) + ENDDO + IF (.NOT.STABLE) THEN + FPE_IN_QP_REDUCTION=.TRUE. + RETURN + ENDIF + DO I=0,2 +## if(AmplitudeReduction){ + RES(I+1)=NORMALIZATION*CMPLX(NRS_RES(I),KIND=KI_NRS) +## }else{ + RES(I+1)=NORMALIZATION*2.D0*DBLE(NRS_RES(I)) +## } + ENDDO + DO I=1,3 + STABLE=STABLE.AND.IEEE_IS_FINITE(DBLE(RES(I))) + STABLE=STABLE.AND.IEEE_IS_FINITE(AIMAG(RES(I))) + ENDDO + IF (.NOT.STABLE) THEN + FPE_IN_QP_REDUCTION=.TRUE. + RES=(0.D0,0.D0) + ENDIF + END +## } +## } diff --git a/madgraph/iolibs/template_files/loop_optimized/TIR_interface.inc b/madgraph/iolibs/template_files/loop_optimized/TIR_interface.inc index 2a58634b30..55563732ba 100644 --- a/madgraph/iolibs/template_files/loop_optimized/TIR_interface.inc +++ b/madgraph/iolibs/template_files/loop_optimized/TIR_interface.inc @@ -49,6 +49,10 @@ C c This variable will be used to detect changes in the TIR library used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ %(complex_dp_format)s TIRCOEFS(0:LOOPMAXCOEFS-1,3),TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) %(complex_dp_format)s PJCOEFS(0:LOOPMAXCOEFS-1,3) @@ -100,7 +104,30 @@ C ---------- C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. Check before +C consulting the cache so an unsupported ID can never reuse old coefficients. + SELECT CASE(MLReductionLib(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLReductionLib(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:',MLReductionLib(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with the first ILIB used. +CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) +IF(LAST_POLE_MODE.NE.LoopPoleMode.OR.(LAST_UV_POLES.NEQV.UV_POLES).OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL %(proc_prefix)sCLEAR_TIR_CACHE() + LAST_POLE_MODE=LoopPoleMode + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES +ENDIF IF(LAST_LIB_USED.eq.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -453,13 +480,22 @@ C C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB ## if(ninja_supports_quad_prec) { - PARAMETER (QP_NLOOPLIB=2) +## if(ninjars_supports_quad_prec) { + PARAMETER (QP_NLOOPLIB=3) ## } else { - PARAMETER (QP_NLOOPLIB=1) + PARAMETER (QP_NLOOPLIB=2) ## } +## } else { +## if(ninjars_supports_quad_prec) { + PARAMETER (QP_NLOOPLIB=2) +## } else { + PARAMETER (QP_NLOOPLIB=1) +## } +## } + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=%(nloop_groups)d) C diff --git a/madgraph/iolibs/template_files/loop_optimized/helas_loop_amplitude.inc b/madgraph/iolibs/template_files/loop_optimized/helas_loop_amplitude.inc index 8edec7774e..00635b74b2 100644 --- a/madgraph/iolibs/template_files/loop_optimized/helas_loop_amplitude.inc +++ b/madgraph/iolibs/template_files/loop_optimized/helas_loop_amplitude.inc @@ -159,6 +159,18 @@ C Ninja is used ## } ENDIF ## } +## if(ninjars_available){ + ELSEIF (MLReductionLib(I_LIB).EQ.8) THEN + IF (.NOT.DOING_QP) THEN + CALL %(proc_prefix)sNINJARS_LOOP(NLOOPLINE,PL,M2L,RANK,LOOPRES(1,SQUAREDSOINDEX,LOOPNUM),S(SQUAREDSOINDEX,LOOPNUM)) + ELSE +## if(ninjars_supports_quad_prec){ + CALL %(proc_prefix)sMP_NINJARS_LOOP(NLOOPLINE,MP_PL,M2L,RANK,LOOPRES(1,SQUAREDSOINDEX,LOOPNUM),S(SQUAREDSOINDEX,LOOPNUM)) +## } else { + STOP 'NinjaRS quadruple precision is unavailable' +## } + ENDIF +## } ELSE C Tensor Integral Reduction is used CALL %(proc_prefix)sTIRLOOP(SQUAREDSOINDEX,LOOPNUM,I_LIB,NLOOPLINE,PL,M2L,RANK,LOOPRES(1,SQUAREDSOINDEX,LOOPNUM),S(SQUAREDSOINDEX,LOOPNUM)) @@ -182,6 +194,18 @@ C Tensor Integral Reduction is used ENDIF ## } +## if(ninjars_available){ + ELSEIF (MLReductionLib(I_LIB).EQ.8) THEN + IF (.NOT.DOING_QP) THEN + CALL %(proc_prefix)sNINJARS_LOOP(NLOOPLINE,PL,M2L,RANK,AMPL(1,NCTAMPS+LOOPNUM),S(1,LOOPNUM)) + ELSE +## if(ninjars_supports_quad_prec){ + CALL %(proc_prefix)sMP_NINJARS_LOOP(NLOOPLINE,MP_PL,M2L,RANK,AMPL(1,NCTAMPS+LOOPNUM),S(1,LOOPNUM)) +## } else { + STOP 'NinjaRS quadruple precision is unavailable' +## } + ENDIF +## } ELSE C Tensor Integral Reduction is used CALL %(proc_prefix)sTIRLOOP(1,LOOPNUM,I_LIB,NLOOPLINE,PL,M2L,RANK,AMPL(1,NCTAMPS+LOOPNUM),S(1,LOOPNUM)) diff --git a/madgraph/iolibs/template_files/loop_optimized/loop_matrix_standalone.inc b/madgraph/iolibs/template_files/loop_optimized/loop_matrix_standalone.inc index 12b322a256..3660630f42 100644 --- a/madgraph/iolibs/template_files/loop_optimized/loop_matrix_standalone.inc +++ b/madgraph/iolibs/template_files/loop_optimized/loop_matrix_standalone.inc @@ -2,7 +2,37 @@ C --=========================================-- C Main subroutine C --=========================================-- - SUBROUTINE %(proc_prefix)sSLOOPMATRIX(P_USER,ANS) +## if(ninjars_available) { + SUBROUTINE %(proc_prefix)sSLOOPMATRIX(P_USER,ANS) + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER (NEXTERNAL=%(nexternal)d) + %(real_dp_format)s P_USER(0:3,NEXTERNAL),ANS(0:3,*) + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/%(proc_prefix)sNRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/%(proc_prefix)sNRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/%(proc_prefix)sNRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + NRS_RETRY_MODE=.FALSE. + NRS_RETRY_USED=.FALSE. + NRS_RETRY_COUNT=0 + NRS_RETRY_PASS=0 + NRS_RETRY_FAIL=0 + NRS_RETRY_HARD_SKIP=0 + NRS_NATIVE_ACC=-1D0 + NRS_COMP_ACC=-1D0 + CALL %(proc_prefix)sSLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +C Guaranteed reset after every ordinary return from the implementation. + NRS_RETRY_MODE=.FALSE. + END + + SUBROUTINE %(proc_prefix)sSLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +## } else { + SUBROUTINE %(proc_prefix)sSLOOPMATRIX(P_USER,ANS) +## } C %(info_lines)s C @@ -17,7 +47,20 @@ C use %(proc_prefix)sPOLYNOMIAL_CONSTANTS USE ALOHA_OBJECT C +## if(ninjars_available) { + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE +## } IMPLICIT NONE +## if(ninjars_available) { + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/%(proc_prefix)sNRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/%(proc_prefix)sNRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/%(proc_prefix)sNRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC +## } C C USER CUSTOMIZABLE OPTIONS C @@ -100,16 +143,25 @@ C These are constants related to the split orders INTEGER NSQUAREDSOP1 PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries -C At present, there are only CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C At present, there are only CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with support INTEGER QP_NLOOPLIB ## if(ninja_supports_quad_prec) { +## if(ninjars_supports_quad_prec) { + PARAMETER (QP_NLOOPLIB=3) +## } else { + PARAMETER (QP_NLOOPLIB=2) +## } +## } else { +## if(ninjars_supports_quad_prec) { PARAMETER (QP_NLOOPLIB=2) ## } else { PARAMETER (QP_NLOOPLIB=1) ## } +## } + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ common/%(proc_prefix)sstability_tests/maxstabilitylength @@ -219,7 +271,7 @@ C For a 1>N process, them BEAMTWO_HELAVGFACTOR would be set to 1. INTEGER NEPS DATA NEPS/0/ C Below are variables to bypass the checkphase and insure stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -281,15 +333,22 @@ C A FLAG TO DENOTE WHETHER THE CORRESPONDING LOOPLIBS ARE AVAILABLE OR NOT common/%(proc_prefix)sLOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is available. C The index 0 is dummy and simply means that the corresponding loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ ## if(ninja_supports_quad_prec) { - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE.,.TRUE.,.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ ## } else { - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE.,.FALSE.,.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.FALSE./ +## } + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ +## if(ninjars_supports_quad_prec) { + DATA LOOPLIBS_QPAVAILABLE(8)/.TRUE./ +## } else { + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ ## } C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT USED ANYWHERE ELSE @@ -480,6 +539,7 @@ IF(ML_INIT) THEN CALL setMadLoopPath(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERComputeUVpoles = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -524,10 +584,22 @@ C Make sure that NROTATIONS_QP and NROTATIONS_DP are set to zero if AUTOMATIC_CA ENDIF +C Check every evaluation because callers may change the mode at runtime. +CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole convention +C that produced them. Diagnostic modes must include cancelling UV/IR loops. +BYPASS_FILTERS=BYPASS_CHECK.OR.LoopPoleMode.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping unavailable tools. + IF(MLReductionLib(1).EQ.8.AND.MLReductionLib(2).EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -766,9 +838,9 @@ ENDDO ## if(LoopInduced) { C For loop-induced processes, we should make sure not to use the first points C to set the filters because it doesn't have a reasonable REF scale yet. -IF(.NOT.BYPASS_CHECK.AND.NPSPOINTS.GE.1) THEN +IF(.NOT.BYPASS_FILTERS.AND.NPSPOINTS.GE.1) THEN ## } else { -IF(.NOT.BYPASS_CHECK) THEN +IF(.NOT.BYPASS_FILTERS) THEN ## } NTRY=NTRY+1 ENDIF @@ -791,7 +863,7 @@ ENDIF CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER).AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) -IF (WriteOutFilters) THEN +IF (WriteOutFilters.AND.LoopPoleMode.LT.0) THEN IF ((HelicityFilterLevel.ne.0).AND.(.NOT. CHECKPHASE).AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HelFilterFN, err=110, status='NEW',action='WRITE') DO I=1,NCOMB @@ -813,7 +885,7 @@ FOUNDLOOPFILTER=.TRUE. ENDIF ENDIF -IF (BYPASS_CHECK) THEN +IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1769,7 +1841,45 @@ C the result cannot be trusted at all and we hardset all accuracies to 1.0 ACC(I)=1.0d0 ENDDO ENDIF +## if(ninjars_available) { +C One explicit compensated DP retry with the same stability checks. + IF(NRS_RETRY_MODE) THEN + NRS_COMP_ACC=MAXVAL(ACC) + NRS_RETRY_MODE=.FALSE. + IF(MAXVAL(ACC).LT.MLSTABTHRES.AND..NOT.FPE_IN_DP_REDUCTION) THEN + NRS_RETRY_PASS=NRS_RETRY_PASS+1 + ELSE + NRS_RETRY_FAIL=NRS_RETRY_FAIL+1 + ENDIF + ENDIF + IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN + IF(MLREDUCTIONLIB(I_LIB).EQ.8.AND..NOT.NRS_RETRY_USED) THEN + NRS_NATIVE_ACC=MAXVAL(ACC) + IF(.NOT.FPE_IN_DP_REDUCTION.AND.ALL(IEEE_IS_FINITE(ACC)).AND.ALL(IEEE_IS_FINITE(DP_RES(:,:,1:N_DP_EVAL)))) THEN + NRS_RETRY_USED=.TRUE. + NRS_RETRY_MODE=.TRUE. + NRS_RETRY_COUNT=NRS_RETRY_COUNT+1 + EVAL_DONE(1)=.TRUE. + DO I=2,MAXSTABILITYLENGTH + EVAL_DONE(I)=.FALSE. + ENDDO + STAB_INDEX=0 + CTMODE=1 + DP_RES=0D0 + IF(NROTATIONS_DP.GE.1) THEN + GOTO 200 + ELSE + GOTO 300 + ENDIF + ELSE + NRS_RETRY_HARD_SKIP=NRS_RETRY_HARD_SKIP+1 + ENDIF + ENDIF +C Mode is off before advancing a backend or entering genuine QP. + NRS_RETRY_MODE=.FALSE. +## } else { IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN +## } I_LIB=I_LIB+1 IF((I_LIB.GT.NLOOPLIB.OR.MLReductionLib(I_LIB).EQ.0).AND.QP_TOOLS_AVAILABLE)THEN I_LIB=INDEX_QP_TOOLS(1) @@ -1899,7 +2009,7 @@ NROTATIONS_DP = NROTATIONS_DP_BU NROTATIONS_QP = NROTATIONS_QP_BU C Reinitialize the check phase logicals and the filters if check bypassed -IF (BYPASS_CHECK) THEN +IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2574,6 +2684,15 @@ C --=========================================-- C Definition of additional access routines C --=========================================-- + SUBROUTINE %(proc_prefix)sSET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE %(proc_prefix)sCOLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose to have COLLIER @@ -2925,7 +3044,7 @@ C Not stable. C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2935,7 +3054,7 @@ C Stable with Samurai C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -3000,8 +3119,14 @@ C Reset it to default value not to affect next runs C The subroutine below perform clean-up duties for MadLoop like de-allocating c arrays SUBROUTINE %(proc_prefix)sEXIT_MADLOOP() +## if(ninjars_available) { + USE MNINJARS, ONLY: NINJARS_FINALIZE +## } ## if(ComputeColorFlows) { CALL %(proc_prefix)sDEALLOCATE_COLOR_FLOWS() +## } +## if(ninjars_available) { + CALL NINJARS_FINALIZE() ## } CONTINUE END diff --git a/madgraph/iolibs/template_files/loop_optimized/mp_compute_loop_coefs.inc b/madgraph/iolibs/template_files/loop_optimized/mp_compute_loop_coefs.inc index c4a80e54e3..bb33ead4b8 100644 --- a/madgraph/iolibs/template_files/loop_optimized/mp_compute_loop_coefs.inc +++ b/madgraph/iolibs/template_files/loop_optimized/mp_compute_loop_coefs.inc @@ -206,7 +206,7 @@ C BEGIN CODE C ---------- C Decide whether to really compute the integrand in quadruple precision or to fake it and copy the double precision computation in the quadruple precision variables. -COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX).eq.6.AND.UseQPIntegrandForNinja) .OR. (MLREDUCTIONLIB(LIBINDEX).eq.1.AND.UseQPIntegrandForCutTools)) +COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX).eq.6.AND.UseQPIntegrandForNinja) .OR. (MLREDUCTIONLIB(LIBINDEX).eq.1.AND.UseQPIntegrandForCutTools) .OR. (MLREDUCTIONLIB(LIBINDEX).eq.8.AND.UseQPIntegrandForNinjaRS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of times for the same PS point during the stability checks. diff --git a/madgraph/iolibs/template_files/loop_optimized/mp_helas_calls_split.inc b/madgraph/iolibs/template_files/loop_optimized/mp_helas_calls_split.inc index fcccd1d0b7..1f3d5b213f 100644 --- a/madgraph/iolibs/template_files/loop_optimized/mp_helas_calls_split.inc +++ b/madgraph/iolibs/template_files/loop_optimized/mp_helas_calls_split.inc @@ -2,7 +2,7 @@ C use %(proc_prefix)sPOLYNOMIAL_CONSTANTS USE ALOHA_OBJECT - IMPLICIT NONE +%(terminal_ieee_use)s IMPLICIT NONE C C CONSTANTS C @@ -37,7 +37,7 @@ C C C LOCAL VARIABLES C - INTEGER I,J,K +%(terminal_ieee_declarations)s INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ %(complex_mp_format)s COEFS(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) diff --git a/madgraph/iolibs/template_files/matrix_loop_induced_madevent.inc b/madgraph/iolibs/template_files/matrix_loop_induced_madevent.inc index d7e7175276..2f05895369 100644 --- a/madgraph/iolibs/template_files/matrix_loop_induced_madevent.inc +++ b/madgraph/iolibs/template_files/matrix_loop_induced_madevent.inc @@ -374,6 +374,8 @@ c c Global variables c c To monitor MadLoop computational aspects. + INTEGER NINJARS_DP_USAGE,NINJARS_QP_USAGE + COMMON/NINJARSSTATS/NINJARS_DP_USAGE,NINJARS_QP_USAGE INTEGER U_RETURN_CODES(0:9) INTEGER T_RETURN_CODES(0:9) INTEGER H_RETURN_CODES(0:9) @@ -399,6 +401,8 @@ c ---- T_RETURN_CODES(T) = T_RETURN_CODES(T)+1 H = (mod(RETURN_CODE,1000)-10*T-U)/100 H_RETURN_CODES(H) = H_RETURN_CODES(H)+1 + IF (H.EQ.2.AND.U.EQ.8) NINJARS_DP_USAGE=NINJARS_DP_USAGE+1 + IF (H.EQ.3.AND.U.EQ.2) NINJARS_QP_USAGE=NINJARS_QP_USAGE+1 MAX_PREC = max(PREC, MAX_PREC) MIN_PREC = min(PREC, MIN_PREC) diff --git a/madgraph/iolibs/template_files/matrix_loop_induced_madevent_group.inc b/madgraph/iolibs/template_files/matrix_loop_induced_madevent_group.inc index 3db529201e..455c3c6d3e 100644 --- a/madgraph/iolibs/template_files/matrix_loop_induced_madevent_group.inc +++ b/madgraph/iolibs/template_files/matrix_loop_induced_madevent_group.inc @@ -383,6 +383,8 @@ c c Global variables c c To monitor MadLoop computational aspects. + INTEGER NINJARS_DP_USAGE,NINJARS_QP_USAGE + COMMON/NINJARSSTATS/NINJARS_DP_USAGE,NINJARS_QP_USAGE INTEGER U_RETURN_CODES(0:9) INTEGER T_RETURN_CODES(0:9) INTEGER H_RETURN_CODES(0:9) @@ -408,6 +410,8 @@ c ---- T_RETURN_CODES(T) = T_RETURN_CODES(T)+1 H = (mod(RETURN_CODE,1000)-10*T-U)/100 H_RETURN_CODES(H) = H_RETURN_CODES(H)+1 + IF (H.EQ.2.AND.U.EQ.8) NINJARS_DP_USAGE=NINJARS_DP_USAGE+1 + IF (H.EQ.3.AND.U.EQ.2) NINJARS_QP_USAGE=NINJARS_QP_USAGE+1 MAX_PREC = max(PREC, MAX_PREC) MIN_PREC = min(PREC, MIN_PREC) diff --git a/madgraph/iolibs/ufo_expression_parsers.py b/madgraph/iolibs/ufo_expression_parsers.py index a70ca51cc8..8f87f47215 100755 --- a/madgraph/iolibs/ufo_expression_parsers.py +++ b/madgraph/iolibs/ufo_expression_parsers.py @@ -716,9 +716,9 @@ def p_expression_func(self, p): elif p[1] == 'sec': p[0] = '1e0_16/sin' + p[2] elif p[1] == 'acsc': p[0] = 'asin(1e0_16/' + p[2] + ')' elif p[1] == 'asec': p[0] = 'acos(1e0_16/' + p[2] + ')' - elif p[1] in ['atan', 'cmath.atan'] : p[0] = 'atan(real' + p[2]+')' - elif p[1] in ['tan', 'cmath.tan']: p[0] = 'tan(real' + p[2]+')' - elif p[1] == 're': p[0] = 'real' + p[2] + elif p[1] in ['atan', 'cmath.atan'] : p[0] = 'atan(real' + p[2][:-1]+',KIND=16))' + elif p[1] in ['tan', 'cmath.tan']: p[0] = 'tan(real' + p[2][:-1]+',KIND=16))' + elif p[1] == 're': p[0] = 'real' + p[2][:-1]+',KIND=16)' elif p[1] == 'im': p[0] = 'imag' + p[2] elif p[1] == 'arg': p[0] = 'mp_arg(CMPLX(' + p[2] + ',KIND=16))' elif p[1] == 'cmath.sqrt' or p[1] == 'sqrt': p[0] = 'sqrt(CMPLX(' + p[2] + ',KIND=16))' @@ -736,9 +736,9 @@ def p_expression_real(self, p): if p[2] == '.real': if p[1].startswith('('): - p[0] = 'real' +p[1] + p[0] = 'real' +p[1][:-1]+',KIND=16)' else: - p[0] = 'real(%s)' % p[1] + p[0] = 'real(%s,KIND=16)' % p[1] elif p[2] == '.imag': if p[1].startswith('('): p[0] = 'imag' +p[1] diff --git a/madgraph/loop/loop_exporters.py b/madgraph/loop/loop_exporters.py index b7bde21cd9..b339d7d335 100755 --- a/madgraph/loop/loop_exporters.py +++ b/madgraph/loop/loop_exporters.py @@ -40,6 +40,7 @@ import madgraph.iolibs.group_subprocs as group_subprocs import madgraph.various.banner as banner_mod import madgraph.various.misc as misc +import madgraph.various.ninjars_install as ninjars_install import madgraph.various.q_polynomial as q_polynomial import madgraph.iolibs.file_writers as writers import madgraph.iolibs.gen_infohtml as gen_infohtml @@ -65,6 +66,12 @@ _file_path = os.path.split(os.path.dirname(os.path.realpath(__file__)))[0] + '/' logger = logging.getLogger('madgraph.loop_exporter') +_FACTORIZED_WL_VERTEX = r'(?:FFV1L1_2|FFV1L2_1)' +_PRIVATE_MP_WL_ROUTINE = (r'(?:TERMINAL_WL_\d+_\d+' + r'(?:_FACTOR_'+_FACTORIZED_WL_VERTEX+r')?|' + r'UPDATE_WL_[2-4]_1_FACTOR_'+_FACTORIZED_WL_VERTEX+r')') +_PRIVATE_MP_WL_CALL = r'\bCALL MP_\w*'+_PRIVATE_MP_WL_ROUTINE+r'\(' + #=============================================================================== # LoopExporterFortran #=============================================================================== @@ -90,6 +97,7 @@ class LoopExporterFortran(object): 'vector_size':0}) include_names = {'ninja' : 'mninja.mod', + 'ninjars' : 'mninjars.mod', 'golem' : 'generic_function_1p.mod', 'samurai':'msamurai.mod', 'collier': 'collier.mod'} @@ -264,6 +272,8 @@ def finalize(self, matrix_element, cmdhistory, MG5options, outputflag): MLCard = banner_mod.MadLoopParam(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')) + if not self.has_loop_induced: + self.set_default_reduction_library(MLCard) # For loop-induced processes and *only* when summing over all helicity configurations # (which is the default for standalone usage), COLLIER is faster than Ninja. if self.has_loop_induced: @@ -279,6 +289,21 @@ def finalize(self, matrix_element, cmdhistory, MG5options, outputflag): MLCard.write(pjoin(self.dir_path, 'Cards', 'MadLoopParams_default.dat')) MLCard.write(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat')) + def set_default_reduction_library(self, card): + """Prefer a usable NinjaRS installation for untouched ordinary defaults.""" + if (getattr(self, 'has_loop_induced', False) or + not getattr(self, 'tir_available_dict', {}).get('ninjars', False) or + 'mlreductionlib' in card.user_set or card['MLReductionLib'] != '6|7|1'): + return False + preferred = ninjars_install.default_reduction_library( + True, getattr(self, 'ninjars_dir', None)) + if preferred != [8]: + return False + # An active value is required: Fortran ignores commented default lines. + card.set('MLReductionLib', '%s|%s' % (preferred[0], card['MLReductionLib']), + user=True) + return True + def write_f2py_makefile(self, model): return @@ -513,6 +538,8 @@ def write_loop_makefile_definitions(self, writer, link_tir_libs, replace_dict['tir_include'] = ' '.join(tir_include) replace_dict['rpaths_libs'] = '' for lib in tir_libs: + if lib.endswith('libninjars.a'): + continue replace_dict['rpaths_libs'] += '-Wl,-rpath,%s '%os.path.dirname(lib) file = file % replace_dict @@ -1460,6 +1487,11 @@ def write_CT_interface(self, writer, matrix_element, optimized_output=False): file = file % replace_dict files.append(file) + + if optimized_output: + ninjars_template = os.path.join(self.template_dir, 'NINJARS_interface.inc') + with open(ninjars_template) as stream: + files.append(stream.read() % replace_dict) # Now collect the different kind of subroutines needed for the # loop HELAS-like calls. @@ -1566,12 +1598,19 @@ def split_HELASCALLS(self, writer, replace_dict, template_name, masterfile, \ in the replace_dict dictionary under the entry entry_name. The context specified will be forwarded to the fileWriter.""" helascalls_replace_dict=copy.copy(replace_dict) + helascalls_replace_dict.setdefault('terminal_ieee_use', '') + helascalls_replace_dict.setdefault('terminal_ieee_declarations', '') helascalls_replace_dict['bunch_name']=bunch_name helascalls_files=[] for i, k in enumerate(range(0, len(helas_calls), n_helas)): helascalls_replace_dict['bunch_number']=i+1 helascalls_replace_dict['helas_calls']=\ '\n'.join(helas_calls[k:k + n_helas]) + if replace_dict.get('terminal_ieee_use'): + has_private = re.search(_PRIVATE_MP_WL_CALL, + helascalls_replace_dict['helas_calls']) + for key in ('terminal_ieee_use', 'terminal_ieee_declarations'): + helascalls_replace_dict[key] = replace_dict[key] if has_private else '' helascalls_replace_dict['required_so_broadcaster']=\ required_so_broadcaster helascalls_replace_dict['continue_label']=continue_label @@ -1899,7 +1938,7 @@ class LoopProcessOptimizedExporterFortranSA(LoopProcessExporterFortranSA): # make sure that ninja appears first in the list of -L because # it is the tool for which the user is most susceptible of # using a standalone version independent of gosam_contrib - all_tir=['pjfry','iregi','ninja','golem','samurai','collier'] + all_tir=['pjfry','iregi','ninja','golem','samurai','collier','ninjars'] def __init__(self, dir_path = "", opt=None): """Initiate the LoopProcessOptimizedExporterFortranSA with directory @@ -1910,14 +1949,15 @@ def __init__(self, dir_path = "", opt=None): # TIR available ones self.tir_available_dict={'pjfry':True,'iregi':True,'golem':True, - 'samurai':True,'ninja':True,'collier':True} + 'samurai':True,'ninja':True,'collier':True,'ninjars':True} for tir in self.all_tir: tir_dir="%s_dir"%tir if tir_dir in self.opt and not self.opt[tir_dir] is None: # Make sure to defer the 'local path' to the current MadGraph7 root. tir_path = self.opt[tir_dir].strip() - if tir_path.startswith('.'): + if tir_path.startswith('.') or ( + tir == 'ninjars' and not os.path.isabs(tir_path)): tir_path = os.path.abspath(pjoin(MG5DIR,tir_path)) setattr(self,tir_dir,tir_path) else: @@ -1945,10 +1985,14 @@ def get_context(self,matrix_element, **opts): except AttributeError: context['ninja_supports_quad_prec'] = False + context['ninjars_supports_quad_prec'] = ( + self.tir_available_dict.get('ninjars', False) and + ninjars_install.supports_quad_precision(getattr(self, 'ninjars_dir', ''))) + for tir in self.all_tir: context['%s_available'%tir]=self.tir_available_dict[tir] # safety check - if tir not in ['golem','pjfry','iregi','samurai','ninja','collier']: + if tir not in ['golem','pjfry','iregi','samurai','ninja','collier','ninjars']: raise MadGraph5Error("%s was not a TIR currently interfaced."%tir_name) return context @@ -1969,11 +2013,23 @@ def loop_optimized_additional_template_setup(self): tir_name=tir libpath = self.link_TIR(os.path.join(self.dir_path, 'lib'), libpath,libname,tir_name=tir_name) + if tir == 'ninjars': + self.ninjars_dir = libpath if libpath != "": - if tir in ['ninja','pjfry','golem','samurai','collier']: + if tir in ['ninja','pjfry','golem','samurai','collier','ninjars']: # It is cleaner to use the original location of the libraries - link_tir_libs.append('-L%s/ -l%s'%(libpath,tir)) - tir_libs.append('%s/lib%s.$(libext)'%(libpath,tir)) + copied_ninjars = tir == 'ninjars' and self.dependencies == 'internal' + if tir == 'ninjars': + link_tir_libs.extend(ninjars_install.pre_link_flags(libpath)) + if copied_ninjars: + link_tir_libs.append('-L$(LIBDIR) -lninjars') + tir_libs.append('$(LIBDIR)libninjars.a') + else: + link_tir_libs.append('-L%s/ -l%s'%(libpath,tir)) + tir_libs.append('%s/lib%s.%s' % ( + libpath, tir, 'a' if tir == 'ninjars' else '$(libext)')) + if tir == 'ninjars': + link_tir_libs.extend(ninjars_install.native_link_flags(libpath)) # For Ninja, we must also link against OneLoop. if tir in ['ninja']: if not any(os.path.isfile(pjoin(libpath,'libavh_olo.%s'%ext)) @@ -1982,13 +2038,16 @@ def loop_optimized_additional_template_setup(self): "The OneLOop library 'libavh_olo.(a|dylib|so)' could no be found in path '%s'. Please place a symlink to it there."%libpath) link_tir_libs.append('-L%s/ -l%s'%(libpath,'avh_olo')) tir_libs.append('%s/lib%s.$(libext)'%(libpath,'avh_olo')) - if tir in ['ninja','golem', 'samurai','collier']: + if tir in ['ninja','golem', 'samurai','collier','ninjars']: trgt_path = pjoin(os.path.dirname(libpath),'include') if os.path.isdir(trgt_path): to_include = misc.find_includes_path(trgt_path, self.include_names[tir]) else: to_include = None + if to_include is None and tir == 'ninjars': + to_include = misc.find_includes_path( + libpath, self.include_names[tir]) # Special possible location for collier if to_include is None and tir=='collier': to_include = misc.find_includes_path( @@ -1998,17 +2057,19 @@ def loop_optimized_additional_template_setup(self): 'Could not find the include directory for %s, looking in %s.\n' % (tir, str(trgt_path))+ 'Generation carries on but you will need to edit the include path by hand in the makefiles.') to_include = '' - tir_include.append('-I %s'%str(to_include)) + tir_include.append('-I %s' % ( + '$(LIBDIR)' if copied_ninjars else str(to_include))) # To be able to easily compile a MadLoop library using # makefiles built outside of the MadGraph7 framework # (such as what is done with the Sherpa interface), we # place here an easy handle on the golem includes name_map = {'golem':'golem95','samurai':'samurai', - 'ninja':'ninja','collier':'collier'} - ln(to_include, starting_dir=pjoin(self.dir_path,'lib'), - name='%s_include'%name_map[tir],abspath=True) - ln(libpath, starting_dir=pjoin(self.dir_path,'lib'), - name='%s_lib'%name_map[tir],abspath=True) + 'ninja':'ninja','collier':'collier','ninjars':'ninjars'} + if not copied_ninjars: + ln(to_include, starting_dir=pjoin(self.dir_path,'lib'), + name='%s_include'%name_map[tir],abspath=True) + ln(libpath, starting_dir=pjoin(self.dir_path,'lib'), + name='%s_lib'%name_map[tir],abspath=True) else : link_tir_libs.append('-l%s'%tir) tir_libs.append('$(LIBDIR)lib%s.$(libext)'%tir) @@ -2050,7 +2111,7 @@ def link_TIR(self, targetPath,libpath,libname,tir_name='TIR'): """Link the TIR source directory inside the target path given in argument""" - if tir_name in ['pjfry','golem','samurai','ninja','collier']: + if tir_name in ['pjfry','golem','samurai','ninja','collier','ninjars']: # not self-contained libraries if (not isinstance(libpath,str)) or (not os.path.exists(libpath)) \ or (not os.path.isfile(pjoin(libpath,libname))): @@ -2062,6 +2123,12 @@ def link_TIR(self, targetPath,libpath,libname,tir_name='TIR'): +" It will not be available.") self.tir_available_dict[tir_name]=False return "" + if tir_name == 'ninjars': + if not ninjars_install.is_available(libpath): + logger.warning("NinjaRS installation at %s is unusable; " + "run 'install ninjars --update'. It will not be available.", libpath) + self.tir_available_dict[tir_name] = False + return "" # Check the version of the tool, if the library was found if tir_name in ['ninja','samurai'] and self.tir_available_dict[tir_name]: # Make sure the librry was indeed installed in the source directory @@ -2088,6 +2155,30 @@ def link_TIR(self, targetPath,libpath,libname,tir_name='TIR'): return "" if self.dependencies=='internal': + if tir_name == 'ninjars': + os.makedirs(targetPath, exist_ok=True) + module_dir = misc.find_includes_path(libpath, 'mninjars.mod') + if module_dir is None: + module_dir = misc.find_includes_path( + pjoin(libpath, os.pardir, 'include'), 'mninjars.mod') + sources = [pjoin(libpath, 'libninjars.a'), + pjoin(module_dir, 'mninjars.mod'), + pjoin(libpath, ninjars_install.CONFIG_NAME), + pjoin(libpath, 'ninjars-native-libs.txt'), + pjoin(libpath, 'ninjars-link-before.txt')] + header = pjoin(libpath, os.pardir, 'include', 'ninjars.h') + if os.path.isfile(header): + sources.append(header) + module_source = pjoin(libpath, os.pardir, 'include', 'mninjars.f90') + if os.path.isfile(module_source): + sources.append(module_source) + for source in sources: + if os.path.isfile(source): + destination = pjoin(targetPath, os.path.basename(source)) + if os.path.abspath(source) != os.path.abspath(destination): + shutil.copy2(source, destination) + self.tir_available_dict[tir_name] = True + return os.path.abspath(targetPath) if tir_name in ['pjfry','golem','samurai','ninja','collier']: self.tir_available_dict[tir_name]=False logger.info("When using the 'output_dependencies=internal' "+\ @@ -2149,7 +2240,7 @@ def link_TIR(self, targetPath,libpath,libname,tir_name='TIR'): self.tir_available_dict[tir_name]=False return "" # We link the tools below directly to the lib directory of the output - if not tir_name in ['pjfry','golem','samurai','ninja','collier']: + if not tir_name in ['pjfry','golem','samurai','ninja','collier','ninjars']: ln(os.path.join(libpath,libname),targetPath,abspath=True) elif self.dependencies=='environment_paths': @@ -2160,7 +2251,7 @@ def link_TIR(self, targetPath,libpath,libname,tir_name='TIR'): logger.info('MadGraph7 is using %s installation found at %s.'%\ (tir_name,newlibpath)) # We link the tools below directly to directly where the library is detected - if not tir_name in ['pjfry','golem','samurai','ninja','collier']: + if not tir_name in ['pjfry','golem','samurai','ninja','collier','ninjars']: ln(newlibpath,targetPath,abspath=True) self.tir_available_dict[tir_name]=True return os.path.dirname(newlibpath) @@ -2309,6 +2400,16 @@ def write_loop_matrix_element_v4(self, writer, matrix_element, fortran_model, filename = 'tir_cache_size.inc' self.write_tir_cache_size_include(writers.FortranWriter(filename)) + # The object graph is necessary but not sufficient: a custom template + # or writer may introduce another COMMON consumer. Fail closed by + # regenerating the ordinary MP batches if the rendered proof fails. + terminal = OptimizedFortranModel.get_terminal_wavefunctions(matrix_element) + if terminal and not self.validate_terminal_wavefunctions( + '.', matrix_element.rep_dict['proc_prefix'], terminal): + logger.debug("Keeping full MP updaters: generated terminal proof unavailable") + self.write_mp_compute_loop_coefs(writers.FortranWriter('mp_compute_loop_coefs.f'), + matrix_element, OptimizedFortranModel, _terminal=False) + return calls def set_optimized_output_specific_replace_dict_entries(self, matrix_element): @@ -2600,11 +2701,174 @@ def write_polynomial_subroutines(self,writer,matrix_element): wl_update[0],wl_update[1],loop_over_vertex_coefs_first=False)) subroutines.append(mp_poly_writer.write_compact_wl_updater(\ wl_update[0],wl_update[1],loop_over_vertex_coefs_first=False)) + if wl_update[1] == 1 and 2 <= wl_update[0] <= 4: + for vertex in ('FFV1L1_2', 'FFV1L2_1'): + name = (mp_poly_writer.sub_prefix+'UPDATE_WL_%d_1_FACTOR_%s' % + (wl_update[0], vertex)) + if len(name) <= 63: + subroutines.append(mp_poly_writer.write_factorized_wl_updater( + wl_update[0], vertex)) + terminal = helas_call_writers.FortranUFOHelasCallWriterOptimized.\ + get_terminal_wavefunctions(matrix_element) + for left, right in sorted(set((item['loop_mother_rank'], item['vertex_rank']) + for item in terminal.values())): + if left == right == 1 or left == 0 or right == 0: + subroutines.append(mp_poly_writer.write_expanded_wl_updater( + left, right, terminal=True)) + else: + subroutines.append(mp_poly_writer.write_compact_wl_updater( + left, right, terminal=True)) + if right == 1 and 2 <= left <= 4: + for vertex in ('FFV1L1_2', 'FFV1L2_1'): + name = (mp_poly_writer.sub_prefix+'TERMINAL_WL_%d_1_FACTOR_%s' % + (left, vertex)) + if len(name) <= 63: + subroutines.append(mp_poly_writer.write_factorized_wl_updater( + left, vertex, terminal=True)) writer.writelines('\n\n'.join(subroutines), context=self.get_context(matrix_element)) - def write_mp_compute_loop_coefs(self, writer, matrix_element, fortran_model): + @staticmethod + def validate_terminal_wavefunctions(directory, prefix, expected): + """Check all rendered consumers before retaining private MP calls.""" + def logical_source(filename): + statements = [] + with open(filename) as stream: + for raw in stream: + if not raw.strip() or raw[0] in 'cC*!': + continue + statement = raw[6:].strip().upper() + if len(raw) > 5 and raw[5] not in ' 0': + if not statements: + raise ValueError("Orphan continuation") + statements[-1] += statement + else: + statements.append(statement) + return '\n'.join(statements) + try: + sources = {os.path.basename(name): logical_source(name) + for name in glob.glob(pjoin(directory, '*.f'))} + batches = sorted((name for name in sources + if re.fullmatch(r'mp_coef_construction_\d+\.f', name)), + key=lambda name: int(re.search(r'(\d+)\.f$', name)[1])) + if not batches: + return False + stem = re.escape('MP_'+prefix.upper()) + update = re.compile(r'CALL '+stem+r'(UPDATE|TERMINAL)_WL_(\d+)_(\d+)' + r'(_FACTOR_'+_FACTORIZED_WL_VERTEX+r')?' + r'\(WL\(1,0,1,(-?\d+)\),(\d+),COEFS,(\d+),(\d+),' + r'WL\(1,0,1,(\d+)\)(,WL_ENTRY_INEXACT)?\)') + create = re.compile(r'CALL '+stem+r'CREATE_LOOP_COEFS\(WL\(1,0,1,(\d+)\),') + producers, consumers, roots, private = {}, set(), set(), {} + for name in batches: + for line in sources[name].splitlines(): + match = update.fullmatch(line) + if match: + mode, left, right, factor, origin, cut, ins, outs, target, flag = match.groups() + left, right, origin, cut, ins, outs, target = map( + int, (left, right, origin, cut, ins, outs, target)) + if (target in producers or target == origin or + (origin not in producers and origin not in (-1, 0)) or + (mode == 'TERMINAL' or bool(factor)) != bool(flag) or + (factor and not (2 <= left <= 4 and right == 1 and + ins == outs == 4 and 0 <= cut <= 4))): + return False + info = dict(loop_mother_rank=left, vertex_rank=right, + loop_mother_number=origin, lcut_size=cut, + in_size=ins, out_size=outs, out=target) + producers[target] = info + consumers.add(origin) + if mode == 'TERMINAL': + private[target] = info + elif create.match(line): + if len(re.findall(r'\bWL\b', line)) != 1: + return False + root = int(create.match(line)[1]) + if root not in producers: + return False + roots.add(root) + elif re.search(r'\bWL\b', line) and not line.startswith(('COMPLEX', 'COMMON')): + return False + if private != expected or not set(private).issubset(roots-consumers): + return False + block = '/'+prefix.upper()+'MP_WL/' + common = 'COMMON'+block+'WL,PL' + for name, text in sources.items(): + declarations = [re.sub(r'\s+', '', line) for line in text.splitlines() + if block in re.sub(r'\s+', '', line)] + if not declarations: + continue + if any(declaration != common for declaration in declarations): + return False + if name in batches: + continue + for line in text.splitlines(): + if line.startswith(('COMPLEX', 'COMMON')): + continue + if re.search(r'\bCALL\b[^\n]*\bWL\b', line): + return False + if len(re.findall(r'\bWL\b', line)) != len(re.findall(r'\bWL\(', line)): + return False + for use in re.finditer(r'\bWL\(([^)\n]*)\)', line): + indices = use[1].split(',') + if len(indices) != 4 or indices[-1] not in ('-1', '0'): + return False + polynomial = sources.get('polynomial.f', '') + merge = re.search(r'(?m)^SUBROUTINE '+stem+r'MERGE_WL\(.*?^END\s*$', + polynomial, re.S | re.M) + create_body = re.search(r'(?m)^SUBROUTINE '+stem+r'CREATE_LOOP_COEFS\(.*?^END\s*$', + polynomial, re.S | re.M) + return bool(merge and create_body and + 'OUT(J)=OUT(J)+WL(I,J,I)*CONST' in merge[0].replace(' ', '') and + len(re.findall(r'\bWL\(', merge[0])) == 2 and + len(re.findall(r'\bWL\b', merge[0])) == 3 and + len(re.findall(r'\bLOOP_WF\b', create_body[0])) == 3 and + re.search(r'(?m)^CALL '+stem+r'MERGE_WL\(LOOP_WF,', create_body[0])) + except (OSError, ValueError, KeyError): + return False + + @staticmethod + def factorize_mp_coef_calls(calls, prefix): + """Select guarded private contractions after recognized vertex calls. + + Selection is local to one generated wavefunction call block. The + Fortran helper verifies the actual stored derivative rows and falls + back to the original updater whenever its numerical contract fails. + """ + vertex_call = re.compile(r'CALL MP_('+_FACTORIZED_WL_VERTEX+r')\(.*?,COEFS\)') + updater = re.compile(r'(CALL MP_'+re.escape(prefix)+ + r'(UPDATE|TERMINAL)_WL_([2-4])_1)' + r'\(WL\(1,0,1,(-?\d+)\),([0-4]),COEFS,4,4,' + r'WL\(1,0,1,(\d+)\)(,WL_ENTRY_INEXACT)?\)') + result = [] + for block in calls: + vertex = None + lines = block.splitlines(keepends=True) + for index, raw in enumerate(lines): + line = raw.rstrip('\r\n') + if not line.strip() or line.lstrip().startswith(('#', '!')): + continue + producer = vertex_call.fullmatch(line) + if producer: + vertex = producer[1] + continue + match = updater.fullmatch(line) + if (vertex and match and int(match[4]) != int(match[6]) and + int(match[6]) > 0 and + (match[2] == 'TERMINAL') == bool(match[7])): + name = match[1][5:]+'_FACTOR_'+vertex + if len(name) <= 63: + rewritten = line.replace(match[1], 'CALL '+name, 1) + if match[2] == 'UPDATE': + rewritten = rewritten[:-1]+',WL_ENTRY_INEXACT)' + lines[index] = rewritten+raw[len(line):] + vertex = None + result.append(''.join(lines)) + return result + + def write_mp_compute_loop_coefs(self, writer, matrix_element, fortran_model, + _terminal=True): """Create the write_mp_compute_loop_coefs.f file.""" if not matrix_element.get('processes') or \ @@ -2631,14 +2895,26 @@ def write_mp_compute_loop_coefs(self, writer, matrix_element, fortran_model): squared_orders=squared_orders, split_orders=split_orders) self.turn_to_mp_calls(born_ct_helas_calls) self.turn_to_mp_calls(uvct_helas_calls) + terminal = (fortran_model.get_terminal_wavefunctions(matrix_element) + if _terminal else {}) coef_construction, coef_merging = fortran_model.get_coef_construction_calls(\ matrix_element,group_loops=self.group_loops, - squared_orders=squared_orders,split_orders=split_orders) + squared_orders=squared_orders,split_orders=split_orders, + terminal_wavefunctions=terminal) # The proc_prefix must be replaced coef_construction = [c % matrix_element.rep_dict for c in coef_construction] self.turn_to_mp_calls(coef_construction) self.turn_to_mp_calls(coef_merging) + coef_construction = self.factorize_mp_coef_calls( + coef_construction, matrix_element.rep_dict['proc_prefix']) + # Add the intrinsic call after MP conversion, which prefixes all CALLs. + private_call = re.compile(r'(?m)^(CALL MP_'+re.escape( + matrix_element.rep_dict['proc_prefix'])+_PRIVATE_MP_WL_ROUTINE+r'\()') + has_private_updates = any(private_call.search(call) for call in coef_construction) + coef_construction = [private_call.sub( + r'CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT)\n\1', call) + for call in coef_construction] file = open(os.path.join(self.template_dir,\ 'mp_compute_loop_coefs.inc')).read() @@ -2660,6 +2936,9 @@ def write_mp_compute_loop_coefs(self, writer, matrix_element, fortran_model): continue_label = 3000, momenta_array_name = 'MP_P', context=context) + if has_private_updates: + replace_dict['terminal_ieee_use'] = ' USE, INTRINSIC :: IEEE_EXCEPTIONS\n' + replace_dict['terminal_ieee_declarations'] = ' LOGICAL WL_ENTRY_INEXACT\n' file=self.split_HELASCALLS(writer,replace_dict,\ 'mp_helas_calls_split.inc',file,coef_construction,\ 'mp_coef_construction','mp_coef_construction', @@ -3052,7 +3331,7 @@ def write_loopmatrix(self, writer, matrix_element, fortran_model, \ looplibs_av=['.TRUE.'] # one should be careful about the order in the following as it must match # the ordering in MadLoopParamsCard. - for tir_lib in ['pjfry','iregi','golem','samurai','ninja','collier']: + for tir_lib in ['pjfry','iregi','golem','samurai','ninja','collier','ninjars']: looplibs_av.append('.TRUE.' if tir_lib in self.all_tir and \ self.tir_available_dict[tir_lib] else '.FALSE.') replace_dict['data_looplibs_av']=','.join(looplibs_av) diff --git a/madgraph/madevent/sum_html.py b/madgraph/madevent/sum_html.py index a59713a11c..311fb63f8e 100755 --- a/madgraph/madevent/sum_html.py +++ b/madgraph/madevent/sum_html.py @@ -33,6 +33,46 @@ import madgraph.various.misc as misc from madgraph import MadGraph5Error +# The first ten entries follow the units-digit histogram written by MadLoop. +# Keep the backend identifiers shared by the XML and NLO log readers. +MADLOOP_UNIT_BACKENDS = ( + ('unidentified', 'Not identified (CTModeRun != -1)'), + ('CutTools_DP', 'CutTools (double precision)'), + ('PJFry', 'PJFry++'), + ('IREGI', 'IREGI'), + ('Golem', 'Golem95'), + ('Samurai', 'Samurai'), + ('Ninja', 'Ninja (double precision)'), + ('COLLIER', 'COLLIER'), + ('Ninja_QP', 'Ninja (quadruple precision)'), + ('CutTools_QP', 'CutTools (quadruple precision)'), +) +MADLOOP_BACKEND_LABELS = dict(MADLOOP_UNIT_BACKENDS + ( + ('NinjaRS_DP', 'NinjaRS (double precision)'), + ('NinjaRS_QP', 'NinjaRS (quadruple precision)'), +)) + + +def decode_madloop_backend_usage(unit_counts, ninjars_dp=0, ninjars_qp=0): + """Decode a legacy units histogram and its optional contextual counters. + + All units slots are occupied. To preserve the public three-digit return + codes, NinjaRS uses (hundreds, units) = (2, 8) for DP and (3, 2) for QP. + Producers count these calls in both the units histogram and dedicated + counters. Split those aliases here, once, for both statistics formats. + Missing dedicated counters mean an old file with only legacy backends. + The input histogram is never modified; decoding can be repeated safely. + """ + usage = {backend: unit_counts[unit] + for unit, (backend, _) in enumerate(MADLOOP_UNIT_BACKENDS)} + for backend, alias, count in ( + ('NinjaRS_DP', 'Ninja_QP', ninjars_dp), + ('NinjaRS_QP', 'PJFry', ninjars_qp)): + usage[backend] = count + usage[alias] -= count + return usage + + class RunStatistics(dict): """ A class to store statistics about a MadEvent run. """ @@ -57,6 +97,8 @@ def __init__(self, *args, **opts): 'Samurai_usage' : 0, 'Ninja_usage' : 0, 'Ninja_QP_usage' : 0, + 'NinjaRS_DP_usage' : 0, + 'NinjaRS_QP_usage' : 0, 'COLLIER_usage' : 0, 'max_precision' : 1.0e99, 'min_precision' : 0.0, @@ -114,15 +156,15 @@ def getData(Node): u_return_code = xml_node.getElementsByTagName('u_return_code') u_codes = [int(_) for _ in getData(u_return_code[0]).split(',')] - self['CutTools_DP_usage'] = u_codes[1] - self['PJFry_usage'] = u_codes[2] - self['IREGI_usage'] = u_codes[3] - self['Golem_usage'] = u_codes[4] - self['Samurai_usage'] = u_codes[5] - self['Ninja_usage'] = u_codes[6] - self['COLLIER_usage'] = u_codes[7] - self['Ninja_QP_usage'] = u_codes[8] - self['CutTools_QP_usage'] = u_codes[9] + ninjars_usage = {} + for precision in ('DP', 'QP'): + nodes = xml_node.getElementsByTagName( + 'ninjars_%s_usage' % precision.lower()) + ninjars_usage[precision] = int(getData(nodes[0])) if nodes else 0 + self.update((backend + '_usage', count) for backend, count in + decode_madloop_backend_usage( + u_codes, ninjars_usage['DP'], ninjars_usage['QP']).items() + if backend != 'unidentified') t_return_code = xml_node.getElementsByTagName('t_return_code') t_codes = [int(_) for _ in getData(t_return_code[0]).split(',')] self['DP_usage'] = t_codes[1] @@ -181,7 +223,9 @@ def nice_output(self,G, no_warning=False): ('Samurai',float(self['Samurai_usage'])/self['n_madloop_calls']), ('COLLIER',float(self['COLLIER_usage'])/self['n_madloop_calls']), ('Ninja_DP',float(self['Ninja_usage'])/self['n_madloop_calls']), - ('Ninja_QP',float(self['Ninja_QP_usage'])/self['n_madloop_calls'])] + ('Ninja_QP',float(self['Ninja_QP_usage'])/self['n_madloop_calls']), + ('NinjaRS_DP',float(self['NinjaRS_DP_usage'])/self['n_madloop_calls']), + ('NinjaRS_QP',float(self['NinjaRS_QP_usage'])/self['n_madloop_calls'])] tools_used = [(_[0],'%.3g'%(100.0*_[1])) for _ in tools_used if _[1] > 0.0 ] diff --git a/madgraph/various/banner.py b/madgraph/various/banner.py index eaa49f8703..4b7e1164d6 100755 --- a/madgraph/various/banner.py +++ b/madgraph/various/banner.py @@ -9105,12 +9105,14 @@ class MadLoopParam(ConfigFile): 4:'Golem95', 5:'Samurai', 6:'Ninja', - 7:'COLLIER'} + 7:'COLLIER', + 8:'NinjaRS'} def default_setup(self): """initialize the directory to the default value""" self.add_param("MLReductionLib", "6|7|1") + self.add_param("LoopPoleMode", -1, allowed=[-1, 0, 1, 2, 3]) self.add_param("IREGIMODE", 2) self.add_param("IREGIRECY", True) self.add_param("CTModeRun", -1) @@ -9132,6 +9134,7 @@ def default_setup(self): self.add_param("LoopInitStartOver", False) self.add_param("HelInitStartOver", False) self.add_param("UseQPIntegrandForNinja", True) + self.add_param("UseQPIntegrandForNinjaRS", True) self.add_param("UseQPIntegrandForCutTools", True) self.add_param("COLLIERMode", 1) self.add_param("COLLIERComputeUVpoles", True) diff --git a/madgraph/various/ninjars_install.py b/madgraph/various/ninjars_install.py new file mode 100644 index 0000000000..5bfeb559e9 --- /dev/null +++ b/madgraph/various/ninjars_install.py @@ -0,0 +1,386 @@ +"""Build and inspect the pinned NinjaRS Fortran interface. + +The implementation lives in vendor/ninjars. Cargo fetches its pinned numerical +dependencies; local source overrides are copied into an isolated build directory +so installing never modifies a developer's reference checkouts. +""" + +import argparse +import hashlib +import json +import logging +import os +from pathlib import Path +import shlex +import shutil +import subprocess +import tempfile + +from madgraph import MadGraph5Error, MG5DIR + +logger = logging.getLogger('madgraph.ninjars_install') +CONFIG_NAME = 'ninjars-config.json' +ABI_VERSION = 4 + + +def read_config(libdir): + """Read installed link and precision information, checking the bridge ABI.""" + try: + with open(os.path.join(libdir, CONFIG_NAME)) as stream: + config = json.load(stream) + except (OSError, TypeError, ValueError) as error: + raise MadGraph5Error( + "Cannot read NinjaRS installation metadata in %s: %s. " + "Run 'install ninjars --update'." % (libdir, error)) + if not isinstance(config, dict) or config.get('abi_version') != ABI_VERSION: + raise MadGraph5Error("Unsupported NinjaRS bridge ABI in %s; " + "run 'install ninjars --update'." % libdir) + flags = config.get('native_libs') + if (not isinstance(flags, list) or + any(not isinstance(flag, str) or '\n' in flag or '\r' in flag + for flag in flags)): + raise MadGraph5Error("Invalid NinjaRS native link metadata in %s; " + "run 'install ninjars --update'." % libdir) + before = config.get('link_before') + if (config.get('link_order_version') != 1 or + not isinstance(before, list) or not before or + any(not isinstance(flag, str) or '\n' in flag or '\r' in flag + for flag in before)): + raise MadGraph5Error("Missing or invalid NinjaRS compiler-runtime link metadata " + "in %s; run 'install ninjars --update'." % libdir) + return config + + +def is_available(libdir): + """Check the installed archive, Fortran interface and native link metadata.""" + if not isinstance(libdir, (str, os.PathLike)) or not libdir: + return False + directory = Path(libdir) + if not directory.is_absolute(): + directory = Path(MG5DIR) / directory + try: + archive = directory / 'libninjars.a' + if archive.stat().st_size <= 8: + return False + with archive.open('rb') as stream: + if stream.read(8) != b'!\n': + return False + config = read_config(directory) + if not any(path.is_file() and path.stat().st_size for path in ( + directory / 'mninjars.mod', directory.parent / 'include' / 'mninjars.mod')): + return False + return (shlex.split((directory / 'ninjars-native-libs.txt').read_text()) == config['native_libs'] and + shlex.split((directory / 'ninjars-link-before.txt').read_text()) == config['link_before']) + except (OSError, ValueError, MadGraph5Error): + return False + + +def default_reduction_library(has_born, libdir): + """Return a fresh timing/profile default, preserving loop-induced policy. + + Only Born-process defaults prefer an installed NinjaRS backend. Exporters + retain their own fallback order and loop-induced tensor-reduction defaults. + Explicit user selections must be left untouched by callers. + """ + return [8] if has_born and is_available(libdir) else [6] + + +def pre_link_flags(libdir): + """Resolve the Fortran compiler runtime before Rust's builtin symbols.""" + return read_config(libdir)['link_before'] + + +def native_link_flags(libdir): + """Return Cargo's platform-specific static-library dependencies.""" + return read_config(libdir)['native_libs'] + + +def supports_quad_precision(libdir): + if not libdir or not os.path.isfile(os.path.join(libdir, 'libninjars.a')): + return False + return read_config(libdir).get('quad_precision') is True + + +def build_parser(): + parser = argparse.ArgumentParser(prog='install ninjars', + description='Install the pinned NinjaRS/oneloopmaster Fortran interface.') + parser.add_argument('--source', metavar='DIRECTORY', + help='local NinjaRS checkout (copied before building)') + parser.add_argument('--oneloop-source', metavar='DIRECTORY', + help='local oneloopmaster checkout (copied before building)') + parser.add_argument('--prefix', metavar='DIRECTORY', + help='override the configured HEPTools installation prefix') + parser.add_argument('--jobs', '-j', type=int, default=None) + parser.add_argument('--update', '--force', dest='force', action='store_true', + help='rebuild using this MadGraph checkout\'s pinned dependencies; ' + 'replace an existing installation after validation') + return parser + + +def _copy_source(source, destination, required): + source = Path(source).expanduser().resolve() + for filename in required: + if not (source / filename).is_file(): + raise MadGraph5Error("Invalid source checkout %s: missing %s" % + (source, filename)) + shutil.copytree(source, destination, ignore=shutil.ignore_patterns( + '.git', 'target', 'references', '__pycache__', '.direnv')) + revision = None + # Do not report an enclosing MadGraph checkout's HEAD for an extracted + # dependency tarball. Git worktrees have a .git file instead of a directory. + if (source / '.git').exists(): + try: + revision = subprocess.check_output( + ['git', '-C', str(source), 'rev-parse', 'HEAD'], + stderr=subprocess.DEVNULL, text=True).strip() + except (OSError, subprocess.CalledProcessError): + pass + # A revision alone cannot identify a modified checkout, or a source tarball. + # Bind precisely the files copied for this build without relying on .git. + files = {path.relative_to(destination).as_posix(): + hashlib.sha256(path.read_bytes()).hexdigest() + for path in sorted(destination.rglob('*')) if path.is_file()} + content = json.dumps(files, sort_keys=True, separators=(',', ':')).encode() + return {'source': str(source), 'revision': revision, + 'source_tree_sha256': hashlib.sha256(content).hexdigest(), + 'source_files': len(files)} + + +def _dependency_provenance(bridge): + """Identify the actual locked sources, including transitive Git patches.""" + import tomllib + + manifest = (bridge / 'Cargo.toml').read_bytes() + lock = (bridge / 'Cargo.lock').read_bytes() + try: + packages = tomllib.loads(lock.decode())['package'] + git_dependencies = [ + {'name': package['name'], 'version': package['version'], + 'source': package['source']} + for package in packages + if package.get('source', '').startswith('git+')] + except (UnicodeDecodeError, tomllib.TOMLDecodeError, KeyError, + TypeError, AttributeError) as error: + raise MadGraph5Error('Invalid resolved NinjaRS Cargo.lock: %s' % error) from error + return {'manifest_sha256': hashlib.sha256(manifest).hexdigest(), + 'lock_sha256': hashlib.sha256(lock).hexdigest(), + 'git_dependencies': sorted(git_dependencies, + key=lambda item: (item['name'], item['source']))} + + +def _prepare_overrides(bridge, stage, options): + """Create Cargo patches pointing only inside the isolated build directory.""" + patches = [] + provenance = {} + if options.source: + target = stage / 'sources' / 'ninjars' + provenance['ninjars'] = _copy_source(options.source, target, [ + 'Cargo.toml', 'crates/ninjars/Cargo.toml', + 'crates/ninjars-symbolica/Cargo.toml']) + patches.append('[patch."https://github.com/alphal00p/ninjars"]') + for name in ('ninjars', 'ninjars-symbolica'): + patches.append('%s = { path = %s }' % ( + name, json.dumps(str(target / 'crates' / name)))) + if options.oneloop_source: + target = stage / 'sources' / 'oneloopmaster' + provenance['oneloopmaster'] = _copy_source( + options.oneloop_source, target, ['Cargo.toml']) + patches.extend([ + '[patch."https://github.com/alphal00p/oneloopmaster.git"]', + 'oneloop = { path = %s }' % json.dumps(str(target))]) + if patches: + (bridge / '.cargo').mkdir(exist_ok=True) + (bridge / '.cargo' / 'config.toml').write_text('\n'.join(patches) + '\n') + return provenance + + +def _run(command, cwd, log, environment): + logger.info("NinjaRS: %s", shlex.join(command)) + with log.open('a') as stream: + stream.write('\n$ %s\n' % shlex.join(command)) + stream.flush() + try: + subprocess.run(command, cwd=str(cwd), env=environment, + stdout=stream, stderr=subprocess.STDOUT, check=True) + except (OSError, subprocess.CalledProcessError) as error: + raise MadGraph5Error("NinjaRS installation failed: %s. " + "See %s" % (error, log)) from error + + +def _publish(installed, destination, stage, prefix): + """Publish the validated tree and owned aliases as one recoverable update.""" + backup = stage / 'previous' + common_lib = prefix / 'lib' + alias_stage = None + changed_links = [] + published = created_common_lib = False + try: + existed = common_lib.exists() or common_lib.is_symlink() + common_lib.mkdir(exist_ok=True) + created_common_lib = not existed + # This directory shares the aliases' filesystem even when prefix/lib + # is a symlink or mount. Rename must also work during rollback. + alias_stage = Path(tempfile.mkdtemp(prefix='.ninjars-links-', dir=str(common_lib))) + saved_links = alias_stage / 'previous-links' + new_links = alias_stage / 'links' + saved_links.mkdir() + new_links.mkdir() + if destination.exists() or destination.is_symlink(): + os.replace(destination, backup) + os.replace(installed, destination) + published = True + for name in ('libninjars.a', 'mninjars.mod', CONFIG_NAME, + 'ninjars-native-libs.txt', 'ninjars-link-before.txt'): + link = common_lib / name + # Existing regular user files and directories belong to the user. + if not link.is_symlink() and link.exists(): + continue + previous = None + if link.is_symlink(): + previous = saved_links / name + # Preserve relative and dangling targets verbatim. + previous.symlink_to(os.readlink(link)) + temporary = new_links / name + temporary.symlink_to(os.path.relpath(destination / 'lib' / name, + common_lib.resolve())) + # Journal before rename: cancellation can arrive just after the + # atomic move, before the next Python instruction executes. + changed_links.append((link, previous, temporary)) + os.replace(temporary, link) + except BaseException as error: + failures = [] + for link, previous, temporary in reversed(changed_links): + if temporary.is_symlink(): + continue # The candidate was never published. + try: + if previous is None: + link.unlink() + else: + os.replace(previous, link) + except OSError as restore_error: + failures.append('%s: %s' % (link, restore_error)) + if published or not installed.exists(): + try: + os.replace(destination, installed) + except OSError as restore_error: + failures.append('%s: %s' % (destination, restore_error)) + if backup.exists() or backup.is_symlink(): + try: + os.replace(backup, destination) + except OSError as restore_error: + failures.append('%s: %s' % (backup, restore_error)) + if not failures and alias_stage is not None: + try: + shutil.rmtree(alias_stage) + except OSError as restore_error: + failures.append('%s: %s' % (alias_stage, restore_error)) + if not failures and created_common_lib: + try: + common_lib.rmdir() # Never remove an existing or nonempty directory. + except OSError as restore_error: + failures.append('%s: %s' % (common_lib, restore_error)) + if failures: + raise MadGraph5Error( + "NinjaRS publication failed (%s); rollback could not restore %s. " + "Recovery files and installation logs are retained in %s." + % (error, '; '.join(failures), ', '.join(str(p) for p in + (stage, alias_stage) if p is not None))) from error + raise + return alias_stage + + +def install(mg_root, prefix, arguments=(), fortran_compiler=None, jobs=None): + """Install, smoke-test and publish NinjaRS; return its library directory.""" + try: + options = build_parser().parse_args(list(arguments)) + except SystemExit as error: + if error.code == 0: + return None + raise MadGraph5Error("Invalid 'install ninjars' options.") from error + jobs = options.jobs if options.jobs is not None else jobs + jobs = 1 if jobs is None else jobs + if jobs < 1: + raise MadGraph5Error('NinjaRS --jobs must be a positive integer.') + prefix = Path(options.prefix or prefix).expanduser().resolve() + destination = prefix / 'ninjars' + if destination.exists() and not options.force: + read_config(destination / 'lib') + if not all((destination / 'lib' / name).is_file() for name in + ('libninjars.a', 'mninjars.mod')): + raise MadGraph5Error("Incomplete NinjaRS installation: " + "run 'install ninjars --update'.") + logger.info("NinjaRS is already installed in %s; use --update to rebuild " + "with this checkout's pinned dependencies.", + destination) + return str(destination / 'lib') + + compiler = fortran_compiler or 'gfortran' + for program in ('cargo', 'make', compiler): + if not shutil.which(program): + raise MadGraph5Error("Installing NinjaRS requires %s on PATH. " + "Install Rust >= 1.96 and a Fortran compiler with REAL(16) support." + % program) + + prefix.mkdir(parents=True, exist_ok=True) + stage = Path(tempfile.mkdtemp(prefix='.ninjars-build-', dir=str(prefix))) + bridge = stage / 'bridge' + installed = stage / 'install' + log = stage / 'install.log' + shutil.copytree(Path(mg_root) / 'vendor' / 'ninjars', bridge, + ignore=shutil.ignore_patterns( + 'target', '.git', '*.o', '*.mod', '*.a', 'build.log', + 'ninjars-native-libs.txt', 'ninjars-link-before.txt', 'smoke')) + provenance = _prepare_overrides(bridge, stage, options) + environment = os.environ.copy() + environment['CARGO_BUILD_JOBS'] = str(jobs) + # Honor an explicitly selected Cargo cache. By default keep it under the + # installation prefix so retries can reuse compiled pinned dependencies. + environment['CARGO_TARGET_DIR'] = str(Path( + environment.get('CARGO_TARGET_DIR', prefix / '.ninjars-build-cache') + ).expanduser().resolve()) + # A global Cargo build-dir may otherwise hash the temporary workspace path, + # defeating reuse even when CARGO_TARGET_DIR is stable. + environment.setdefault('CARGO_BUILD_BUILD_DIR', str( + Path(environment['CARGO_TARGET_DIR']) / 'build')) + if provenance: + # Resolve changed path sources while retaining other locked versions. + _run(['cargo', 'metadata', '--format-version=1'], bridge, log, environment) + _run(['make', 'install', 'PREFIX=' + str(installed), 'FC=' + compiler], + bridge, log, environment) + + libdir = installed / 'lib' + try: + native_libs = shlex.split((libdir / 'ninjars-native-libs.txt').read_text()) + link_before = shlex.split((libdir / 'ninjars-link-before.txt').read_text()) + except (OSError, ValueError) as error: + raise MadGraph5Error("NinjaRS build did not produce native link metadata. " + "See %s" % log) from error + config = {'abi_version': ABI_VERSION, 'quad_precision': True, + 'native_libs': native_libs, 'local_sources': provenance, + 'fortran_compiler': compiler, 'link_before': link_before, + 'link_order_version': 1, + 'compiler_runtime': 'gnu-linux-libgcc_s-before-rust', + 'build_provenance': _dependency_provenance(bridge)} + (libdir / CONFIG_NAME).write_text(json.dumps(config, indent=2) + '\n') + # This exercises the installed Fortran module and both numerical domains. + smoke = stage / 'smoke' + _run([compiler, '-I' + str(libdir), str(bridge / 'smoke.f90')] + + link_before + [str(libdir / 'libninjars.a')] + native_libs + ['-o', str(smoke)], + bridge, log, environment) + _run([str(smoke)], bridge, log, environment) + shutil.copy2(log, installed / 'install.log') + shutil.copy2(bridge / 'Cargo.lock', installed / 'Cargo.lock') + shutil.copy2(bridge / 'Cargo.toml', installed / 'Cargo.toml') + + alias_stage = _publish(installed, destination, stage, prefix) + # Publication has committed. A cleanup error must not turn a working + # installation into a reported failure or attempt to restore a backup + # that cleanup may already have partly removed. + for temporary in (alias_stage, stage): + try: + shutil.rmtree(temporary) + except OSError as error: + logger.warning("NinjaRS is installed successfully, but staging cleanup " + "failed in %s: %s", temporary, error) + logger.info("NinjaRS successfully installed in %s.", destination) + return str(destination / 'lib') diff --git a/madgraph/various/process_checks.py b/madgraph/various/process_checks.py index c73724e36d..cfa535d731 100755 --- a/madgraph/various/process_checks.py +++ b/madgraph/various/process_checks.py @@ -60,6 +60,7 @@ import contextlib import madgraph.various.rambo as rambo import madgraph.various.misc as misc +import madgraph.various.ninjars_install as ninjars_install import madgraph.various.progressbar as pbar import madgraph.various.banner as bannermod import madgraph.various.progressbar as pbar @@ -1338,6 +1339,170 @@ def time_matrix_element(self, matrix_element, reusing = False, return None dir_name=res_timings['dir_path'] + # Preserve exact timing inputs/results before profile's stability pass + # rewrites the driver, filters and result.dat. All capture is outside + # make_and_run's existing timers and does not change its calls/settings. + import hashlib + import json + + timing_metadata = { + 'schema': 'madloop-profile-timing-metadata-v1', + 'process': proc_name, + 'export_dir': os.path.abspath(export_dir), + 'subprocess_dir': os.path.abspath(dir_name), + 'requested_split_orders': split_orders, + 'stages': [], + 'selected_timing_helicity': None, + 'per_evaluation_statuses_available': False, + 'limitations': [ + 'Stock CLI timing retains result.dat rather than a complete point/status stream.', + 'Its Fortran point generator has its own state; a Python seed alone does not identify that stream.', + 'Stage point counts can differ between backends because stock timing estimates its run length.', + 'Raw output file freshness is not guaranteed, especially for boot-and-stop; identities are observations only.' + ]} + metadata_dir = pjoin(export_dir, 'SavedRunInfos') + metadata_path = pjoin(metadata_dir, 'profile_timing_metadata.json') + + def timing_file(path, include_text=False): + record = {'path': os.path.abspath(path)} + if os.path.isfile(path): + with open(path, 'rb') as stream: + contents = stream.read() + record.update(sha256=hashlib.sha256(contents).hexdigest(), + bytes=len(contents), realpath=os.path.realpath(path), + mtime_ns=os.stat(path).st_mtime_ns) + if include_text: + record['text'] = contents.decode('utf-8') + else: + record['available'] = False + return record + + def timing_runtime(): + records = {} + seen = set() + library_dir = pjoin(export_dir, 'lib') + for directory, directories, names in os.walk(library_dir, followlinks=True): + real = os.path.realpath(directory) + if real in seen: + directories[:] = [] + continue + seen.add(real) + for name in sorted(names): + if (name.endswith(('.a', '.dylib', '.mod')) or + re.search(r'\.so(?:\.[0-9]+)*$', name) or + name in ('ninjars-config.json', 'ninjars-native-libs.txt', + 'ninjars-link-before.txt')): + path = pjoin(directory, name) + records[os.path.relpath(path, export_dir)] = timing_file(path) + for name in ('Source/make_opts', 'SubProcesses/MadLoop_makefile_definitions'): + records[name] = timing_file(pjoin(export_dir, name)) + return records + + def verify_timing_runtime(): + # Runtime archives are static during the stock timing stages. + # Reuse their once-hashed context; do not stream large archives + # through the cache after every timed invocation. + for record in timing_metadata['runtime_files'].values(): + path = record['path'] + if record.get('available') is False: + unchanged = not os.path.isfile(path) + elif os.path.isfile(path): + current = os.stat(path) + unchanged = (current.st_size == record['bytes'] and + current.st_mtime_ns == record['mtime_ns'] and + os.path.realpath(path) == record['realpath']) + else: + unchanged = False + if not unchanged: + raise MadGraph5Error('Timing runtime changed during measurement: %s'%path) + + def save_timing_metadata(): + if not os.path.isdir(metadata_dir): + os.makedirs(metadata_dir) + with open(metadata_path, 'w') as stream: + json.dump(timing_metadata, stream, indent=2, allow_nan=False) + stream.write('\n') + + def capture_timing_stage(name, compile_seconds, wall_seconds, ram_usage): + verify_timing_runtime() + driver_path = pjoin(dir_name, 'check_sa.f') + loop_path = pjoin(dir_name, 'loop_matrix.f') + with open(driver_path) as stream: + driver = stream.read() + with open(loop_path) as stream: + loop = stream.read() + # Fixed-form continuation markers are irrelevant to these literals. + flat = re.sub(r'\n [^ 0] ?', '', driver) + npoints = re.search(r'NPSPOINTS\s*=\s*([0-9]+)', flat, re.I) + readps = re.search(r'READPS\s*=\s*(\.TRUE\.|\.FALSE\.)', flat, re.I) + helicity = re.search(r'SLOOPMATRIXHEL_THRES\s*\(\s*P\s*,\s*([+-]?[0-9]+)', flat, re.I) + target = re.search(r'SET_COUPLINGORDERS_TARGET\s*\(\s*([+-]?[0-9]+)', flat, re.I) + flags = {} + for flag in ('SKIPLOOPEVAL', 'BOOTANDSTOP'): + values = re.findall(flag+r'\s*=\s*(\.TRUE\.|\.FALSE\.)', loop, re.I) + flags[flag] = (values[0].upper() == '.TRUE.' if values and + len(set(value.upper() for value in values)) == 1 else None) + effective = dict(self.get_MadLoop_Params(pjoin(export_dir, 'Cards', 'MadLoopParams.dat'))) + source_dir = pjoin(metadata_dir, '%02d_%s'%(len(timing_metadata['stages']), name)) + if not os.path.isdir(source_dir): + os.makedirs(source_dir) + source_snapshots = {} + for filename, source_path in (('check_sa.f', driver_path), ('loop_matrix.f', loop_path)): + target_path = pjoin(source_dir, filename) + shutil.copyfile(source_path, target_path) + source_snapshots[filename] = timing_file(target_path) + # Match LHA_loadcard: direct file, then Cards in cwd and 5 parents. + physical_card_paths = [pjoin(dir_name,'param_card.dat')] + physical_card_paths.extend(pjoin(dir_name,*([os.pardir]*depth), + 'Cards','param_card.dat') for depth in range(6)) + physical_card_path = next((path for path in physical_card_paths + if os.path.isfile(path)),physical_card_paths[0]) + stage = { + 'name': name, + 'actual_npoints': int(npoints.group(1)) if npoints else None, + 'read_ps': readps.group(1).upper() == '.TRUE.' if readps else None, + 'helicity_one_based_index': int(helicity.group(1)) if helicity else -1, + 'split_orders_target': int(target.group(1)) if target else None, + 'energy_assignment_lines': [line.strip() for line in driver.splitlines() + if re.search(r'\bSQRTS\s*=', line, re.I)], + 'flags': flags, + 'check_sa': timing_file(driver_path), + 'loop_matrix': timing_file(loop_path), + 'executable': timing_file(pjoin(dir_name, 'check')), + 'source_snapshots': source_snapshots, + 'parameter_card': timing_file(pjoin(export_dir, 'Cards', 'param_card.dat'), True), + 'subprocess_parameter_card': timing_file(physical_card_path, True), + 'effective_madloop_card': timing_file(pjoin(export_dir, 'Cards', 'MadLoopParams.dat'), True), + 'madloop_card_aliases': [timing_file(path, True) for path in sorted(glob.glob( + pjoin(export_dir, 'SubProcesses', '**', 'MadLoopParams.dat'), recursive=True))], + 'effective_madloop_parameters': effective, + 'runtime_files_reference': 'runtime_files', + 'runtime_stat_unchanged': True, + 'raw_outputs': {'result.dat': timing_file(pjoin(dir_name, 'result.dat'), True)}, + 'raw_output_freshness_verified': False, + 'compile_seconds': compile_seconds, + 'wall_seconds': wall_seconds, + 'ram_usage': ram_usage, + 'boot_wall_seconds': (wall_seconds if name == 'boot' else res_timings.get('Booting_time')), + 'derived_seconds_per_point': None, + 'per_evaluation_statuses_available': False} + if name in ('polarized_full', 'unpolarized_full', 'unpolarized_skip', 'polarized_skip'): + denominator = stage['actual_npoints'] + if denominator and stage['boot_wall_seconds'] is not None and wall_seconds is not None: + stage['derived_seconds_per_point'] = (wall_seconds-stage['boot_wall_seconds'])/denominator + timing_metadata['stages'].append(stage) + save_timing_metadata() + + def finish_timing_metadata(): + verify_timing_runtime() + # Copy before adding the metadata reference to the return dictionary. + timing_metadata['timing_result'] = copy.deepcopy(res_timings) + save_timing_metadata() + res_timings['timing_metadata'] = {'schema': timing_metadata['schema'], + 'path': os.path.abspath(metadata_path)} + + timing_metadata['runtime_files'] = timing_runtime() + def check_disk_usage(path): return subprocess.check_output( [f"du -shc {path}"], shell=True, encoding="utf8" @@ -1361,10 +1526,12 @@ def check_disk_usage(path): read_ps = False, npoints = 3, hel_config = -1, split_orders=split_orders) compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + capture_timing_stage('estimate', compile_time, run_time, ram_usage) time_per_ps_estimate = run_time/3.0 self.boot_time_setup(dir_name,bootandstop=True) compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + capture_timing_stage('boot', compile_time, run_time, ram_usage) res_timings['Booting_time'] = run_time self.boot_time_setup(dir_name,bootandstop=False) @@ -1389,6 +1556,28 @@ def check_disk_usage(path): res_timings['n_contrib_hel']=n_contrib_hel res_timings['n_tot_hel']=len(helicities) + helicity_path = pjoin(dir_name, 'MadLoop5_resources', '%sHelConfigs.dat'%proc_prefix) + physical_tuple = None + if os.path.isfile(helicity_path): + with open(helicity_path) as stream: + configurations = [line.split() for line in stream if line.strip()] + if 0 < contributing_hel <= len(configurations): + physical_tuple = [int(value) for value in configurations[contributing_hel-1]] + timing_metadata['selected_timing_helicity'] = { + 'one_based_index': contributing_hel, + 'physical_tuple': physical_tuple, + 'helicity_configurations': timing_file(helicity_path, True), + 'filter': timing_file(pjoin(dir_name, 'MadLoop5_resources', '%sHelFilter.dat'%proc_prefix), True), + 'filter_tokens': list(helicities), + 'contributing_count': n_contrib_hel, + 'total_count': len(helicities)} + raw_backends = self.get_MadLoop_Params( + pjoin(export_dir, 'Cards', 'MadLoopParams.dat'))['MLReductionLib'] + timing_metadata['reduction_backends'] = ([int(tool.strip()) for tool in raw_backends.split('|') + if tool.strip()] if isinstance(raw_backends, str) else [int(tool) for tool in raw_backends]) + timing_metadata['backend_labels'] = [bannermod.MadLoopParam._ID_reduction_tool_map.get( + tool, str(tool)) for tool in timing_metadata['reduction_backends']] + save_timing_metadata() # We aim at a 30 sec run if not make_it_quick: @@ -1403,6 +1592,7 @@ def check_disk_usage(path): read_ps = False, npoints = target_pspoints_number*2, \ hel_config = contributing_hel, split_orders=split_orders) compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + capture_timing_stage('polarized_full', compile_time, run_time, ram_usage) if compile_time == None: return None @@ -1418,6 +1608,7 @@ def check_disk_usage(path): split_orders=split_orders) compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name, checkRam=True) + capture_timing_stage('unpolarized_full', compile_time, run_time, ram_usage) if compile_time == None: return None res_timings['run_unpolarized_total']=\ @@ -1425,6 +1616,7 @@ def check_disk_usage(path): res_timings['ram_usage'] = ram_usage if not self.loop_optimized_output: + finish_timing_metadata() return res_timings # For the loop optimized output, we also check the time spent in @@ -1440,6 +1632,7 @@ def check_disk_usage(path): read_ps = False, npoints = target_pspoints_number, hel_config = -1, split_orders=split_orders) compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + capture_timing_stage('unpolarized_skip', compile_time, run_time, ram_usage) if compile_time == None: return None res_timings['run_unpolarized_coefs']=\ (run_time-res_timings['Booting_time'])/target_pspoints_number @@ -1448,6 +1641,7 @@ def check_disk_usage(path): read_ps = False, npoints = target_pspoints_number*2, \ hel_config = contributing_hel, split_orders=split_orders) compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + capture_timing_stage('polarized_skip', compile_time, run_time, ram_usage) if compile_time == None: return None res_timings['run_polarized_coefs']=\ (run_time-res_timings['Booting_time'])/(target_pspoints_number*2) @@ -1455,6 +1649,7 @@ def check_disk_usage(path): # Restitute the original file. self.skip_loop_evaluation_setup(dir_name,skip=False) + finish_timing_metadata() return res_timings #=============================================================================== @@ -1484,6 +1679,28 @@ def check_matrix_element_stability(self, matrix_element,options=None, isinstance(matrix_element, base_objects.Process))) # Helper functions + def relative_spread(values): + """Keep exact zeros and zero-mean disagreements distinguishable.""" + spread = max(values) - min(values) + average = abs(sum(values) / len(values)) + if not (math.isfinite(spread) and math.isfinite(average)): + # Preserve the original arithmetic unless finite inputs overflow. + scale = max(abs(value) for value in values) + normalized = [value / scale for value in values] + spread = max(normalized) - min(normalized) + average = abs(sum(normalized) / len(normalized)) + if average == 0.0: + return 0.0 if spread == 0.0 else float('inf') + return spread / average + + def stop_stability_checker(checker): + # Invalid results abort this run; do not leave its checker alive. + try: + checker.kill() + except OSError: + pass + checker.wait() + def format_PS_point(ps, rotation=0): """ Write out the specified PS point to the file dir_path/PS.input while rotating it if rotation!=0. We consider only rotations of 90 @@ -1550,16 +1767,22 @@ def pick_PS_point(proc, options): tools=misc.make_unique(tools) # remove the duplication ones # not self-contained tir libraries - tool_var={'pjfry':2,'golem':4,'samurai':5,'ninja':6,'collier':7} - for tool in ['pjfry','golem','samurai','ninja','collier']: + tool_var={'pjfry':2,'golem':4,'samurai':5,'ninja':6,'collier':7,'ninjars':8} + for tool in ['pjfry','golem','samurai','ninja','collier','ninjars']: tool_dir='%s_dir'%tool if not tool_dir in self.tir_dir: + if tool == 'ninjars' and tool_var[tool] in tools: + raise MadGraph5Error("Requested NinjaRS library is unavailable. " + "Run 'install ninjars'.") continue tool_libpath=self.tir_dir[tool_dir] tool_libname="lib%s.a"%tool if (not isinstance(tool_libpath,str)) or (not os.path.exists(tool_libpath)) \ or (not os.path.isfile(pjoin(tool_libpath,tool_libname))): if tool_var[tool] in tools: + if tool == 'ninjars': + raise MadGraph5Error("Requested NinjaRS library is unavailable. " + "Run 'install ninjars'.") tools.remove(tool_var[tool]) if not tools: return None @@ -1570,7 +1793,7 @@ def pick_PS_point(proc, options): else: process = matrix_element proc_name = process.shell_string()[2:] - export_dir=pjoin(self.mg_root,("SAVED" if keep_folder else "")+\ + export_dir=pjoin(self.output_path,("SAVED" if keep_folder else "")+\ temp_dir_prefix+"_%s"%proc_name) tools_name=bannermod.MadLoopParam._ID_reduction_tool_map @@ -1597,7 +1820,7 @@ def pick_PS_point(proc, options): # The exceptional PS points are those which stay unstable in quad prec. Exceptional_PS_points = [] - MLoptions=MLOptions + MLoptions=copy.deepcopy(MLOptions) MLoptions["MLReductionLib"]=tool clean = (tool==tools[0]) and not nPoints==0 if infos_IN==None or (tool_name not in infos_IN): @@ -1745,7 +1968,7 @@ def pick_PS_point(proc, options): # identical PS points with vec(p_1)=-vec(p_2), it is best not to remove # the helicityFilter double check if len(process['legs'])==3: - self.fix_MadLoopParamCard(dir_path, mp=False, + self.fix_MadLoopParamCard(pjoin(export_dir,'Cards'), mp=False, loop_filter=False, DoubleCheckHelicityFilter=True) StabChecker = subprocess.Popen([pjoin(dir_path,'StabilityCheckDriver')], @@ -1795,14 +2018,14 @@ def pick_PS_point(proc, options): split_orders=split_orders)) dp_dict['Rotation%i'%rotation]=dp_res[-1] # Make sure all results make sense - if any([not res for res in dp_res]): + if any(res is None or not math.isfinite(res) for res in dp_res): + stop_stability_checker(StabChecker) return None - dp_accuracy =((max(dp_res)-min(dp_res))/ - abs(sum(dp_res)/len(dp_res))) + dp_accuracy = relative_spread(dp_res) dp_dict['Accuracy'] = dp_accuracy if dp_accuracy>accuracy_threshold: - if tool in [1,6]: - # Only CutTools or Ninja can use QP + if tool in [1,6,8]: + # CutTools, Ninja and NinjaRS can use QP UPS = [i,p] qp_res=[] PSPoint = format_PS_point(p,0) @@ -1818,17 +2041,17 @@ def pick_PS_point(proc, options): split_orders=split_orders)) qp_dict['Rotation%i'%rotation]=qp_res[-1] # Make sure all results make sense - if any([not res for res in qp_res]): + if any(res is None or not math.isfinite(res) for res in qp_res): + stop_stability_checker(StabChecker) return None - qp_accuracy = ((max(qp_res)-min(qp_res))/ - abs(sum(qp_res)/len(qp_res))) + qp_accuracy = relative_spread(qp_res) qp_dict['Accuracy']=qp_accuracy if qp_accuracy>accuracy_threshold: EPS = [i,p] else: - # Simply consider the point as a UPS when not using - # CutTools + # Keep a UPS without an external QP evaluation for + # reduction libraries that do not support this path. UPS = [i,p] except KeyboardInterrupt: @@ -1955,6 +2178,18 @@ def get_me_value(cls, StabChecker, PSpoint, mode, hel=-1, mu_r=-1.0, raise MadGraph5Error("The MadLoop stability checker crashed with return code = %d, and last output:\n\nstdout: %s\nstderr: %s\n"%\ (ret_code, last_non_empty, error)) + # A missing finite record must not inherit the general parser's + # zero default: an explicitly printed FIN 0 is a valid result. + finite_rows = [line.split() for line in res.splitlines() + if line.split()[:1] == ['FIN']] + if len(finite_rows) != 1 or len(finite_rows[0]) != 2: + return None + try: + finite_value = float(finite_rows[0][1]) + except ValueError: + return None + if not math.isfinite(finite_value): + return None return cls.parse_check_output(res,format='tuple')[0][0] except IOError as e: logging.warning("Error while running MadLoop. Exception = %s"%str(e)) @@ -2199,19 +2434,35 @@ def check_profile(process_definition, param_card = None,cuttools="",tir={}, if not myProfiler.loop_optimized_output: MLoptions={} else: - MLoptions=MLOptions + MLoptions=copy.deepcopy(MLOptions) + # Prefer an installed NinjaRS backend for Born-process profiles unless + # the caller explicitly selected a reduction list. + has_born = (matrix_element.get('has_born') if reusing else + matrix_element.get('processes')[0].get('has_born')) + if 'MLReductionLib' not in MLoptions or not MLoptions['MLReductionLib']: + MLoptions['MLReductionLib'] = ninjars_install.default_reduction_library( + has_born, tir.get('ninjars_dir')) timing2 = myProfiler.time_matrix_element(matrix_element, reusing, param_card, keep_folder=keep_folder,options=options, MLOptions = MLoptions) - timing2['reduction_tool'] = MLoptions['MLReductionLib'][0] - if timing2 == None: return None, None + timing2['reduction_tool'] = MLoptions.get('MLReductionLib', [1])[0] + # The timing info is made of the merged two dictionaries timing = dict(list(timing1.items())+list(timing2.items())) + if 'timing_metadata' in timing: + import json + metadata_path = timing['timing_metadata']['path'] + with open(metadata_path) as stream: + metadata = json.load(stream) + metadata['profile_timing_result'] = copy.deepcopy(timing) + with open(metadata_path, 'w') as stream: + json.dump(metadata, stream, indent=2, allow_nan=False) + stream.write('\n') stability = myProfiler.check_matrix_element_stability(matrix_element, options=options, infos_IN=timing,param_card=param_card, keep_folder = keep_folder, @@ -2251,7 +2502,7 @@ def check_stability(process_definition, param_card = None,cuttools="",tir={}, if not myStabilityChecker.loop_optimized_output: MLoptions = {} else: - MLoptions = MLOptions + MLoptions = copy.deepcopy(MLOptions) # Make sure that the poles computation is disabled for COLLIER if 'COLLIERComputeUVpoles' not in MLoptions: MLoptions['COLLIERComputeUVpoles']=False @@ -2284,6 +2535,8 @@ def check_stability(process_definition, param_card = None,cuttools="",tir={}, MLoptions["MLReductionLib"].extend([6]) if "collier_dir" in tir: MLoptions["MLReductionLib"].extend([7]) + if "ninjars_dir" in tir: + MLoptions["MLReductionLib"].extend([8]) stability = myStabilityChecker.check_matrix_element_stability(matrix_element, options=options,param_card=param_card, @@ -2320,7 +2573,7 @@ def check_timing(process_definition, param_card= None, cuttools="",tir={}, if not myTimer.loop_optimized_output: MLoptions = {} else: - MLoptions = MLOptions + MLoptions = copy.deepcopy(MLOptions) # Make sure that the poles computation is disabled for COLLIER if 'COLLIERComputeUVpoles' not in MLoptions: MLoptions['COLLIERComputeUVpoles']=False @@ -2329,10 +2582,13 @@ def check_timing(process_definition, param_card= None, cuttools="",tir={}, # And the COLLIER global cache is active, if not specified if 'COLLIERGlobalCache' not in MLoptions: MLoptions['COLLIERGlobalCache']=-1 - # And time NINJA by default if not specified: + # Prefer installed NinjaRS for Born processes when not specified. if 'MLReductionLib' not in MLoptions or \ len(MLoptions['MLReductionLib'])==0: - MLoptions['MLReductionLib'] = [6] + has_born = (matrix_element.get('has_born') if reusing else + matrix_element.get('processes')[0].get('has_born')) + MLoptions['MLReductionLib'] = ninjars_install.default_reduction_library( + has_born, tir.get('ninjars_dir')) timing2 = myTimer.time_matrix_element(matrix_element, reusing, param_card, keep_folder = keep_folder, options=options, @@ -2344,7 +2600,7 @@ def check_timing(process_definition, param_card= None, cuttools="",tir={}, # Return the merged two dictionaries res = dict(list(timing1.items())+list(timing2.items())) res['loop_optimized_output']=myTimer.loop_optimized_output - res['reduction_tool'] = MLoptions['MLReductionLib'][0] + res['reduction_tool'] = MLoptions.get('MLReductionLib', [1])[0] return res #=============================================================================== @@ -2637,12 +2893,27 @@ def output_stability(stability, output_path, reusing=False): def accuracy(eval_list): """ Compute the accuracy from different evaluations.""" - return (2.0*(max(eval_list)-min(eval_list))/ - abs(max(eval_list)+min(eval_list))) + largest, smallest = max(eval_list), min(eval_list) + spread = largest-smallest + denominator = abs(largest+smallest) + if not (math.isfinite(2.0*spread) and math.isfinite(denominator)): + scale = max(abs(largest),abs(smallest)) + largest, smallest = largest/scale, smallest/scale + spread = largest-smallest + denominator = abs(largest+smallest) + if denominator == 0.0: + return 0.0 if spread == 0.0 else float('inf') + return 2.0*spread/denominator def best_estimate(eval_list): """ Returns the best estimate from different evaluations.""" - return (max(eval_list)+min(eval_list))/2.0 + largest, smallest = max(eval_list), min(eval_list) + total = largest+smallest + return total/2.0 if math.isfinite(total) else largest/2.0+smallest/2.0 + + def log_accuracy(value): + # A zero diagnostic ratio has logarithm -inf; do not alter raw samples. + return float('-inf') if value == 0.0 else math.log(value)/math.log(10) def loop_direction_test_power(eval_list): """ Computes the loop direction test power P is computed as follow: @@ -2660,18 +2931,20 @@ def loop_direction_test_power(eval_list): other_evals = [eval[key] for key in eval.keys() if key not in \ ['CTModeB','Accuracy']] if accuracy(other_evals)!=0.0 and accuracy(loop_dir_evals)!=0.0: - powers.append(accuracy(loop_dir_evals)/accuracy(other_evals)) + power=accuracy(loop_dir_evals)/accuracy(other_evals) + if not math.isnan(power): + powers.append(power) n_fail=0 for p in powers: - if (math.log(p)/math.log(10))<-3: + if log_accuracy(p)<-3: n_fail+=1 if len(powers)==0: return (None,None,None) - return (math.log(median(powers))/math.log(10), - math.log(min(powers))/math.log(10), + return (log_accuracy(median(powers)), + log_accuracy(min(powers)), n_fail/len(powers)) def test_consistency(dp_eval_list, qp_eval_list): @@ -2687,15 +2960,17 @@ def test_consistency(dp_eval_list, qp_eval_list): if key!='Accuracy'] if (abs(best_estimate(qp_evals)-best_estimate(dp_evals)))!=0.0 and \ accuracy(dp_evals)!=0.0: - consistencies.append(accuracy(dp_evals)/(abs(\ - best_estimate(qp_evals)-best_estimate(dp_evals)))) + consistency=accuracy(dp_evals)/(abs(\ + best_estimate(qp_evals)-best_estimate(dp_evals))) + if not math.isnan(consistency): + consistencies.append(consistency) if len(consistencies)==0: return (None,None,None) - return (math.log(median(consistencies))/math.log(10), - math.log(min(consistencies))/math.log(10), - math.log(max(consistencies))/math.log(10)) + return (log_accuracy(median(consistencies)), + log_accuracy(min(consistencies)), + log_accuracy(max(consistencies))) def median(orig_list): """ Find the median of a sorted float list. """ @@ -2709,6 +2984,22 @@ def median(orig_list): # Define shortcut f = format_output opt = stability['loop_optimized_output'] + for toolname, tool_data in stability['Stability'].items(): + for precision in ['DP_stability','QP_stability']: + for evaluation in tool_data[precision]: + if precision == 'QP_stability' and evaluation == {}: + continue + try: + invalid = (math.isnan(evaluation['Accuracy']) or + evaluation['Accuracy'] < 0.0 or + any(not math.isfinite(value) for key,value in + evaluation.items() if key != 'Accuracy')) + except (KeyError,TypeError,ValueError): + invalid = True + if invalid: + raise MadGraph5Error('Invalid stability data for %s (%s). ' + 'Remove stale saved stability data and rerun without -reuse.' + % (toolname,precision)) mode = 'optimized' if opt else 'default' process = stability['Process'] @@ -2790,12 +3081,12 @@ def median(orig_list): # Use nicer name for the XML tag in the log file xml_toolname = {'GOLEM95':'GOLEM','IREGI':'IREGI', 'CUTTOOLS':'CUTTOOLS','PJFRY++':'PJFRY', - 'NINJA':'NINJA','SAMURAI':'SAMURAI', + 'NINJA':'NINJA','NINJARS':'NINJARS','SAMURAI':'SAMURAI', 'COLLIER':'COLLIER'}[toolname.upper()] if len(UPS)>0: res_str_i = "\nDetails of the %d/%d UPS encountered by %s\n"\ %(len(UPS),nPS,toolname) - prefix = 'DP' if toolname=='CutTools' else '' + prefix = 'DP' if toolname in ['CutTools','Ninja','NinjaRS'] else '' res_str_i += "|= %s Median inaccuracy.......... %s\n"\ %(prefix,f(median(UPS_stability_DP),'%.2e')) res_str_i += "|= %s Max accuracy............... %s\n"\ @@ -2804,7 +3095,7 @@ def median(orig_list): %(prefix,f(max(UPS_stability_DP),'%.2e')) (pmed,pmin,pfrac)=loop_direction_test_power(\ [stab['DP_stability'][U[0]] for U in UPS]) - if toolname=='CutTools': + if toolname in ['CutTools','Ninja','NinjaRS']: res_str_i += "|= UPS DP loop_dir test power.... %s,%s\n"\ %(f(pmed,'%.1f'),f(pmin,'%.1f')) res_str_i += "|= UPS DP fraction with power<-3. %s\n"\ @@ -2885,19 +3176,16 @@ def median(orig_list): logFile.write('\n'%xml_toolname.upper()) # Set the x-range so that it spans [10**-17,10**(min_digit_accuracy)] if max(DP_stability)>0.0: - min_digit_acc=int(math.log(max(DP_stability))/math.log(10)) + largest_accuracy=max(DP_stability) + min_digit_acc=(int(math.log(largest_accuracy)/math.log(10)) + if math.isfinite(largest_accuracy) else 0) if min_digit_acc>=0: min_digit_acc = min_digit_acc+1 + min_digit_acc=max(-16,min(308,min_digit_acc)) accuracies=[10**(-17+(i/5.0)) for i in range(5*(17+min_digit_acc)+1)] else: - logFile.writelines('%.4e %.4e\n'%(accuracies[i], 0.0) for i in \ - range(len(accuracies))) - logFile.write('\n') - res_str_i += '\nPerfect accuracy over all the trial PS points. No plot'+\ - ' is output then.' - logFile.write('Perfect accuracy over all the trial PS points.') - res_str +=res_str_i - continue + accuracies=[10**(-17+(i/5.0)) for i in range(5*17+1)] + res_str_i += '\nPerfect accuracy over all the trial PS points.' accuracy_dict[toolname]=accuracies if max(accuracies) > max_acc: max_acc=max(accuracies) diff --git a/madgraph/various/q_polynomial.py b/madgraph/various/q_polynomial.py index 9d6349f962..9d6bc63ff8 100755 --- a/madgraph/various/q_polynomial.py +++ b/madgraph/various/q_polynomial.py @@ -474,7 +474,109 @@ def format_power(pow): return '\n\n'.join(subroutines) - def write_compact_wl_updater(self,r_1,r_2,loop_over_vertex_coefs_first=True): + def _sparse_qp_updater_parts(self, r_1, r_2, compact, terminal=False): + """Emit exact-zero guards, with the original exceptional path intact. + + Restrict pruning to finite binary128 operands and nearest rounding. + Integer classification avoids signaling on a NaN in an empty update. + """ + na = get_number_of_coefs_for_rank(r_1)-1 + nb = get_number_of_coefs_for_rank(r_2)-1 + name = '%sUPDATE_WL_%d_%d' % (self.sub_prefix, r_1, r_2) + declarations = """ TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST +""" + if compact: + declarations += """ LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L +""" + else: + declarations += """ LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K +""" + preparation = """CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) +WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST +IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:{na},1:LCUT_SIZE),KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:{na},1:LCUT_SIZE)))).OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:{nb},1:IN_SIZE),KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:{nb},1:IN_SIZE))))) THEN + CALL {name}_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN +ENDIF +""".format(na=na, nb=nb, name=name) + if terminal: + declarations += " LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT\n" + # Private generated calls consume only the diagonal. The bounded + # operands cannot overflow/underflow or raise invalid; omitted + # inexact operations are already sticky and cannot trap. + preparation = """CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) +WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST +WL_ALREADY=WL_ENTRY_INEXACT +WL_HALT=.TRUE. +IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) +IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT.OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.{nca}.GT.65536.OR.{ncb}.GT.65536.OR..NOT.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:{na},1:LCUT_SIZE),KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:{na},1:LCUT_SIZE)))).OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:{nb},1:IN_SIZE),KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:{nb},1:IN_SIZE))))) THEN + CALL {name}(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN +ENDIF +""".format(na=na, nb=nb, nca=na+1, ncb=nb+1, name=name) + if compact: + preparation += """WL_AZERO(1:IN_SIZE,0:{na},1:LCUT_SIZE)=.FALSE. +IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,{na} + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)).AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO +ENDIF +""".format(na=na) + else: + preparation += """WL_SKIP=.FALSE. +IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:{na},1:LCUT_SIZE),KIND=16))).AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:{na},1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:{nb},WL_K),KIND=16))).AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:{nb},WL_K))))) WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:{nb},WL_K).EQ.0) + ENDDO + ENDIF + ENDDO +ENDIF +""".format(na=na, nb=nb) + # ASSOCIATE avoids a mutable local scratch array: FKS uses + # -fno-automatic, which would give it SAVE, forbidden in ELEMENTAL code. + classifier = """CONTAINS +ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X).NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE +END FUNCTION +""" + if terminal: + classifier += """ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X).NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3-BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15).GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE +END FUNCTION +""" + return declarations, preparation, classifier + + def write_compact_wl_updater(self,r_1,r_2,loop_over_vertex_coefs_first=True, + _sparse=True, terminal=False): """ Give out the subroutine to update a polynomial of rank r_1 with one of rank r_2 """ @@ -490,25 +592,39 @@ def write_compact_wl_updater(self,r_1,r_2,loop_over_vertex_coefs_first=True): # coefficients equal to zero lines=[] + sparse = (_sparse and self.coef_format == 'complex*32' and + loop_over_vertex_coefs_first) + if terminal and not sparse: + raise PolynomialError("Terminal updates require the sparse QP vertex-first kernel") + declarations = preparation = classifier = '' + if sparse: + declarations, preparation, classifier = \ + self._sparse_qp_updater_parts(r_1, r_2, True, terminal) # Start by writing out the header: lines.append( """SUBROUTINE %(sub_prefix)sUPDATE_WL_%(r_1)d_%(r_2)d(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) USE %(proc_prefix)sPOLYNOMIAL_CONSTANTS - implicit none +%(ieee_use)s implicit none INTEGER I,J,K,L,M %(coef_format)s A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) %(coef_format)s B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) %(coef_format)s OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE - INTEGER NEW_POSITION +%(sparse_declarations)s INTEGER NEW_POSITION %(coef_format)s UPDATER_COEF """%{'sub_prefix':self.sub_prefix,'proc_prefix':self.proc_prefix, - 'r_1':r_1,'r_2':r_2,'coef_format':self.coef_format}) + 'r_1':r_1,'r_2':r_2,'coef_format':self.coef_format, + 'ieee_use':' USE, INTRINSIC :: IEEE_ARITHMETIC\n' if sparse else '', + 'sparse_declarations':declarations}) # Start the loop on the elements i,j of the vector OUT(i,coef,j) lines.append("C Welcome to the computational heart of MadLoop...") + if sparse: + lines.append(preparation) if loop_over_vertex_coefs_first: + # Traverse coefficients within each last-index array plane. Keeping + # M and K outside I preserves the summation order of every output. lines.append("OUT(:,:,:)=%s"%self.czero) lines.append( """DO J=1,OUT_SIZE @@ -516,9 +632,9 @@ def write_compact_wl_updater(self,r_1,r_2,loop_over_vertex_coefs_first=True): DO K=1,IN_SIZE UPDATER_COEF = B(J,M,K) IF (UPDATER_COEF.EQ.%s) CYCLE - DO L=0,%d - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE +{zero_prepare} DO I=1,LCUT_SIZE + DO L=0,%d +{zero_guard} NEW_POSITION = COMB_COEF_POS(L,M) OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I)*UPDATER_COEF ENDDO ENDDO @@ -528,6 +644,12 @@ def write_compact_wl_updater(self,r_1,r_2,loop_over_vertex_coefs_first=True): """%(get_number_of_coefs_for_rank(r_2)-1, self.czero, get_number_of_coefs_for_rank(r_1)-1)) + lines[-1] = lines[-1].replace('{zero_prepare}', """ WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) +""" if sparse else '').replace('{zero_guard}', """ IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF +""" if sparse else '') else: lines.append("OUT(:,:,:)=%s"%self.czero) lines.append( @@ -549,11 +671,211 @@ def write_compact_wl_updater(self,r_1,r_2,loop_over_vertex_coefs_first=True): self.czero, get_number_of_coefs_for_rank(r_2)-1)) + if sparse: + lines.append(classifier) lines.append("END") # return the subroutine - return '\n'.join(lines) + result = '\n'.join(lines) + if terminal: + name = '%sUPDATE_WL_%d_%d' % (self.sub_prefix, r_1, r_2) + result = result.replace('SUBROUTINE '+name+'(', + 'SUBROUTINE '+name.replace('UPDATE_WL_', 'TERMINAL_WL_')+'(', 1) + result = result.replace('OUT_SIZE,OUT)\n', 'OUT_SIZE,OUT,WL_ENTRY_INEXACT)\n', 1) + result = result.replace(' USE, INTRINSIC :: IEEE_ARITHMETIC\n', + ' USE, INTRINSIC :: IEEE_ARITHMETIC\n USE, INTRINSIC :: IEEE_EXCEPTIONS\n', 1) + result = result.replace(' DO I=1,LCUT_SIZE', + ' DO I=J,MIN(J,LCUT_SIZE)', 1) + elif sparse: + name = '%sUPDATE_WL_%d_%d' % (self.sub_prefix, r_1, r_2) + dense = self.write_compact_wl_updater( + r_1, r_2, loop_over_vertex_coefs_first, _sparse=False) + result += '\n\n' + dense.replace( + 'SUBROUTINE '+name+'(', 'SUBROUTINE '+name+'_DENSE(', 1) + return result + + def write_factorized_wl_updater(self, rank, vertex, terminal=False): + """Private QP FFV updater sharing the four derivative contractions. + + The two supported fermion orientations have derivative rows related by + signed real/imaginary permutations. Check that relation on the actual + stored coefficients before forming B(:,1,:)*A once. This changes sum + association, so require bounded finite binary128 inputs, nearest + rounding, disabled traps and an already-sticky entry INEXACT flag. + Unsupported inputs use the unchanged public updater. - def write_expanded_wl_updater(self,r_1,r_2): + Only generated calls selected by the exporter may use these helpers. + A terminal call additionally needs the existing proof that only its + diagonal is consumed. Public routines and DP arithmetic are untouched. + """ + if vertex.startswith('MP_'): + vertex = vertex[3:] + if (self.coef_format != 'complex*32' or rank not in (2, 3, 4) or + vertex not in ('FFV1L1_2', 'FFV1L2_1')): + raise PolynomialError("Factorized updates require QP FFV1L1_2 or " + "FFV1L2_1 at ranks 2, 3 or 4") + + # Entries are (source row of B(:,q0,:), real phase, imaginary phase). + # Every model's rounded coefficients must satisfy these identities at + # runtime; the routine name alone never authorizes a factorization. + common_q0 = ((1, 1, 0), (2, 1, 0), (3, 1, 0), (4, 1, 0)) + common_q2 = ((2, 0, 1), (1, 0, -1), (4, 0, -1), (3, 0, 1)) + if vertex == 'FFV1L1_2': + rows = (common_q0, + ((2, -1, 0), (1, -1, 0), (4, 1, 0), (3, 1, 0)), + common_q2, + ((1, -1, 0), (2, 1, 0), (3, 1, 0), (4, -1, 0))) + else: + rows = (common_q0, + ((2, 1, 0), (1, 1, 0), (4, -1, 0), (3, -1, 0)), + common_q2, + ((1, 1, 0), (2, -1, 0), (3, -1, 0), (4, 1, 0))) + required = [set(row[j][0] for row in rows) for j in range(4)] + + def rotate(value, real, imag): + if (real, imag) == (1, 0): + return value + if (real, imag) == (-1, 0): + return "(-%s)" % value + if (real, imag) == (0, 1): + return "CMPLX(-AIMAG(%s),REAL(%s,KIND=16),KIND=16)" % (value, value) + return "CMPLX(AIMAG(%s),-REAL(%s,KIND=16),KIND=16)" % (value, value) + + name = self.sub_prefix + ('TERMINAL' if terminal else 'UPDATE') + name += '_WL_%d_1' % rank + private = name + '_FACTOR_' + vertex + if len(private) > 63: + raise PolynomialError("Factorized updater name exceeds 63 characters") + source = self.write_compact_wl_updater(rank, 1, terminal=terminal) + if not terminal: + source = source.split('\n\nSUBROUTINE ' + name + '_DENSE(', 1)[0] + source = source.replace('SUBROUTINE ' + name + '(', + 'SUBROUTINE ' + private + '(', 1) + if 'USE, INTRINSIC :: IEEE_EXCEPTIONS' not in source: + source = source.replace(' implicit none', + ' USE, INTRINSIC :: IEEE_EXCEPTIONS\n implicit none', 1) + if not terminal: + source = source.replace('OUT_SIZE,OUT)\n', + 'OUT_SIZE,OUT,WL_ENTRY_INEXACT)\n', 1) + source = source.replace(' implicit none', + ' implicit none\n LOGICAL WL_ENTRY_INEXACT', 1) + + ncoef = get_number_of_coefs_for_rank(rank) + mapping = ','.join('.TRUE.' if r in required[j-1] else '.FALSE.' + for j in range(1, 5) for r in range(1, 5)) + source = source.replace(' INTEGER I,J,K,L,M\n', + ' INTEGER I,J,K,L,M,R,HALT_INDEX\n' + ' COMPLEX*32 U(4,0:%d,MAXLWFSIZE)\n' % (ncoef-1) + + ' LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/%s/),(/4,4/))\n' % mapping + + ' LOGICAL HALT_FLAGS(SIZE(IEEE_ALL))\n', 1) + extra = ',WL_ENTRY_INEXACT' if terminal else '' + fallback = (' CALL %s(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT%s)\n' + ' RETURN\n') % (name, extra) + guard = """C Experimental derivative-row factorization; changed rounding +IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXLWFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN +{fallback}ENDIF +DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN +{fallback} ENDIF +ENDDO +CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) +IF(ANY(HALT_FLAGS)) THEN +{fallback}ENDIF +IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:{na},1:LCUT_SIZE),KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:{na},1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE),KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE))))) THEN +{fallback}ENDIF +""".format(fallback=fallback, na=ncoef-1) + source = source.replace( + 'C Welcome to the computational heart of MadLoop...', guard, 1) + + # Numerical complex equality ignores either component's zero sign, + # including in a nonzero coefficient. This is a changed-association + # finite-accuracy contract, not a promise of identical output zero bits. + relation_guard = '' + for m, row in enumerate(rows, 1): + for j, (r, real, imag) in enumerate(row, 1): + value = rotate('B(%d,1,K)' % r, real, imag) + relation_guard += """DO K=1,4 + IF(B({j},{m},K).NE.{value}) THEN +{fallback} ENDIF +ENDDO +""".format(j=j, m=m, value=value, fallback=fallback) + + iloop = 'DO I=J,MIN(J,LCUT_SIZE)' if terminal else 'DO I=1,LCUT_SIZE' + # Keep B0 operations, K order and both existing zero guards unchanged. + b0 = """DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.{zero}) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + {iloop} + DO L=0,{na} + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO +ENDDO +""".format(zero=self.czero, iloop=iloop, na=ncoef-1) + contraction = """U={zero} +DO I=1,LCUT_SIZE + DO R=1,4 +""".format(zero=self.czero) + if terminal: + contraction += ' IF(.NOT.NEEDED(R,I)) CYCLE\n' + contraction += """ DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.{zero}) CYCLE + DO L=0,{na} + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO +ENDDO +""".format(zero=self.czero, na=ncoef-1) + shifts = '' + for j in range(1, 5): + for m, row in enumerate(rows, 1): + r, real, imag = row[j-1] + value = rotate('U(%d,L,I)' % r, real, imag) + active_i = ('DO I=%d,MIN(%d,LCUT_SIZE)' % (j, j) + if terminal else 'DO I=1,LCUT_SIZE') + shifts += """{iloop} + DO L=0,{na} + NEW_POSITION=COMB_COEF_POS(L,{m}) + OUT({j},NEW_POSITION,I)=OUT({j},NEW_POSITION,I)+{value} + ENDDO +ENDDO +""".format(iloop=active_i, na=ncoef-1, m=m, j=j, value=value) + start = source.index('OUT(:,:,:)=', source.index('C Experimental')) + end = source.index('\nCONTAINS', start) + body = 'C FACTOR_FAST_PATH\nOUT(:,:,:)=%s\n' % self.czero + source = source[:start] + relation_guard + body + b0 + contraction + shifts + source[end:] + # With |component| exponents <=1000 and at most 40 real products in an + # output, products and every cancellation grid remain normal binary128. + # Integer classification preserves signaling-NaN flags before fallback; + # ASSOCIATE also remains valid with the FKS -fno-automatic build flag. + bounded = """ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X).NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15).GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) GATHER_BOUNDED=.TRUE. + END ASSOCIATE +END FUNCTION +""" + last = source.rindex('\nEND') + return source[:last] + '\n' + bounded + source[last:] + + def write_expanded_wl_updater(self,r_1,r_2,_sparse=True,terminal=False): """ Give out the subroutine to update a polynomial of rank r_1 with one of rank r_2 """ @@ -567,26 +889,42 @@ def write_expanded_wl_updater(self,r_1,r_2): # with a rank 1 updater. lines=[] + sparse = _sparse and self.coef_format == 'complex*32' + if terminal and not sparse: + raise PolynomialError("Terminal updates require the sparse QP kernel") + declarations = preparation = classifier = '' + if sparse: + declarations, preparation, classifier = \ + self._sparse_qp_updater_parts(r_1, r_2, False, terminal) # Start by writing out the header: lines.append( """SUBROUTINE %(sub_prefix)sUPDATE_WL_%(r_1)d_%(r_2)d(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) USE %(proc_prefix)sPOLYNOMIAL_CONSTANTS - INTEGER I,J,K +%(ieee_use)s INTEGER I,J,K %(coef_format)s A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) %(coef_format)s B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) %(coef_format)s OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE -"""%{'sub_prefix':self.sub_prefix,'proc_prefix':self.proc_prefix, - 'r_1':r_1,'r_2':r_2,'coef_format':self.coef_format}) +%(sparse_declarations)s"""%{'sub_prefix':self.sub_prefix,'proc_prefix':self.proc_prefix, + 'r_1':r_1,'r_2':r_2,'coef_format':self.coef_format, + 'ieee_use':' USE, INTRINSIC :: IEEE_ARITHMETIC\n' if sparse else '', + 'sparse_declarations':declarations}) - # Start the loop on the elements i,j of the vector OUT(i,coef,j) + # Traverse the first array index contiguously. Each fixed output still + # receives the same arithmetic statements in ascending K order. + if sparse: + lines.append(preparation) lines.append("DO I=1,LCUT_SIZE") - lines.append(" DO J=1,OUT_SIZE") - lines.append(" DO K=0,%d"%(get_number_of_coefs_for_rank(r_2+r_1)-1)) + lines.append(" DO K=0,%d"%(get_number_of_coefs_for_rank(r_2+r_1)-1)) + lines.append(" DO J=1,OUT_SIZE") lines.append(" OUT(J,K,I)=%s"%self.czero) lines.append(" ENDDO") - lines.append(" DO K=1,IN_SIZE") + lines.append(" ENDDO") + lines.append(" DO K=1,IN_SIZE") + lines.append(" DO J=1,OUT_SIZE") + if sparse: + lines.append(" IF(WL_SKIP(J,K)) CYCLE") # Now we write the lines defining the coefs of OUT(j,*,i) from those # of A(k,*,i) and B(j,*,k) @@ -617,10 +955,27 @@ def write_expanded_wl_updater(self,r_1,r_2): lines.append(" ENDDO") lines.append(" ENDDO") lines.append("ENDDO") + if sparse: + lines.append(classifier) lines.append("END") # return the subroutine - return '\n'.join(lines) + result = '\n'.join(lines) + if terminal: + name = '%sUPDATE_WL_%d_%d' % (self.sub_prefix, r_1, r_2) + result = result.replace('SUBROUTINE '+name+'(', + 'SUBROUTINE '+name.replace('UPDATE_WL_', 'TERMINAL_WL_')+'(', 1) + result = result.replace('OUT_SIZE,OUT)\n', 'OUT_SIZE,OUT,WL_ENTRY_INEXACT)\n', 1) + result = result.replace(' USE, INTRINSIC :: IEEE_ARITHMETIC\n', + ' USE, INTRINSIC :: IEEE_ARITHMETIC\n USE, INTRINSIC :: IEEE_EXCEPTIONS\n', 1) + result = result.replace(' DO K=1,IN_SIZE\n DO J=1,OUT_SIZE', + ' DO K=1,IN_SIZE\n DO J=I,I', 1) + elif sparse: + name = '%sUPDATE_WL_%d_%d' % (self.sub_prefix, r_1, r_2) + dense = self.write_expanded_wl_updater(r_1, r_2, _sparse=False) + result += '\n\n' + dense.replace( + 'SUBROUTINE '+name+'(', 'SUBROUTINE '+name+'_DENSE(', 1) + return result def write_polynomial_evaluator(self): """ Give out the subroutine to evaluate a polynomial of a rank up to diff --git a/tests/acceptance_tests/test_cmd.py b/tests/acceptance_tests/test_cmd.py index c9cde7b309..14aa43103e 100755 --- a/tests/acceptance_tests/test_cmd.py +++ b/tests/acceptance_tests/test_cmd.py @@ -235,6 +235,7 @@ def test_config(self): 'max_npoint_for_channel': 0, 'low_mem_multicore_nlo_generation': False, 'ninja': './HEPTools/lib', + 'ninjars': None, 'samurai': None, 'max_t_for_channel': 99, 'zerowidth_tchannel': True, diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%TIR_interface.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%TIR_interface.f index efca4a073e..c953f2e866 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%TIR_interface.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%TIR_interface.f @@ -53,6 +53,10 @@ SUBROUTINE TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL,M2L C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -84,8 +88,38 @@ SUBROUTINE TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL,M2L C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -364,9 +398,10 @@ SUBROUTINE CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK,COMPLEX_MASS C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=1) C diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%loop_matrix.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%loop_matrix.f index d94ef0b838..e040c30e63 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%loop_matrix.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%loop_matrix.f @@ -80,13 +80,15 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/STABILITY_TESTS/MAXSTABILITYLENGTH @@ -194,7 +196,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -247,23 +249,24 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE./ + $ ,.FALSE.,.FALSE.,.FALSE./ COMMON/LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -470,6 +473,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -506,10 +510,29 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -748,7 +771,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -774,7 +797,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -800,7 +823,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1094,8 +1117,8 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ.-1.OR.IS_HEL_SELECTED(HELPICKED)) $ THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1661,7 +1684,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2373,6 +2396,15 @@ INTEGER FUNCTION ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2744,7 +2776,8 @@ SUBROUTINE SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2754,7 +2787,8 @@ SUBROUTINE SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%mp_coef_construction_1.f index 4b863b79eb..bc4b109a13 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -89,7 +91,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L3_2(PL(0,1),W(2),GC_5,ZERO,ZERO,PL(0,2),COEFS) CALL MP_UPDATE_WL_0_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) CALL MP_FFV2L1_2(PL(0,2),W(3),GC_11,ZERO,ZERO,PL(0,3),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,2),4,COEFS,4,4,WL(1,0,1,3)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,2),4,COEFS,4,4,WL(1,0,1,3) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,3),2,4,1,1,1,2,H) C At this point, all loop coefficients needed for (QCD=2 QED=2), C i.e. of split order ID=1, are computed. diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%mp_compute_loop_coefs.f index 363d4843a9..59a3229c50 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%mp_compute_loop_coefs.f @@ -174,7 +174,8 @@ SUBROUTINE MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%polynomial.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%polynomial.f index a0b0a34816..577b6dcc5d 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%polynomial.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%polynomial.f @@ -335,11 +335,13 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -347,6 +349,75 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -355,11 +426,13 @@ SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -375,11 +448,13 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -391,6 +466,79 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -399,11 +547,13 @@ SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -423,11 +573,13 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -450,18 +602,51 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -480,4 +665,165 @@ SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) ENDDO ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT + $ ,WL_ENTRY_INEXACT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + END diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%TIR_interface.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%TIR_interface.f index 6081ca1842..6a50073e38 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%TIR_interface.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%TIR_interface.f @@ -53,6 +53,10 @@ SUBROUTINE TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL,M2L C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -84,8 +88,38 @@ SUBROUTINE TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL,M2L C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -364,9 +398,10 @@ SUBROUTINE CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK,COMPLEX_MASS C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=1) C diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%loop_matrix.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%loop_matrix.f index 6841c1bd57..a7809d2997 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%loop_matrix.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%loop_matrix.f @@ -80,13 +80,15 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/STABILITY_TESTS/MAXSTABILITYLENGTH @@ -194,7 +196,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -247,23 +249,24 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE./ + $ ,.FALSE.,.FALSE.,.FALSE./ COMMON/LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -470,6 +473,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -506,10 +510,29 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -748,7 +771,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -774,7 +797,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -800,7 +823,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1094,8 +1117,8 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ.-1.OR.IS_HEL_SELECTED(HELPICKED)) $ THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1661,7 +1684,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2373,6 +2396,15 @@ INTEGER FUNCTION ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2744,7 +2776,8 @@ SUBROUTINE SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2754,7 +2787,8 @@ SUBROUTINE SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%mp_coef_construction_1.f index 1424f364a1..f77f0fda77 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -89,7 +91,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L3_1(PL(0,1),W(2),GC_5,ZERO,ZERO,PL(0,2),COEFS) CALL MP_UPDATE_WL_0_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) CALL MP_FFV2L2_1(PL(0,2),W(3),GC_11,ZERO,ZERO,PL(0,3),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,2),4,COEFS,4,4,WL(1,0,1,3)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,2),4,COEFS,4,4,WL(1,0,1,3) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,3),2,4,1,1,1,2,H) C At this point, all loop coefficients needed for (QCD=2 QED=2), C i.e. of split order ID=1, are computed. diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%mp_compute_loop_coefs.f index 96d4195c51..063939b701 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%mp_compute_loop_coefs.f @@ -174,7 +174,8 @@ SUBROUTINE MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%polynomial.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%polynomial.f index a0b0a34816..577b6dcc5d 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%polynomial.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%polynomial.f @@ -335,11 +335,13 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -347,6 +349,75 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -355,11 +426,13 @@ SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -375,11 +448,13 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -391,6 +466,79 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -399,11 +547,13 @@ SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -423,11 +573,13 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -450,18 +602,51 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -480,4 +665,165 @@ SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) ENDDO ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT + $ ,WL_ENTRY_INEXACT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + END diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%TIR_interface.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%TIR_interface.f index 1597482d97..fdbe8e2f43 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%TIR_interface.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%TIR_interface.f @@ -53,6 +53,10 @@ SUBROUTINE TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL,M2L C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -84,8 +88,38 @@ SUBROUTINE TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL,M2L C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -364,9 +398,10 @@ SUBROUTINE CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK,COMPLEX_MASS C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=25) C diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%loop_matrix.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%loop_matrix.f index dd281468fd..634f9aa29e 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%loop_matrix.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%loop_matrix.f @@ -80,13 +80,15 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/STABILITY_TESTS/MAXSTABILITYLENGTH @@ -194,7 +196,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -247,23 +249,24 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE./ + $ ,.FALSE.,.FALSE.,.FALSE./ COMMON/LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -471,6 +474,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -507,10 +511,29 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -749,7 +772,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -775,7 +798,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -801,7 +824,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1095,8 +1118,8 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ.-1.OR.IS_HEL_SELECTED(HELPICKED)) $ THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1662,7 +1685,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2384,6 +2407,15 @@ INTEGER FUNCTION ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2755,7 +2787,8 @@ SUBROUTINE SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2765,7 +2798,8 @@ SUBROUTINE SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%mp_coef_construction_1.f index 2f894a7a89..04b6e007e1 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -89,7 +91,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,1)) CALL MP_VVV1L2P0_1(PL(0,1),W(6),GC_4,CMPLX(ZERO,KIND=16),PL(0,2) $ ,COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,2),2,4,1,1,1,16,H) C Coefficient construction for loop diagram with ID 3 CALL MP_VVS1L1_3(PL(0,0),W(5),GC_92,CMPLX(CMASS_MDL_MW,KIND=16) @@ -97,7 +101,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,1,WL(1,0,1,3)) CALL MP_VVS1L3P0_1(PL(0,3),W(6),GC_93,CMPLX(ZERO,KIND=16),PL(0,4) $ ,COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,3),4,COEFS,1,4,WL(1,0,1,4)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,3),4,COEFS,1,4,WL(1,0,1,4) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,4),0,4,1,1,1,17,H) C Coefficient construction for loop diagram with ID 4 CALL MP_FFV2L3_1(PL(0,0),W(3),GC_124,CMPLX(ZERO,KIND=16),PL(0,5) @@ -108,7 +114,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,5),4,COEFS,4,4,WL(1,0,1,6)) CALL MP_VVV1L1P0_3(PL(0,6),W(5),GC_4,CMPLX(CMASS_MDL_MW,KIND=16) $ ,PL(0,7),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,7),2,4,2,1,1,18,H) C Coefficient construction for loop diagram with ID 5 CALL MP_FFV1L1P0_3(PL(0,0),W(1),GC_1,CMPLX(ZERO,KIND=16),PL(0,8) @@ -119,7 +127,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,8),4,COEFS,4,4,WL(1,0,1,9)) CALL MP_FFV2L1_2(PL(0,9),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0,10) $ ,COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1,10)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1,10) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,10),2,4,3,1,1,19,H) C Coefficient construction for loop diagram with ID 6 CALL MP_FFV1L3_1(PL(0,0),W(1),GC_1,CMPLX(ZERO,KIND=16),PL(0,11) @@ -130,7 +140,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,12)) CALL MP_VVV1L2P0_1(PL(0,12),W(6),GC_4,CMPLX(ZERO,KIND=16),PL(0 $ ,13),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,13)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,13) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,13),2,4,4,1,1,20,H) C Coefficient construction for loop diagram with ID 7 CALL MP_FFV2L3_1(PL(0,12),W(3),GC_124,CMPLX(ZERO,KIND=16),PL(0 @@ -138,7 +150,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,14)) CALL MP_FFV1L2P0_3(PL(0,14),W(4),GC_3,CMPLX(ZERO,KIND=16),PL(0 $ ,15),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,14),4,COEFS,4,4,WL(1,0,1,15)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,14),4,COEFS,4,4,WL(1,0,1,15) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,15),2,4,5,1,1,21,H) C Coefficient construction for loop diagram with ID 8 CALL MP_FFV2L3_1(PL(0,0),W(1),GC_124,CMPLX(ZERO,KIND=16),PL(0,16) @@ -149,7 +163,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,16),4,COEFS,4,4,WL(1,0,1,17)) CALL MP_VVV1L1P0_2(PL(0,17),W(6),GC_4,CMPLX(CMASS_MDL_MW,KIND=16) $ ,PL(0,18),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,18),2,4,6,1,1,22,H) C Coefficient construction for loop diagram with ID 9 CALL MP_FFV1L3_2(PL(0,17),W(4),GC_3,CMPLX(ZERO,KIND=16),PL(0,19) @@ -157,12 +173,16 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,19)) CALL MP_FFV2L1P0_3(PL(0,19),W(3),GC_124,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,20),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,19),4,COEFS,4,4,WL(1,0,1,20)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,19),4,COEFS,4,4,WL(1,0,1,20) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,20),2,4,7,1,1,23,H) C Coefficient construction for loop diagram with ID 10 CALL MP_VVVV2L4P0_3(PL(0,0),W(5),W(6),GC_54,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,21),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,21)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,21) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,21),0,4,8,2,1,24,H) C Coefficient construction for loop diagram with ID 11 CALL MP_VVV1L3P0_2(PL(0,0),W(5),GC_71,CMPLX(CMASS_MDL_MW,KIND=16) @@ -170,7 +190,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,22)) CALL MP_VVV1L1P0_3(PL(0,22),W(6),GC_71,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,23),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,22),4,COEFS,4,4,WL(1,0,1,23)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,22),4,COEFS,4,4,WL(1,0,1,23) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,23),2,4,9,1,1,25,H) C Coefficient construction for loop diagram with ID 12 CALL MP_VVS1L2_3(PL(0,0),W(5),GC_85,CMPLX(CMASS_MDL_MW,KIND=16) @@ -178,7 +200,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,1,WL(1,0,1,24)) CALL MP_VVS1L3P0_2(PL(0,24),W(6),GC_84,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,25),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,24),4,COEFS,1,4,WL(1,0,1,25)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,24),4,COEFS,1,4,WL(1,0,1,25) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,25),0,4,9,1,1,26,H) C Coefficient construction for loop diagram with ID 13 CALL MP_FFV2L3_1(PL(0,0),W(3),GC_80,CMPLX(ZERO,KIND=16),PL(0,26) @@ -189,7 +213,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1,27)) CALL MP_VVV1L2P0_3(PL(0,27),W(5),GC_71,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,28),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,28)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,28) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,28),2,4,10,1,1,27,H) C Coefficient construction for loop diagram with ID 14 CALL MP_FFV2L1P0_3(PL(0,0),W(3),GC_80,CMPLX(CMASS_MDL_MZ,KIND=16) @@ -200,7 +226,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,30)) CALL MP_FFV2L1_2(PL(0,30),W(5),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,31),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,30),4,COEFS,4,4,WL(1,0,1,31)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,30),4,COEFS,4,4,WL(1,0,1,31) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,31),2,4,11,1,1,28,H) C Coefficient construction for loop diagram with ID 15 CALL MP_FFV2_4L2P0_3(PL(0,5),W(4),GC_68,GC_77,CMPLX(CMASS_MDL_MZ @@ -208,7 +236,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,5),4,COEFS,4,4,WL(1,0,1,32)) CALL MP_VVV1L3P0_2(PL(0,32),W(5),GC_71,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,33),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1,33)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1,33) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,33),2,4,12,1,1,29,H) C Coefficient construction for loop diagram with ID 16 CALL MP_FFV2_3L1P0_3(PL(0,0),W(1),GC_68,GC_76,CMPLX(CMASS_MDL_MZ @@ -219,7 +249,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,34),4,COEFS,4,4,WL(1,0,1,35)) CALL MP_FFV2L1_2(PL(0,35),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,36),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,35),4,COEFS,4,4,WL(1,0,1,36)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,35),4,COEFS,4,4,WL(1,0,1,36) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,36),2,4,13,1,1,30,H) C Coefficient construction for loop diagram with ID 17 CALL MP_FFV2_3L3_1(PL(0,0),W(1),GC_68,GC_76,CMPLX(ZERO,KIND=16) @@ -230,7 +262,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,37),4,COEFS,4,4,WL(1,0,1,38)) CALL MP_VVV1L1P0_3(PL(0,38),W(6),GC_71,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,39),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,39)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,39) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,39),2,4,14,1,1,31,H) C Coefficient construction for loop diagram with ID 18 CALL MP_FFV2L3_2(PL(0,38),W(4),GC_124,CMPLX(ZERO,KIND=16),PL(0 @@ -238,7 +272,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,40)) CALL MP_FFV2L1P0_3(PL(0,40),W(3),GC_80,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,41),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,40),4,COEFS,4,4,WL(1,0,1,41)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,40),4,COEFS,4,4,WL(1,0,1,41) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,41),2,4,15,1,1,32,H) C Coefficient construction for loop diagram with ID 19 CALL MP_FFV2L3_1(PL(0,38),W(3),GC_124,CMPLX(ZERO,KIND=16),PL(0 @@ -246,7 +282,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,42)) CALL MP_FFV2_4L2P0_3(PL(0,42),W(4),GC_68,GC_77 $ ,CMPLX(CMASS_MDL_MZ,KIND=16),PL(0,43),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,42),4,COEFS,4,4,WL(1,0,1,43)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,42),4,COEFS,4,4,WL(1,0,1,43) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,43),2,4,16,1,1,33,H) C Coefficient construction for loop diagram with ID 20 CALL MP_FFV2_5L2P0_3(PL(0,16),W(2),GC_69,GC_76 @@ -254,7 +292,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,16),4,COEFS,4,4,WL(1,0,1,44)) CALL MP_VVV1L3P0_1(PL(0,44),W(6),GC_71,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,45),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,45)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,45) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,45),2,4,17,1,1,34,H) C Coefficient construction for loop diagram with ID 21 CALL MP_FFV2L3_1(PL(0,44),W(3),GC_80,CMPLX(ZERO,KIND=16),PL(0,46) @@ -262,7 +302,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,46)) CALL MP_FFV2L2P0_3(PL(0,46),W(4),GC_124,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,47),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,46),4,COEFS,4,4,WL(1,0,1,47)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,46),4,COEFS,4,4,WL(1,0,1,47) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,47),2,4,18,1,1,35,H) C Coefficient construction for loop diagram with ID 22 CALL MP_FFV2_4L3_2(PL(0,44),W(4),GC_68,GC_77,CMPLX(ZERO,KIND=16) @@ -270,12 +312,16 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,48)) CALL MP_FFV2L1P0_3(PL(0,48),W(3),GC_124,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,49),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,48),4,COEFS,4,4,WL(1,0,1,49)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,48),4,COEFS,4,4,WL(1,0,1,49) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,49),2,4,19,1,1,36,H) C Coefficient construction for loop diagram with ID 23 CALL MP_VVSS1L4_3(PL(0,0),W(5),W(6),GC_52,CMPLX(CMASS_MDL_MH $ ,KIND=16),PL(0,50),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,50)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,50) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,50),0,1,20,2,1,37,H) C Coefficient construction for loop diagram with ID 24 CALL MP_VSS1L3_2(PL(0,0),W(5),GC_55,CMPLX(CMASS_MDL_MW,KIND=16) @@ -283,7 +329,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,51)) CALL MP_VSS1L2_3(PL(0,51),W(6),GC_55,CMPLX(CMASS_MDL_MH,KIND=16) $ ,PL(0,52),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,51),1,COEFS,1,1,WL(1,0,1,52)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,51),1,COEFS,1,1,WL(1,0,1,52) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,52),2,1,21,1,1,38,H) C Coefficient construction for loop diagram with ID 25 CALL MP_VVS1L2_3(PL(0,0),W(5),GC_90,CMPLX(CMASS_MDL_MH,KIND=16) @@ -291,12 +339,16 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,1,WL(1,0,1,53)) CALL MP_VVS1L3P0_1(PL(0,53),W(6),GC_90,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,54),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,53),4,COEFS,1,4,WL(1,0,1,54)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,53),4,COEFS,1,4,WL(1,0,1,54) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,54),0,4,22,1,1,39,H) C Coefficient construction for loop diagram with ID 26 CALL MP_VVSS1L4_3(PL(0,0),W(5),W(6),GC_52,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,55),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,55)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,55) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,55),0,1,8,2,1,40,H) C Coefficient construction for loop diagram with ID 27 CALL MP_VSS1L2_3(PL(0,0),W(5),GC_57,CMPLX(CMASS_MDL_MW,KIND=16) @@ -304,17 +356,23 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,56)) CALL MP_VSS1L3_2(PL(0,56),W(6),GC_56,CMPLX(CMASS_MDL_MZ,KIND=16) $ ,PL(0,57),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,56),1,COEFS,1,1,WL(1,0,1,57)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,56),1,COEFS,1,1,WL(1,0,1,57) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,57),2,1,9,1,1,41,H) C Coefficient construction for loop diagram with ID 28 CALL MP_VVVV2L3P0_1(PL(0,0),W(5),W(6),GC_53,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,58),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,58)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,58) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,58),0,4,23,1,1,42,H) C Coefficient construction for loop diagram with ID 29 CALL MP_VVSS1L4_3(PL(0,0),W(5),W(6),GC_52,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,59),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,59)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,59) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,59),0,1,23,1,1,43,H) C Coefficient construction for loop diagram with ID 30 CALL MP_UUV1L1_2(PL(0,0),W(5),GC_3,CMPLX(MDL_MW,KIND=16),PL(0,60) @@ -322,7 +380,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,60)) CALL MP_UUV1L1_2(PL(0,60),W(6),GC_3,CMPLX(ZERO,KIND=16),PL(0,61) $ ,COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,60),1,COEFS,1,1,WL(1,0,1,61)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,60),1,COEFS,1,1,WL(1,0,1,61) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,61),2,1,1,1,1,44,H) C Coefficient construction for loop diagram with ID 31 CALL MP_UUV1L2_1(PL(0,0),W(5),GC_4,CMPLX(MDL_MW,KIND=16),PL(0,62) @@ -330,7 +390,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,62)) CALL MP_UUV1L2_1(PL(0,62),W(6),GC_4,CMPLX(ZERO,KIND=16),PL(0,63) $ ,COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,62),1,COEFS,1,1,WL(1,0,1,63)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,62),1,COEFS,1,1,WL(1,0,1,63) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,63),2,1,1,1,1,45,H) C Coefficient construction for loop diagram with ID 32 CALL MP_UUV1L1_2(PL(0,0),W(5),GC_70,CMPLX(MDL_MW,KIND=16),PL(0 @@ -338,7 +400,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,64)) CALL MP_UUV1L1_2(PL(0,64),W(6),GC_70,CMPLX(MDL_MZ,KIND=16),PL(0 $ ,65),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,64),1,COEFS,1,1,WL(1,0,1,65)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,64),1,COEFS,1,1,WL(1,0,1,65) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,65),2,1,9,1,1,46,H) C Coefficient construction for loop diagram with ID 33 CALL MP_UUV1L2_1(PL(0,0),W(5),GC_71,CMPLX(MDL_MW,KIND=16),PL(0 @@ -346,7 +410,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,66)) CALL MP_UUV1L2_1(PL(0,66),W(6),GC_71,CMPLX(MDL_MZ,KIND=16),PL(0 $ ,67),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,66),1,COEFS,1,1,WL(1,0,1,67)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,66),1,COEFS,1,1,WL(1,0,1,67) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,67),2,1,9,1,1,47,H) C Coefficient construction for loop diagram with ID 34 CALL MP_FFV2L1_2(PL(0,0),W(5),GC_124,CMPLX(ZERO,KIND=16),PL(0,68) @@ -354,7 +420,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,68)) CALL MP_FFV2L1_2(PL(0,68),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,69),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,68),4,COEFS,4,4,WL(1,0,1,69)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,68),4,COEFS,4,4,WL(1,0,1,69) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,69),2,4,24,1,2,48,H) C Coefficient construction for loop diagram with ID 35 CALL MP_FFV2L1_2(PL(0,0),W(5),GC_124,CMPLX(CMASS_MDL_MT,KIND=16) @@ -362,7 +430,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,70)) CALL MP_FFV2L1_2(PL(0,70),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,71),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,70),4,COEFS,4,4,WL(1,0,1,71)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,70),4,COEFS,4,4,WL(1,0,1,71) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,71),2,4,25,1,1,49,H) C Coefficient construction for loop diagram with ID 36 CALL MP_FFV2L1_2(PL(0,0),W(5),GC_124,CMPLX(ZERO,KIND=16),PL(0,72) @@ -370,7 +440,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,72)) CALL MP_FFV2L1_2(PL(0,72),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,73),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,72),4,COEFS,4,4,WL(1,0,1,73)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,72),4,COEFS,4,4,WL(1,0,1,73) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,73),2,4,24,1,3,50,H) C At this point, all loop coefficients needed for (QCD=0 QED=6), C i.e. of split order ID=1, are computed. diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%mp_compute_loop_coefs.f index 061320d378..84d07c8cb0 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%mp_compute_loop_coefs.f @@ -174,7 +174,8 @@ SUBROUTINE MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%polynomial.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%polynomial.f index 4e66dd6f9e..bc53b929b8 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%polynomial.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_dxu_veep%V0_dxu_veep%polynomial.f @@ -335,11 +335,13 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -351,6 +353,79 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -359,11 +434,13 @@ SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -383,11 +460,13 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -409,6 +488,89 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -417,11 +579,13 @@ SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -451,11 +615,13 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -463,6 +629,75 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -471,11 +706,13 @@ SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -491,11 +728,13 @@ SUBROUTINE UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -507,6 +746,79 @@ SUBROUTINE UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -515,11 +827,13 @@ SUBROUTINE MP_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -539,11 +853,13 @@ SUBROUTINE UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -566,18 +882,52 @@ SUBROUTINE UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) SUBROUTINE MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -596,4 +946,370 @@ SUBROUTINE MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) ENDDO ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_TERMINAL_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT + $ ,WL_ENTRY_INEXACT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.1.GT.65536.OR.1.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:0,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT + $ ,WL_ENTRY_INEXACT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_TERMINAL_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT + $ ,WL_ENTRY_INEXACT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + END diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%TIR_interface.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%TIR_interface.f index 7061b5ad06..082bd2cce1 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%TIR_interface.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%TIR_interface.f @@ -53,6 +53,10 @@ SUBROUTINE TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL,M2L C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -84,8 +88,38 @@ SUBROUTINE TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL,M2L C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -364,9 +398,10 @@ SUBROUTINE CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK,COMPLEX_MASS C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=25) C diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%loop_matrix.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%loop_matrix.f index e4df7d4205..e0bda68c1b 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%loop_matrix.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%loop_matrix.f @@ -80,13 +80,15 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/STABILITY_TESTS/MAXSTABILITYLENGTH @@ -194,7 +196,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -247,23 +249,24 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE./ + $ ,.FALSE.,.FALSE.,.FALSE./ COMMON/LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -471,6 +474,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -507,10 +511,29 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -749,7 +772,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -775,7 +798,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -801,7 +824,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1095,8 +1118,8 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ.-1.OR.IS_HEL_SELECTED(HELPICKED)) $ THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1662,7 +1685,7 @@ SUBROUTINE SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2384,6 +2407,15 @@ INTEGER FUNCTION ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2755,7 +2787,8 @@ SUBROUTINE SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2765,7 +2798,8 @@ SUBROUTINE SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%mp_coef_construction_1.f index 994f60c732..a9319546b6 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -89,7 +91,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,1)) CALL MP_VVV1L2P0_1(PL(0,1),W(6),GC_4,CMPLX(ZERO,KIND=16),PL(0,2) $ ,COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,2),2,4,1,1,1,16,H) C Coefficient construction for loop diagram with ID 3 CALL MP_VVS1L1_3(PL(0,0),W(5),GC_92,CMPLX(CMASS_MDL_MW,KIND=16) @@ -97,7 +101,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,1,WL(1,0,1,3)) CALL MP_VVS1L3P0_1(PL(0,3),W(6),GC_93,CMPLX(ZERO,KIND=16),PL(0,4) $ ,COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,3),4,COEFS,1,4,WL(1,0,1,4)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,3),4,COEFS,1,4,WL(1,0,1,4) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,4),0,4,1,1,1,17,H) C Coefficient construction for loop diagram with ID 4 CALL MP_FFV2L3_1(PL(0,0),W(3),GC_124,CMPLX(ZERO,KIND=16),PL(0,5) @@ -108,7 +114,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,5),4,COEFS,4,4,WL(1,0,1,6)) CALL MP_VVV1L1P0_3(PL(0,6),W(5),GC_4,CMPLX(CMASS_MDL_MW,KIND=16) $ ,PL(0,7),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,7),2,4,2,1,1,18,H) C Coefficient construction for loop diagram with ID 5 CALL MP_FFV1L2P0_3(PL(0,0),W(1),GC_2,CMPLX(ZERO,KIND=16),PL(0,8) @@ -119,7 +127,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,8),4,COEFS,4,4,WL(1,0,1,9)) CALL MP_FFV2L2_1(PL(0,9),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0,10) $ ,COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1,10)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1,10) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,10),2,4,3,1,1,19,H) C Coefficient construction for loop diagram with ID 6 CALL MP_FFV1L3_2(PL(0,0),W(1),GC_2,CMPLX(ZERO,KIND=16),PL(0,11) @@ -130,7 +140,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,12)) CALL MP_VVV1L2P0_1(PL(0,12),W(6),GC_4,CMPLX(ZERO,KIND=16),PL(0 $ ,13),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,13)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,13) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,13),2,4,4,1,1,20,H) C Coefficient construction for loop diagram with ID 7 CALL MP_FFV2L3_1(PL(0,12),W(3),GC_124,CMPLX(ZERO,KIND=16),PL(0 @@ -138,7 +150,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,14)) CALL MP_FFV1L2P0_3(PL(0,14),W(4),GC_3,CMPLX(ZERO,KIND=16),PL(0 $ ,15),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,14),4,COEFS,4,4,WL(1,0,1,15)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,14),4,COEFS,4,4,WL(1,0,1,15) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,15),2,4,5,1,1,21,H) C Coefficient construction for loop diagram with ID 8 CALL MP_FFV2L3_2(PL(0,0),W(1),GC_124,CMPLX(ZERO,KIND=16),PL(0,16) @@ -149,7 +163,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,16),4,COEFS,4,4,WL(1,0,1,17)) CALL MP_VVV1L1P0_2(PL(0,17),W(6),GC_4,CMPLX(CMASS_MDL_MW,KIND=16) $ ,PL(0,18),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,18),2,4,6,1,1,22,H) C Coefficient construction for loop diagram with ID 9 CALL MP_FFV1L3_2(PL(0,17),W(4),GC_3,CMPLX(ZERO,KIND=16),PL(0,19) @@ -157,12 +173,16 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,19)) CALL MP_FFV2L1P0_3(PL(0,19),W(3),GC_124,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,20),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,19),4,COEFS,4,4,WL(1,0,1,20)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,19),4,COEFS,4,4,WL(1,0,1,20) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,20),2,4,7,1,1,23,H) C Coefficient construction for loop diagram with ID 10 CALL MP_VVVV2L4P0_3(PL(0,0),W(5),W(6),GC_54,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,21),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,21)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,21) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,21),0,4,8,2,1,24,H) C Coefficient construction for loop diagram with ID 11 CALL MP_VVV1L3P0_2(PL(0,0),W(5),GC_71,CMPLX(CMASS_MDL_MW,KIND=16) @@ -170,7 +190,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,22)) CALL MP_VVV1L1P0_3(PL(0,22),W(6),GC_71,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,23),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,22),4,COEFS,4,4,WL(1,0,1,23)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,22),4,COEFS,4,4,WL(1,0,1,23) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,23),2,4,9,1,1,25,H) C Coefficient construction for loop diagram with ID 12 CALL MP_VVS1L2_3(PL(0,0),W(5),GC_85,CMPLX(CMASS_MDL_MW,KIND=16) @@ -178,7 +200,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,1,WL(1,0,1,24)) CALL MP_VVS1L3P0_2(PL(0,24),W(6),GC_84,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,25),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,24),4,COEFS,1,4,WL(1,0,1,25)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,24),4,COEFS,1,4,WL(1,0,1,25) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,25),0,4,9,1,1,26,H) C Coefficient construction for loop diagram with ID 13 CALL MP_FFV2L3_1(PL(0,0),W(3),GC_80,CMPLX(ZERO,KIND=16),PL(0,26) @@ -189,7 +213,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1,27)) CALL MP_VVV1L2P0_3(PL(0,27),W(5),GC_71,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,28),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,28)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,28) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,28),2,4,10,1,1,27,H) C Coefficient construction for loop diagram with ID 14 CALL MP_FFV2L1P0_3(PL(0,0),W(3),GC_80,CMPLX(CMASS_MDL_MZ,KIND=16) @@ -200,7 +226,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,30)) CALL MP_FFV2L1_2(PL(0,30),W(5),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,31),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,30),4,COEFS,4,4,WL(1,0,1,31)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,30),4,COEFS,4,4,WL(1,0,1,31) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,31),2,4,11,1,1,28,H) C Coefficient construction for loop diagram with ID 15 CALL MP_FFV2_4L2P0_3(PL(0,5),W(4),GC_68,GC_77,CMPLX(CMASS_MDL_MZ @@ -208,7 +236,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,5),4,COEFS,4,4,WL(1,0,1,32)) CALL MP_VVV1L3P0_2(PL(0,32),W(5),GC_71,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,33),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1,33)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1,33) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,33),2,4,12,1,1,29,H) C Coefficient construction for loop diagram with ID 16 CALL MP_FFV2_5L2P0_3(PL(0,0),W(1),GC_69,GC_76,CMPLX(CMASS_MDL_MZ @@ -219,7 +249,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,34),4,COEFS,4,4,WL(1,0,1,35)) CALL MP_FFV2L2_1(PL(0,35),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,36),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,35),4,COEFS,4,4,WL(1,0,1,36)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,35),4,COEFS,4,4,WL(1,0,1,36) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,36),2,4,13,1,1,30,H) C Coefficient construction for loop diagram with ID 17 CALL MP_FFV2_5L3_2(PL(0,0),W(1),GC_69,GC_76,CMPLX(ZERO,KIND=16) @@ -230,7 +262,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,37),4,COEFS,4,4,WL(1,0,1,38)) CALL MP_VVV1L1P0_3(PL(0,38),W(6),GC_71,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,39),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,39)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,39) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,39),2,4,14,1,1,31,H) C Coefficient construction for loop diagram with ID 18 CALL MP_FFV2L3_2(PL(0,38),W(4),GC_124,CMPLX(ZERO,KIND=16),PL(0 @@ -238,7 +272,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,40)) CALL MP_FFV2L1P0_3(PL(0,40),W(3),GC_80,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,41),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,40),4,COEFS,4,4,WL(1,0,1,41)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,40),4,COEFS,4,4,WL(1,0,1,41) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,41),2,4,15,1,1,32,H) C Coefficient construction for loop diagram with ID 19 CALL MP_FFV2L3_1(PL(0,38),W(3),GC_124,CMPLX(ZERO,KIND=16),PL(0 @@ -246,7 +282,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,42)) CALL MP_FFV2_4L2P0_3(PL(0,42),W(4),GC_68,GC_77 $ ,CMPLX(CMASS_MDL_MZ,KIND=16),PL(0,43),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,42),4,COEFS,4,4,WL(1,0,1,43)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,42),4,COEFS,4,4,WL(1,0,1,43) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,43),2,4,16,1,1,33,H) C Coefficient construction for loop diagram with ID 20 CALL MP_FFV2_3L1P0_3(PL(0,16),W(2),GC_68,GC_76 @@ -254,7 +292,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_0(WL(1,0,1,16),4,COEFS,4,4,WL(1,0,1,44)) CALL MP_VVV1L3P0_1(PL(0,44),W(6),GC_71,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,45),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,45)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,45) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,45),2,4,17,1,1,34,H) C Coefficient construction for loop diagram with ID 21 CALL MP_FFV2L3_1(PL(0,44),W(3),GC_80,CMPLX(ZERO,KIND=16),PL(0,46) @@ -262,7 +302,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,46)) CALL MP_FFV2L2P0_3(PL(0,46),W(4),GC_124,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,47),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,46),4,COEFS,4,4,WL(1,0,1,47)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,46),4,COEFS,4,4,WL(1,0,1,47) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,47),2,4,18,1,1,35,H) C Coefficient construction for loop diagram with ID 22 CALL MP_FFV2_4L3_2(PL(0,44),W(4),GC_68,GC_77,CMPLX(ZERO,KIND=16) @@ -270,12 +312,16 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,48)) CALL MP_FFV2L1P0_3(PL(0,48),W(3),GC_124,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,49),COEFS) - CALL MP_UPDATE_WL_2_0(WL(1,0,1,48),4,COEFS,4,4,WL(1,0,1,49)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_2_0(WL(1,0,1,48),4,COEFS,4,4,WL(1,0,1,49) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,49),2,4,19,1,1,36,H) C Coefficient construction for loop diagram with ID 23 CALL MP_VVSS1L4_3(PL(0,0),W(5),W(6),GC_52,CMPLX(CMASS_MDL_MH $ ,KIND=16),PL(0,50),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,50)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,50) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,50),0,1,20,2,1,37,H) C Coefficient construction for loop diagram with ID 24 CALL MP_VSS1L3_2(PL(0,0),W(5),GC_55,CMPLX(CMASS_MDL_MW,KIND=16) @@ -283,7 +329,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,51)) CALL MP_VSS1L2_3(PL(0,51),W(6),GC_55,CMPLX(CMASS_MDL_MH,KIND=16) $ ,PL(0,52),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,51),1,COEFS,1,1,WL(1,0,1,52)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,51),1,COEFS,1,1,WL(1,0,1,52) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,52),2,1,21,1,1,38,H) C Coefficient construction for loop diagram with ID 25 CALL MP_VVS1L2_3(PL(0,0),W(5),GC_90,CMPLX(CMASS_MDL_MH,KIND=16) @@ -291,12 +339,16 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,1,WL(1,0,1,53)) CALL MP_VVS1L3P0_1(PL(0,53),W(6),GC_90,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,54),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,53),4,COEFS,1,4,WL(1,0,1,54)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,53),4,COEFS,1,4,WL(1,0,1,54) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,54),0,4,22,1,1,39,H) C Coefficient construction for loop diagram with ID 26 CALL MP_VVSS1L4_3(PL(0,0),W(5),W(6),GC_52,CMPLX(CMASS_MDL_MZ $ ,KIND=16),PL(0,55),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,55)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,55) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,55),0,1,8,2,1,40,H) C Coefficient construction for loop diagram with ID 27 CALL MP_VSS1L2_3(PL(0,0),W(5),GC_57,CMPLX(CMASS_MDL_MW,KIND=16) @@ -304,17 +356,23 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,56)) CALL MP_VSS1L3_2(PL(0,56),W(6),GC_56,CMPLX(CMASS_MDL_MZ,KIND=16) $ ,PL(0,57),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,56),1,COEFS,1,1,WL(1,0,1,57)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,56),1,COEFS,1,1,WL(1,0,1,57) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,57),2,1,9,1,1,41,H) C Coefficient construction for loop diagram with ID 28 CALL MP_VVVV2L3P0_1(PL(0,0),W(5),W(6),GC_53,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,58),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,58)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,58) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,58),0,4,23,1,1,42,H) C Coefficient construction for loop diagram with ID 29 CALL MP_VVSS1L4_3(PL(0,0),W(5),W(6),GC_52,CMPLX(CMASS_MDL_MW $ ,KIND=16),PL(0,59),COEFS) - CALL MP_UPDATE_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,59)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_0_0(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,59) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,59),0,1,23,1,1,43,H) C Coefficient construction for loop diagram with ID 30 CALL MP_UUV1L1_2(PL(0,0),W(5),GC_3,CMPLX(MDL_MW,KIND=16),PL(0,60) @@ -322,7 +380,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,60)) CALL MP_UUV1L1_2(PL(0,60),W(6),GC_3,CMPLX(ZERO,KIND=16),PL(0,61) $ ,COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,60),1,COEFS,1,1,WL(1,0,1,61)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,60),1,COEFS,1,1,WL(1,0,1,61) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,61),2,1,1,1,1,44,H) C Coefficient construction for loop diagram with ID 31 CALL MP_UUV1L2_1(PL(0,0),W(5),GC_4,CMPLX(MDL_MW,KIND=16),PL(0,62) @@ -330,7 +390,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,62)) CALL MP_UUV1L2_1(PL(0,62),W(6),GC_4,CMPLX(ZERO,KIND=16),PL(0,63) $ ,COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,62),1,COEFS,1,1,WL(1,0,1,63)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,62),1,COEFS,1,1,WL(1,0,1,63) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,63),2,1,1,1,1,45,H) C Coefficient construction for loop diagram with ID 32 CALL MP_UUV1L1_2(PL(0,0),W(5),GC_70,CMPLX(MDL_MW,KIND=16),PL(0 @@ -338,7 +400,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,64)) CALL MP_UUV1L1_2(PL(0,64),W(6),GC_70,CMPLX(MDL_MZ,KIND=16),PL(0 $ ,65),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,64),1,COEFS,1,1,WL(1,0,1,65)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,64),1,COEFS,1,1,WL(1,0,1,65) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,65),2,1,9,1,1,46,H) C Coefficient construction for loop diagram with ID 33 CALL MP_UUV1L2_1(PL(0,0),W(5),GC_71,CMPLX(MDL_MW,KIND=16),PL(0 @@ -346,7 +410,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,66)) CALL MP_UUV1L2_1(PL(0,66),W(6),GC_71,CMPLX(MDL_MZ,KIND=16),PL(0 $ ,67),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,66),1,COEFS,1,1,WL(1,0,1,67)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,66),1,COEFS,1,1,WL(1,0,1,67) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,67),2,1,9,1,1,47,H) C Coefficient construction for loop diagram with ID 34 CALL MP_FFV2L1_2(PL(0,0),W(5),GC_124,CMPLX(ZERO,KIND=16),PL(0,68) @@ -354,7 +420,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,68)) CALL MP_FFV2L1_2(PL(0,68),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,69),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,68),4,COEFS,4,4,WL(1,0,1,69)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,68),4,COEFS,4,4,WL(1,0,1,69) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,69),2,4,24,1,2,48,H) C Coefficient construction for loop diagram with ID 35 CALL MP_FFV2L1_2(PL(0,0),W(5),GC_124,CMPLX(CMASS_MDL_MT,KIND=16) @@ -362,7 +430,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,70)) CALL MP_FFV2L1_2(PL(0,70),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,71),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,70),4,COEFS,4,4,WL(1,0,1,71)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,70),4,COEFS,4,4,WL(1,0,1,71) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,71),2,4,25,1,1,49,H) C Coefficient construction for loop diagram with ID 36 CALL MP_FFV2L1_2(PL(0,0),W(5),GC_124,CMPLX(ZERO,KIND=16),PL(0,72) @@ -370,7 +440,9 @@ SUBROUTINE MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,72)) CALL MP_FFV2L1_2(PL(0,72),W(6),GC_124,CMPLX(ZERO,KIND=16),PL(0 $ ,73),COEFS) - CALL MP_UPDATE_WL_1_1(WL(1,0,1,72),4,COEFS,4,4,WL(1,0,1,73)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_TERMINAL_WL_1_1(WL(1,0,1,72),4,COEFS,4,4,WL(1,0,1,73) + $ ,WL_ENTRY_INEXACT) CALL MP_CREATE_LOOP_COEFS(WL(1,0,1,73),2,4,24,1,3,50,H) C At this point, all loop coefficients needed for (QCD=0 QED=6), C i.e. of split order ID=1, are computed. diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%mp_compute_loop_coefs.f index d326c61723..34db570827 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%mp_compute_loop_coefs.f @@ -174,7 +174,8 @@ SUBROUTINE MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%polynomial.f b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%polynomial.f index 4e66dd6f9e..bc53b929b8 100644 --- a/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%polynomial.f +++ b/tests/input_files/IOTestsComparison/IOExportFKSTest/test_wprod_fksew/%SubProcesses%P0_udx_veep%V0_udx_veep%polynomial.f @@ -335,11 +335,13 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -351,6 +353,79 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -359,11 +434,13 @@ SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -383,11 +460,13 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -409,6 +488,89 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -417,11 +579,13 @@ SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -451,11 +615,13 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -463,6 +629,75 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -471,11 +706,13 @@ SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -491,11 +728,13 @@ SUBROUTINE UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -507,6 +746,79 @@ SUBROUTINE UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) END SUBROUTINE MP_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) USE POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -515,11 +827,13 @@ SUBROUTINE MP_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -539,11 +853,13 @@ SUBROUTINE UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -566,18 +882,52 @@ SUBROUTINE UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) SUBROUTINE MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -596,4 +946,370 @@ SUBROUTINE MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) ENDDO ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_TERMINAL_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT + $ ,WL_ENTRY_INEXACT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.1.GT.65536.OR.1.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:0,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT + $ ,WL_ENTRY_INEXACT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_TERMINAL_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT + $ ,WL_ENTRY_INEXACT) + USE POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + END diff --git a/tests/input_files/IOTestsComparison/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/polynomial.f b/tests/input_files/IOTestsComparison/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/polynomial.f index 43b855f3a7..b1ed84da94 100644 --- a/tests/input_files/IOTestsComparison/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/polynomial.f +++ b/tests/input_files/IOTestsComparison/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/polynomial.f @@ -272,11 +272,13 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -296,11 +298,13 @@ SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -320,11 +324,13 @@ SUBROUTINE UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -354,11 +360,13 @@ SUBROUTINE MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -388,11 +396,13 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -408,11 +418,13 @@ SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -428,11 +440,13 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -462,11 +476,13 @@ SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -496,11 +512,13 @@ SUBROUTINE UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -570,11 +588,13 @@ SUBROUTINE MP_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) diff --git a/tests/input_files/IOTestsComparison/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/polynomial.f b/tests/input_files/IOTestsComparison/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/polynomial.f index dfcdde307d..a1d7898503 100644 --- a/tests/input_files/IOTestsComparison/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/polynomial.f +++ b/tests/input_files/IOTestsComparison/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/polynomial.f @@ -312,11 +312,13 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -336,11 +338,13 @@ SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -360,11 +364,13 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -380,11 +386,13 @@ SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -400,11 +408,13 @@ SUBROUTINE UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -454,11 +464,13 @@ SUBROUTINE MP_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -508,11 +520,13 @@ SUBROUTINE UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,69 + DO K=0,69 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -656,11 +670,13 @@ SUBROUTINE MP_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,69 + DO K=0,69 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -804,11 +820,13 @@ SUBROUTINE UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -878,11 +896,13 @@ SUBROUTINE MP_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -952,11 +972,13 @@ SUBROUTINE UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -986,11 +1008,13 @@ SUBROUTINE MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -1020,11 +1044,13 @@ SUBROUTINE UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -1044,11 +1070,13 @@ SUBROUTINE MP_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -1068,11 +1096,13 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -1102,11 +1132,13 @@ SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -1136,11 +1168,13 @@ SUBROUTINE UPDATE_WL_4_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,69 + DO K=0,69 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -1225,11 +1259,13 @@ SUBROUTINE MP_UPDATE_WL_4_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,69 + DO K=0,69 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) diff --git a/tests/input_files/IOTestsComparison/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/polynomial.f b/tests/input_files/IOTestsComparison/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/polynomial.f index d3a383c9a0..484a4832f7 100644 --- a/tests/input_files/IOTestsComparison/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/polynomial.f +++ b/tests/input_files/IOTestsComparison/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/polynomial.f @@ -252,11 +252,13 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -276,11 +278,13 @@ SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -300,11 +304,13 @@ SUBROUTINE UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -334,11 +340,13 @@ SUBROUTINE MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -368,11 +376,13 @@ SUBROUTINE UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -392,11 +402,13 @@ SUBROUTINE MP_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -416,11 +428,13 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -436,11 +450,13 @@ SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -456,11 +472,13 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -490,11 +508,13 @@ SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) diff --git a/tests/input_files/IOTestsComparison/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/polynomial.f b/tests/input_files/IOTestsComparison/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/polynomial.f index 3c1f7d48d2..28de629560 100644 --- a/tests/input_files/IOTestsComparison/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/polynomial.f +++ b/tests/input_files/IOTestsComparison/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/polynomial.f @@ -272,11 +272,13 @@ SUBROUTINE UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -296,11 +298,13 @@ SUBROUTINE MP_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -320,11 +324,13 @@ SUBROUTINE UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -340,11 +346,13 @@ SUBROUTINE MP_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -360,11 +368,13 @@ SUBROUTINE UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -414,11 +424,13 @@ SUBROUTINE MP_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -468,11 +480,13 @@ SUBROUTINE UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -542,11 +556,13 @@ SUBROUTINE MP_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -616,11 +632,13 @@ SUBROUTINE UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -650,11 +668,13 @@ SUBROUTINE MP_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -684,11 +704,13 @@ SUBROUTINE UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -708,11 +730,13 @@ SUBROUTINE MP_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -732,11 +756,13 @@ SUBROUTINE UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -766,11 +792,13 @@ SUBROUTINE MP_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) diff --git a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_eq_4.f b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_eq_4.f index d3ff82d954..13d60c7e55 100644 --- a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_eq_4.f +++ b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_eq_4.f @@ -3,6 +3,33 @@ C --=========================================-- SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER (NEXTERNAL=4) + REAL*8 P_USER(0:3,NEXTERNAL),ANS(0:3,*) + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + NRS_RETRY_MODE=.FALSE. + NRS_RETRY_USED=.FALSE. + NRS_RETRY_COUNT=0 + NRS_RETRY_PASS=0 + NRS_RETRY_FAIL=0 + NRS_RETRY_HARD_SKIP=0 + NRS_NATIVE_ACC=-1D0 + NRS_COMP_ACC=-1D0 + CALL ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +C Guaranteed reset after every ordinary return from the +C implementation. + NRS_RETRY_MODE=.FALSE. + END + + SUBROUTINE ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) C C Generated by MadGraph7 v. %(version)s, %(date)s C By the MadGraph7 Development Team @@ -19,7 +46,16 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT C + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC C C USER CUSTOMIZABLE OPTIONS C @@ -85,13 +121,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -199,7 +237,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -252,23 +290,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.TRUE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -479,6 +518,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -515,10 +555,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -757,7 +816,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -783,7 +842,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -809,7 +868,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1128,8 +1187,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1543,7 +1602,45 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ACC(I)=1.0D0 ENDDO ENDIF +C One explicit compensated DP retry with the same stability +C checks. + IF(NRS_RETRY_MODE) THEN + NRS_COMP_ACC=MAXVAL(ACC) + NRS_RETRY_MODE=.FALSE. + IF(MAXVAL(ACC).LT.MLSTABTHRES.AND..NOT.FPE_IN_DP_REDUCTION) + $ THEN + NRS_RETRY_PASS=NRS_RETRY_PASS+1 + ELSE + NRS_RETRY_FAIL=NRS_RETRY_FAIL+1 + ENDIF + ENDIF IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN + IF(MLREDUCTIONLIB(I_LIB).EQ.8.AND..NOT.NRS_RETRY_USED) THEN + NRS_NATIVE_ACC=MAXVAL(ACC) + IF(.NOT.FPE_IN_DP_REDUCTION.AND.ALL(IEEE_IS_FINITE(ACC)) + $ .AND.ALL(IEEE_IS_FINITE(DP_RES(:,:,1:N_DP_EVAL)))) THEN + NRS_RETRY_USED=.TRUE. + NRS_RETRY_MODE=.TRUE. + NRS_RETRY_COUNT=NRS_RETRY_COUNT+1 + EVAL_DONE(1)=.TRUE. + DO I=2,MAXSTABILITYLENGTH + EVAL_DONE(I)=.FALSE. + ENDDO + STAB_INDEX=0 + CTMODE=1 + DP_RES=0D0 + IF(NROTATIONS_DP.GE.1) THEN + GOTO 200 + ELSE + GOTO 300 + ENDIF + ELSE + NRS_RETRY_HARD_SKIP=NRS_RETRY_HARD_SKIP+1 + ENDIF + ENDIF +C Mode is off before advancing a backend or entering genuine +C QP. + NRS_RETRY_MODE=.FALSE. I_LIB=I_LIB+1 IF((I_LIB.GT.NLOOPLIB.OR.MLREDUCTIONLIB(I_LIB).EQ.0) $ .AND.QP_TOOLS_AVAILABLE)THEN @@ -1695,7 +1792,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2450,6 +2547,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2832,7 +2938,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2842,7 +2949,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -2909,6 +3017,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C de-allocating C arrays SUBROUTINE ML5_0_EXIT_MADLOOP() + USE MNINJARS, ONLY: NINJARS_FINALIZE + CALL NINJARS_FINALIZE() CONTINUE END diff --git a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_gt_0_QEDAmpAndQEDsq_gt_2.f b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_gt_0_QEDAmpAndQEDsq_gt_2.f index 400ed23b8f..3d93f9411a 100644 --- a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_gt_0_QEDAmpAndQEDsq_gt_2.f +++ b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_gt_0_QEDAmpAndQEDsq_gt_2.f @@ -3,6 +3,33 @@ C --=========================================-- SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER (NEXTERNAL=4) + REAL*8 P_USER(0:3,NEXTERNAL),ANS(0:3,*) + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + NRS_RETRY_MODE=.FALSE. + NRS_RETRY_USED=.FALSE. + NRS_RETRY_COUNT=0 + NRS_RETRY_PASS=0 + NRS_RETRY_FAIL=0 + NRS_RETRY_HARD_SKIP=0 + NRS_NATIVE_ACC=-1D0 + NRS_COMP_ACC=-1D0 + CALL ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +C Guaranteed reset after every ordinary return from the +C implementation. + NRS_RETRY_MODE=.FALSE. + END + + SUBROUTINE ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) C C Generated by MadGraph7 v. %(version)s, %(date)s C By the MadGraph7 Development Team @@ -19,7 +46,16 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT C + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC C C USER CUSTOMIZABLE OPTIONS C @@ -85,13 +121,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -199,7 +237,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -252,23 +290,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.TRUE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -479,6 +518,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -515,10 +555,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -757,7 +816,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -783,7 +842,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -809,7 +868,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1129,8 +1188,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1544,7 +1603,45 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ACC(I)=1.0D0 ENDDO ENDIF +C One explicit compensated DP retry with the same stability +C checks. + IF(NRS_RETRY_MODE) THEN + NRS_COMP_ACC=MAXVAL(ACC) + NRS_RETRY_MODE=.FALSE. + IF(MAXVAL(ACC).LT.MLSTABTHRES.AND..NOT.FPE_IN_DP_REDUCTION) + $ THEN + NRS_RETRY_PASS=NRS_RETRY_PASS+1 + ELSE + NRS_RETRY_FAIL=NRS_RETRY_FAIL+1 + ENDIF + ENDIF IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN + IF(MLREDUCTIONLIB(I_LIB).EQ.8.AND..NOT.NRS_RETRY_USED) THEN + NRS_NATIVE_ACC=MAXVAL(ACC) + IF(.NOT.FPE_IN_DP_REDUCTION.AND.ALL(IEEE_IS_FINITE(ACC)) + $ .AND.ALL(IEEE_IS_FINITE(DP_RES(:,:,1:N_DP_EVAL)))) THEN + NRS_RETRY_USED=.TRUE. + NRS_RETRY_MODE=.TRUE. + NRS_RETRY_COUNT=NRS_RETRY_COUNT+1 + EVAL_DONE(1)=.TRUE. + DO I=2,MAXSTABILITYLENGTH + EVAL_DONE(I)=.FALSE. + ENDDO + STAB_INDEX=0 + CTMODE=1 + DP_RES=0D0 + IF(NROTATIONS_DP.GE.1) THEN + GOTO 200 + ELSE + GOTO 300 + ENDIF + ELSE + NRS_RETRY_HARD_SKIP=NRS_RETRY_HARD_SKIP+1 + ENDIF + ENDIF +C Mode is off before advancing a backend or entering genuine +C QP. + NRS_RETRY_MODE=.FALSE. I_LIB=I_LIB+1 IF((I_LIB.GT.NLOOPLIB.OR.MLREDUCTIONLIB(I_LIB).EQ.0) $ .AND.QP_TOOLS_AVAILABLE)THEN @@ -1696,7 +1793,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2621,6 +2718,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -3003,7 +3109,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -3013,7 +3120,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -3080,6 +3188,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C de-allocating C arrays SUBROUTINE ML5_0_EXIT_MADLOOP() + USE MNINJARS, ONLY: NINJARS_FINALIZE + CALL NINJARS_FINALIZE() CONTINUE END diff --git a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_gt_4.f b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_gt_4.f index c470f263de..2d8e8ce816 100644 --- a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_gt_4.f +++ b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QCDsq_gt_4.f @@ -3,6 +3,33 @@ C --=========================================-- SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER (NEXTERNAL=4) + REAL*8 P_USER(0:3,NEXTERNAL),ANS(0:3,*) + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + NRS_RETRY_MODE=.FALSE. + NRS_RETRY_USED=.FALSE. + NRS_RETRY_COUNT=0 + NRS_RETRY_PASS=0 + NRS_RETRY_FAIL=0 + NRS_RETRY_HARD_SKIP=0 + NRS_NATIVE_ACC=-1D0 + NRS_COMP_ACC=-1D0 + CALL ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +C Guaranteed reset after every ordinary return from the +C implementation. + NRS_RETRY_MODE=.FALSE. + END + + SUBROUTINE ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) C C Generated by MadGraph7 v. %(version)s, %(date)s C By the MadGraph7 Development Team @@ -19,7 +46,16 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT C + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC C C USER CUSTOMIZABLE OPTIONS C @@ -79,13 +115,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -193,7 +231,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -246,23 +284,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.TRUE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -471,6 +510,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -507,10 +547,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -749,7 +808,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -775,7 +834,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -801,7 +860,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1098,8 +1157,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1513,7 +1572,45 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ACC(I)=1.0D0 ENDDO ENDIF +C One explicit compensated DP retry with the same stability +C checks. + IF(NRS_RETRY_MODE) THEN + NRS_COMP_ACC=MAXVAL(ACC) + NRS_RETRY_MODE=.FALSE. + IF(MAXVAL(ACC).LT.MLSTABTHRES.AND..NOT.FPE_IN_DP_REDUCTION) + $ THEN + NRS_RETRY_PASS=NRS_RETRY_PASS+1 + ELSE + NRS_RETRY_FAIL=NRS_RETRY_FAIL+1 + ENDIF + ENDIF IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN + IF(MLREDUCTIONLIB(I_LIB).EQ.8.AND..NOT.NRS_RETRY_USED) THEN + NRS_NATIVE_ACC=MAXVAL(ACC) + IF(.NOT.FPE_IN_DP_REDUCTION.AND.ALL(IEEE_IS_FINITE(ACC)) + $ .AND.ALL(IEEE_IS_FINITE(DP_RES(:,:,1:N_DP_EVAL)))) THEN + NRS_RETRY_USED=.TRUE. + NRS_RETRY_MODE=.TRUE. + NRS_RETRY_COUNT=NRS_RETRY_COUNT+1 + EVAL_DONE(1)=.TRUE. + DO I=2,MAXSTABILITYLENGTH + EVAL_DONE(I)=.FALSE. + ENDDO + STAB_INDEX=0 + CTMODE=1 + DP_RES=0D0 + IF(NROTATIONS_DP.GE.1) THEN + GOTO 200 + ELSE + GOTO 300 + ENDIF + ELSE + NRS_RETRY_HARD_SKIP=NRS_RETRY_HARD_SKIP+1 + ENDIF + ENDIF +C Mode is off before advancing a backend or entering genuine +C QP. + NRS_RETRY_MODE=.FALSE. I_LIB=I_LIB+1 IF((I_LIB.GT.NLOOPLIB.OR.MLREDUCTIONLIB(I_LIB).EQ.0) $ .AND.QP_TOOLS_AVAILABLE)THEN @@ -1665,7 +1762,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2396,6 +2493,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2767,7 +2873,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2777,7 +2884,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -2844,6 +2952,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C de-allocating C arrays SUBROUTINE ML5_0_EXIT_MADLOOP() + USE MNINJARS, ONLY: NINJARS_FINALIZE + CALL NINJARS_FINALIZE() CONTINUE END diff --git a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QEDsq_le_4.f b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QEDsq_le_4.f index a0f3b054a1..72aba76938 100644 --- a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QEDsq_le_4.f +++ b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_QEDsq_le_4.f @@ -3,6 +3,33 @@ C --=========================================-- SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER (NEXTERNAL=4) + REAL*8 P_USER(0:3,NEXTERNAL),ANS(0:3,*) + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + NRS_RETRY_MODE=.FALSE. + NRS_RETRY_USED=.FALSE. + NRS_RETRY_COUNT=0 + NRS_RETRY_PASS=0 + NRS_RETRY_FAIL=0 + NRS_RETRY_HARD_SKIP=0 + NRS_NATIVE_ACC=-1D0 + NRS_COMP_ACC=-1D0 + CALL ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +C Guaranteed reset after every ordinary return from the +C implementation. + NRS_RETRY_MODE=.FALSE. + END + + SUBROUTINE ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) C C Generated by MadGraph7 v. %(version)s, %(date)s C By the MadGraph7 Development Team @@ -19,7 +46,16 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT C + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC C C USER CUSTOMIZABLE OPTIONS C @@ -85,13 +121,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -199,7 +237,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -252,23 +290,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.TRUE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -479,6 +518,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -515,10 +555,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -757,7 +816,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -783,7 +842,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -809,7 +868,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1129,8 +1188,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1544,7 +1603,45 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ACC(I)=1.0D0 ENDDO ENDIF +C One explicit compensated DP retry with the same stability +C checks. + IF(NRS_RETRY_MODE) THEN + NRS_COMP_ACC=MAXVAL(ACC) + NRS_RETRY_MODE=.FALSE. + IF(MAXVAL(ACC).LT.MLSTABTHRES.AND..NOT.FPE_IN_DP_REDUCTION) + $ THEN + NRS_RETRY_PASS=NRS_RETRY_PASS+1 + ELSE + NRS_RETRY_FAIL=NRS_RETRY_FAIL+1 + ENDIF + ENDIF IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN + IF(MLREDUCTIONLIB(I_LIB).EQ.8.AND..NOT.NRS_RETRY_USED) THEN + NRS_NATIVE_ACC=MAXVAL(ACC) + IF(.NOT.FPE_IN_DP_REDUCTION.AND.ALL(IEEE_IS_FINITE(ACC)) + $ .AND.ALL(IEEE_IS_FINITE(DP_RES(:,:,1:N_DP_EVAL)))) THEN + NRS_RETRY_USED=.TRUE. + NRS_RETRY_MODE=.TRUE. + NRS_RETRY_COUNT=NRS_RETRY_COUNT+1 + EVAL_DONE(1)=.TRUE. + DO I=2,MAXSTABILITYLENGTH + EVAL_DONE(I)=.FALSE. + ENDDO + STAB_INDEX=0 + CTMODE=1 + DP_RES=0D0 + IF(NROTATIONS_DP.GE.1) THEN + GOTO 200 + ELSE + GOTO 300 + ENDIF + ELSE + NRS_RETRY_HARD_SKIP=NRS_RETRY_HARD_SKIP+1 + ENDIF + ENDIF +C Mode is off before advancing a backend or entering genuine +C QP. + NRS_RETRY_MODE=.FALSE. I_LIB=I_LIB+1 IF((I_LIB.GT.NLOOPLIB.OR.MLREDUCTIONLIB(I_LIB).EQ.0) $ .AND.QP_TOOLS_AVAILABLE)THEN @@ -1696,7 +1793,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2638,6 +2735,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -3020,7 +3126,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -3030,7 +3137,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -3097,6 +3205,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C de-allocating C arrays SUBROUTINE ML5_0_EXIT_MADLOOP() + USE MNINJARS, ONLY: NINJARS_FINALIZE + CALL NINJARS_FINALIZE() CONTINUE END diff --git a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_WGTsq_le_10_QEDAmpAndQEDsq_gt_2.f b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_WGTsq_le_10_QEDAmpAndQEDsq_gt_2.f index e8e72d3b45..b6dcf20593 100644 --- a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_WGTsq_le_10_QEDAmpAndQEDsq_gt_2.f +++ b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_WGTsq_le_10_QEDAmpAndQEDsq_gt_2.f @@ -3,6 +3,33 @@ C --=========================================-- SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER (NEXTERNAL=4) + REAL*8 P_USER(0:3,NEXTERNAL),ANS(0:3,*) + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + NRS_RETRY_MODE=.FALSE. + NRS_RETRY_USED=.FALSE. + NRS_RETRY_COUNT=0 + NRS_RETRY_PASS=0 + NRS_RETRY_FAIL=0 + NRS_RETRY_HARD_SKIP=0 + NRS_NATIVE_ACC=-1D0 + NRS_COMP_ACC=-1D0 + CALL ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +C Guaranteed reset after every ordinary return from the +C implementation. + NRS_RETRY_MODE=.FALSE. + END + + SUBROUTINE ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) C C Generated by MadGraph7 v. %(version)s, %(date)s C By the MadGraph7 Development Team @@ -19,7 +46,16 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT C + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC C C USER CUSTOMIZABLE OPTIONS C @@ -85,13 +121,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -199,7 +237,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -252,23 +290,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.TRUE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -479,6 +518,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -515,10 +555,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -757,7 +816,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -783,7 +842,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -809,7 +868,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1129,8 +1188,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1544,7 +1603,45 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ACC(I)=1.0D0 ENDDO ENDIF +C One explicit compensated DP retry with the same stability +C checks. + IF(NRS_RETRY_MODE) THEN + NRS_COMP_ACC=MAXVAL(ACC) + NRS_RETRY_MODE=.FALSE. + IF(MAXVAL(ACC).LT.MLSTABTHRES.AND..NOT.FPE_IN_DP_REDUCTION) + $ THEN + NRS_RETRY_PASS=NRS_RETRY_PASS+1 + ELSE + NRS_RETRY_FAIL=NRS_RETRY_FAIL+1 + ENDIF + ENDIF IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN + IF(MLREDUCTIONLIB(I_LIB).EQ.8.AND..NOT.NRS_RETRY_USED) THEN + NRS_NATIVE_ACC=MAXVAL(ACC) + IF(.NOT.FPE_IN_DP_REDUCTION.AND.ALL(IEEE_IS_FINITE(ACC)) + $ .AND.ALL(IEEE_IS_FINITE(DP_RES(:,:,1:N_DP_EVAL)))) THEN + NRS_RETRY_USED=.TRUE. + NRS_RETRY_MODE=.TRUE. + NRS_RETRY_COUNT=NRS_RETRY_COUNT+1 + EVAL_DONE(1)=.TRUE. + DO I=2,MAXSTABILITYLENGTH + EVAL_DONE(I)=.FALSE. + ENDDO + STAB_INDEX=0 + CTMODE=1 + DP_RES=0D0 + IF(NROTATIONS_DP.GE.1) THEN + GOTO 200 + ELSE + GOTO 300 + ENDIF + ELSE + NRS_RETRY_HARD_SKIP=NRS_RETRY_HARD_SKIP+1 + ENDIF + ENDIF +C Mode is off before advancing a backend or entering genuine +C QP. + NRS_RETRY_MODE=.FALSE. I_LIB=I_LIB+1 IF((I_LIB.GT.NLOOPLIB.OR.MLREDUCTIONLIB(I_LIB).EQ.0) $ .AND.QP_TOOLS_AVAILABLE)THEN @@ -1696,7 +1793,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2621,6 +2718,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -3003,7 +3109,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -3013,7 +3120,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -3080,6 +3188,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C de-allocating C arrays SUBROUTINE ML5_0_EXIT_MADLOOP() + USE MNINJARS, ONLY: NINJARS_FINALIZE + CALL NINJARS_FINALIZE() CONTINUE END diff --git a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_default.f b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_default.f index ef70763e28..821cbfbff9 100644 --- a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_default.f +++ b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDQEDpert_default.f @@ -3,6 +3,33 @@ C --=========================================-- SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER (NEXTERNAL=4) + REAL*8 P_USER(0:3,NEXTERNAL),ANS(0:3,*) + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + NRS_RETRY_MODE=.FALSE. + NRS_RETRY_USED=.FALSE. + NRS_RETRY_COUNT=0 + NRS_RETRY_PASS=0 + NRS_RETRY_FAIL=0 + NRS_RETRY_HARD_SKIP=0 + NRS_NATIVE_ACC=-1D0 + NRS_COMP_ACC=-1D0 + CALL ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +C Guaranteed reset after every ordinary return from the +C implementation. + NRS_RETRY_MODE=.FALSE. + END + + SUBROUTINE ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) C C Generated by MadGraph7 v. %(version)s, %(date)s C By the MadGraph7 Development Team @@ -19,7 +46,16 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT C + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC C C USER CUSTOMIZABLE OPTIONS C @@ -85,13 +121,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -199,7 +237,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -252,23 +290,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.TRUE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -479,6 +518,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -515,10 +555,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -757,7 +816,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -783,7 +842,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -809,7 +868,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1128,8 +1187,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1543,7 +1602,45 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ACC(I)=1.0D0 ENDDO ENDIF +C One explicit compensated DP retry with the same stability +C checks. + IF(NRS_RETRY_MODE) THEN + NRS_COMP_ACC=MAXVAL(ACC) + NRS_RETRY_MODE=.FALSE. + IF(MAXVAL(ACC).LT.MLSTABTHRES.AND..NOT.FPE_IN_DP_REDUCTION) + $ THEN + NRS_RETRY_PASS=NRS_RETRY_PASS+1 + ELSE + NRS_RETRY_FAIL=NRS_RETRY_FAIL+1 + ENDIF + ENDIF IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN + IF(MLREDUCTIONLIB(I_LIB).EQ.8.AND..NOT.NRS_RETRY_USED) THEN + NRS_NATIVE_ACC=MAXVAL(ACC) + IF(.NOT.FPE_IN_DP_REDUCTION.AND.ALL(IEEE_IS_FINITE(ACC)) + $ .AND.ALL(IEEE_IS_FINITE(DP_RES(:,:,1:N_DP_EVAL)))) THEN + NRS_RETRY_USED=.TRUE. + NRS_RETRY_MODE=.TRUE. + NRS_RETRY_COUNT=NRS_RETRY_COUNT+1 + EVAL_DONE(1)=.TRUE. + DO I=2,MAXSTABILITYLENGTH + EVAL_DONE(I)=.FALSE. + ENDDO + STAB_INDEX=0 + CTMODE=1 + DP_RES=0D0 + IF(NROTATIONS_DP.GE.1) THEN + GOTO 200 + ELSE + GOTO 300 + ENDIF + ELSE + NRS_RETRY_HARD_SKIP=NRS_RETRY_HARD_SKIP+1 + ENDIF + ENDIF +C Mode is off before advancing a backend or entering genuine +C QP. + NRS_RETRY_MODE=.FALSE. I_LIB=I_LIB+1 IF((I_LIB.GT.NLOOPLIB.OR.MLREDUCTIONLIB(I_LIB).EQ.0) $ .AND.QP_TOOLS_AVAILABLE)THEN @@ -1695,7 +1792,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2450,6 +2547,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2832,7 +2938,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2842,7 +2949,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -2909,6 +3017,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C de-allocating C arrays SUBROUTINE ML5_0_EXIT_MADLOOP() + USE MNINJARS, ONLY: NINJARS_FINALIZE + CALL NINJARS_FINALIZE() CONTINUE END diff --git a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDpert_default.f b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDpert_default.f index 582c1563e7..8c5fe0527e 100644 --- a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDpert_default.f +++ b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QCDpert_default.f @@ -3,6 +3,33 @@ C --=========================================-- SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER (NEXTERNAL=4) + REAL*8 P_USER(0:3,NEXTERNAL),ANS(0:3,*) + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + NRS_RETRY_MODE=.FALSE. + NRS_RETRY_USED=.FALSE. + NRS_RETRY_COUNT=0 + NRS_RETRY_PASS=0 + NRS_RETRY_FAIL=0 + NRS_RETRY_HARD_SKIP=0 + NRS_NATIVE_ACC=-1D0 + NRS_COMP_ACC=-1D0 + CALL ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +C Guaranteed reset after every ordinary return from the +C implementation. + NRS_RETRY_MODE=.FALSE. + END + + SUBROUTINE ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) C C Generated by MadGraph7 v. %(version)s, %(date)s C By the MadGraph7 Development Team @@ -19,7 +46,16 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT C + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC C C USER CUSTOMIZABLE OPTIONS C @@ -79,13 +115,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -193,7 +231,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -246,23 +284,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.TRUE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -471,6 +510,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -507,10 +547,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -749,7 +808,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -775,7 +834,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -801,7 +860,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1098,8 +1157,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1513,7 +1572,45 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ACC(I)=1.0D0 ENDDO ENDIF +C One explicit compensated DP retry with the same stability +C checks. + IF(NRS_RETRY_MODE) THEN + NRS_COMP_ACC=MAXVAL(ACC) + NRS_RETRY_MODE=.FALSE. + IF(MAXVAL(ACC).LT.MLSTABTHRES.AND..NOT.FPE_IN_DP_REDUCTION) + $ THEN + NRS_RETRY_PASS=NRS_RETRY_PASS+1 + ELSE + NRS_RETRY_FAIL=NRS_RETRY_FAIL+1 + ENDIF + ENDIF IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN + IF(MLREDUCTIONLIB(I_LIB).EQ.8.AND..NOT.NRS_RETRY_USED) THEN + NRS_NATIVE_ACC=MAXVAL(ACC) + IF(.NOT.FPE_IN_DP_REDUCTION.AND.ALL(IEEE_IS_FINITE(ACC)) + $ .AND.ALL(IEEE_IS_FINITE(DP_RES(:,:,1:N_DP_EVAL)))) THEN + NRS_RETRY_USED=.TRUE. + NRS_RETRY_MODE=.TRUE. + NRS_RETRY_COUNT=NRS_RETRY_COUNT+1 + EVAL_DONE(1)=.TRUE. + DO I=2,MAXSTABILITYLENGTH + EVAL_DONE(I)=.FALSE. + ENDDO + STAB_INDEX=0 + CTMODE=1 + DP_RES=0D0 + IF(NROTATIONS_DP.GE.1) THEN + GOTO 200 + ELSE + GOTO 300 + ENDIF + ELSE + NRS_RETRY_HARD_SKIP=NRS_RETRY_HARD_SKIP+1 + ENDIF + ENDIF +C Mode is off before advancing a backend or entering genuine +C QP. + NRS_RETRY_MODE=.FALSE. I_LIB=I_LIB+1 IF((I_LIB.GT.NLOOPLIB.OR.MLREDUCTIONLIB(I_LIB).EQ.0) $ .AND.QP_TOOLS_AVAILABLE)THEN @@ -1665,7 +1762,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2396,6 +2493,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2767,7 +2873,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2777,7 +2884,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -2844,6 +2952,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C de-allocating C arrays SUBROUTINE ML5_0_EXIT_MADLOOP() + USE MNINJARS, ONLY: NINJARS_FINALIZE + CALL NINJARS_FINALIZE() CONTINUE END diff --git a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QEDpert_default.f b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QEDpert_default.f index 2a3f18c112..82f394726e 100644 --- a/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QEDpert_default.f +++ b/tests/input_files/IOTestsComparison/LoopSquaredOrder_IOTest/Loop_sqso_uux_ddx/loop_matrix_QEDpert_default.f @@ -3,6 +3,33 @@ C --=========================================-- SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER (NEXTERNAL=4) + REAL*8 P_USER(0:3,NEXTERNAL),ANS(0:3,*) + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC + NRS_RETRY_MODE=.FALSE. + NRS_RETRY_USED=.FALSE. + NRS_RETRY_COUNT=0 + NRS_RETRY_PASS=0 + NRS_RETRY_FAIL=0 + NRS_RETRY_HARD_SKIP=0 + NRS_NATIVE_ACC=-1D0 + NRS_COMP_ACC=-1D0 + CALL ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) +C Guaranteed reset after every ordinary return from the +C implementation. + NRS_RETRY_MODE=.FALSE. + END + + SUBROUTINE ML5_0_SLOOPMATRIX_RETRY_IMPL(P_USER,ANS) C C Generated by MadGraph7 v. %(version)s, %(date)s C By the MadGraph7 Development Team @@ -19,7 +46,16 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT C + USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE IMPLICIT NONE + LOGICAL NRS_RETRY_MODE,NRS_RETRY_USED + INTEGER NRS_RETRY_COUNT,NRS_RETRY_PASS,NRS_RETRY_FAIL + INTEGER NRS_RETRY_HARD_SKIP + REAL*8 NRS_NATIVE_ACC,NRS_COMP_ACC + COMMON/ML5_0_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED + COMMON/ML5_0_NRS_RETRY_STATS/NRS_RETRY_COUNT,NRS_RETRY_PASS, + $ NRS_RETRY_FAIL,NRS_RETRY_HARD_SKIP + COMMON/ML5_0_NRS_RETRY_ACC/NRS_NATIVE_ACC,NRS_COMP_ACC C C USER CUSTOMIZABLE OPTIONS C @@ -79,13 +115,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -193,7 +231,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -246,23 +284,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.TRUE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -471,6 +510,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -507,10 +547,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -749,7 +808,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -775,7 +834,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -801,7 +860,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1098,8 +1157,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1513,7 +1572,45 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ACC(I)=1.0D0 ENDDO ENDIF +C One explicit compensated DP retry with the same stability +C checks. + IF(NRS_RETRY_MODE) THEN + NRS_COMP_ACC=MAXVAL(ACC) + NRS_RETRY_MODE=.FALSE. + IF(MAXVAL(ACC).LT.MLSTABTHRES.AND..NOT.FPE_IN_DP_REDUCTION) + $ THEN + NRS_RETRY_PASS=NRS_RETRY_PASS+1 + ELSE + NRS_RETRY_FAIL=NRS_RETRY_FAIL+1 + ENDIF + ENDIF IF(MAXVAL(ACC).GE.MLSTABTHRES) THEN + IF(MLREDUCTIONLIB(I_LIB).EQ.8.AND..NOT.NRS_RETRY_USED) THEN + NRS_NATIVE_ACC=MAXVAL(ACC) + IF(.NOT.FPE_IN_DP_REDUCTION.AND.ALL(IEEE_IS_FINITE(ACC)) + $ .AND.ALL(IEEE_IS_FINITE(DP_RES(:,:,1:N_DP_EVAL)))) THEN + NRS_RETRY_USED=.TRUE. + NRS_RETRY_MODE=.TRUE. + NRS_RETRY_COUNT=NRS_RETRY_COUNT+1 + EVAL_DONE(1)=.TRUE. + DO I=2,MAXSTABILITYLENGTH + EVAL_DONE(I)=.FALSE. + ENDDO + STAB_INDEX=0 + CTMODE=1 + DP_RES=0D0 + IF(NROTATIONS_DP.GE.1) THEN + GOTO 200 + ELSE + GOTO 300 + ENDIF + ELSE + NRS_RETRY_HARD_SKIP=NRS_RETRY_HARD_SKIP+1 + ENDIF + ENDIF +C Mode is off before advancing a backend or entering genuine +C QP. + NRS_RETRY_MODE=.FALSE. I_LIB=I_LIB+1 IF((I_LIB.GT.NLOOPLIB.OR.MLREDUCTIONLIB(I_LIB).EQ.0) $ .AND.QP_TOOLS_AVAILABLE)THEN @@ -1665,7 +1762,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2394,6 +2491,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2765,7 +2871,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2775,7 +2882,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -2842,6 +2950,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C de-allocating C arrays SUBROUTINE ML5_0_EXIT_MADLOOP() + USE MNINJARS, ONLY: NINJARS_FINALIZE + CALL NINJARS_FINALIZE() CONTINUE END diff --git a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%MadLoopCommons.f b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%MadLoopCommons.f index 54ca9884e9..ba3e8f8307 100644 --- a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%MadLoopCommons.f +++ b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%MadLoopCommons.f @@ -278,7 +278,8 @@ INTEGER FUNCTION SET_RET_CODE_U(MLRED,DOING_QP,STABLE) C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -290,7 +291,8 @@ INTEGER FUNCTION SET_RET_CODE_U(MLRED,DOING_QP,STABLE) C U == 7 C Stable with COLLIER. C U == 8 -C Stable with Ninja in quadruple precision. +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C @@ -323,15 +325,19 @@ INTEGER FUNCTION SET_RET_CODE_U(MLRED,DOING_QP,STABLE) ELSEIF(MLRED.EQ.6)THEN SET_RET_CODE_U=8 RETURN + ELSEIF(MLRED.EQ.8)THEN + SET_RET_CODE_U=2 + RETURN ELSE - STOP 'Only CutTools and Ninja can use quardruple precision' + STOP 'Only CutTools, Ninja and NinjaRS can use quadruple' + $ //' precision' ENDIF ENDIF - IF(MLRED.GE.1.AND.MLRED.LE.7)THEN + IF(MLRED.GE.1.AND.MLRED.LE.8)THEN SET_RET_CODE_U=MLRED ELSE - STOP 'Only CutTools, PJFry++, IREGI, Golem95, Samurai, Ninja' - $ //' and COLLIER are available' + STOP 'Unknown MadLoop reduction library; supported IDs are 1' + $ //' through 8' ENDIF END @@ -382,9 +388,12 @@ SUBROUTINE DETECT_LOOPLIB(LIBNUM,NLOOPLINE,RANK,COMPLEX_MASS ELSEIF(LIBNUM.EQ.7)THEN C Collier CALL DETECT_COLLIER(NLOOPLINE,RANK,COMPLEX_MASS,LPASS) + ELSEIF(LIBNUM.EQ.8)THEN +C NinjaRS + CALL DETECT_NINJARS(NLOOPLINE,RANK,COMPLEX_MASS,LPASS) ELSE - STOP 'Only CutTools, PJFry++, IREGI, Golem95, Samurai, Ninja' - $ //' and COLLIER are available' + STOP 'Unknown MadLoop reduction library; supported IDs are 1' + $ //' through 8' ENDIF RETURN END @@ -498,6 +507,16 @@ SUBROUTINE DETECT_NINJA(NLOOPLINE,RANK,COMPLEX_MASS,LPASS) RETURN END + SUBROUTINE DETECT_NINJARS(NLOOPLINE,RANK,COMPLEX_MASS,LPASS) +C NinjaRS tensor reduction supports rank at most n+2 in both +C precisions. + IMPLICIT NONE + INTEGER NLOOPLINE,RANK + LOGICAL COMPLEX_MASS,LPASS + LPASS=NLOOPLINE.GE.1.AND.RANK.GE.0.AND. + & RANK.LE.NLOOPLINE+2 + END + SUBROUTINE DETECT_COLLIER(NLOOPLINE,RANK,COMPLEX_MASS,LPASS) C C Detect whether Collier can be used or not diff --git a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%MadLoopParamReader.f b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%MadLoopParamReader.f index d8b4951a10..37c3266305 100644 --- a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%MadLoopParamReader.f +++ b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%MadLoopParamReader.f @@ -33,6 +33,13 @@ subroutine MadLoopParamReader(filename, printParam) stop 'CTModeRun must be >= -1 and <=6.' endif + else if (buff .eq. '#LoopPoleMode') then + read(666,*,end=999) LoopPoleMode + if (LoopPoleMode.lt.-1.or.LoopPoleMode.gt.3) then + write(*,*) 'LoopPoleMode must be -1, 0, 1, 2 or 3.' + stop 1 + endif + else if (buff .eq. '#COLLIERGlobalCache') then read(666,*,end=999) COLLIERGlobalCache if (COLLIERGlobalCache .lt. -1) then @@ -136,6 +143,9 @@ subroutine MadLoopParamReader(filename, printParam) else if (buff .eq. '#UseQPIntegrandForNinja') then read(666,*,end=999) UseQPIntegrandForNinja + else if (buff .eq. '#UseQPIntegrandForNinjaRS') then + read(666,*,end=999) UseQPIntegrandForNinjaRS + else if (buff .eq. '#UseQPIntegrandForCutTools') then read(666,*,end=999) UseQPIntegrandForCutTools @@ -155,7 +165,7 @@ subroutine MadLoopParamReader(filename, printParam) else if (buff .eq. '#MLReductionLib') then read(666,*,end=999) MLReductionLib_str - MLReductionLib(1:7)=0 + MLReductionLib(1:9)=0 MLReductionLib_str_save=MLReductionLib_str j=0 DO @@ -179,6 +189,8 @@ subroutine MadLoopParamReader(filename, printParam) MLRed=6 ELSEIF(MLReductionLib_char.EQ.'7 ')THEN MLRed=7 + ELSEIF(MLReductionLib_char.EQ.'8 ')THEN + MLRed=8 ELSE PRINT *, 'MLReductionLib is wrong: '// $ TRIM(MLReductionLib_str_save) @@ -242,6 +254,19 @@ subroutine MadLoopParamReader(filename, printParam) 998 continue if(printParam.and..not.paramPrinted) then +C A partial card may omit MLReductionLib. Print the effective list rather +C than the uninitialized local string used only while parsing that entry. + MLReductionLib_str_save='' + DO i=1,9 + IF(MLReductionLib(i).EQ.0) EXIT + WRITE(MLReductionLib_char,'(I1)') MLReductionLib(i) + IF(i.EQ.1) THEN + MLReductionLib_str_save=TRIM(MLReductionLib_char) + ELSE + MLReductionLib_str_save=TRIM(MLReductionLib_str_save)// + & '|'//TRIM(MLReductionLib_char) + ENDIF + ENDDO write(*,*) & '===============================================================' if (couldRead) then @@ -255,6 +280,7 @@ subroutine MadLoopParamReader(filename, printParam) write(*,*) ' > MLReductionLib = ' $ //TRIM(MLReductionLib_str_save) write(*,*) ' > CTModeRun = ',CTModeRun + write(*,*) ' > LoopPoleMode = ',LoopPoleMode write(*,*) ' > MLStabThres = ',MLStabThres write(*,*) ' > NRotations_DP = ',NRotations_DP write(*,*) ' > NRotations_QP = ',NRotations_QP @@ -275,6 +301,8 @@ subroutine MadLoopParamReader(filename, printParam) write(*,*) ' > WriteOutFilters = ',WriteOutFilters write(*,*) ' > UseQPIntegrandForNinja = ', &UseQPIntegrandForNinja + write(*,*) ' > UseQPIntegrandForNinjaRS = ', + &UseQPIntegrandForNinjaRS write(*,*) ' > UseQPIntegrandForCutTools = ', &UseQPIntegrandForCutTools write(*,*) ' > IREGIMODE = ',IREGIMODE @@ -308,7 +336,8 @@ subroutine DefaultParam() MLReductionLib(1)=6 MLReductionLib(2)=7 MLReductionLib(3)=1 - MLReductionLib(4:7)=0 + MLReductionLib(4:9)=0 + LoopPoleMode=-1 IREGIMODE=2 IREGIRECY=.TRUE. COLLIERComputeIRpoles = .TRUE. @@ -339,5 +368,76 @@ subroutine DefaultParam() ImprovePSPoint=2 UseQPIntegrandForCutTools=.True. UseQPIntegrandForNinja=.True. + UseQPIntegrandForNinjaRS=.True. end + + SUBROUTINE ML_SET_LOOP_POLE_MODE(MODE) +C Pending requests have the same global scope as /MADLOOP/ and ML_INIT. +C A setter from any subprocess overrides the card for all subprocesses. + IMPLICIT NONE + INTEGER MODE,REQUESTED_LOOP_POLE_MODE + INCLUDE 'MadLoopParams.inc' + COMMON/ML_LOOP_POLE_REQUEST/REQUESTED_LOOP_POLE_MODE + IF(MODE.LT.-1.OR.MODE.GT.3) THEN + WRITE(*,*) 'LoopPoleMode must be -1, 0, 1, 2 or 3.' + STOP 1 + ENDIF + REQUESTED_LOOP_POLE_MODE=MODE + LoopPoleMode=MODE + END + + SUBROUTINE ML_APPLY_LOOP_POLE_MODE() +C Restore the most recent request after the first global card read. + IMPLICIT NONE + INTEGER REQUESTED_LOOP_POLE_MODE + INCLUDE 'MadLoopParams.inc' + COMMON/ML_LOOP_POLE_REQUEST/REQUESTED_LOOP_POLE_MODE + IF(REQUESTED_LOOP_POLE_MODE.NE.-2) THEN + LoopPoleMode=REQUESTED_LOOP_POLE_MODE + ENDIF + END + + BLOCK DATA ML_LOOP_POLE_REQUEST_INIT +C The shared reader is linked once, even in a multi-subprocess library. + IMPLICIT NONE + INTEGER REQUESTED_LOOP_POLE_MODE + COMMON/ML_LOOP_POLE_REQUEST/REQUESTED_LOOP_POLE_MODE + DATA REQUESTED_LOOP_POLE_MODE/-2/ + END + + SUBROUTINE ML_LOOP_POLE_FLAGS(COMPUTE_UV,COMPUTE_IR) +C The generic selector affects bare loop integrals only. The legacy +C COLLIER switches remain effective when LoopPoleMode is -1. + IMPLICIT NONE + LOGICAL COMPUTE_UV,COMPUTE_IR + INCLUDE 'MadLoopParams.inc' + COMPUTE_UV=COLLIERComputeUVpoles + COMPUTE_IR=COLLIERComputeIRpoles + IF(LoopPoleMode.GE.0) THEN + COMPUTE_UV=LoopPoleMode.EQ.0.OR.LoopPoleMode.EQ.1 + COMPUTE_IR=LoopPoleMode.EQ.0.OR.LoopPoleMode.EQ.2 + ENDIF + END + + SUBROUTINE ML_CHECK_LOOP_POLE_MODE() +C Reject unsupported rescue chains rather than silently returning +C combined poles after a UV-only or IR-only reduction fails. + IMPLICIT NONE + INTEGER I + INCLUDE 'MadLoopParams.inc' + IF(LoopPoleMode.LT.-1.OR.LoopPoleMode.GT.3) THEN + WRITE(*,*) 'LoopPoleMode must be -1, 0, 1, 2 or 3.' + STOP 1 + ENDIF + IF(LoopPoleMode.LE.0) RETURN + DO I=1,9 + IF(MLReductionLib(I).EQ.0) EXIT + IF(MLReductionLib(I).NE.7.AND.MLReductionLib(I).NE.8) THEN + WRITE(*,*) 'LoopPoleMode=1, 2 or 3 requires NinjaRS/COLLIER.' + WRITE(*,*) 'Set MLReductionLib to 8, 7 or 8|7, including', + & ' only supported rescue backends.' + STOP 1 + ENDIF + ENDDO + END diff --git a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%COLLIER_interface.f b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%COLLIER_interface.f index 81d217b250..ff32d3ab01 100644 --- a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%COLLIER_interface.f +++ b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%COLLIER_interface.f @@ -47,6 +47,10 @@ SUBROUTINE ML5_0_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L INTEGER CURR_RANK, SGN INTEGER CURR_INDEX INTEGER CURR_MAXCOEF + INTEGER LAST_POLE_MODE + LOGICAL COMPUTE_UV,COMPUTE_IR,LAST_UV,LAST_IR + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV,LAST_IR/.TRUE.,.TRUE./ REAL*8 RBUFF(0:3) INTEGER COEFMAP_ZERO(0:LOOPMAXCOEFS-1) @@ -148,6 +152,34 @@ SUBROUTINE ML5_0_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L CALL CITE('Denner:2016kdg','one-loop reduction with COLLIER') ENDIF +C Pole selection is part of the tensor-cache key. Preserve the +C legacy +C booleans, so returning to mode -1 restores the caller's old +C choices. + CALL ML_LOOP_POLE_FLAGS(COMPUTE_UV,COMPUTE_IR) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV.NEQV.COMPUTE_UV) + $ .OR.(LAST_IR.NEQV.COMPUTE_IR)) THEN + IF(LAST_POLE_MODE.NE.-2) THEN + CALL ML5_0_CLEAR_COLLIER_CACHE() + IF(COLLIERGLOBALCACHE.NE.0) THEN + IF(COLLIERGLOBALCACHE.EQ.-1) THEN + CALL INITCACHESYSTEM_CLL(N_CACHES*NPROCS,MAXNEXTERNAL) + ELSE + CALL INITCACHESYSTEM_CLL(N_CACHES*NPROCS + $ ,COLLIERGLOBALCACHE) + ENDIF + CALL SWITCHOFFCACHESYSTEM_CLL() + NCALLS_IN_CACHE=-1 + NCOLLIERCALLS=0 + IF(COLLIER_CACHE_ACTIVE.EQ.1) CALL + $ SWITCHONCACHE_CLL((UNIQUE_ID-1)*N_CACHES+1) + ENDIF + ENDIF + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV=COMPUTE_UV + LAST_IR=COMPUTE_IR + ENDIF + C Initialize the event if it is the first time collier is called C on this PS point IF(MUST_INIT_EVENT) THEN @@ -202,11 +234,11 @@ SUBROUTINE ML5_0_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L ENDDO CALL INITEVENT_CLL((UNIQUE_ID-1)*N_CACHES+1) NCOLLIERCALLS(1) = 0 - IF(COLLIERCOMPUTEUVPOLES.AND.COLLIERUSECACHEFORPOLES) THEN + IF(COMPUTE_UV.AND.COLLIERUSECACHEFORPOLES) THEN CALL INITEVENT_CLL((UNIQUE_ID-1)*N_CACHES+2) NCOLLIERCALLS(2) = 0 ENDIF - IF(COLLIERCOMPUTEIRPOLES.AND.COLLIERUSECACHEFORPOLES) THEN + IF(COMPUTE_IR.AND.COLLIERUSECACHEFORPOLES) THEN CALL INITEVENT_CLL((UNIQUE_ID-1)*N_CACHES+3) NCOLLIERCALLS(3) = 0 CALL INITEVENT_CLL((UNIQUE_ID-1)*N_CACHES+4) @@ -359,7 +391,7 @@ SUBROUTINE ML5_0_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L ENDIF C Now compute the UV poles if asked for - IF (COLLIERCOMPUTEUVPOLES) THEN + IF (COMPUTE_UV) THEN IF(COLLIER_CACHE_ACTIVE.EQ.1) THEN CALL SWITCHOFFCACHE_CLL((UNIQUE_ID-1)*N_CACHES+1) IF(COLLIERUSECACHEFORPOLES) THEN @@ -387,7 +419,7 @@ SUBROUTINE ML5_0_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L ENDIF C Now compute the IR poles if asked for - IF (COLLIERCOMPUTEIRPOLES) THEN + IF (COMPUTE_IR) THEN IF(COLLIER_CACHE_ACTIVE.EQ.1) THEN CALL SWITCHOFFCACHE_CLL((UNIQUE_ID-1)*N_CACHES+1) IF(COLLIERUSECACHEFORPOLES) THEN @@ -443,13 +475,13 @@ SUBROUTINE ML5_0_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L SGN = 1 ENDIF TIRCOEFS(I,1) = SGN*TNTEN(C0,C1,C2,C3) - IF (COLLIERCOMPUTEUVPOLES) THEN + IF (COMPUTE_UV) THEN TIRCOEFS(I,2) = SGN*( TNTEN_UV(C0,C1,C2,C3)-TNTEN(C0,C1,C2 $ ,C3) ) ELSE TIRCOEFS(I,2) = DCMPLX(0.0D0,0.0D0) ENDIF - IF (COLLIERCOMPUTEIRPOLES) THEN + IF (COMPUTE_IR) THEN TIRCOEFS(I,2) = TIRCOEFS(I,2) + SGN*( TNTEN_IR1(C0,C1,C2,C3) $ -TNTEN(C0,C1,C2,C3) ) TIRCOEFS(I,3) = SGN*( TNTEN_IR2(C0,C1,C2,C3)-TNTEN(C0,C1,C2 diff --git a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%TIR_interface.f b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%TIR_interface.f index 690760bf46..61a4020a24 100644 --- a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%TIR_interface.f +++ b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%TIR_interface.f @@ -52,6 +52,10 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -83,8 +87,38 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL ML5_0_CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -374,9 +408,10 @@ SUBROUTINE ML5_0_CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=28) C diff --git a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%loop_matrix.f b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%loop_matrix.f index 0c7ea80e73..e44949dc31 100644 --- a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%loop_matrix.f +++ b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%loop_matrix.f @@ -79,13 +79,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -193,7 +195,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -246,23 +248,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.FALSE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -471,6 +474,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -507,10 +511,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -749,7 +772,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -775,7 +798,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -801,7 +824,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1098,8 +1121,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1665,7 +1688,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2413,6 +2436,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2784,7 +2816,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2794,7 +2827,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%mp_coef_construction_1.f index f285ef90a4..868c2f4883 100644 --- a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -87,7 +89,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_VVV1L2P0_1(PL(0,0),W(5),GC_4,ZERO,ZERO,PL(0,1),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,1)) CALL MP_VVV1L2P0_1(PL(0,1),W(8),GC_4,ZERO,ZERO,PL(0,2),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,2),2,4,1,2,1,86,H) C Coefficient construction for loop diagram with ID 5 CALL MP_FFV1L3_1(PL(0,0),W(3),GC_5,MDL_MT,MDL_WT,PL(0,3),COEFS) @@ -95,7 +99,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L2P0_3(PL(0,3),W(4),GC_5,ZERO,ZERO,PL(0,4),COEFS) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,3),4,COEFS,4,4,WL(1,0,1,4)) CALL MP_VVV1L2P0_1(PL(0,4),W(5),GC_4,ZERO,ZERO,PL(0,5),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,5),2,4,2,1,1,87,H) C Coefficient construction for loop diagram with ID 6 CALL MP_FFV1L1P0_3(PL(0,0),W(3),GC_5,ZERO,ZERO,PL(0,6),COEFS) @@ -103,13 +109,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L3_2(PL(0,6),W(4),GC_5,MDL_MT,MDL_WT,PL(0,7),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7)) CALL MP_FFV1L1_2(PL(0,7),W(5),GC_5,MDL_MT,MDL_WT,PL(0,8),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,8),2,4,3,1,1,88,H) C Coefficient construction for loop diagram with ID 7 CALL MP_FFV1L1P0_3(PL(0,0),W(6),GC_5,ZERO,ZERO,PL(0,9),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,9)) CALL MP_FFV1L3_2(PL(0,9),W(9),GC_5,MDL_MT,MDL_WT,PL(0,10),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1,10)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1 + $ ,10),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,10),1,4,4,1,1,89,H) C Coefficient construction for loop diagram with ID 8 CALL MP_VVV1L2P0_1(PL(0,0),W(2),GC_4,ZERO,ZERO,PL(0,11),COEFS) @@ -118,8 +128,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,12) $ ) CALL MP_FFV1L1P0_3(PL(0,12),W(6),GC_5,ZERO,ZERO,PL(0,13),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,13) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1 + $ ,13),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,13),2,4,5,1,1,90,H) C Coefficient construction for loop diagram with ID 9 CALL MP_FFV1L2_1(PL(0,0),W(2),GC_5,MDL_MT,MDL_WT,PL(0,14),COEFS) @@ -128,23 +139,26 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,14),4,COEFS,4,4,WL(1,0,1,15) $ ) CALL MP_FFV1L3_1(PL(0,15),W(6),GC_5,MDL_MT,MDL_WT,PL(0,16),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1,16) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1 + $ ,16),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,16),2,4,6,1,1,91,H) C Coefficient construction for loop diagram with ID 10 CALL MP_FFV1L1P0_3(PL(0,0),W(10),GC_5,ZERO,ZERO,PL(0,17),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,17)) CALL MP_FFV1L3_2(PL(0,17),W(7),GC_5,MDL_MT,MDL_WT,PL(0,18),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1 + $ ,18),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,18),1,4,7,1,1,92,H) C Coefficient construction for loop diagram with ID 11 CALL MP_FFV1L3_1(PL(0,11),W(3),GC_5,MDL_MT,MDL_WT,PL(0,19),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,19) $ ) CALL MP_FFV1L2P0_3(PL(0,19),W(7),GC_5,ZERO,ZERO,PL(0,20),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,19),4,COEFS,4,4,WL(1,0,1,20) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,19),4,COEFS,4,4,WL(1,0,1 + $ ,20),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,20),2,4,8,1,1,93,H) C Coefficient construction for loop diagram with ID 12 CALL MP_FFV1L1_2(PL(0,0),W(2),GC_5,MDL_MT,MDL_WT,PL(0,21),COEFS) @@ -153,8 +167,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1,22) $ ) CALL MP_FFV1L3_2(PL(0,22),W(7),GC_5,MDL_MT,MDL_WT,PL(0,23),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,22),4,COEFS,4,4,WL(1,0,1,23) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,22),4,COEFS,4,4,WL(1,0,1 + $ ,23),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,23),2,4,9,1,1,94,H) C Coefficient construction for loop diagram with ID 13 CALL MP_VVV1L2P0_1(PL(0,0),W(1),GC_4,ZERO,ZERO,PL(0,24),COEFS) @@ -163,16 +178,18 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,25) $ ) CALL MP_FFV1L1P0_3(PL(0,25),W(10),GC_5,ZERO,ZERO,PL(0,26),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,25),4,COEFS,4,4,WL(1,0,1,26) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,25),4,COEFS,4,4,WL(1,0,1 + $ ,26),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,26),2,4,10,1,1,95,H) C Coefficient construction for loop diagram with ID 14 CALL MP_FFV1L3_1(PL(0,24),W(3),GC_5,MDL_MT,MDL_WT,PL(0,27),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,27) $ ) CALL MP_FFV1L2P0_3(PL(0,27),W(9),GC_5,ZERO,ZERO,PL(0,28),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,28) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1 + $ ,28),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,28),2,4,11,1,1,96,H) C Coefficient construction for loop diagram with ID 15 CALL MP_VVV1L2P0_1(PL(0,24),W(2),GC_4,ZERO,ZERO,PL(0,29),COEFS) @@ -182,45 +199,53 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,30) $ ) CALL MP_FFV1L1P0_3(PL(0,30),W(3),GC_5,ZERO,ZERO,PL(0,31),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,30),4,COEFS,4,4,WL(1,0,1,31) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,30),4,COEFS,4,4,WL(1,0,1 + $ ,31),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,31),3,4,12,1,1,97,H) C Coefficient construction for loop diagram with ID 16 CALL MP_FFV1L3_1(PL(0,29),W(3),GC_5,MDL_MT,MDL_WT,PL(0,32),COEFS) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,32) $ ) CALL MP_FFV1L2P0_3(PL(0,32),W(4),GC_5,ZERO,ZERO,PL(0,33),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1,33) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1 + $ ,33),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,33),3,4,13,1,1,98,H) C Coefficient construction for loop diagram with ID 17 CALL MP_VVV1L2P0_1(PL(0,29),W(8),GC_4,ZERO,ZERO,PL(0,34),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,34) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1 + $ ,34),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,34),3,4,14,1,1,99,H) C Coefficient construction for loop diagram with ID 18 CALL MP_VVVV1L2P0_1(PL(0,24),W(8),W(2),GC_6,ZERO,ZERO,PL(0,35) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,35) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1 + $ ,35),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,24),W(8),W(2),GC_6,ZERO,ZERO,PL(0,36) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,36) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1 + $ ,36),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,24),W(8),W(2),GC_6,ZERO,ZERO,PL(0,37) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,37) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1 + $ ,37),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,35),1,4,15,2,1,100,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,36),1,4,15,2,1,101,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,37),1,4,15,2,1,102,H) C Coefficient construction for loop diagram with ID 19 CALL MP_FFV1L2_1(PL(0,27),W(2),GC_5,MDL_MT,MDL_WT,PL(0,38),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,38) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,27),4,COEFS + $ ,4,4,WL(1,0,1,38),WL_ENTRY_INEXACT) CALL MP_FFV1L2P0_3(PL(0,38),W(4),GC_5,ZERO,ZERO,PL(0,39),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,39) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 + $ ,39),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,39),3,4,16,1,1,103,H) C Coefficient construction for loop diagram with ID 20 CALL MP_FFV1L2_1(PL(0,0),W(1),GC_5,MDL_MT,MDL_WT,PL(0,40),COEFS) @@ -230,8 +255,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ) CALL MP_FFV1L3_1(PL(0,41),W(10),GC_5,MDL_MT,MDL_WT,PL(0,42) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,41),4,COEFS,4,4,WL(1,0,1,42) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,41),4,COEFS,4,4,WL(1,0,1 + $ ,42),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,42),2,4,17,1,1,104,H) C Coefficient construction for loop diagram with ID 21 CALL MP_FFV1L1_2(PL(0,0),W(1),GC_5,MDL_MT,MDL_WT,PL(0,43),COEFS) @@ -240,22 +266,26 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,43),4,COEFS,4,4,WL(1,0,1,44) $ ) CALL MP_FFV1L3_2(PL(0,44),W(9),GC_5,MDL_MT,MDL_WT,PL(0,45),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,45) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1 + $ ,45),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,45),2,4,18,1,1,105,H) C Coefficient construction for loop diagram with ID 22 CALL MP_VVVV1L2P0_1(PL(0,11),W(8),W(1),GC_6,ZERO,ZERO,PL(0,46) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,46) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,46),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,11),W(8),W(1),GC_6,ZERO,ZERO,PL(0,47) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,47) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,47),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,11),W(8),W(1),GC_6,ZERO,ZERO,PL(0,48) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,48) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,48),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,46),1,4,19,2,1,106,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,47),1,4,19,2,1,107,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,48),1,4,19,2,1,108,H) @@ -264,8 +294,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,49) $ ) CALL MP_FFV1L3_2(PL(0,49),W(4),GC_5,MDL_MT,MDL_WT,PL(0,50),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,49),4,COEFS,4,4,WL(1,0,1,50) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,49),4,COEFS,4,4,WL(1,0,1 + $ ,50),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,50),3,4,20,1,1,109,H) C Coefficient construction for loop diagram with ID 24 CALL MP_FFV1L2_1(PL(0,40),W(2),GC_5,MDL_MT,MDL_WT,PL(0,51),COEFS) @@ -275,8 +306,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,51),4,COEFS,4,4,WL(1,0,1,52) $ ) CALL MP_FFV1L3_1(PL(0,52),W(3),GC_5,MDL_MT,MDL_WT,PL(0,53),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,52),4,COEFS,4,4,WL(1,0,1,53) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,52),4,COEFS,4,4,WL(1,0,1 + $ ,53),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,53),3,4,21,1,1,110,H) C Coefficient construction for loop diagram with ID 25 CALL MP_FFV1L1_2(PL(0,43),W(2),GC_5,MDL_MT,MDL_WT,PL(0,54),COEFS) @@ -286,8 +318,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,54),4,COEFS,4,4,WL(1,0,1,55) $ ) CALL MP_FFV1L3_2(PL(0,55),W(4),GC_5,MDL_MT,MDL_WT,PL(0,56),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,55),4,COEFS,4,4,WL(1,0,1,56) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,55),4,COEFS,4,4,WL(1,0,1 + $ ,56),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,56),3,4,22,1,1,111,H) C Coefficient construction for loop diagram with ID 26 CALL MP_VVVV1L2P0_1(PL(0,0),W(2),W(1),GC_6,ZERO,ZERO,PL(0,57) @@ -300,27 +333,36 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,59)) CALL MP_VVV1L2P0_1(PL(0,57),W(8),GC_4,ZERO,ZERO,PL(0,60),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,57),4,COEFS,4,4,WL(1,0,1,60) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,57),4,COEFS,4,4,WL(1,0,1 + $ ,60),WL_ENTRY_INEXACT) CALL MP_VVV1L2P0_1(PL(0,58),W(8),GC_4,ZERO,ZERO,PL(0,61),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,58),4,COEFS,4,4,WL(1,0,1,61) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,58),4,COEFS,4,4,WL(1,0,1 + $ ,61),WL_ENTRY_INEXACT) CALL MP_VVV1L2P0_1(PL(0,59),W(8),GC_4,ZERO,ZERO,PL(0,62),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,59),4,COEFS,4,4,WL(1,0,1,62) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,59),4,COEFS,4,4,WL(1,0,1 + $ ,62),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,60),1,4,23,2,1,112,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,61),1,4,23,2,1,113,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,62),1,4,23,2,1,114,H) C Coefficient construction for loop diagram with ID 27 CALL MP_VVVV1L2P0_1(PL(0,4),W(2),W(1),GC_6,ZERO,ZERO,PL(0,63) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,63)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1 + $ ,63),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,4),W(2),W(1),GC_6,ZERO,ZERO,PL(0,64) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,64)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1 + $ ,64),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,4),W(2),W(1),GC_6,ZERO,ZERO,PL(0,65) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,65)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1 + $ ,65),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,63),1,4,24,1,1,115,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,64),1,4,24,1,1,116,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,65),1,4,24,1,1,117,H) @@ -328,8 +370,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_GHGHGL2_1(PL(0,0),W(5),GC_4,ZERO,ZERO,PL(0,66),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,66)) CALL MP_GHGHGL2_1(PL(0,66),W(8),GC_4,ZERO,ZERO,PL(0,67),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,66),1,COEFS,1,1,WL(1,0,1,67) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,66),1,COEFS,1,1,WL(1,0,1 + $ ,67),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,67),2,1,1,1,1,118,H) C Coefficient construction for loop diagram with ID 29 CALL MP_GHGHGL1_2(PL(0,0),W(1),GC_4,ZERO,ZERO,PL(0,68),COEFS) @@ -338,8 +381,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,68),1,COEFS,1,1,WL(1,0,1,69) $ ) CALL MP_GHGHGL1_2(PL(0,69),W(8),GC_4,ZERO,ZERO,PL(0,70),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,69),1,COEFS,1,1,WL(1,0,1,70) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,69),1,COEFS,1,1,WL(1,0,1 + $ ,70),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,70),3,1,14,1,1,119,H) C Coefficient construction for loop diagram with ID 30 CALL MP_GHGHGL2_1(PL(0,0),W(1),GC_4,ZERO,ZERO,PL(0,71),COEFS) @@ -348,15 +392,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,71),1,COEFS,1,1,WL(1,0,1,72) $ ) CALL MP_GHGHGL2_1(PL(0,72),W(8),GC_4,ZERO,ZERO,PL(0,73),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,72),1,COEFS,1,1,WL(1,0,1,73) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,72),1,COEFS,1,1,WL(1,0,1 + $ ,73),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,73),3,1,14,1,1,120,H) C Coefficient construction for loop diagram with ID 31 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,ZERO,ZERO,PL(0,74),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,74)) CALL MP_FFV1L2_1(PL(0,74),W(8),GC_5,ZERO,ZERO,PL(0,75),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,74),4,COEFS,4,4,WL(1,0,1,75) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,74),4,COEFS,4,4,WL(1,0,1 + $ ,75),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,75),2,4,1,1,4,121,H) C Coefficient construction for loop diagram with ID 32 CALL MP_FFV1L1_2(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,76),COEFS) @@ -365,8 +411,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,76),4,COEFS,4,4,WL(1,0,1,77) $ ) CALL MP_FFV1L1_2(PL(0,77),W(8),GC_5,ZERO,ZERO,PL(0,78),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,77),4,COEFS,4,4,WL(1,0,1,78) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,77),4 + $ ,COEFS,4,4,WL(1,0,1,78),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,78),3,4,14,1,4,122,H) C Coefficient construction for loop diagram with ID 33 CALL MP_FFV1L2_1(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,79),COEFS) @@ -375,15 +422,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,79),4,COEFS,4,4,WL(1,0,1,80) $ ) CALL MP_FFV1L2_1(PL(0,80),W(8),GC_5,ZERO,ZERO,PL(0,81),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,80),4,COEFS,4,4,WL(1,0,1,81) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,80),4 + $ ,COEFS,4,4,WL(1,0,1,81),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,81),3,4,14,1,4,123,H) C Coefficient construction for loop diagram with ID 34 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,MDL_MB,ZERO,PL(0,82),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,82)) CALL MP_FFV1L2_1(PL(0,82),W(8),GC_5,MDL_MB,ZERO,PL(0,83),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,82),4,COEFS,4,4,WL(1,0,1,83) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,82),4,COEFS,4,4,WL(1,0,1 + $ ,83),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,83),2,4,25,1,1,124,H) C Coefficient construction for loop diagram with ID 35 CALL MP_FFV1L1_2(PL(0,0),W(1),GC_5,MDL_MB,ZERO,PL(0,84),COEFS) @@ -392,8 +441,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,84),4,COEFS,4,4,WL(1,0,1,85) $ ) CALL MP_FFV1L1_2(PL(0,85),W(8),GC_5,MDL_MB,ZERO,PL(0,86),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1,86) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,85),4 + $ ,COEFS,4,4,WL(1,0,1,86),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,86),3,4,26,1,1,125,H) C Coefficient construction for loop diagram with ID 36 CALL MP_FFV1L2_1(PL(0,0),W(1),GC_5,MDL_MB,ZERO,PL(0,87),COEFS) @@ -402,25 +452,29 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,87),4,COEFS,4,4,WL(1,0,1,88) $ ) CALL MP_FFV1L2_1(PL(0,88),W(8),GC_5,MDL_MB,ZERO,PL(0,89),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,88),4,COEFS,4,4,WL(1,0,1,89) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,88),4 + $ ,COEFS,4,4,WL(1,0,1,89),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,89),3,4,26,1,1,126,H) C Coefficient construction for loop diagram with ID 37 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,MDL_MT,MDL_WT,PL(0,90),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,90)) CALL MP_FFV1L2_1(PL(0,90),W(8),GC_5,MDL_MT,MDL_WT,PL(0,91),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,90),4,COEFS,4,4,WL(1,0,1,91) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,90),4,COEFS,4,4,WL(1,0,1 + $ ,91),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,91),2,4,27,1,1,127,H) C Coefficient construction for loop diagram with ID 38 CALL MP_FFV1L1_2(PL(0,54),W(8),GC_5,MDL_MT,MDL_WT,PL(0,92),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,54),4,COEFS,4,4,WL(1,0,1,92) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,54),4 + $ ,COEFS,4,4,WL(1,0,1,92),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,92),3,4,28,1,1,128,H) C Coefficient construction for loop diagram with ID 39 CALL MP_FFV1L2_1(PL(0,51),W(8),GC_5,MDL_MT,MDL_WT,PL(0,93),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,51),4,COEFS,4,4,WL(1,0,1,93) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,51),4 + $ ,COEFS,4,4,WL(1,0,1,93),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,93),3,4,28,1,1,129,H) C At this point, all loop coefficients needed for (QCD=6), i.e. of C split order ID=1, are computed. diff --git a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%mp_compute_loop_coefs.f index 39f9180351..cba826a1a9 100644 --- a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%mp_compute_loop_coefs.f @@ -173,7 +173,8 @@ SUBROUTINE ML5_0_MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%polynomial.f b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%polynomial.f index b7dfc1c310..94d3fceece 100644 --- a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%polynomial.f +++ b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/TIR_output/%ggttx_IOTest%SubProcesses%P0_gg_ttx%polynomial.f @@ -416,11 +416,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -434,18 +436,94 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -466,11 +544,13 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -494,18 +574,104 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -536,11 +702,13 @@ SUBROUTINE ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -554,18 +722,94 @@ SUBROUTINE ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -586,11 +830,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -600,18 +846,90 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -628,11 +946,13 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -656,18 +976,105 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -707,9 +1114,9 @@ SUBROUTINE ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE DO K=1,IN_SIZE UPDATER_COEF = B(J,M,K) IF (UPDATER_COEF.EQ.(0.0D0,0.0D0)) CYCLE - DO L=0,14 - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION = COMB_COEF_POS(L,M) OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) $ *UPDATER_COEF ENDDO @@ -723,25 +1130,62 @@ SUBROUTINE ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC IMPLICIT NONE INTEGER I,J,K,L,M COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L INTEGER NEW_POSITION COMPLEX*32 UPDATER_COEF C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) DO J=1,OUT_SIZE DO M=0,4 DO K=1,IN_SIZE UPDATER_COEF = B(J,M,K) IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE - DO L=0,14 - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) $ *UPDATER_COEF ENDDO @@ -750,79 +1194,2363 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + END - SUBROUTINE ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS - INTEGER I,J,K - COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF - DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 - OUT(J,K,I)=(0.0D0,0.0D0) - ENDDO +C Welcome to the computational heart of MadLoop... + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 DO K=1,IN_SIZE - OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) - OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) - OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) - OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) - OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) - OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) - OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) - OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) - OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) - OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) - OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) - OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) - OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) - OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) - OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) - OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) - OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) - OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) - OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) - OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) - OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) - OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) - OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) - OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) - OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) - OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) - OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) - OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) - OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) - OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) - OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) - OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) - OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) - OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) - OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO ENDDO ENDDO ENDDO + END - SUBROUTINE MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L1_2(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) USE ML5_0_POLYNOMIAL_CONSTANTS - INTEGER I,J,K + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF - DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 - OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) - ENDDO - DO K=1,IN_SIZE - OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L2_1(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=(0.0D0,0.0D0) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:34,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:34,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_0_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.1.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:0,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_1_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.1.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_3_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.35.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:34,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:34,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) @@ -860,4 +3588,38 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + END diff --git a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/loop_induced_standalone_output/%gghLI_IOTest%SubProcesses%P0_gg_h%loop_matrix.f b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/loop_induced_standalone_output/%gghLI_IOTest%SubProcesses%P0_gg_h%loop_matrix.f index b86e455de8..3d2d7b1d3c 100644 --- a/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/loop_induced_standalone_output/%gghLI_IOTest%SubProcesses%P0_gg_h%loop_matrix.f +++ b/tests/input_files/IOTestsComparison/MadLoop_output_from_the_interface/loop_induced_standalone_output/%gghLI_IOTest%SubProcesses%P0_gg_h%loop_matrix.f @@ -103,13 +103,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -230,7 +232,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -287,23 +289,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.FALSE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -516,6 +519,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -572,10 +576,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -811,7 +834,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C first points C to set the filters because it doesn't have a reasonable REF C scale yet. - IF(.NOT.BYPASS_CHECK.AND.NPSPOINTS.GE.1) THEN + IF(.NOT.BYPASS_FILTERS.AND.NPSPOINTS.GE.1) THEN NTRY=NTRY+1 ENDIF @@ -837,7 +860,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -863,7 +886,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1247,8 +1270,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C The if statement below is not strictly necessary but C makes it clear when it is executed. ELSEIF(H.EQ.USERHEL.OR.USERHEL.EQ.-1) THEN -C Make sure that no polarization constraint filters -C out this helicity +C Make sure that no polarization constraint filters out +C this helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(H)) THEN C If both computational method is used, then we must @@ -1262,8 +1285,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF IF (H.EQ.USERHEL.OR.USERHEL.EQ.-1) THEN -C Make sure that no polarization constraint filters -C out this helicity +C Make sure that no polarization constraint filters out +C this helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(H)) THEN CALL @@ -1351,8 +1374,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1587,7 +1610,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C point using SLOOPMATRIX_THRES). C It is possible to simply remove the if statement below to have C a running reference scale which always depends on the -C MAXNREF_EVALS *last* evaluations. +C MAXNREF_EVALS *last* evaluations. IF (NPSPOINTS.LE.MAXNREF_EVALS) THEN TMPR = ABS(ANS(1,0)) + ABS(ANS(2,0)) + ABS(ANS(3,0)) IF (TMPR.NE.0.0D0) THEN @@ -2007,7 +2030,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2731,6 +2754,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -3117,7 +3149,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -3127,7 +3160,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/TestCmdMatchBox.moved/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%polynomial.f b/tests/input_files/IOTestsComparison/TestCmdMatchBox.moved/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%polynomial.f index 79a4df05aa..b704c4b788 100644 --- a/tests/input_files/IOTestsComparison/TestCmdMatchBox.moved/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%polynomial.f +++ b/tests/input_files/IOTestsComparison/TestCmdMatchBox.moved/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%polynomial.f @@ -311,11 +311,13 @@ SUBROUTINE MG5_1_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -337,11 +339,13 @@ SUBROUTINE MP_MG5_1_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -363,11 +367,13 @@ SUBROUTINE MG5_1_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -399,11 +405,13 @@ SUBROUTINE MP_MG5_1_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -435,11 +443,13 @@ SUBROUTINE MG5_1_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -461,11 +471,13 @@ SUBROUTINE MP_MG5_1_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -487,11 +499,13 @@ SUBROUTINE MG5_1_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -509,11 +523,13 @@ SUBROUTINE MP_MG5_1_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -531,11 +547,13 @@ SUBROUTINE MG5_1_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -567,11 +585,13 @@ SUBROUTINE MP_MG5_1_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) diff --git a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%COLLIER_interface.f b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%COLLIER_interface.f index 9841fa3f17..cf447abaec 100644 --- a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%COLLIER_interface.f +++ b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%COLLIER_interface.f @@ -47,6 +47,10 @@ SUBROUTINE MG5_1_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L INTEGER CURR_RANK, SGN INTEGER CURR_INDEX INTEGER CURR_MAXCOEF + INTEGER LAST_POLE_MODE + LOGICAL COMPUTE_UV,COMPUTE_IR,LAST_UV,LAST_IR + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV,LAST_IR/.TRUE.,.TRUE./ REAL*8 RBUFF(0:3) INTEGER COEFMAP_ZERO(0:LOOPMAXCOEFS-1) @@ -140,6 +144,34 @@ SUBROUTINE MG5_1_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L CALL CITE('Denner:2016kdg','one-loop reduction with COLLIER') ENDIF +C Pole selection is part of the tensor-cache key. Preserve the +C legacy +C booleans, so returning to mode -1 restores the caller's old +C choices. + CALL ML_LOOP_POLE_FLAGS(COMPUTE_UV,COMPUTE_IR) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV.NEQV.COMPUTE_UV) + $ .OR.(LAST_IR.NEQV.COMPUTE_IR)) THEN + IF(LAST_POLE_MODE.NE.-2) THEN + CALL MG5_1_CLEAR_COLLIER_CACHE() + IF(COLLIERGLOBALCACHE.NE.0) THEN + IF(COLLIERGLOBALCACHE.EQ.-1) THEN + CALL INITCACHESYSTEM_CLL(N_CACHES*NPROCS,MAXNEXTERNAL) + ELSE + CALL INITCACHESYSTEM_CLL(N_CACHES*NPROCS + $ ,COLLIERGLOBALCACHE) + ENDIF + CALL SWITCHOFFCACHESYSTEM_CLL() + NCALLS_IN_CACHE=-1 + NCOLLIERCALLS=0 + IF(COLLIER_CACHE_ACTIVE.EQ.1) CALL + $ SWITCHONCACHE_CLL((UNIQUE_ID-1)*N_CACHES+1) + ENDIF + ENDIF + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV=COMPUTE_UV + LAST_IR=COMPUTE_IR + ENDIF + C Initialize the event if it is the first time collier is called C on this PS point IF(MUST_INIT_EVENT) THEN @@ -194,11 +226,11 @@ SUBROUTINE MG5_1_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L ENDDO CALL INITEVENT_CLL((UNIQUE_ID-1)*N_CACHES+1) NCOLLIERCALLS(1) = 0 - IF(COLLIERCOMPUTEUVPOLES.AND.COLLIERUSECACHEFORPOLES) THEN + IF(COMPUTE_UV.AND.COLLIERUSECACHEFORPOLES) THEN CALL INITEVENT_CLL((UNIQUE_ID-1)*N_CACHES+2) NCOLLIERCALLS(2) = 0 ENDIF - IF(COLLIERCOMPUTEIRPOLES.AND.COLLIERUSECACHEFORPOLES) THEN + IF(COMPUTE_IR.AND.COLLIERUSECACHEFORPOLES) THEN CALL INITEVENT_CLL((UNIQUE_ID-1)*N_CACHES+3) NCOLLIERCALLS(3) = 0 CALL INITEVENT_CLL((UNIQUE_ID-1)*N_CACHES+4) @@ -351,7 +383,7 @@ SUBROUTINE MG5_1_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L ENDIF C Now compute the UV poles if asked for - IF (COLLIERCOMPUTEUVPOLES) THEN + IF (COMPUTE_UV) THEN IF(COLLIER_CACHE_ACTIVE.EQ.1) THEN CALL SWITCHOFFCACHE_CLL((UNIQUE_ID-1)*N_CACHES+1) IF(COLLIERUSECACHEFORPOLES) THEN @@ -379,7 +411,7 @@ SUBROUTINE MG5_1_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L ENDIF C Now compute the IR poles if asked for - IF (COLLIERCOMPUTEIRPOLES) THEN + IF (COMPUTE_IR) THEN IF(COLLIER_CACHE_ACTIVE.EQ.1) THEN CALL SWITCHOFFCACHE_CLL((UNIQUE_ID-1)*N_CACHES+1) IF(COLLIERUSECACHEFORPOLES) THEN @@ -435,13 +467,13 @@ SUBROUTINE MG5_1_COLLIERLOOP(CTMODE, NLOOPLINE,RANK,PL,PDEN,M2L SGN = 1 ENDIF TIRCOEFS(I,1) = SGN*TNTEN(C0,C1,C2,C3) - IF (COLLIERCOMPUTEUVPOLES) THEN + IF (COMPUTE_UV) THEN TIRCOEFS(I,2) = SGN*( TNTEN_UV(C0,C1,C2,C3)-TNTEN(C0,C1,C2 $ ,C3) ) ELSE TIRCOEFS(I,2) = DCMPLX(0.0D0,0.0D0) ENDIF - IF (COLLIERCOMPUTEIRPOLES) THEN + IF (COMPUTE_IR) THEN TIRCOEFS(I,2) = TIRCOEFS(I,2) + SGN*( TNTEN_IR1(C0,C1,C2,C3) $ -TNTEN(C0,C1,C2,C3) ) TIRCOEFS(I,3) = SGN*( TNTEN_IR2(C0,C1,C2,C3)-TNTEN(C0,C1,C2 diff --git a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%TIR_interface.f b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%TIR_interface.f index 2a5088d43b..2c31c2ed35 100644 --- a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%TIR_interface.f +++ b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%TIR_interface.f @@ -52,6 +52,10 @@ SUBROUTINE MG5_1_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -83,8 +87,38 @@ SUBROUTINE MG5_1_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL MG5_1_CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -374,9 +408,10 @@ SUBROUTINE MG5_1_CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=13) C diff --git a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%loop_matrix.f b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%loop_matrix.f index e5fe71a74e..5d054f88b9 100644 --- a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%loop_matrix.f +++ b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%loop_matrix.f @@ -79,13 +79,15 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/MG5_1_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -193,7 +195,7 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -246,23 +248,24 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.TRUE.,.TRUE./ + $ ,.TRUE.,.TRUE.,.FALSE./ COMMON/MG5_1_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -471,6 +474,7 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -507,10 +511,29 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -749,7 +772,7 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -775,7 +798,7 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -801,7 +824,7 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1098,8 +1121,8 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.MG5_1_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1665,7 +1688,7 @@ SUBROUTINE MG5_1_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2403,6 +2426,15 @@ INTEGER FUNCTION MG5_1_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE MG5_1_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE MG5_1_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2774,7 +2806,8 @@ SUBROUTINE MG5_1_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2784,7 +2817,8 @@ SUBROUTINE MG5_1_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%mp_coef_construction_1.f index 712a98f20e..77b076bcb5 100644 --- a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE MG5_1_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -87,7 +89,9 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_VVV1L2P0_1(PL(0,0),W(5),GC_4,ZERO,ZERO,PL(0,1),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,1)) CALL MP_VVV1L2P0_1(PL(0,1),W(7),GC_4,ZERO,ZERO,PL(0,2),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2) + $ ,WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,2),2,4,1,2,1,55,H) C Coefficient construction for loop diagram with ID 4 CALL MP_FFV1L3_1(PL(0,0),W(3),GC_5,ZERO,ZERO,PL(0,3),COEFS) @@ -95,7 +99,9 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L2P0_3(PL(0,3),W(4),GC_5,ZERO,ZERO,PL(0,4),COEFS) CALL MP_MG5_1_UPDATE_WL_1_0(WL(1,0,1,3),4,COEFS,4,4,WL(1,0,1,4)) CALL MP_VVV1L2P0_1(PL(0,4),W(5),GC_4,ZERO,ZERO,PL(0,5),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5) + $ ,WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,5),2,4,2,1,1,56,H) C Coefficient construction for loop diagram with ID 5 CALL MP_FFV1L1P0_3(PL(0,0),W(3),GC_5,ZERO,ZERO,PL(0,6),COEFS) @@ -103,13 +109,17 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L3_2(PL(0,6),W(4),GC_5,ZERO,ZERO,PL(0,7),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7)) CALL MP_FFV1L1_2(PL(0,7),W(5),GC_5,ZERO,ZERO,PL(0,8),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8) + $ ,WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,8),2,4,2,1,1,57,H) C Coefficient construction for loop diagram with ID 6 CALL MP_VVV1L2P0_1(PL(0,0),W(6),GC_4,ZERO,ZERO,PL(0,9),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,9)) CALL MP_VVV1L2P0_1(PL(0,9),W(8),GC_4,ZERO,ZERO,PL(0,10),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1,10)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1 + $ ,10),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,10),2,4,3,2,1,58,H) C Coefficient construction for loop diagram with ID 7 CALL MP_FFV1L3_1(PL(0,0),W(2),GC_5,ZERO,ZERO,PL(0,11),COEFS) @@ -118,8 +128,9 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_MG5_1_UPDATE_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,12) $ ) CALL MP_VVV1L2P0_1(PL(0,12),W(6),GC_4,ZERO,ZERO,PL(0,13),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,13) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1 + $ ,13),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,13),2,4,4,1,1,59,H) C Coefficient construction for loop diagram with ID 8 CALL MP_FFV1L1P0_3(PL(0,0),W(2),GC_5,ZERO,ZERO,PL(0,14),COEFS) @@ -128,8 +139,9 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,14),4,COEFS,4,4,WL(1,0,1,15) $ ) CALL MP_FFV1L1_2(PL(0,15),W(6),GC_5,ZERO,ZERO,PL(0,16),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1,16) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1 + $ ,16),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,16),2,4,4,1,1,60,H) C Coefficient construction for loop diagram with ID 9 CALL MP_FFV1L3_2(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,17),COEFS) @@ -138,8 +150,9 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_MG5_1_UPDATE_WL_1_0(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18) $ ) CALL MP_VVV1L2P0_1(PL(0,18),W(8),GC_4,ZERO,ZERO,PL(0,19),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,18),4,COEFS,4,4,WL(1,0,1,19) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,18),4,COEFS,4,4,WL(1,0,1 + $ ,19),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,19),2,4,5,1,1,61,H) C Coefficient construction for loop diagram with ID 10 CALL MP_FFV1L2P0_3(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,20),COEFS) @@ -148,8 +161,9 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,20),4,COEFS,4,4,WL(1,0,1,21) $ ) CALL MP_FFV1L2_1(PL(0,21),W(8),GC_5,ZERO,ZERO,PL(0,22),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1,22) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1 + $ ,22),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,22),2,4,5,1,1,62,H) C Coefficient construction for loop diagram with ID 11 CALL MP_FFV1L3_1(PL(0,20),W(2),GC_5,ZERO,ZERO,PL(0,23),COEFS) @@ -159,101 +173,115 @@ SUBROUTINE MG5_1_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_MG5_1_UPDATE_WL_1_0(WL(1,0,1,23),4,COEFS,4,4,WL(1,0,1,24) $ ) CALL MP_FFV1L3_1(PL(0,24),W(3),GC_5,ZERO,ZERO,PL(0,25),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,25) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1 + $ ,25),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,25),2,4,6,1,1,63,H) C Coefficient construction for loop diagram with ID 12 CALL MP_FFV1L2_1(PL(0,23),W(7),GC_5,ZERO,ZERO,PL(0,26),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,23),4,COEFS,4,4,WL(1,0,1,26) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,23),4,COEFS,4,4,WL(1,0,1 + $ ,26),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,26),2,4,7,1,1,64,H) C Coefficient construction for loop diagram with ID 13 CALL MP_FFV1L1P0_3(PL(0,17),W(2),GC_5,ZERO,ZERO,PL(0,27),COEFS) CALL MP_MG5_1_UPDATE_WL_1_0(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,27) $ ) CALL MP_VVV1L2P0_1(PL(0,27),W(7),GC_4,ZERO,ZERO,PL(0,28),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,28) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1 + $ ,28),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,28),2,4,7,1,1,65,H) C Coefficient construction for loop diagram with ID 14 CALL MP_FFV1L3_2(PL(0,27),W(4),GC_5,ZERO,ZERO,PL(0,29),COEFS) CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,29) $ ) CALL MP_FFV1L1P0_3(PL(0,29),W(3),GC_5,ZERO,ZERO,PL(0,30),COEFS) - CALL MP_MG5_1_UPDATE_WL_2_0(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,30) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_2_0(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1 + $ ,30),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,30),2,4,6,1,1,66,H) C Coefficient construction for loop diagram with ID 15 CALL MP_FFV1L3_1(PL(0,27),W(3),GC_5,ZERO,ZERO,PL(0,31),COEFS) CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,31) $ ) CALL MP_FFV1L2P0_3(PL(0,31),W(4),GC_5,ZERO,ZERO,PL(0,32),COEFS) - CALL MP_MG5_1_UPDATE_WL_2_0(WL(1,0,1,31),4,COEFS,4,4,WL(1,0,1,32) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_2_0(WL(1,0,1,31),4,COEFS,4,4,WL(1,0,1 + $ ,32),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,32),2,4,8,1,1,67,H) C Coefficient construction for loop diagram with ID 16 CALL MP_FFV1L3_1(PL(0,18),W(2),GC_5,ZERO,ZERO,PL(0,33),COEFS) CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,18),4,COEFS,4,4,WL(1,0,1,33) $ ) CALL MP_FFV1L2P0_3(PL(0,33),W(4),GC_5,ZERO,ZERO,PL(0,34),COEFS) - CALL MP_MG5_1_UPDATE_WL_2_0(WL(1,0,1,33),4,COEFS,4,4,WL(1,0,1,34) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_2_0(WL(1,0,1,33),4,COEFS,4,4,WL(1,0,1 + $ ,34),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,34),2,4,9,1,1,68,H) C Coefficient construction for loop diagram with ID 17 CALL MP_GHGHGL2_1(PL(0,0),W(5),GC_4,ZERO,ZERO,PL(0,35),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,35)) CALL MP_GHGHGL2_1(PL(0,35),W(7),GC_4,ZERO,ZERO,PL(0,36),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,35),1,COEFS,1,1,WL(1,0,1,36) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,35),1,COEFS,1,1,WL(1,0,1 + $ ,36),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,36),2,1,1,1,1,69,H) C Coefficient construction for loop diagram with ID 18 CALL MP_GHGHGL2_1(PL(0,0),W(6),GC_4,ZERO,ZERO,PL(0,37),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,37)) CALL MP_GHGHGL2_1(PL(0,37),W(8),GC_4,ZERO,ZERO,PL(0,38),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,37),1,COEFS,1,1,WL(1,0,1,38) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,37),1,COEFS,1,1,WL(1,0,1 + $ ,38),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,38),2,1,3,1,1,70,H) C Coefficient construction for loop diagram with ID 19 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,ZERO,ZERO,PL(0,39),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,39)) CALL MP_FFV1L2_1(PL(0,39),W(7),GC_5,ZERO,ZERO,PL(0,40),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,39),4,COEFS,4,4,WL(1,0,1,40) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,39),4,COEFS,4,4,WL(1,0,1 + $ ,40),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,40),2,4,1,1,4,71,H) C Coefficient construction for loop diagram with ID 20 CALL MP_FFV1L2_1(PL(0,0),W(6),GC_5,ZERO,ZERO,PL(0,41),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,41)) CALL MP_FFV1L2_1(PL(0,41),W(8),GC_5,ZERO,ZERO,PL(0,42),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,41),4,COEFS,4,4,WL(1,0,1,42) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,41),4,COEFS,4,4,WL(1,0,1 + $ ,42),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,42),2,4,3,1,4,72,H) C Coefficient construction for loop diagram with ID 21 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,MDL_MB,ZERO,PL(0,43),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,43)) CALL MP_FFV1L2_1(PL(0,43),W(7),GC_5,MDL_MB,ZERO,PL(0,44),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,43),4,COEFS,4,4,WL(1,0,1,44) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,43),4,COEFS,4,4,WL(1,0,1 + $ ,44),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,44),2,4,10,1,1,73,H) C Coefficient construction for loop diagram with ID 22 CALL MP_FFV1L2_1(PL(0,0),W(6),GC_5,MDL_MB,ZERO,PL(0,45),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,45)) CALL MP_FFV1L2_1(PL(0,45),W(8),GC_5,MDL_MB,ZERO,PL(0,46),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,45),4,COEFS,4,4,WL(1,0,1,46) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,45),4,COEFS,4,4,WL(1,0,1 + $ ,46),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,46),2,4,11,1,1,74,H) C Coefficient construction for loop diagram with ID 23 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,MDL_MT,MDL_WT,PL(0,47),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,47)) CALL MP_FFV1L2_1(PL(0,47),W(7),GC_5,MDL_MT,MDL_WT,PL(0,48),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,47),4,COEFS,4,4,WL(1,0,1,48) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,47),4,COEFS,4,4,WL(1,0,1 + $ ,48),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,48),2,4,12,1,1,75,H) C Coefficient construction for loop diagram with ID 24 CALL MP_FFV1L2_1(PL(0,0),W(6),GC_5,MDL_MT,MDL_WT,PL(0,49),COEFS) CALL MP_MG5_1_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,49)) CALL MP_FFV1L2_1(PL(0,49),W(8),GC_5,MDL_MT,MDL_WT,PL(0,50),COEFS) - CALL MP_MG5_1_UPDATE_WL_1_1(WL(1,0,1,49),4,COEFS,4,4,WL(1,0,1,50) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_MG5_1_TERMINAL_WL_1_1(WL(1,0,1,49),4,COEFS,4,4,WL(1,0,1 + $ ,50),WL_ENTRY_INEXACT) CALL MP_MG5_1_CREATE_LOOP_COEFS(WL(1,0,1,50),2,4,13,1,1,76,H) C At this point, all loop coefficients needed for (QCD=6), i.e. of C split order ID=1, are computed. diff --git a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%mp_compute_loop_coefs.f index 00fd0c655b..277dba7fc1 100644 --- a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%mp_compute_loop_coefs.f @@ -173,7 +173,8 @@ SUBROUTINE MG5_1_MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%polynomial.f b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%polynomial.f index 72a1e4e57e..5c1bed22fe 100644 --- a/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%polynomial.f +++ b/tests/input_files/IOTestsComparison/TestCmdMatchBox/MatchBoxOutput/%TEST%SubProcesses%P1_uux_uux%polynomial.f @@ -375,11 +375,13 @@ SUBROUTINE MG5_1_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -393,18 +395,94 @@ SUBROUTINE MG5_1_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_MG5_1_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE MG5_1_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_MG5_1_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_MG5_1_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE MG5_1_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -425,11 +503,13 @@ SUBROUTINE MG5_1_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -452,6 +532,90 @@ SUBROUTINE MG5_1_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_MG5_1_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) + USE MG5_1_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_MG5_1_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_MG5_1_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE MG5_1_POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -460,11 +624,13 @@ SUBROUTINE MP_MG5_1_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -495,11 +661,13 @@ SUBROUTINE MG5_1_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -512,6 +680,80 @@ SUBROUTINE MG5_1_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_MG5_1_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) + USE MG5_1_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_MG5_1_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_MG5_1_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE MG5_1_POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -520,11 +762,13 @@ SUBROUTINE MP_MG5_1_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -545,11 +789,13 @@ SUBROUTINE MG5_1_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -558,6 +804,76 @@ SUBROUTINE MG5_1_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_MG5_1_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) + USE MG5_1_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_MG5_1_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_MG5_1_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE MG5_1_POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -566,11 +882,13 @@ SUBROUTINE MP_MG5_1_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -587,11 +905,13 @@ SUBROUTINE MG5_1_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -615,18 +935,290 @@ SUBROUTINE MG5_1_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_MG5_1_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE MG5_1_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_MG5_1_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_MG5_1_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE MG5_1_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_MG5_1_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE MG5_1_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_MG5_1_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_MG5_1_TERMINAL_WL_2_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE MG5_1_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_MG5_1_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -645,4 +1237,38 @@ SUBROUTINE MP_MG5_1_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + END diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/%..%..%Source%MODEL%model_functions.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/%..%..%Source%MODEL%model_functions.f index 0a5f1443ac..232e1b1ab3 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/%..%..%Source%MODEL%model_functions.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/%..%..%Source%MODEL%model_functions.f @@ -546,7 +546,7 @@ COMPLEX*32 FUNCTION MP_RECMS(CONDITION,EXPR) IF(CONDITION)THEN MP_RECMS=EXPR ELSE - MP_RECMS=CMPLX(REAL(EXPR),KIND=16) + MP_RECMS=CMPLX(REAL(EXPR,KIND=16),KIND=16) ENDIF END @@ -555,16 +555,16 @@ COMPLEX*32 FUNCTION MP_REGLOG(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16)) THEN MP_REGLOG=(0.0E0_16,0.0E0_16) @@ -577,16 +577,16 @@ COMPLEX*32 FUNCTION MP_REGLOGP(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGP=(0.0E0_16,0.0E0_16) @@ -604,16 +604,16 @@ COMPLEX*32 FUNCTION MP_REGLOGM(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGM=(0.0E0_16,0.0E0_16) @@ -633,10 +633,10 @@ COMPLEX*32 FUNCTION MP_REGSQRT(ARG_IN) COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF MP_REGSQRT=SQRT(ARG) END @@ -645,7 +645,7 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 EXPR1_IN,EXPR2_IN COMPLEX*32 EXPR1,EXPR2 @@ -655,16 +655,16 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) EXPR1=EXPR1_IN EXPR2=EXPR2_IN IF(ABS(IMAGPART(EXPR1)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16) + EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR1,KIND=16)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1)) + EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1),KIND=16) ENDIF IF(ABS(IMAGPART(EXPR2)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16) + EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR2,KIND=16)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2)) + EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2),KIND=16) ENDIF IF(EXPR1.EQ.(0.0E0_16,0.0E0_16))THEN MP_GRREGLOG=(0.0E0_16,0.0E0_16) @@ -795,7 +795,7 @@ COMPLEX*32 FUNCTION MP_B0F(P2,M12,M22) COMPLEX*32 ZERO,TWOPII PARAMETER (ZERO=(0.0E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) REAL*16 M,M2,GA,GA2 REAL*16 TINY @@ -898,7 +898,7 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) GA=-IMAGPART(P2)/M ENDIF GAMMA0=ONE+M12/P2-M22/P2 - GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2 + GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY)/P2 IF(ABS(GA).EQ.0.0E0_16)THEN MP_SQRT_TRAJECTORY=SQRT(GAMMA0**2-4.0E0_16*GAMMA1) RETURN @@ -907,15 +907,17 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG PREFACTOR=1.0E0_16 GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGIM1=GAMMA0I**2-4.0E0_16*GAMMA1I DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGI=GAMMA0I**2-4.0E0_16*GAMMA1I IF(IMAGPART(ARGI)*IMAGPART(ARGIM1).LT.0.0E0_16)THEN INTERSECTION=IMAGPART(ARGIM1)*(REAL(ARGI,KIND=16) @@ -941,7 +943,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) PARAMETER (ZERO=(0.0E0_16,0.0E0_16),ONE=(1.0E0_16,0.0E0_16)) PARAMETER (HALF=(0.5E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 GAMMA0,GAMMAP,GAMMAM,SQRTTERM REAL*16 M,GA,DGA,GA_START @@ -978,7 +980,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG ADDFACTOR(1:4)=ZERO GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) @@ -989,7 +991,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) ARGIM1(4)=(GAMMAMI-ONE)/GAMMAMI DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/loop_matrix.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/loop_matrix.f index 4d9b04a3d6..a571244116 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/loop_matrix.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/loop_matrix.f @@ -440,6 +440,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANSRETURNED) STOP 1 ENDIF ENDIF +C The non-optimized output uses CutTools regardless of the +C requested chain. + IF(LOOPPOLEMODE.GT.0) THEN + WRITE(*,*) 'LoopPoleMode=1, 2 or 3 requires optimized MadLoop' + $ //' output with NinjaRS or COLLIER.' + WRITE(*,*) 'Regenerate with loop_optimized_output enabled and' + $ //' MLReductionLib=8 or 7.' + STOP 1 + ENDIF IF (LOCAL_ML_INIT) THEN C Setup the file paths CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%model_functions.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%model_functions.f index 0a5f1443ac..232e1b1ab3 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%model_functions.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%model_functions.f @@ -546,7 +546,7 @@ COMPLEX*32 FUNCTION MP_RECMS(CONDITION,EXPR) IF(CONDITION)THEN MP_RECMS=EXPR ELSE - MP_RECMS=CMPLX(REAL(EXPR),KIND=16) + MP_RECMS=CMPLX(REAL(EXPR,KIND=16),KIND=16) ENDIF END @@ -555,16 +555,16 @@ COMPLEX*32 FUNCTION MP_REGLOG(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16)) THEN MP_REGLOG=(0.0E0_16,0.0E0_16) @@ -577,16 +577,16 @@ COMPLEX*32 FUNCTION MP_REGLOGP(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGP=(0.0E0_16,0.0E0_16) @@ -604,16 +604,16 @@ COMPLEX*32 FUNCTION MP_REGLOGM(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGM=(0.0E0_16,0.0E0_16) @@ -633,10 +633,10 @@ COMPLEX*32 FUNCTION MP_REGSQRT(ARG_IN) COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF MP_REGSQRT=SQRT(ARG) END @@ -645,7 +645,7 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 EXPR1_IN,EXPR2_IN COMPLEX*32 EXPR1,EXPR2 @@ -655,16 +655,16 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) EXPR1=EXPR1_IN EXPR2=EXPR2_IN IF(ABS(IMAGPART(EXPR1)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16) + EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR1,KIND=16)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1)) + EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1),KIND=16) ENDIF IF(ABS(IMAGPART(EXPR2)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16) + EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR2,KIND=16)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2)) + EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2),KIND=16) ENDIF IF(EXPR1.EQ.(0.0E0_16,0.0E0_16))THEN MP_GRREGLOG=(0.0E0_16,0.0E0_16) @@ -795,7 +795,7 @@ COMPLEX*32 FUNCTION MP_B0F(P2,M12,M22) COMPLEX*32 ZERO,TWOPII PARAMETER (ZERO=(0.0E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) REAL*16 M,M2,GA,GA2 REAL*16 TINY @@ -898,7 +898,7 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) GA=-IMAGPART(P2)/M ENDIF GAMMA0=ONE+M12/P2-M22/P2 - GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2 + GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY)/P2 IF(ABS(GA).EQ.0.0E0_16)THEN MP_SQRT_TRAJECTORY=SQRT(GAMMA0**2-4.0E0_16*GAMMA1) RETURN @@ -907,15 +907,17 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG PREFACTOR=1.0E0_16 GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGIM1=GAMMA0I**2-4.0E0_16*GAMMA1I DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGI=GAMMA0I**2-4.0E0_16*GAMMA1I IF(IMAGPART(ARGI)*IMAGPART(ARGIM1).LT.0.0E0_16)THEN INTERSECTION=IMAGPART(ARGIM1)*(REAL(ARGI,KIND=16) @@ -941,7 +943,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) PARAMETER (ZERO=(0.0E0_16,0.0E0_16),ONE=(1.0E0_16,0.0E0_16)) PARAMETER (HALF=(0.5E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 GAMMA0,GAMMAP,GAMMAM,SQRTTERM REAL*16 M,GA,DGA,GA_START @@ -978,7 +980,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG ADDFACTOR(1:4)=ZERO GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) @@ -989,7 +991,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) ARGIM1(4)=(GAMMAMI-ONE)/GAMMAMI DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/loop_matrix.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/loop_matrix.f index d37628da38..d1c7ecb009 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/loop_matrix.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/loop_matrix.f @@ -440,6 +440,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANSRETURNED) STOP 1 ENDIF ENDIF +C The non-optimized output uses CutTools regardless of the +C requested chain. + IF(LOOPPOLEMODE.GT.0) THEN + WRITE(*,*) 'LoopPoleMode=1, 2 or 3 requires optimized MadLoop' + $ //' output with NinjaRS or COLLIER.' + WRITE(*,*) 'Regenerate with loop_optimized_output enabled and' + $ //' MLReductionLib=8 or 7.' + STOP 1 + ENDIF IF (LOCAL_ML_INIT) THEN C Setup the file paths CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/%..%..%Source%MODEL%model_functions.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/%..%..%Source%MODEL%model_functions.f index 0a5f1443ac..232e1b1ab3 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/%..%..%Source%MODEL%model_functions.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/%..%..%Source%MODEL%model_functions.f @@ -546,7 +546,7 @@ COMPLEX*32 FUNCTION MP_RECMS(CONDITION,EXPR) IF(CONDITION)THEN MP_RECMS=EXPR ELSE - MP_RECMS=CMPLX(REAL(EXPR),KIND=16) + MP_RECMS=CMPLX(REAL(EXPR,KIND=16),KIND=16) ENDIF END @@ -555,16 +555,16 @@ COMPLEX*32 FUNCTION MP_REGLOG(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16)) THEN MP_REGLOG=(0.0E0_16,0.0E0_16) @@ -577,16 +577,16 @@ COMPLEX*32 FUNCTION MP_REGLOGP(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGP=(0.0E0_16,0.0E0_16) @@ -604,16 +604,16 @@ COMPLEX*32 FUNCTION MP_REGLOGM(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGM=(0.0E0_16,0.0E0_16) @@ -633,10 +633,10 @@ COMPLEX*32 FUNCTION MP_REGSQRT(ARG_IN) COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF MP_REGSQRT=SQRT(ARG) END @@ -645,7 +645,7 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 EXPR1_IN,EXPR2_IN COMPLEX*32 EXPR1,EXPR2 @@ -655,16 +655,16 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) EXPR1=EXPR1_IN EXPR2=EXPR2_IN IF(ABS(IMAGPART(EXPR1)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16) + EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR1,KIND=16)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1)) + EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1),KIND=16) ENDIF IF(ABS(IMAGPART(EXPR2)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16) + EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR2,KIND=16)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2)) + EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2),KIND=16) ENDIF IF(EXPR1.EQ.(0.0E0_16,0.0E0_16))THEN MP_GRREGLOG=(0.0E0_16,0.0E0_16) @@ -795,7 +795,7 @@ COMPLEX*32 FUNCTION MP_B0F(P2,M12,M22) COMPLEX*32 ZERO,TWOPII PARAMETER (ZERO=(0.0E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) REAL*16 M,M2,GA,GA2 REAL*16 TINY @@ -898,7 +898,7 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) GA=-IMAGPART(P2)/M ENDIF GAMMA0=ONE+M12/P2-M22/P2 - GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2 + GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY)/P2 IF(ABS(GA).EQ.0.0E0_16)THEN MP_SQRT_TRAJECTORY=SQRT(GAMMA0**2-4.0E0_16*GAMMA1) RETURN @@ -907,15 +907,17 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG PREFACTOR=1.0E0_16 GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGIM1=GAMMA0I**2-4.0E0_16*GAMMA1I DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGI=GAMMA0I**2-4.0E0_16*GAMMA1I IF(IMAGPART(ARGI)*IMAGPART(ARGIM1).LT.0.0E0_16)THEN INTERSECTION=IMAGPART(ARGIM1)*(REAL(ARGI,KIND=16) @@ -941,7 +943,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) PARAMETER (ZERO=(0.0E0_16,0.0E0_16),ONE=(1.0E0_16,0.0E0_16)) PARAMETER (HALF=(0.5E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 GAMMA0,GAMMAP,GAMMAM,SQRTTERM REAL*16 M,GA,DGA,GA_START @@ -978,7 +980,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG ADDFACTOR(1:4)=ZERO GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) @@ -989,7 +991,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) ARGIM1(4)=(GAMMAMI-ONE)/GAMMAMI DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/TIR_interface.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/TIR_interface.f index db630cfcb5..20b3cfc9dc 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/TIR_interface.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/TIR_interface.f @@ -52,6 +52,10 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -83,8 +87,38 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL ML5_0_CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -360,9 +394,10 @@ SUBROUTINE ML5_0_CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=9) C diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/loop_matrix.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/loop_matrix.f index 00ed04a178..25c7712024 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/loop_matrix.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/loop_matrix.f @@ -79,13 +79,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -193,7 +195,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -246,23 +248,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE./ + $ ,.FALSE.,.FALSE.,.FALSE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -472,6 +475,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -508,10 +512,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -750,7 +773,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -776,7 +799,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -802,7 +825,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1093,8 +1116,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1660,7 +1683,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2379,6 +2402,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2750,7 +2782,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2760,7 +2793,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/mp_coef_construction_1.f index 2d9ecce6ad..f8fc18172f 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -89,13 +91,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV2L2_1(PL(0,1),W(7),GC_11,ZERO,ZERO,PL(0,2),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) CALL MP_FFV1L2P0_3(PL(0,2),W(6),GC_5,ZERO,ZERO,PL(0,3),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,2),4,COEFS,4,4,WL(1,0,1,3)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,2),4,COEFS,4,4,WL(1,0,1,3) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,3),2,4,1,1,1,29,H) C Coefficient construction for loop diagram with ID 4 CALL MP_FFV1L2P0_3(PL(0,0),W(6),GC_5,ZERO,ZERO,PL(0,4),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,4)) CALL MP_FFV1L3_1(PL(0,4),W(9),GC_5,ZERO,ZERO,PL(0,5),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,5),1,4,2,1,1,30,H) C Coefficient construction for loop diagram with ID 5 CALL MP_FFV1L3_2(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,6),COEFS) @@ -103,7 +109,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV2L1_2(PL(0,6),W(7),GC_11,ZERO,ZERO,PL(0,7),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7)) CALL MP_FFV1L1P0_3(PL(0,7),W(8),GC_5,ZERO,ZERO,PL(0,8),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,8),2,4,3,1,1,31,H) C Coefficient construction for loop diagram with ID 6 CALL MP_FFV1L2P0_3(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,9),COEFS) @@ -114,23 +122,26 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,10),4,COEFS,4,4,WL(1,0,1,11) $ ) CALL MP_FFV2L2_1(PL(0,11),W(7),GC_11,ZERO,ZERO,PL(0,12),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,12) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,12),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,12),3,4,4,1,1,32,H) C Coefficient construction for loop diagram with ID 7 CALL MP_FFV2L2_1(PL(0,10),W(7),GC_11,ZERO,ZERO,PL(0,13),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,10),4,COEFS,4,4,WL(1,0,1,13) $ ) CALL MP_FFV1L2_1(PL(0,13),W(5),GC_5,ZERO,ZERO,PL(0,14),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,13),4,COEFS,4,4,WL(1,0,1,14) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,13),4 + $ ,COEFS,4,4,WL(1,0,1,14),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,14),3,4,5,1,1,33,H) C Coefficient construction for loop diagram with ID 8 CALL MP_FFV1L1_2(PL(0,6),W(5),GC_5,ZERO,ZERO,PL(0,15),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,15)) CALL MP_FFV1L1P0_3(PL(0,15),W(9),GC_5,ZERO,ZERO,PL(0,16),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1,16) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1 + $ ,16),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,16),2,4,6,1,1,34,H) C Coefficient construction for loop diagram with ID 9 CALL MP_VVV1L2P0_1(PL(0,9),W(5),GC_4,ZERO,ZERO,PL(0,17),COEFS) @@ -139,27 +150,31 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18) $ ) CALL MP_FFV2L2_1(PL(0,18),W(7),GC_11,ZERO,ZERO,PL(0,19),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,18),4,COEFS,4,4,WL(1,0,1,19) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,18),4,COEFS,4,4,WL(1,0,1 + $ ,19),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,19),3,4,7,1,1,35,H) C Coefficient construction for loop diagram with ID 10 CALL MP_FFV1L3_1(PL(0,17),W(9),GC_5,ZERO,ZERO,PL(0,20),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,20) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1 + $ ,20),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,20),2,4,6,1,1,36,H) C Coefficient construction for loop diagram with ID 11 CALL MP_FFV1L1P0_3(PL(0,0),W(8),GC_5,ZERO,ZERO,PL(0,21),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,21)) CALL MP_FFV1L3_2(PL(0,21),W(10),GC_5,ZERO,ZERO,PL(0,22),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1,22) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1 + $ ,22),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,22),1,4,8,1,1,37,H) C Coefficient construction for loop diagram with ID 12 CALL MP_FFV1L2_1(PL(0,1),W(5),GC_5,ZERO,ZERO,PL(0,23),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,23)) CALL MP_FFV1L2P0_3(PL(0,23),W(10),GC_5,ZERO,ZERO,PL(0,24),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,23),4,COEFS,4,4,WL(1,0,1,24) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,23),4,COEFS,4,4,WL(1,0,1 + $ ,24),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,24),2,4,9,1,1,38,H) C Coefficient construction for loop diagram with ID 13 CALL MP_FFV1L1P0_3(PL(0,0),W(2),GC_5,ZERO,ZERO,PL(0,25),COEFS) @@ -168,8 +183,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,25),4,COEFS,4,4,WL(1,0,1,26) $ ) CALL MP_FFV1L3_2(PL(0,26),W(10),GC_5,ZERO,ZERO,PL(0,27),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1,27) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1 + $ ,27),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,27),2,4,9,1,1,39,H) GOTO 1001 diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/mp_compute_loop_coefs.f index 0829a8b514..4928a1770a 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/mp_compute_loop_coefs.f @@ -173,7 +173,8 @@ SUBROUTINE ML5_0_MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/polynomial.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/polynomial.f index 997fb47c31..4b3c28f00c 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/polynomial.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/polynomial.f @@ -379,11 +379,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -397,18 +399,94 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -429,11 +507,13 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -457,18 +537,104 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -499,11 +665,13 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -527,18 +695,105 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -569,11 +824,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -583,18 +840,90 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -620,9 +949,9 @@ SUBROUTINE ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE DO K=1,IN_SIZE UPDATER_COEF = B(J,M,K) IF (UPDATER_COEF.EQ.(0.0D0,0.0D0)) CYCLE - DO L=0,14 - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION = COMB_COEF_POS(L,M) OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) $ *UPDATER_COEF ENDDO @@ -636,25 +965,109 @@ SUBROUTINE ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC IMPLICIT NONE INTEGER I,J,K,L,M COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L INTEGER NEW_POSITION COMPLEX*32 UPDATER_COEF C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) DO J=1,OUT_SIZE DO M=0,4 DO K=1,IN_SIZE UPDATER_COEF = B(J,M,K) IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE - DO L=0,14 - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION = COMB_COEF_POS(L,M) OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) $ *UPDATER_COEF ENDDO @@ -664,3 +1077,1936 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L1_2(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L2_1(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_0_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.1.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:0,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%model_functions.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%model_functions.f index 0a5f1443ac..232e1b1ab3 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%model_functions.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%model_functions.f @@ -546,7 +546,7 @@ COMPLEX*32 FUNCTION MP_RECMS(CONDITION,EXPR) IF(CONDITION)THEN MP_RECMS=EXPR ELSE - MP_RECMS=CMPLX(REAL(EXPR),KIND=16) + MP_RECMS=CMPLX(REAL(EXPR,KIND=16),KIND=16) ENDIF END @@ -555,16 +555,16 @@ COMPLEX*32 FUNCTION MP_REGLOG(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16)) THEN MP_REGLOG=(0.0E0_16,0.0E0_16) @@ -577,16 +577,16 @@ COMPLEX*32 FUNCTION MP_REGLOGP(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGP=(0.0E0_16,0.0E0_16) @@ -604,16 +604,16 @@ COMPLEX*32 FUNCTION MP_REGLOGM(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGM=(0.0E0_16,0.0E0_16) @@ -633,10 +633,10 @@ COMPLEX*32 FUNCTION MP_REGSQRT(ARG_IN) COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF MP_REGSQRT=SQRT(ARG) END @@ -645,7 +645,7 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 EXPR1_IN,EXPR2_IN COMPLEX*32 EXPR1,EXPR2 @@ -655,16 +655,16 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) EXPR1=EXPR1_IN EXPR2=EXPR2_IN IF(ABS(IMAGPART(EXPR1)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16) + EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR1,KIND=16)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1)) + EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1),KIND=16) ENDIF IF(ABS(IMAGPART(EXPR2)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16) + EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR2,KIND=16)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2)) + EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2),KIND=16) ENDIF IF(EXPR1.EQ.(0.0E0_16,0.0E0_16))THEN MP_GRREGLOG=(0.0E0_16,0.0E0_16) @@ -795,7 +795,7 @@ COMPLEX*32 FUNCTION MP_B0F(P2,M12,M22) COMPLEX*32 ZERO,TWOPII PARAMETER (ZERO=(0.0E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) REAL*16 M,M2,GA,GA2 REAL*16 TINY @@ -898,7 +898,7 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) GA=-IMAGPART(P2)/M ENDIF GAMMA0=ONE+M12/P2-M22/P2 - GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2 + GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY)/P2 IF(ABS(GA).EQ.0.0E0_16)THEN MP_SQRT_TRAJECTORY=SQRT(GAMMA0**2-4.0E0_16*GAMMA1) RETURN @@ -907,15 +907,17 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG PREFACTOR=1.0E0_16 GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGIM1=GAMMA0I**2-4.0E0_16*GAMMA1I DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGI=GAMMA0I**2-4.0E0_16*GAMMA1I IF(IMAGPART(ARGI)*IMAGPART(ARGIM1).LT.0.0E0_16)THEN INTERSECTION=IMAGPART(ARGIM1)*(REAL(ARGI,KIND=16) @@ -941,7 +943,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) PARAMETER (ZERO=(0.0E0_16,0.0E0_16),ONE=(1.0E0_16,0.0E0_16)) PARAMETER (HALF=(0.5E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 GAMMA0,GAMMAP,GAMMAM,SQRTTERM REAL*16 M,GA,DGA,GA_START @@ -978,7 +980,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG ADDFACTOR(1:4)=ZERO GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) @@ -989,7 +991,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) ARGIM1(4)=(GAMMAMI-ONE)/GAMMAMI DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/TIR_interface.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/TIR_interface.f index 370924b1f5..11330b9b2e 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/TIR_interface.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/TIR_interface.f @@ -52,6 +52,10 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -83,8 +87,38 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL ML5_0_CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -360,9 +394,10 @@ SUBROUTINE ML5_0_CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=106) C diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/loop_matrix.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/loop_matrix.f index 6aa3a49eac..42f919592a 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/loop_matrix.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/loop_matrix.f @@ -79,13 +79,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -193,7 +195,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -246,23 +248,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE./ + $ ,.FALSE.,.FALSE.,.FALSE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -472,6 +475,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -508,10 +512,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -750,7 +773,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -776,7 +799,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -802,7 +825,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1093,8 +1116,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1660,7 +1683,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2379,6 +2402,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2750,7 +2782,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2760,7 +2793,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/mp_coef_construction_1.f index 1c8da43d4a..c6fe9603d9 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -87,13 +89,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L1P0_3(PL(0,0),W(7),GC_5,ZERO,ZERO,PL(0,1),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,1)) CALL MP_FFV1L3_2(PL(0,1),W(13),GC_5,MDL_MB,ZERO,PL(0,2),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,2),1,4,1,1,1,253,H) C Coefficient construction for loop diagram with ID 10 CALL MP_VVV1L2P0_1(PL(0,0),W(6),GC_4,ZERO,ZERO,PL(0,3),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,3)) CALL MP_VVV1L2P0_1(PL(0,3),W(14),GC_4,ZERO,ZERO,PL(0,4),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,3),4,COEFS,4,4,WL(1,0,1,4)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,3),4,COEFS,4,4,WL(1,0,1,4) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,4),2,4,2,2,1,254,H) C Coefficient construction for loop diagram with ID 11 CALL MP_FFV1L2P0_3(PL(0,0),W(5),GC_5,ZERO,ZERO,PL(0,5),COEFS) @@ -101,7 +107,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_VVV1L2P0_1(PL(0,5),W(6),GC_4,ZERO,ZERO,PL(0,6),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,5),4,COEFS,4,4,WL(1,0,1,6)) CALL MP_FFV1L3_1(PL(0,6),W(7),GC_5,MDL_MB,ZERO,PL(0,7),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,7),2,4,3,1,1,255,H) C Coefficient construction for loop diagram with ID 12 CALL MP_FFV1L3_2(PL(0,0),W(5),GC_5,MDL_MB,ZERO,PL(0,8),COEFS) @@ -109,19 +117,24 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L1_2(PL(0,8),W(6),GC_5,MDL_MB,ZERO,PL(0,9),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,8),4,COEFS,4,4,WL(1,0,1,9)) CALL MP_FFV1L1P0_3(PL(0,9),W(7),GC_5,ZERO,ZERO,PL(0,10),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1,10)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1 + $ ,10),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,10),2,4,4,1,1,256,H) C Coefficient construction for loop diagram with ID 13 CALL MP_FFV1L2P0_3(PL(0,0),W(8),GC_5,ZERO,ZERO,PL(0,11),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,11)) CALL MP_FFV1L3_1(PL(0,11),W(15),GC_5,MDL_MT,MDL_WT,PL(0,12) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,12) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,12),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,12),1,4,5,1,1,257,H) C Coefficient construction for loop diagram with ID 14 CALL MP_VVV1L2P0_1(PL(0,3),W(16),GC_4,ZERO,ZERO,PL(0,13),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,3),4,COEFS,4,4,WL(1,0,1,13)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,3),4,COEFS,4,4,WL(1,0,1 + $ ,13),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,13),2,4,6,2,1,258,H) C Coefficient construction for loop diagram with ID 15 CALL MP_FFV1L1P0_3(PL(0,0),W(4),GC_5,ZERO,ZERO,PL(0,14),COEFS) @@ -130,8 +143,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,14),4,COEFS,4,4,WL(1,0,1,15) $ ) CALL MP_FFV1L3_2(PL(0,15),W(8),GC_5,MDL_MT,MDL_WT,PL(0,16),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1,16) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1 + $ ,16),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,16),2,4,7,1,1,259,H) C Coefficient construction for loop diagram with ID 16 CALL MP_FFV1L3_1(PL(0,0),W(4),GC_5,MDL_MT,MDL_WT,PL(0,17),COEFS) @@ -140,8 +154,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18) $ ) CALL MP_FFV1L2P0_3(PL(0,18),W(8),GC_5,ZERO,ZERO,PL(0,19),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,18),4,COEFS,4,4,WL(1,0,1,19) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,18),4,COEFS,4,4,WL(1,0,1 + $ ,19),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,19),2,4,8,1,1,260,H) C Coefficient construction for loop diagram with ID 17 CALL MP_FFV2L1_2(PL(0,0),W(3),GC_11,MDL_MT,MDL_WT,PL(0,20),COEFS) @@ -150,16 +165,18 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,20),4,COEFS,4,4,WL(1,0,1,21) $ ) CALL MP_FFV1L3_2(PL(0,21),W(13),GC_5,MDL_MB,ZERO,PL(0,22),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1,22) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1 + $ ,22),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,22),2,4,9,1,1,261,H) C Coefficient construction for loop diagram with ID 18 CALL MP_VVV1L2P0_1(PL(0,21),W(6),GC_4,ZERO,ZERO,PL(0,23),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1,23) $ ) CALL MP_FFV1L3_2(PL(0,23),W(5),GC_5,MDL_MB,ZERO,PL(0,24),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,23),4,COEFS,4,4,WL(1,0,1,24) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,23),4,COEFS,4,4,WL(1,0,1 + $ ,24),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,24),3,4,10,1,1,262,H) C Coefficient construction for loop diagram with ID 19 CALL MP_FFV2L2_1(PL(0,0),W(3),GC_11,MDL_MB,ZERO,PL(0,25),COEFS) @@ -171,45 +188,51 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1,27) $ ) CALL MP_FFV1L2_1(PL(0,27),W(6),GC_5,MDL_MT,MDL_WT,PL(0,28),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,28) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,27),4 + $ ,COEFS,4,4,WL(1,0,1,28),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,28),3,4,11,1,1,263,H) C Coefficient construction for loop diagram with ID 20 CALL MP_FFV1L3_2(PL(0,21),W(5),GC_5,MDL_MB,ZERO,PL(0,29),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1,29) $ ) CALL MP_FFV1L1_2(PL(0,29),W(6),GC_5,MDL_MB,ZERO,PL(0,30),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,30) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,29),4 + $ ,COEFS,4,4,WL(1,0,1,30),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,30),3,4,12,1,1,264,H) C Coefficient construction for loop diagram with ID 21 CALL MP_FFV1L3_1(PL(0,26),W(15),GC_5,MDL_MT,MDL_WT,PL(0,31) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1,31) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1 + $ ,31),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,31),2,4,13,1,1,265,H) C Coefficient construction for loop diagram with ID 22 CALL MP_FFV1L2P0_3(PL(0,0),W(10),GC_5,ZERO,ZERO,PL(0,32),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,32)) CALL MP_FFV1L3_1(PL(0,32),W(17),GC_5,MDL_MB,ZERO,PL(0,33),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1,33) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1 + $ ,33),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,33),1,4,14,1,1,266,H) C Coefficient construction for loop diagram with ID 23 CALL MP_FFV1L1P0_3(PL(0,0),W(9),GC_5,ZERO,ZERO,PL(0,34),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,34)) CALL MP_FFV1L3_2(PL(0,34),W(18),GC_5,MDL_MT,MDL_WT,PL(0,35) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,34),4,COEFS,4,4,WL(1,0,1,35) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,34),4,COEFS,4,4,WL(1,0,1 + $ ,35),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,35),1,4,15,1,1,267,H) C Coefficient construction for loop diagram with ID 24 CALL MP_FFV1L1P0_3(PL(0,20),W(9),GC_5,ZERO,ZERO,PL(0,36),COEFS) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,20),4,COEFS,4,4,WL(1,0,1,36) $ ) CALL MP_FFV1L3_2(PL(0,36),W(10),GC_5,MDL_MB,ZERO,PL(0,37),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,36),4,COEFS,4,4,WL(1,0,1,37) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,36),4,COEFS,4,4,WL(1,0,1 + $ ,37),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,37),2,4,16,1,1,268,H) C Coefficient construction for loop diagram with ID 25 CALL MP_VVV1L2P0_1(PL(0,0),W(2),GC_4,ZERO,ZERO,PL(0,38),COEFS) @@ -218,8 +241,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,39) $ ) CALL MP_FFV1L1P0_3(PL(0,39),W(17),GC_5,ZERO,ZERO,PL(0,40),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,39),4,COEFS,4,4,WL(1,0,1,40) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,39),4,COEFS,4,4,WL(1,0,1 + $ ,40),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,40),2,4,17,1,1,269,H) C Coefficient construction for loop diagram with ID 26 CALL MP_FFV2L1_2(PL(0,39),W(3),GC_11,MDL_MT,MDL_WT,PL(0,41) @@ -227,28 +251,32 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,39),4,COEFS,4,4,WL(1,0,1,41) $ ) CALL MP_FFV1L1P0_3(PL(0,41),W(9),GC_5,ZERO,ZERO,PL(0,42),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,41),4,COEFS,4,4,WL(1,0,1,42) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,41),4,COEFS,4,4,WL(1,0,1 + $ ,42),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,42),3,4,18,1,1,270,H) C Coefficient construction for loop diagram with ID 27 CALL MP_FFV1L3_1(PL(0,38),W(9),GC_5,MDL_MT,MDL_WT,PL(0,43),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,43) $ ) CALL MP_FFV1L2P0_3(PL(0,43),W(8),GC_5,ZERO,ZERO,PL(0,44),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,43),4,COEFS,4,4,WL(1,0,1,44) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,43),4,COEFS,4,4,WL(1,0,1 + $ ,44),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,44),2,4,19,1,1,271,H) C Coefficient construction for loop diagram with ID 28 CALL MP_FFV1L3_1(PL(0,11),W(19),GC_5,MDL_MT,MDL_WT,PL(0,45) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,45) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,45),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,45),1,4,5,1,1,272,H) C Coefficient construction for loop diagram with ID 29 CALL MP_FFV1L3_2(PL(0,34),W(20),GC_5,MDL_MT,MDL_WT,PL(0,46) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,34),4,COEFS,4,4,WL(1,0,1,46) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,34),4,COEFS,4,4,WL(1,0,1 + $ ,46),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,46),1,4,20,1,1,273,H) C Coefficient construction for loop diagram with ID 30 CALL MP_FFV1L1_2(PL(0,0),W(2),GC_5,MDL_MT,MDL_WT,PL(0,47),COEFS) @@ -257,14 +285,16 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,47),4,COEFS,4,4,WL(1,0,1,48) $ ) CALL MP_FFV1L3_2(PL(0,48),W(8),GC_5,MDL_MT,MDL_WT,PL(0,49),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,48),4,COEFS,4,4,WL(1,0,1,49) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,48),4,COEFS,4,4,WL(1,0,1 + $ ,49),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,49),2,4,21,1,1,274,H) C Coefficient construction for loop diagram with ID 31 CALL MP_FFV1L3_1(PL(0,26),W(19),GC_5,MDL_MT,MDL_WT,PL(0,50) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1,50) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1 + $ ,50),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,50),2,4,13,1,1,275,H) C Coefficient construction for loop diagram with ID 32 CALL MP_FFV1L2_1(PL(0,0),W(2),GC_5,MDL_MB,ZERO,PL(0,51),COEFS) @@ -273,8 +303,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,51),4,COEFS,4,4,WL(1,0,1,52) $ ) CALL MP_FFV1L3_1(PL(0,52),W(17),GC_5,MDL_MB,ZERO,PL(0,53),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,52),4,COEFS,4,4,WL(1,0,1,53) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,52),4,COEFS,4,4,WL(1,0,1 + $ ,53),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,53),2,4,22,1,1,276,H) C Coefficient construction for loop diagram with ID 33 CALL MP_FFV1L1_2(PL(0,0),W(2),GC_5,MDL_MB,ZERO,PL(0,54),COEFS) @@ -287,8 +318,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,55),4,COEFS,4,4,WL(1,0,1,56) $ ) CALL MP_FFV1L3_2(PL(0,56),W(5),GC_5,MDL_MB,ZERO,PL(0,57),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,56),4,COEFS,4,4,WL(1,0,1,57) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,56),4,COEFS,4,4,WL(1,0,1 + $ ,57),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,57),3,4,23,1,1,277,H) C Coefficient construction for loop diagram with ID 34 CALL MP_FFV1L2_1(PL(0,0),W(2),GC_5,MDL_MT,MDL_WT,PL(0,58),COEFS) @@ -300,77 +332,89 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,59),4,COEFS,4,4,WL(1,0,1,60) $ ) CALL MP_FFV1L3_1(PL(0,60),W(9),GC_5,MDL_MT,MDL_WT,PL(0,61),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,60),4,COEFS,4,4,WL(1,0,1,61) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,60),4,COEFS,4,4,WL(1,0,1 + $ ,61),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,61),3,4,24,1,1,278,H) C Coefficient construction for loop diagram with ID 35 CALL MP_FFV1L1P0_3(PL(0,0),W(12),GC_5,ZERO,ZERO,PL(0,62),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,62)) CALL MP_FFV1L3_2(PL(0,62),W(21),GC_5,MDL_MT,MDL_WT,PL(0,63) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,62),4,COEFS,4,4,WL(1,0,1,63) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,62),4,COEFS,4,4,WL(1,0,1 + $ ,63),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,63),1,4,25,1,1,279,H) C Coefficient construction for loop diagram with ID 36 CALL MP_FFV1L2P0_3(PL(0,0),W(11),GC_5,ZERO,ZERO,PL(0,64),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,64)) CALL MP_FFV1L3_1(PL(0,64),W(22),GC_5,MDL_MB,ZERO,PL(0,65),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,64),4,COEFS,4,4,WL(1,0,1,65) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,64),4,COEFS,4,4,WL(1,0,1 + $ ,65),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,65),1,4,26,1,1,280,H) C Coefficient construction for loop diagram with ID 37 CALL MP_FFV1L1P0_3(PL(0,20),W(12),GC_5,ZERO,ZERO,PL(0,66),COEFS) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,20),4,COEFS,4,4,WL(1,0,1,66) $ ) CALL MP_FFV1L3_2(PL(0,66),W(11),GC_5,MDL_MB,ZERO,PL(0,67),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,66),4,COEFS,4,4,WL(1,0,1,67) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,66),4,COEFS,4,4,WL(1,0,1 + $ ,67),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,67),2,4,27,1,1,281,H) C Coefficient construction for loop diagram with ID 38 CALL MP_FFV1L3_1(PL(0,38),W(4),GC_5,MDL_MT,MDL_WT,PL(0,68),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,68) $ ) CALL MP_FFV1L2P0_3(PL(0,68),W(21),GC_5,ZERO,ZERO,PL(0,69),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,68),4,COEFS,4,4,WL(1,0,1,69) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,68),4,COEFS,4,4,WL(1,0,1 + $ ,69),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,69),2,4,28,1,1,282,H) C Coefficient construction for loop diagram with ID 39 CALL MP_FFV2L2_1(PL(0,68),W(3),GC_11,MDL_MB,ZERO,PL(0,70),COEFS) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,68),4,COEFS,4,4,WL(1,0,1,70) $ ) CALL MP_FFV1L2P0_3(PL(0,70),W(11),GC_5,ZERO,ZERO,PL(0,71),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,70),4,COEFS,4,4,WL(1,0,1,71) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,70),4,COEFS,4,4,WL(1,0,1 + $ ,71),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,71),3,4,29,1,1,283,H) C Coefficient construction for loop diagram with ID 40 CALL MP_FFV1L3_1(PL(0,38),W(7),GC_5,MDL_MB,ZERO,PL(0,72),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,72) $ ) CALL MP_FFV1L2P0_3(PL(0,72),W(11),GC_5,ZERO,ZERO,PL(0,73),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,72),4,COEFS,4,4,WL(1,0,1,73) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,72),4,COEFS,4,4,WL(1,0,1 + $ ,73),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,73),2,4,30,1,1,284,H) C Coefficient construction for loop diagram with ID 41 CALL MP_FFV1L3_2(PL(0,1),W(23),GC_5,MDL_MB,ZERO,PL(0,74),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,74)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1 + $ ,74),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,74),1,4,1,1,1,285,H) C Coefficient construction for loop diagram with ID 42 CALL MP_FFV1L3_1(PL(0,64),W(24),GC_5,MDL_MB,ZERO,PL(0,75),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,64),4,COEFS,4,4,WL(1,0,1,75) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,64),4,COEFS,4,4,WL(1,0,1 + $ ,75),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,75),1,4,31,1,1,286,H) C Coefficient construction for loop diagram with ID 43 CALL MP_FFV1L1P0_3(PL(0,54),W(7),GC_5,ZERO,ZERO,PL(0,76),COEFS) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,54),4,COEFS,4,4,WL(1,0,1,76) $ ) CALL MP_FFV1L3_2(PL(0,76),W(11),GC_5,MDL_MB,ZERO,PL(0,77),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,76),4,COEFS,4,4,WL(1,0,1,77) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,76),4,COEFS,4,4,WL(1,0,1 + $ ,77),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,77),2,4,32,1,1,287,H) C Coefficient construction for loop diagram with ID 44 CALL MP_FFV1L3_2(PL(0,21),W(23),GC_5,MDL_MB,ZERO,PL(0,78),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1,78) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1 + $ ,78),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,78),2,4,9,1,1,288,H) C Coefficient construction for loop diagram with ID 45 CALL MP_FFV1L1P0_3(PL(0,47),W(4),GC_5,ZERO,ZERO,PL(0,79),COEFS) @@ -378,24 +422,27 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ) CALL MP_FFV1L3_2(PL(0,79),W(21),GC_5,MDL_MT,MDL_WT,PL(0,80) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,79),4,COEFS,4,4,WL(1,0,1,80) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,79),4,COEFS,4,4,WL(1,0,1 + $ ,80),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,80),2,4,33,1,1,289,H) C Coefficient construction for loop diagram with ID 46 CALL MP_FFV1L2P0_3(PL(0,59),W(11),GC_5,ZERO,ZERO,PL(0,81),COEFS) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,59),4,COEFS,4,4,WL(1,0,1,81) $ ) CALL MP_FFV1L3_1(PL(0,81),W(4),GC_5,MDL_MT,MDL_WT,PL(0,82),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,81),4,COEFS,4,4,WL(1,0,1,82) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,81),4,COEFS,4,4,WL(1,0,1 + $ ,82),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,82),3,4,34,1,1,290,H) C Coefficient construction for loop diagram with ID 47 CALL MP_FFV1L1P0_3(PL(0,55),W(4),GC_5,ZERO,ZERO,PL(0,83),COEFS) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,55),4,COEFS,4,4,WL(1,0,1,83) $ ) CALL MP_FFV1L3_2(PL(0,83),W(11),GC_5,MDL_MB,ZERO,PL(0,84),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,83),4,COEFS,4,4,WL(1,0,1,84) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,83),4,COEFS,4,4,WL(1,0,1 + $ ,84),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,84),3,4,35,1,1,291,H) C Coefficient construction for loop diagram with ID 48 CALL MP_VVV1L2P0_1(PL(0,0),W(1),GC_4,ZERO,ZERO,PL(0,85),COEFS) @@ -404,8 +451,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1,86) $ ) CALL MP_FFV1L1P0_3(PL(0,86),W(22),GC_5,ZERO,ZERO,PL(0,87),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,86),4,COEFS,4,4,WL(1,0,1,87) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,86),4,COEFS,4,4,WL(1,0,1 + $ ,87),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,87),2,4,36,1,1,292,H) C Coefficient construction for loop diagram with ID 49 CALL MP_FFV2L1_2(PL(0,86),W(3),GC_11,MDL_MT,MDL_WT,PL(0,88) @@ -413,8 +461,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,86),4,COEFS,4,4,WL(1,0,1,88) $ ) CALL MP_FFV1L1P0_3(PL(0,88),W(12),GC_5,ZERO,ZERO,PL(0,89),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,88),4,COEFS,4,4,WL(1,0,1,89) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,88),4,COEFS,4,4,WL(1,0,1 + $ ,89),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,89),3,4,37,1,1,293,H) C Coefficient construction for loop diagram with ID 50 CALL MP_FFV1L3_1(PL(0,85),W(12),GC_5,MDL_MT,MDL_WT,PL(0,90) @@ -422,32 +471,36 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1,90) $ ) CALL MP_FFV1L2P0_3(PL(0,90),W(8),GC_5,ZERO,ZERO,PL(0,91),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,90),4,COEFS,4,4,WL(1,0,1,91) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,90),4,COEFS,4,4,WL(1,0,1 + $ ,91),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,91),2,4,38,1,1,294,H) C Coefficient construction for loop diagram with ID 51 CALL MP_FFV1L3_1(PL(0,85),W(4),GC_5,MDL_MT,MDL_WT,PL(0,92),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1,92) $ ) CALL MP_FFV1L2P0_3(PL(0,92),W(18),GC_5,ZERO,ZERO,PL(0,93),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,92),4,COEFS,4,4,WL(1,0,1,93) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,92),4,COEFS,4,4,WL(1,0,1 + $ ,93),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,93),2,4,39,1,1,295,H) C Coefficient construction for loop diagram with ID 52 CALL MP_FFV2L2_1(PL(0,92),W(3),GC_11,MDL_MB,ZERO,PL(0,94),COEFS) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,92),4,COEFS,4,4,WL(1,0,1,94) $ ) CALL MP_FFV1L2P0_3(PL(0,94),W(10),GC_5,ZERO,ZERO,PL(0,95),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,94),4,COEFS,4,4,WL(1,0,1,95) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,94),4,COEFS,4,4,WL(1,0,1 + $ ,95),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,95),3,4,40,1,1,296,H) C Coefficient construction for loop diagram with ID 53 CALL MP_FFV1L3_1(PL(0,85),W(7),GC_5,MDL_MB,ZERO,PL(0,96),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1,96) $ ) CALL MP_FFV1L2P0_3(PL(0,96),W(10),GC_5,ZERO,ZERO,PL(0,97),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,96),4,COEFS,4,4,WL(1,0,1,97) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,96),4,COEFS,4,4,WL(1,0,1 + $ ,97),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,97),2,4,41,1,1,297,H) C Coefficient construction for loop diagram with ID 54 CALL MP_VVV1L2P0_1(PL(0,85),W(2),GC_4,ZERO,ZERO,PL(0,98),COEFS) @@ -461,8 +514,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,99),4,COEFS,4,4,WL(1,0,1 $ ,100)) CALL MP_FFV1L1P0_3(PL(0,100),W(4),GC_5,ZERO,ZERO,PL(0,101),COEFS) - CALL MP_ML5_0_UPDATE_WL_4_0(WL(1,0,1,100),4,COEFS,4,4,WL(1,0,1 - $ ,101)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_4_0(WL(1,0,1,100),4,COEFS,4,4,WL(1,0,1 + $ ,101),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,101),4,4,42,1,1,298,H) C Coefficient construction for loop diagram with ID 55 CALL MP_FFV1L3_1(PL(0,98),W(4),GC_5,MDL_MT,MDL_WT,PL(0,102) @@ -474,36 +528,42 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,102),4,COEFS,4,4,WL(1,0,1 $ ,103)) CALL MP_FFV1L2P0_3(PL(0,103),W(5),GC_5,ZERO,ZERO,PL(0,104),COEFS) - CALL MP_ML5_0_UPDATE_WL_4_0(WL(1,0,1,103),4,COEFS,4,4,WL(1,0,1 - $ ,104)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_4_0(WL(1,0,1,103),4,COEFS,4,4,WL(1,0,1 + $ ,104),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,104),4,4,43,1,1,299,H) C Coefficient construction for loop diagram with ID 56 CALL MP_VVV1L2P0_1(PL(0,98),W(14),GC_4,ZERO,ZERO,PL(0,105),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,98),4,COEFS,4,4,WL(1,0,1 - $ ,105)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,98),4,COEFS,4,4,WL(1,0,1 + $ ,105),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,105),3,4,44,1,1,300,H) C Coefficient construction for loop diagram with ID 57 CALL MP_FFV1L1P0_3(PL(0,99),W(7),GC_5,ZERO,ZERO,PL(0,106),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,99),4,COEFS,4,4,WL(1,0,1 - $ ,106)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,99),4,COEFS,4,4,WL(1,0,1 + $ ,106),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,106),3,4,45,1,1,301,H) C Coefficient construction for loop diagram with ID 58 CALL MP_FFV1L3_1(PL(0,98),W(7),GC_5,MDL_MB,ZERO,PL(0,107),COEFS) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,98),4,COEFS,4,4,WL(1,0,1 $ ,107)) CALL MP_FFV1L2P0_3(PL(0,107),W(5),GC_5,ZERO,ZERO,PL(0,108),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,107),4,COEFS,4,4,WL(1,0,1 - $ ,108)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,107),4,COEFS,4,4,WL(1,0,1 + $ ,108),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,108),3,4,46,1,1,302,H) C Coefficient construction for loop diagram with ID 59 CALL MP_VVV1L2P0_1(PL(0,98),W(16),GC_4,ZERO,ZERO,PL(0,109),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,98),4,COEFS,4,4,WL(1,0,1 - $ ,109)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,98),4,COEFS,4,4,WL(1,0,1 + $ ,109),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,109),3,4,47,1,1,303,H) C Coefficient construction for loop diagram with ID 60 CALL MP_FFV1L2P0_3(PL(0,102),W(8),GC_5,ZERO,ZERO,PL(0,110),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,102),4,COEFS,4,4,WL(1,0,1 - $ ,110)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,102),4,COEFS,4,4,WL(1,0,1 + $ ,110),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,110),3,4,48,1,1,304,H) C Coefficient construction for loop diagram with ID 61 CALL MP_FFV1L3_2(PL(0,98),W(8),GC_5,MDL_MT,MDL_WT,PL(0,111) @@ -511,65 +571,78 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,98),4,COEFS,4,4,WL(1,0,1 $ ,111)) CALL MP_FFV1L1P0_3(PL(0,111),W(4),GC_5,ZERO,ZERO,PL(0,112),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,111),4,COEFS,4,4,WL(1,0,1 - $ ,112)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,111),4,COEFS,4,4,WL(1,0,1 + $ ,112),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,112),3,4,49,1,1,305,H) C Coefficient construction for loop diagram with ID 62 CALL MP_FFV1L1P0_3(PL(0,86),W(24),GC_5,ZERO,ZERO,PL(0,113),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,86),4,COEFS,4,4,WL(1,0,1 - $ ,113)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,86),4,COEFS,4,4,WL(1,0,1 + $ ,113),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,113),2,4,50,1,1,306,H) C Coefficient construction for loop diagram with ID 63 CALL MP_FFV1L1_2(PL(0,86),W(2),GC_5,MDL_MB,ZERO,PL(0,114),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,86),4,COEFS,4,4,WL(1,0,1 - $ ,114)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,86),4,COEFS + $ ,4,4,WL(1,0,1,114),WL_ENTRY_INEXACT) CALL MP_FFV1L1P0_3(PL(0,114),W(7),GC_5,ZERO,ZERO,PL(0,115),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,114),4,COEFS,4,4,WL(1,0,1 - $ ,115)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,114),4,COEFS,4,4,WL(1,0,1 + $ ,115),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,115),3,4,51,1,1,307,H) C Coefficient construction for loop diagram with ID 64 CALL MP_VVVV1L2P0_1(PL(0,85),W(14),W(2),GC_6,ZERO,ZERO,PL(0,116) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 - $ ,116)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 + $ ,116),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,85),W(14),W(2),GC_6,ZERO,ZERO,PL(0,117) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 - $ ,117)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 + $ ,117),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,85),W(14),W(2),GC_6,ZERO,ZERO,PL(0,118) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 - $ ,118)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 + $ ,118),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,116),1,4,52,2,1,308,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,117),1,4,52,2,1,309,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,118),1,4,52,2,1,310,H) C Coefficient construction for loop diagram with ID 65 CALL MP_FFV1L2P0_3(PL(0,92),W(20),GC_5,ZERO,ZERO,PL(0,119),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,92),4,COEFS,4,4,WL(1,0,1 - $ ,119)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,92),4,COEFS,4,4,WL(1,0,1 + $ ,119),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,119),2,4,53,1,1,311,H) C Coefficient construction for loop diagram with ID 66 CALL MP_FFV1L2_1(PL(0,92),W(2),GC_5,MDL_MT,MDL_WT,PL(0,120) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,92),4,COEFS,4,4,WL(1,0,1 - $ ,120)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,92),4,COEFS + $ ,4,4,WL(1,0,1,120),WL_ENTRY_INEXACT) CALL MP_FFV1L2P0_3(PL(0,120),W(8),GC_5,ZERO,ZERO,PL(0,121),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,120),4,COEFS,4,4,WL(1,0,1 - $ ,121)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,120),4,COEFS,4,4,WL(1,0,1 + $ ,121),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,121),3,4,54,1,1,312,H) C Coefficient construction for loop diagram with ID 67 CALL MP_VVVV1L2P0_1(PL(0,85),W(16),W(2),GC_6,ZERO,ZERO,PL(0,122) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 - $ ,122)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 + $ ,122),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,85),W(16),W(2),GC_6,ZERO,ZERO,PL(0,123) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 - $ ,123)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 + $ ,123),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,85),W(16),W(2),GC_6,ZERO,ZERO,PL(0,124) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 - $ ,124)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1 + $ ,124),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,122),1,4,55,2,1,313,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,123),1,4,55,2,1,314,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,124),1,4,55,2,1,315,H) @@ -579,28 +652,33 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,120),4,COEFS,4,4,WL(1,0,1 $ ,125)) CALL MP_FFV1L2P0_3(PL(0,125),W(5),GC_5,ZERO,ZERO,PL(0,126),COEFS) - CALL MP_ML5_0_UPDATE_WL_4_0(WL(1,0,1,125),4,COEFS,4,4,WL(1,0,1 - $ ,126)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_4_0(WL(1,0,1,125),4,COEFS,4,4,WL(1,0,1 + $ ,126),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,126),4,4,56,1,1,316,H) C Coefficient construction for loop diagram with ID 69 CALL MP_FFV1L2_1(PL(0,94),W(2),GC_5,MDL_MB,ZERO,PL(0,127),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,94),4,COEFS,4,4,WL(1,0,1 - $ ,127)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_UPDATE_WL_3_1_FACTOR_FFV1L2_1(WL(1,0,1,94),4,COEFS + $ ,4,4,WL(1,0,1,127),WL_ENTRY_INEXACT) CALL MP_FFV1L2P0_3(PL(0,127),W(5),GC_5,ZERO,ZERO,PL(0,128),COEFS) - CALL MP_ML5_0_UPDATE_WL_4_0(WL(1,0,1,127),4,COEFS,4,4,WL(1,0,1 - $ ,128)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_4_0(WL(1,0,1,127),4,COEFS,4,4,WL(1,0,1 + $ ,128),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,128),4,4,57,1,1,317,H) C Coefficient construction for loop diagram with ID 70 CALL MP_FFV1L3_1(PL(0,11),W(25),GC_5,MDL_MT,MDL_WT,PL(0,129) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 - $ ,129)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,129),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,129),1,4,58,1,1,318,H) C Coefficient construction for loop diagram with ID 71 CALL MP_FFV1L3_2(PL(0,62),W(26),GC_5,MDL_MT,MDL_WT,PL(0,130) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,62),4,COEFS,4,4,WL(1,0,1 - $ ,130)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,62),4,COEFS,4,4,WL(1,0,1 + $ ,130),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,130),1,4,59,1,1,319,H) C Coefficient construction for loop diagram with ID 72 CALL MP_FFV1L1_2(PL(0,0),W(1),GC_5,MDL_MT,MDL_WT,PL(0,131),COEFS) @@ -612,14 +690,16 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,132)) CALL MP_FFV1L3_2(PL(0,132),W(8),GC_5,MDL_MT,MDL_WT,PL(0,133) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,132),4,COEFS,4,4,WL(1,0,1 - $ ,133)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,132),4,COEFS,4,4,WL(1,0,1 + $ ,133),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,133),2,4,60,1,1,320,H) C Coefficient construction for loop diagram with ID 73 CALL MP_FFV1L3_1(PL(0,26),W(25),GC_5,MDL_MT,MDL_WT,PL(0,134) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1 - $ ,134)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,26),4,COEFS,4,4,WL(1,0,1 + $ ,134),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,134),2,4,61,1,1,321,H) C Coefficient construction for loop diagram with ID 74 CALL MP_FFV1L2_1(PL(0,0),W(1),GC_5,MDL_MB,ZERO,PL(0,135),COEFS) @@ -630,8 +710,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,136)) CALL MP_FFV1L3_1(PL(0,136),W(22),GC_5,MDL_MB,ZERO,PL(0,137) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,136),4,COEFS,4,4,WL(1,0,1 - $ ,137)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,136),4,COEFS,4,4,WL(1,0,1 + $ ,137),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,137),2,4,62,1,1,322,H) C Coefficient construction for loop diagram with ID 75 CALL MP_FFV1L1_2(PL(0,0),W(1),GC_5,MDL_MB,ZERO,PL(0,138),COEFS) @@ -646,8 +727,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,139),4,COEFS,4,4,WL(1,0,1 $ ,140)) CALL MP_FFV1L3_2(PL(0,140),W(5),GC_5,MDL_MB,ZERO,PL(0,141),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,140),4,COEFS,4,4,WL(1,0,1 - $ ,141)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,140),4,COEFS,4,4,WL(1,0,1 + $ ,141),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,141),3,4,63,1,1,323,H) C Coefficient construction for loop diagram with ID 76 CALL MP_FFV1L2_1(PL(0,0),W(1),GC_5,MDL_MT,MDL_WT,PL(0,142),COEFS) @@ -662,18 +744,21 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,144)) CALL MP_FFV1L3_1(PL(0,144),W(12),GC_5,MDL_MT,MDL_WT,PL(0,145) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,144),4,COEFS,4,4,WL(1,0,1 - $ ,145)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,144),4,COEFS,4,4,WL(1,0,1 + $ ,145),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,145),3,4,64,1,1,324,H) C Coefficient construction for loop diagram with ID 77 CALL MP_FFV1L3_2(PL(0,1),W(27),GC_5,MDL_MB,ZERO,PL(0,146),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,146) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1 + $ ,146),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,146),1,4,65,1,1,325,H) C Coefficient construction for loop diagram with ID 78 CALL MP_FFV1L3_1(PL(0,32),W(28),GC_5,MDL_MB,ZERO,PL(0,147),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1 - $ ,147)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1 + $ ,147),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,147),1,4,66,1,1,326,H) C Coefficient construction for loop diagram with ID 79 CALL MP_FFV1L1P0_3(PL(0,138),W(7),GC_5,ZERO,ZERO,PL(0,148),COEFS) @@ -681,13 +766,15 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,148)) CALL MP_FFV1L3_2(PL(0,148),W(10),GC_5,MDL_MB,ZERO,PL(0,149) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,148),4,COEFS,4,4,WL(1,0,1 - $ ,149)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,148),4,COEFS,4,4,WL(1,0,1 + $ ,149),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,149),2,4,67,1,1,327,H) C Coefficient construction for loop diagram with ID 80 CALL MP_FFV1L3_2(PL(0,21),W(27),GC_5,MDL_MB,ZERO,PL(0,150),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1 - $ ,150)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1 + $ ,150),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,150),2,4,68,1,1,328,H) C Coefficient construction for loop diagram with ID 81 CALL MP_FFV1L1P0_3(PL(0,131),W(4),GC_5,ZERO,ZERO,PL(0,151),COEFS) @@ -695,8 +782,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,151)) CALL MP_FFV1L3_2(PL(0,151),W(18),GC_5,MDL_MT,MDL_WT,PL(0,152) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,151),4,COEFS,4,4,WL(1,0,1 - $ ,152)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,151),4,COEFS,4,4,WL(1,0,1 + $ ,152),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,152),2,4,69,1,1,329,H) C Coefficient construction for loop diagram with ID 82 CALL MP_FFV1L2P0_3(PL(0,143),W(10),GC_5,ZERO,ZERO,PL(0,153) @@ -705,8 +793,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,153)) CALL MP_FFV1L3_1(PL(0,153),W(4),GC_5,MDL_MT,MDL_WT,PL(0,154) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,153),4,COEFS,4,4,WL(1,0,1 - $ ,154)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,153),4,COEFS,4,4,WL(1,0,1 + $ ,154),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,154),3,4,70,1,1,330,H) C Coefficient construction for loop diagram with ID 83 CALL MP_FFV1L1P0_3(PL(0,139),W(4),GC_5,ZERO,ZERO,PL(0,155),COEFS) @@ -714,42 +803,49 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,155)) CALL MP_FFV1L3_2(PL(0,155),W(10),GC_5,MDL_MB,ZERO,PL(0,156) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,155),4,COEFS,4,4,WL(1,0,1 - $ ,156)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,155),4,COEFS,4,4,WL(1,0,1 + $ ,156),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,156),3,4,71,1,1,331,H) C Coefficient construction for loop diagram with ID 84 CALL MP_FFV1L1P0_3(PL(0,39),W(28),GC_5,ZERO,ZERO,PL(0,157),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,39),4,COEFS,4,4,WL(1,0,1 - $ ,157)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,39),4,COEFS,4,4,WL(1,0,1 + $ ,157),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,157),2,4,72,1,1,332,H) C Coefficient construction for loop diagram with ID 85 CALL MP_VVV1L2P0_1(PL(0,136),W(2),GC_4,ZERO,ZERO,PL(0,158),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,136),4,COEFS,4,4,WL(1,0,1 $ ,158)) CALL MP_FFV1L3_1(PL(0,158),W(7),GC_5,MDL_MB,ZERO,PL(0,159),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,158),4,COEFS,4,4,WL(1,0,1 - $ ,159)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,158),4,COEFS,4,4,WL(1,0,1 + $ ,159),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,159),3,4,73,1,1,333,H) C Coefficient construction for loop diagram with ID 86 CALL MP_VVVV1L2P0_1(PL(0,38),W(14),W(1),GC_6,ZERO,ZERO,PL(0,160) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 - $ ,160)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 + $ ,160),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,38),W(14),W(1),GC_6,ZERO,ZERO,PL(0,161) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 - $ ,161)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 + $ ,161),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,38),W(14),W(1),GC_6,ZERO,ZERO,PL(0,162) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 - $ ,162)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 + $ ,162),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,160),1,4,74,2,1,334,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,161),1,4,74,2,1,335,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,162),1,4,74,2,1,336,H) C Coefficient construction for loop diagram with ID 87 CALL MP_FFV1L2P0_3(PL(0,68),W(26),GC_5,ZERO,ZERO,PL(0,163),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,68),4,COEFS,4,4,WL(1,0,1 - $ ,163)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,68),4,COEFS,4,4,WL(1,0,1 + $ ,163),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,163),2,4,75,1,1,337,H) C Coefficient construction for loop diagram with ID 88 CALL MP_VVV1L2P0_1(PL(0,151),W(2),GC_4,ZERO,ZERO,PL(0,164),COEFS) @@ -757,22 +853,26 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,164)) CALL MP_FFV1L3_2(PL(0,164),W(8),GC_5,MDL_MT,MDL_WT,PL(0,165) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,164),4,COEFS,4,4,WL(1,0,1 - $ ,165)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,164),4,COEFS,4,4,WL(1,0,1 + $ ,165),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,165),3,4,76,1,1,338,H) C Coefficient construction for loop diagram with ID 89 CALL MP_VVVV1L2P0_1(PL(0,38),W(16),W(1),GC_6,ZERO,ZERO,PL(0,166) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 - $ ,166)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 + $ ,166),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,38),W(16),W(1),GC_6,ZERO,ZERO,PL(0,167) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 - $ ,167)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 + $ ,167),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,38),W(16),W(1),GC_6,ZERO,ZERO,PL(0,168) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 - $ ,168)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 + $ ,168),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,166),1,4,77,2,1,339,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,167),1,4,77,2,1,340,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,168),1,4,77,2,1,341,H) @@ -782,27 +882,31 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,169)) CALL MP_FFV1L3_1(PL(0,169),W(4),GC_5,MDL_MT,MDL_WT,PL(0,170) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,169),4,COEFS,4,4,WL(1,0,1 - $ ,170)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_1(WL(1,0,1,169),4,COEFS,4,4,WL(1,0,1 + $ ,170),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,170),4,4,78,1,1,342,H) C Coefficient construction for loop diagram with ID 91 CALL MP_VVV1L2P0_1(PL(0,155),W(2),GC_4,ZERO,ZERO,PL(0,171),COEFS) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,155),4,COEFS,4,4,WL(1,0,1 $ ,171)) CALL MP_FFV1L3_2(PL(0,171),W(5),GC_5,MDL_MB,ZERO,PL(0,172),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,171),4,COEFS,4,4,WL(1,0,1 - $ ,172)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_1(WL(1,0,1,171),4,COEFS,4,4,WL(1,0,1 + $ ,172),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,172),4,4,79,1,1,343,H) C Coefficient construction for loop diagram with ID 92 CALL MP_FFV1L3_1(PL(0,52),W(28),GC_5,MDL_MB,ZERO,PL(0,173),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,52),4,COEFS,4,4,WL(1,0,1 - $ ,173)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,52),4,COEFS,4,4,WL(1,0,1 + $ ,173),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,173),2,4,80,1,1,344,H) C Coefficient construction for loop diagram with ID 93 CALL MP_FFV1L3_1(PL(0,136),W(24),GC_5,MDL_MB,ZERO,PL(0,174) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,136),4,COEFS,4,4,WL(1,0,1 - $ ,174)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,136),4,COEFS,4,4,WL(1,0,1 + $ ,174),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,174),2,4,81,1,1,345,H) C Coefficient construction for loop diagram with ID 94 CALL MP_FFV1L1_2(PL(0,138),W(2),GC_5,MDL_MB,ZERO,PL(0,175),COEFS) @@ -812,8 +916,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,175),4,COEFS,4,4,WL(1,0,1 $ ,176)) CALL MP_FFV1L3_2(PL(0,176),W(5),GC_5,MDL_MB,ZERO,PL(0,177),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,176),4,COEFS,4,4,WL(1,0,1 - $ ,177)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,176),4,COEFS,4,4,WL(1,0,1 + $ ,177),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,177),3,4,82,1,1,346,H) C Coefficient construction for loop diagram with ID 95 CALL MP_FFV1L2_1(PL(0,135),W(2),GC_5,MDL_MB,ZERO,PL(0,178),COEFS) @@ -823,20 +928,23 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,178),4,COEFS,4,4,WL(1,0,1 $ ,179)) CALL MP_FFV1L3_1(PL(0,179),W(7),GC_5,MDL_MB,ZERO,PL(0,180),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,179),4,COEFS,4,4,WL(1,0,1 - $ ,180)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,179),4,COEFS,4,4,WL(1,0,1 + $ ,180),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,180),3,4,83,1,1,347,H) C Coefficient construction for loop diagram with ID 96 CALL MP_FFV1L3_2(PL(0,79),W(26),GC_5,MDL_MT,MDL_WT,PL(0,181) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,79),4,COEFS,4,4,WL(1,0,1 - $ ,181)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,79),4,COEFS,4,4,WL(1,0,1 + $ ,181),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,181),2,4,84,1,1,348,H) C Coefficient construction for loop diagram with ID 97 CALL MP_FFV1L3_2(PL(0,151),W(20),GC_5,MDL_MT,MDL_WT,PL(0,182) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,151),4,COEFS,4,4,WL(1,0,1 - $ ,182)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,151),4,COEFS,4,4,WL(1,0,1 + $ ,182),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,182),2,4,85,1,1,349,H) C Coefficient construction for loop diagram with ID 98 CALL MP_FFV1L2_1(PL(0,142),W(2),GC_5,MDL_MT,MDL_WT,PL(0,183) @@ -848,8 +956,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,184)) CALL MP_FFV1L3_1(PL(0,184),W(4),GC_5,MDL_MT,MDL_WT,PL(0,185) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,184),4,COEFS,4,4,WL(1,0,1 - $ ,185)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,184),4,COEFS,4,4,WL(1,0,1 + $ ,185),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,185),3,4,86,1,1,350,H) C Coefficient construction for loop diagram with ID 99 CALL MP_FFV1L1_2(PL(0,131),W(2),GC_5,MDL_MT,MDL_WT,PL(0,186) @@ -861,20 +970,23 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,187)) CALL MP_FFV1L3_2(PL(0,187),W(8),GC_5,MDL_MT,MDL_WT,PL(0,188) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,187),4,COEFS,4,4,WL(1,0,1 - $ ,188)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,187),4,COEFS,4,4,WL(1,0,1 + $ ,188),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,188),3,4,87,1,1,351,H) C Coefficient construction for loop diagram with ID 100 CALL MP_FFV1L2_1(PL(0,143),W(2),GC_5,MDL_MB,ZERO,PL(0,189),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,143),4,COEFS,4,4,WL(1,0,1 - $ ,189)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,143),4 + $ ,COEFS,4,4,WL(1,0,1,189),WL_ENTRY_INEXACT) CALL MP_FFV1L2P0_3(PL(0,189),W(5),GC_5,ZERO,ZERO,PL(0,190),COEFS) CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,189),4,COEFS,4,4,WL(1,0,1 $ ,190)) CALL MP_FFV1L3_1(PL(0,190),W(4),GC_5,MDL_MT,MDL_WT,PL(0,191) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,190),4,COEFS,4,4,WL(1,0,1 - $ ,191)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_1(WL(1,0,1,190),4,COEFS,4,4,WL(1,0,1 + $ ,191),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,191),4,4,88,1,1,352,H) C Coefficient construction for loop diagram with ID 101 CALL MP_FFV2L2_1(PL(0,183),W(3),GC_11,MDL_MB,ZERO,PL(0,192) @@ -886,20 +998,23 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,193)) CALL MP_FFV1L3_1(PL(0,193),W(4),GC_5,MDL_MT,MDL_WT,PL(0,194) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,193),4,COEFS,4,4,WL(1,0,1 - $ ,194)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_1(WL(1,0,1,193),4,COEFS,4,4,WL(1,0,1 + $ ,194),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,194),4,4,89,1,1,353,H) C Coefficient construction for loop diagram with ID 102 CALL MP_FFV1L1_2(PL(0,139),W(2),GC_5,MDL_MT,MDL_WT,PL(0,195) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,139),4,COEFS,4,4,WL(1,0,1 - $ ,195)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,139),4 + $ ,COEFS,4,4,WL(1,0,1,195),WL_ENTRY_INEXACT) CALL MP_FFV1L1P0_3(PL(0,195),W(4),GC_5,ZERO,ZERO,PL(0,196),COEFS) CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,195),4,COEFS,4,4,WL(1,0,1 $ ,196)) CALL MP_FFV1L3_2(PL(0,196),W(5),GC_5,MDL_MB,ZERO,PL(0,197),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,196),4,COEFS,4,4,WL(1,0,1 - $ ,197)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_1(WL(1,0,1,196),4,COEFS,4,4,WL(1,0,1 + $ ,197),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,197),4,4,90,1,1,354,H) C Coefficient construction for loop diagram with ID 103 CALL MP_FFV2L1_2(PL(0,175),W(3),GC_11,MDL_MT,MDL_WT,PL(0,198) @@ -910,8 +1025,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,198),4,COEFS,4,4,WL(1,0,1 $ ,199)) CALL MP_FFV1L3_2(PL(0,199),W(5),GC_5,MDL_MB,ZERO,PL(0,200),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,199),4,COEFS,4,4,WL(1,0,1 - $ ,200)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_1(WL(1,0,1,199),4,COEFS,4,4,WL(1,0,1 + $ ,200),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,200),4,4,91,1,1,355,H) C Coefficient construction for loop diagram with ID 104 CALL MP_FFV1L3_2(PL(0,187),W(5),GC_5,MDL_MB,ZERO,PL(0,201),COEFS) @@ -919,8 +1035,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,201)) CALL MP_FFV2L1_2(PL(0,201),W(3),GC_11,MDL_MT,MDL_WT,PL(0,202) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,201),4,COEFS,4,4,WL(1,0,1 - $ ,202)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_1(WL(1,0,1,201),4,COEFS,4,4,WL(1,0,1 + $ ,202),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,202),4,4,92,1,1,356,H) C Coefficient construction for loop diagram with ID 105 CALL MP_FFV1L3_1(PL(0,179),W(4),GC_5,MDL_MT,MDL_WT,PL(0,203) @@ -929,8 +1046,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,203)) CALL MP_FFV2L2_1(PL(0,203),W(3),GC_11,MDL_MB,ZERO,PL(0,204) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_3_1(WL(1,0,1,203),4,COEFS,4,4,WL(1,0,1 - $ ,204)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_1(WL(1,0,1,203),4,COEFS,4,4,WL(1,0,1 + $ ,204),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,204),4,4,93,1,1,357,H) C Coefficient construction for loop diagram with ID 106 CALL MP_VVVV1L2P0_1(PL(0,5),W(2),W(1),GC_6,ZERO,ZERO,PL(0,205) @@ -946,14 +1064,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,5),4,COEFS,4,4,WL(1,0,1,207) $ ) CALL MP_FFV1L3_1(PL(0,205),W(7),GC_5,MDL_MB,ZERO,PL(0,208),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,205),4,COEFS,4,4,WL(1,0,1 - $ ,208)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,205),4,COEFS,4,4,WL(1,0,1 + $ ,208),WL_ENTRY_INEXACT) CALL MP_FFV1L3_1(PL(0,206),W(7),GC_5,MDL_MB,ZERO,PL(0,209),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,206),4,COEFS,4,4,WL(1,0,1 - $ ,209)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,206),4,COEFS,4,4,WL(1,0,1 + $ ,209),WL_ENTRY_INEXACT) CALL MP_FFV1L3_1(PL(0,207),W(7),GC_5,MDL_MB,ZERO,PL(0,210),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,207),4,COEFS,4,4,WL(1,0,1 - $ ,210)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,207),4,COEFS,4,4,WL(1,0,1 + $ ,210),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,208),1,4,94,1,1,358,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,209),1,4,94,1,1,359,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,210),1,4,94,1,1,360,H) @@ -972,16 +1093,19 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ) CALL MP_VVV1L2P0_1(PL(0,211),W(14),GC_4,ZERO,ZERO,PL(0,214) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,211),4,COEFS,4,4,WL(1,0,1 - $ ,214)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,211),4,COEFS,4,4,WL(1,0,1 + $ ,214),WL_ENTRY_INEXACT) CALL MP_VVV1L2P0_1(PL(0,212),W(14),GC_4,ZERO,ZERO,PL(0,215) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,212),4,COEFS,4,4,WL(1,0,1 - $ ,215)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,212),4,COEFS,4,4,WL(1,0,1 + $ ,215),WL_ENTRY_INEXACT) CALL MP_VVV1L2P0_1(PL(0,213),W(14),GC_4,ZERO,ZERO,PL(0,216) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,213),4,COEFS,4,4,WL(1,0,1 - $ ,216)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,213),4,COEFS,4,4,WL(1,0,1 + $ ,216),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,214),1,4,95,2,1,361,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,215),1,4,95,2,1,362,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,216),1,4,95,2,1,363,H) @@ -1000,32 +1124,38 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,219)) CALL MP_FFV1L3_2(PL(0,217),W(8),GC_5,MDL_MT,MDL_WT,PL(0,220) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,217),4,COEFS,4,4,WL(1,0,1 - $ ,220)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,217),4,COEFS,4,4,WL(1,0,1 + $ ,220),WL_ENTRY_INEXACT) CALL MP_FFV1L3_2(PL(0,218),W(8),GC_5,MDL_MT,MDL_WT,PL(0,221) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,218),4,COEFS,4,4,WL(1,0,1 - $ ,221)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,218),4,COEFS,4,4,WL(1,0,1 + $ ,221),WL_ENTRY_INEXACT) CALL MP_FFV1L3_2(PL(0,219),W(8),GC_5,MDL_MT,MDL_WT,PL(0,222) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,219),4,COEFS,4,4,WL(1,0,1 - $ ,222)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,219),4,COEFS,4,4,WL(1,0,1 + $ ,222),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,220),1,4,96,1,1,364,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,221),1,4,96,1,1,365,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,222),1,4,96,1,1,366,H) C Coefficient construction for loop diagram with ID 109 CALL MP_VVV1L2P0_1(PL(0,211),W(16),GC_4,ZERO,ZERO,PL(0,223) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,211),4,COEFS,4,4,WL(1,0,1 - $ ,223)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,211),4,COEFS,4,4,WL(1,0,1 + $ ,223),WL_ENTRY_INEXACT) CALL MP_VVV1L2P0_1(PL(0,212),W(16),GC_4,ZERO,ZERO,PL(0,224) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,212),4,COEFS,4,4,WL(1,0,1 - $ ,224)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,212),4,COEFS,4,4,WL(1,0,1 + $ ,224),WL_ENTRY_INEXACT) CALL MP_VVV1L2P0_1(PL(0,213),W(16),GC_4,ZERO,ZERO,PL(0,225) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,213),4,COEFS,4,4,WL(1,0,1 - $ ,225)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,213),4,COEFS,4,4,WL(1,0,1 + $ ,225),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,223),1,4,97,2,1,367,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,224),1,4,97,2,1,368,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,225),1,4,97,2,1,369,H) @@ -1043,14 +1173,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1 $ ,228)) CALL MP_FFV1L3_2(PL(0,226),W(5),GC_5,MDL_MB,ZERO,PL(0,229),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,226),4,COEFS,4,4,WL(1,0,1 - $ ,229)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,226),4,COEFS,4,4,WL(1,0,1 + $ ,229),WL_ENTRY_INEXACT) CALL MP_FFV1L3_2(PL(0,227),W(5),GC_5,MDL_MB,ZERO,PL(0,230),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,227),4,COEFS,4,4,WL(1,0,1 - $ ,230)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,227),4,COEFS,4,4,WL(1,0,1 + $ ,230),WL_ENTRY_INEXACT) CALL MP_FFV1L3_2(PL(0,228),W(5),GC_5,MDL_MB,ZERO,PL(0,231),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,228),4,COEFS,4,4,WL(1,0,1 - $ ,231)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,228),4,COEFS,4,4,WL(1,0,1 + $ ,231),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,229),2,4,98,1,1,370,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,230),2,4,98,1,1,371,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,231),2,4,98,1,1,372,H) @@ -1059,13 +1192,15 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,232) $ ) CALL MP_GHGHGL2_1(PL(0,232),W(14),GC_4,ZERO,ZERO,PL(0,233),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,232),1,COEFS,1,1,WL(1,0,1 - $ ,233)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,232),1,COEFS,1,1,WL(1,0,1 + $ ,233),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,233),2,1,2,1,1,373,H) C Coefficient construction for loop diagram with ID 112 CALL MP_GHGHGL2_1(PL(0,232),W(16),GC_4,ZERO,ZERO,PL(0,234),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,232),1,COEFS,1,1,WL(1,0,1 - $ ,234)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,232),1,COEFS,1,1,WL(1,0,1 + $ ,234),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,234),2,1,6,1,1,374,H) C Coefficient construction for loop diagram with ID 113 CALL MP_GHGHGL1_2(PL(0,0),W(1),GC_4,ZERO,ZERO,PL(0,235),COEFS) @@ -1075,13 +1210,15 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,235),1,COEFS,1,1,WL(1,0,1 $ ,236)) CALL MP_GHGHGL1_2(PL(0,236),W(14),GC_4,ZERO,ZERO,PL(0,237),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,236),1,COEFS,1,1,WL(1,0,1 - $ ,237)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,236),1,COEFS,1,1,WL(1,0,1 + $ ,237),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,237),3,1,44,1,1,375,H) C Coefficient construction for loop diagram with ID 114 CALL MP_GHGHGL1_2(PL(0,236),W(16),GC_4,ZERO,ZERO,PL(0,238),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,236),1,COEFS,1,1,WL(1,0,1 - $ ,238)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,236),1,COEFS,1,1,WL(1,0,1 + $ ,238),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,238),3,1,47,1,1,376,H) C Coefficient construction for loop diagram with ID 115 CALL MP_GHGHGL2_1(PL(0,0),W(1),GC_4,ZERO,ZERO,PL(0,239),COEFS) @@ -1091,26 +1228,30 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,239),1,COEFS,1,1,WL(1,0,1 $ ,240)) CALL MP_GHGHGL2_1(PL(0,240),W(14),GC_4,ZERO,ZERO,PL(0,241),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,240),1,COEFS,1,1,WL(1,0,1 - $ ,241)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,240),1,COEFS,1,1,WL(1,0,1 + $ ,241),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,241),3,1,44,1,1,377,H) C Coefficient construction for loop diagram with ID 116 CALL MP_GHGHGL2_1(PL(0,240),W(16),GC_4,ZERO,ZERO,PL(0,242),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,240),1,COEFS,1,1,WL(1,0,1 - $ ,242)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,240),1,COEFS,1,1,WL(1,0,1 + $ ,242),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,242),3,1,47,1,1,378,H) C Coefficient construction for loop diagram with ID 117 CALL MP_FFV1L2_1(PL(0,0),W(6),GC_5,ZERO,ZERO,PL(0,243),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,243) $ ) CALL MP_FFV1L2_1(PL(0,243),W(14),GC_5,ZERO,ZERO,PL(0,244),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,243),4,COEFS,4,4,WL(1,0,1 - $ ,244)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,243),4,COEFS,4,4,WL(1,0,1 + $ ,244),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,244),2,4,2,1,4,379,H) C Coefficient construction for loop diagram with ID 118 CALL MP_FFV1L2_1(PL(0,243),W(16),GC_5,ZERO,ZERO,PL(0,245),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,243),4,COEFS,4,4,WL(1,0,1 - $ ,245)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,243),4,COEFS,4,4,WL(1,0,1 + $ ,245),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,245),2,4,6,1,4,380,H) C Coefficient construction for loop diagram with ID 119 CALL MP_FFV1L1_2(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,246),COEFS) @@ -1120,13 +1261,15 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,246),4,COEFS,4,4,WL(1,0,1 $ ,247)) CALL MP_FFV1L1_2(PL(0,247),W(14),GC_5,ZERO,ZERO,PL(0,248),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,247),4,COEFS,4,4,WL(1,0,1 - $ ,248)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,247),4 + $ ,COEFS,4,4,WL(1,0,1,248),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,248),3,4,44,1,4,381,H) C Coefficient construction for loop diagram with ID 120 CALL MP_FFV1L1_2(PL(0,247),W(16),GC_5,ZERO,ZERO,PL(0,249),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,247),4,COEFS,4,4,WL(1,0,1 - $ ,249)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,247),4 + $ ,COEFS,4,4,WL(1,0,1,249),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,249),3,4,47,1,4,382,H) C Coefficient construction for loop diagram with ID 121 CALL MP_FFV1L2_1(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,250),COEFS) @@ -1136,13 +1279,15 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,250),4,COEFS,4,4,WL(1,0,1 $ ,251)) CALL MP_FFV1L2_1(PL(0,251),W(14),GC_5,ZERO,ZERO,PL(0,252),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,251),4,COEFS,4,4,WL(1,0,1 - $ ,252)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,251),4 + $ ,COEFS,4,4,WL(1,0,1,252),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,252),3,4,44,1,4,383,H) C Coefficient construction for loop diagram with ID 122 CALL MP_FFV1L2_1(PL(0,251),W(16),GC_5,ZERO,ZERO,PL(0,253),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,251),4,COEFS,4,4,WL(1,0,1 - $ ,253)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,251),4 + $ ,COEFS,4,4,WL(1,0,1,253),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,253),3,4,47,1,4,384,H) C Coefficient construction for loop diagram with ID 123 CALL MP_FFV1L2_1(PL(0,0),W(6),GC_5,MDL_MB,ZERO,PL(0,254),COEFS) @@ -1150,38 +1295,44 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ) CALL MP_FFV1L2_1(PL(0,254),W(14),GC_5,MDL_MB,ZERO,PL(0,255) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,254),4,COEFS,4,4,WL(1,0,1 - $ ,255)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,254),4,COEFS,4,4,WL(1,0,1 + $ ,255),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,255),2,4,99,1,1,385,H) C Coefficient construction for loop diagram with ID 124 CALL MP_FFV1L2_1(PL(0,254),W(16),GC_5,MDL_MB,ZERO,PL(0,256) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,254),4,COEFS,4,4,WL(1,0,1 - $ ,256)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,254),4,COEFS,4,4,WL(1,0,1 + $ ,256),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,256),2,4,100,1,1,386,H) C Coefficient construction for loop diagram with ID 125 CALL MP_FFV1L1_2(PL(0,175),W(14),GC_5,MDL_MB,ZERO,PL(0,257) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,175),4,COEFS,4,4,WL(1,0,1 - $ ,257)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,175),4 + $ ,COEFS,4,4,WL(1,0,1,257),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,257),3,4,101,1,1,387,H) C Coefficient construction for loop diagram with ID 126 CALL MP_FFV1L1_2(PL(0,175),W(16),GC_5,MDL_MB,ZERO,PL(0,258) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,175),4,COEFS,4,4,WL(1,0,1 - $ ,258)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,175),4 + $ ,COEFS,4,4,WL(1,0,1,258),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,258),3,4,102,1,1,388,H) C Coefficient construction for loop diagram with ID 127 CALL MP_FFV1L2_1(PL(0,178),W(14),GC_5,MDL_MB,ZERO,PL(0,259) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,178),4,COEFS,4,4,WL(1,0,1 - $ ,259)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,178),4 + $ ,COEFS,4,4,WL(1,0,1,259),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,259),3,4,101,1,1,389,H) C Coefficient construction for loop diagram with ID 128 CALL MP_FFV1L2_1(PL(0,178),W(16),GC_5,MDL_MB,ZERO,PL(0,260) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,178),4,COEFS,4,4,WL(1,0,1 - $ ,260)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,178),4 + $ ,COEFS,4,4,WL(1,0,1,260),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,260),3,4,102,1,1,390,H) C Coefficient construction for loop diagram with ID 129 CALL MP_FFV1L2_1(PL(0,0),W(6),GC_5,MDL_MT,MDL_WT,PL(0,261),COEFS) @@ -1189,38 +1340,44 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ) CALL MP_FFV1L2_1(PL(0,261),W(14),GC_5,MDL_MT,MDL_WT,PL(0,262) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,261),4,COEFS,4,4,WL(1,0,1 - $ ,262)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,261),4,COEFS,4,4,WL(1,0,1 + $ ,262),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,262),2,4,103,1,1,391,H) C Coefficient construction for loop diagram with ID 130 CALL MP_FFV1L2_1(PL(0,261),W(16),GC_5,MDL_MT,MDL_WT,PL(0,263) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,261),4,COEFS,4,4,WL(1,0,1 - $ ,263)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,261),4,COEFS,4,4,WL(1,0,1 + $ ,263),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,263),2,4,104,1,1,392,H) C Coefficient construction for loop diagram with ID 131 CALL MP_FFV1L1_2(PL(0,186),W(14),GC_5,MDL_MT,MDL_WT,PL(0,264) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,186),4,COEFS,4,4,WL(1,0,1 - $ ,264)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,186),4 + $ ,COEFS,4,4,WL(1,0,1,264),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,264),3,4,105,1,1,393,H) C Coefficient construction for loop diagram with ID 132 CALL MP_FFV1L1_2(PL(0,186),W(16),GC_5,MDL_MT,MDL_WT,PL(0,265) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,186),4,COEFS,4,4,WL(1,0,1 - $ ,265)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,186),4 + $ ,COEFS,4,4,WL(1,0,1,265),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,265),3,4,106,1,1,394,H) C Coefficient construction for loop diagram with ID 133 CALL MP_FFV1L2_1(PL(0,183),W(14),GC_5,MDL_MT,MDL_WT,PL(0,266) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,183),4,COEFS,4,4,WL(1,0,1 - $ ,266)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,183),4 + $ ,COEFS,4,4,WL(1,0,1,266),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,266),3,4,105,1,1,395,H) C Coefficient construction for loop diagram with ID 134 CALL MP_FFV1L2_1(PL(0,183),W(16),GC_5,MDL_MT,MDL_WT,PL(0,267) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,183),4,COEFS,4,4,WL(1,0,1 - $ ,267)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,183),4 + $ ,COEFS,4,4,WL(1,0,1,267),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,267),3,4,106,1,1,396,H) GOTO 1001 diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/mp_compute_loop_coefs.f index 223f3920fb..b67830d8d0 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/mp_compute_loop_coefs.f @@ -173,7 +173,8 @@ SUBROUTINE ML5_0_MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/polynomial.f b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/polynomial.f index b95ec862d1..be4967a597 100644 --- a/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/polynomial.f +++ b/tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/polynomial.f @@ -451,11 +451,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -465,18 +467,90 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -493,11 +567,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -510,6 +586,80 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -518,11 +668,13 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -543,11 +695,13 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -570,6 +724,90 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -578,11 +816,13 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -613,11 +853,13 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -641,18 +883,105 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -683,11 +1012,13 @@ SUBROUTINE ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -701,18 +1032,94 @@ SUBROUTINE ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -742,9 +1149,9 @@ SUBROUTINE ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE DO K=1,IN_SIZE UPDATER_COEF = B(J,M,K) IF (UPDATER_COEF.EQ.(0.0D0,0.0D0)) CYCLE - DO L=0,14 - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION = COMB_COEF_POS(L,M) OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) $ *UPDATER_COEF ENDDO @@ -758,25 +1165,62 @@ SUBROUTINE ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC IMPLICIT NONE INTEGER I,J,K,L,M COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L INTEGER NEW_POSITION COMPLEX*32 UPDATER_COEF C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) DO J=1,OUT_SIZE DO M=0,4 DO K=1,IN_SIZE UPDATER_COEF = B(J,M,K) IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE - DO L=0,14 - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) $ *UPDATER_COEF ENDDO @@ -785,78 +1229,3560 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + END - SUBROUTINE ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS - INTEGER I,J,K - COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF - DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 - OUT(J,K,I)=(0.0D0,0.0D0) - ENDDO +C Welcome to the computational heart of MadLoop... + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 DO K=1,IN_SIZE - OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) - OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) - OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) - OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) - OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) - OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) - OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) - OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) - OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) - OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) - OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) - OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) - OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) - OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) - OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) - OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) - OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) - OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) - OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) - OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) - OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) - OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) - OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) - OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) - OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) - OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) - OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) - OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) - OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) - OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) - OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) - OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) - OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) - OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) - OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO ENDDO ENDDO ENDDO + END - SUBROUTINE MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L1_2(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) USE ML5_0_POLYNOMIAL_CONSTANTS - INTEGER I,J,K + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L2_1(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=(0.0D0,0.0D0) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:34,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:34,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + INTEGER NEW_POSITION + COMPLEX*16 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + OUT(:,:,:)=(0.0D0,0.0D0) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.(0.0D0,0.0D0)) CYCLE + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:34,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,34 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,34 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_1_FACTOR_FFV1L1_2(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:34,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:34 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:34,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,34 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,34 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,34 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_1_FACTOR_FFV1L2_1(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:34,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:34 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:34,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,34 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,34 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,34 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE ML5_0_UPDATE_WL_4_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,69 + DO J=1,OUT_SIZE + OUT(J,K,I)=(0.0D0,0.0D0) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + OUT(J,35,I)=OUT(J,35,I)+A(K,35,I)*B(J,0,K) + OUT(J,36,I)=OUT(J,36,I)+A(K,36,I)*B(J,0,K) + OUT(J,37,I)=OUT(J,37,I)+A(K,37,I)*B(J,0,K) + OUT(J,38,I)=OUT(J,38,I)+A(K,38,I)*B(J,0,K) + OUT(J,39,I)=OUT(J,39,I)+A(K,39,I)*B(J,0,K) + OUT(J,40,I)=OUT(J,40,I)+A(K,40,I)*B(J,0,K) + OUT(J,41,I)=OUT(J,41,I)+A(K,41,I)*B(J,0,K) + OUT(J,42,I)=OUT(J,42,I)+A(K,42,I)*B(J,0,K) + OUT(J,43,I)=OUT(J,43,I)+A(K,43,I)*B(J,0,K) + OUT(J,44,I)=OUT(J,44,I)+A(K,44,I)*B(J,0,K) + OUT(J,45,I)=OUT(J,45,I)+A(K,45,I)*B(J,0,K) + OUT(J,46,I)=OUT(J,46,I)+A(K,46,I)*B(J,0,K) + OUT(J,47,I)=OUT(J,47,I)+A(K,47,I)*B(J,0,K) + OUT(J,48,I)=OUT(J,48,I)+A(K,48,I)*B(J,0,K) + OUT(J,49,I)=OUT(J,49,I)+A(K,49,I)*B(J,0,K) + OUT(J,50,I)=OUT(J,50,I)+A(K,50,I)*B(J,0,K) + OUT(J,51,I)=OUT(J,51,I)+A(K,51,I)*B(J,0,K) + OUT(J,52,I)=OUT(J,52,I)+A(K,52,I)*B(J,0,K) + OUT(J,53,I)=OUT(J,53,I)+A(K,53,I)*B(J,0,K) + OUT(J,54,I)=OUT(J,54,I)+A(K,54,I)*B(J,0,K) + OUT(J,55,I)=OUT(J,55,I)+A(K,55,I)*B(J,0,K) + OUT(J,56,I)=OUT(J,56,I)+A(K,56,I)*B(J,0,K) + OUT(J,57,I)=OUT(J,57,I)+A(K,57,I)*B(J,0,K) + OUT(J,58,I)=OUT(J,58,I)+A(K,58,I)*B(J,0,K) + OUT(J,59,I)=OUT(J,59,I)+A(K,59,I)*B(J,0,K) + OUT(J,60,I)=OUT(J,60,I)+A(K,60,I)*B(J,0,K) + OUT(J,61,I)=OUT(J,61,I)+A(K,61,I)*B(J,0,K) + OUT(J,62,I)=OUT(J,62,I)+A(K,62,I)*B(J,0,K) + OUT(J,63,I)=OUT(J,63,I)+A(K,63,I)*B(J,0,K) + OUT(J,64,I)=OUT(J,64,I)+A(K,64,I)*B(J,0,K) + OUT(J,65,I)=OUT(J,65,I)+A(K,65,I)*B(J,0,K) + OUT(J,66,I)=OUT(J,66,I)+A(K,66,I)*B(J,0,K) + OUT(J,67,I)=OUT(J,67,I)+A(K,67,I)*B(J,0,K) + OUT(J,68,I)=OUT(J,68,I)+A(K,68,I)*B(J,0,K) + OUT(J,69,I)=OUT(J,69,I)+A(K,69,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_4_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:69,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:69,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_4_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:69,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:69,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,69 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + OUT(J,35,I)=OUT(J,35,I)+A(K,35,I)*B(J,0,K) + OUT(J,36,I)=OUT(J,36,I)+A(K,36,I)*B(J,0,K) + OUT(J,37,I)=OUT(J,37,I)+A(K,37,I)*B(J,0,K) + OUT(J,38,I)=OUT(J,38,I)+A(K,38,I)*B(J,0,K) + OUT(J,39,I)=OUT(J,39,I)+A(K,39,I)*B(J,0,K) + OUT(J,40,I)=OUT(J,40,I)+A(K,40,I)*B(J,0,K) + OUT(J,41,I)=OUT(J,41,I)+A(K,41,I)*B(J,0,K) + OUT(J,42,I)=OUT(J,42,I)+A(K,42,I)*B(J,0,K) + OUT(J,43,I)=OUT(J,43,I)+A(K,43,I)*B(J,0,K) + OUT(J,44,I)=OUT(J,44,I)+A(K,44,I)*B(J,0,K) + OUT(J,45,I)=OUT(J,45,I)+A(K,45,I)*B(J,0,K) + OUT(J,46,I)=OUT(J,46,I)+A(K,46,I)*B(J,0,K) + OUT(J,47,I)=OUT(J,47,I)+A(K,47,I)*B(J,0,K) + OUT(J,48,I)=OUT(J,48,I)+A(K,48,I)*B(J,0,K) + OUT(J,49,I)=OUT(J,49,I)+A(K,49,I)*B(J,0,K) + OUT(J,50,I)=OUT(J,50,I)+A(K,50,I)*B(J,0,K) + OUT(J,51,I)=OUT(J,51,I)+A(K,51,I)*B(J,0,K) + OUT(J,52,I)=OUT(J,52,I)+A(K,52,I)*B(J,0,K) + OUT(J,53,I)=OUT(J,53,I)+A(K,53,I)*B(J,0,K) + OUT(J,54,I)=OUT(J,54,I)+A(K,54,I)*B(J,0,K) + OUT(J,55,I)=OUT(J,55,I)+A(K,55,I)*B(J,0,K) + OUT(J,56,I)=OUT(J,56,I)+A(K,56,I)*B(J,0,K) + OUT(J,57,I)=OUT(J,57,I)+A(K,57,I)*B(J,0,K) + OUT(J,58,I)=OUT(J,58,I)+A(K,58,I)*B(J,0,K) + OUT(J,59,I)=OUT(J,59,I)+A(K,59,I)*B(J,0,K) + OUT(J,60,I)=OUT(J,60,I)+A(K,60,I)*B(J,0,K) + OUT(J,61,I)=OUT(J,61,I)+A(K,61,I)*B(J,0,K) + OUT(J,62,I)=OUT(J,62,I)+A(K,62,I)*B(J,0,K) + OUT(J,63,I)=OUT(J,63,I)+A(K,63,I)*B(J,0,K) + OUT(J,64,I)=OUT(J,64,I)+A(K,64,I)*B(J,0,K) + OUT(J,65,I)=OUT(J,65,I)+A(K,65,I)*B(J,0,K) + OUT(J,66,I)=OUT(J,66,I)+A(K,66,I)*B(J,0,K) + OUT(J,67,I)=OUT(J,67,I)+A(K,67,I)*B(J,0,K) + OUT(J,68,I)=OUT(J,68,I)+A(K,68,I)*B(J,0,K) + OUT(J,69,I)=OUT(J,69,I)+A(K,69,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_4_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,69 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + OUT(J,35,I)=OUT(J,35,I)+A(K,35,I)*B(J,0,K) + OUT(J,36,I)=OUT(J,36,I)+A(K,36,I)*B(J,0,K) + OUT(J,37,I)=OUT(J,37,I)+A(K,37,I)*B(J,0,K) + OUT(J,38,I)=OUT(J,38,I)+A(K,38,I)*B(J,0,K) + OUT(J,39,I)=OUT(J,39,I)+A(K,39,I)*B(J,0,K) + OUT(J,40,I)=OUT(J,40,I)+A(K,40,I)*B(J,0,K) + OUT(J,41,I)=OUT(J,41,I)+A(K,41,I)*B(J,0,K) + OUT(J,42,I)=OUT(J,42,I)+A(K,42,I)*B(J,0,K) + OUT(J,43,I)=OUT(J,43,I)+A(K,43,I)*B(J,0,K) + OUT(J,44,I)=OUT(J,44,I)+A(K,44,I)*B(J,0,K) + OUT(J,45,I)=OUT(J,45,I)+A(K,45,I)*B(J,0,K) + OUT(J,46,I)=OUT(J,46,I)+A(K,46,I)*B(J,0,K) + OUT(J,47,I)=OUT(J,47,I)+A(K,47,I)*B(J,0,K) + OUT(J,48,I)=OUT(J,48,I)+A(K,48,I)*B(J,0,K) + OUT(J,49,I)=OUT(J,49,I)+A(K,49,I)*B(J,0,K) + OUT(J,50,I)=OUT(J,50,I)+A(K,50,I)*B(J,0,K) + OUT(J,51,I)=OUT(J,51,I)+A(K,51,I)*B(J,0,K) + OUT(J,52,I)=OUT(J,52,I)+A(K,52,I)*B(J,0,K) + OUT(J,53,I)=OUT(J,53,I)+A(K,53,I)*B(J,0,K) + OUT(J,54,I)=OUT(J,54,I)+A(K,54,I)*B(J,0,K) + OUT(J,55,I)=OUT(J,55,I)+A(K,55,I)*B(J,0,K) + OUT(J,56,I)=OUT(J,56,I)+A(K,56,I)*B(J,0,K) + OUT(J,57,I)=OUT(J,57,I)+A(K,57,I)*B(J,0,K) + OUT(J,58,I)=OUT(J,58,I)+A(K,58,I)*B(J,0,K) + OUT(J,59,I)=OUT(J,59,I)+A(K,59,I)*B(J,0,K) + OUT(J,60,I)=OUT(J,60,I)+A(K,60,I)*B(J,0,K) + OUT(J,61,I)=OUT(J,61,I)+A(K,61,I)*B(J,0,K) + OUT(J,62,I)=OUT(J,62,I)+A(K,62,I)*B(J,0,K) + OUT(J,63,I)=OUT(J,63,I)+A(K,63,I)*B(J,0,K) + OUT(J,64,I)=OUT(J,64,I)+A(K,64,I)*B(J,0,K) + OUT(J,65,I)=OUT(J,65,I)+A(K,65,I)*B(J,0,K) + OUT(J,66,I)=OUT(J,66,I)+A(K,66,I)*B(J,0,K) + OUT(J,67,I)=OUT(J,67,I)+A(K,67,I)*B(J,0,K) + OUT(J,68,I)=OUT(J,68,I)+A(K,68,I)*B(J,0,K) + OUT(J,69,I)=OUT(J,69,I)+A(K,69,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_0_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.1.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:0,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_1_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.1.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_3_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.35.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:34,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:34,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 + DO K=0,34 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -895,177 +4821,987 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO ENDDO ENDDO - END - - SUBROUTINE ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) - USE ML5_0_POLYNOMIAL_CONSTANTS - IMPLICIT NONE - INTEGER I,J,K,L,M - COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) - INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE - INTEGER NEW_POSITION - COMPLEX*16 UPDATER_COEF - -C Welcome to the computational heart of MadLoop... - OUT(:,:,:)=(0.0D0,0.0D0) - DO J=1,OUT_SIZE - DO M=0,4 + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.35.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:34,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,34 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,34 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_3_1_FACTOR_FFV1L1_2(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:34,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:34 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.35.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:34,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,34 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,34 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE DO K=1,IN_SIZE - UPDATER_COEF = B(J,M,K) - IF (UPDATER_COEF.EQ.(0.0D0,0.0D0)) CYCLE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE DO L=0,34 - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE - OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) - $ *UPDATER_COEF - ENDDO + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF ENDDO ENDDO ENDDO ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION END - SUBROUTINE MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) + SUBROUTINE MP_ML5_0_TERMINAL_WL_3_1_FACTOR_FFV1L2_1(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE - INTEGER I,J,K,L,M + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:34,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT INTEGER NEW_POSITION COMPLEX*32 UPDATER_COEF -C Welcome to the computational heart of MadLoop... +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:34 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.35.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:34,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,34 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_3_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) DO J=1,OUT_SIZE - DO M=0,4 - DO K=1,IN_SIZE - UPDATER_COEF = B(J,M,K) - IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) DO L=0,34 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE - OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) - $ *UPDATER_COEF - ENDDO + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF ENDDO ENDDO ENDDO ENDDO - - END - - SUBROUTINE ML5_0_UPDATE_WL_4_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) - USE ML5_0_POLYNOMIAL_CONSTANTS - INTEGER I,J,K - COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) - INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE - + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,69 - OUT(J,K,I)=(0.0D0,0.0D0) - ENDDO + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE DO K=1,IN_SIZE - OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) - OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) - OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) - OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) - OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) - OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) - OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) - OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) - OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) - OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) - OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) - OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) - OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) - OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) - OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) - OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) - OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) - OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) - OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) - OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) - OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) - OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) - OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) - OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) - OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) - OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) - OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) - OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) - OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) - OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) - OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) - OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) - OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) - OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) - OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) - OUT(J,35,I)=OUT(J,35,I)+A(K,35,I)*B(J,0,K) - OUT(J,36,I)=OUT(J,36,I)+A(K,36,I)*B(J,0,K) - OUT(J,37,I)=OUT(J,37,I)+A(K,37,I)*B(J,0,K) - OUT(J,38,I)=OUT(J,38,I)+A(K,38,I)*B(J,0,K) - OUT(J,39,I)=OUT(J,39,I)+A(K,39,I)*B(J,0,K) - OUT(J,40,I)=OUT(J,40,I)+A(K,40,I)*B(J,0,K) - OUT(J,41,I)=OUT(J,41,I)+A(K,41,I)*B(J,0,K) - OUT(J,42,I)=OUT(J,42,I)+A(K,42,I)*B(J,0,K) - OUT(J,43,I)=OUT(J,43,I)+A(K,43,I)*B(J,0,K) - OUT(J,44,I)=OUT(J,44,I)+A(K,44,I)*B(J,0,K) - OUT(J,45,I)=OUT(J,45,I)+A(K,45,I)*B(J,0,K) - OUT(J,46,I)=OUT(J,46,I)+A(K,46,I)*B(J,0,K) - OUT(J,47,I)=OUT(J,47,I)+A(K,47,I)*B(J,0,K) - OUT(J,48,I)=OUT(J,48,I)+A(K,48,I)*B(J,0,K) - OUT(J,49,I)=OUT(J,49,I)+A(K,49,I)*B(J,0,K) - OUT(J,50,I)=OUT(J,50,I)+A(K,50,I)*B(J,0,K) - OUT(J,51,I)=OUT(J,51,I)+A(K,51,I)*B(J,0,K) - OUT(J,52,I)=OUT(J,52,I)+A(K,52,I)*B(J,0,K) - OUT(J,53,I)=OUT(J,53,I)+A(K,53,I)*B(J,0,K) - OUT(J,54,I)=OUT(J,54,I)+A(K,54,I)*B(J,0,K) - OUT(J,55,I)=OUT(J,55,I)+A(K,55,I)*B(J,0,K) - OUT(J,56,I)=OUT(J,56,I)+A(K,56,I)*B(J,0,K) - OUT(J,57,I)=OUT(J,57,I)+A(K,57,I)*B(J,0,K) - OUT(J,58,I)=OUT(J,58,I)+A(K,58,I)*B(J,0,K) - OUT(J,59,I)=OUT(J,59,I)+A(K,59,I)*B(J,0,K) - OUT(J,60,I)=OUT(J,60,I)+A(K,60,I)*B(J,0,K) - OUT(J,61,I)=OUT(J,61,I)+A(K,61,I)*B(J,0,K) - OUT(J,62,I)=OUT(J,62,I)+A(K,62,I)*B(J,0,K) - OUT(J,63,I)=OUT(J,63,I)+A(K,63,I)*B(J,0,K) - OUT(J,64,I)=OUT(J,64,I)+A(K,64,I)*B(J,0,K) - OUT(J,65,I)=OUT(J,65,I)+A(K,65,I)*B(J,0,K) - OUT(J,66,I)=OUT(J,66,I)+A(K,66,I)*B(J,0,K) - OUT(J,67,I)=OUT(J,67,I)+A(K,67,I)*B(J,0,K) - OUT(J,68,I)=OUT(J,68,I)+A(K,68,I)*B(J,0,K) - OUT(J,69,I)=OUT(J,69,I)+A(K,69,I)*B(J,0,K) + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,34 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO ENDDO ENDDO ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,34 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + END - SUBROUTINE MP_ML5_0_UPDATE_WL_4_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) + SUBROUTINE MP_ML5_0_TERMINAL_WL_4_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.70.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:69,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:69,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_4_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:69,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:69,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,69 + DO K=0,69 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -1139,4 +5875,38 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_4_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + END diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/%..%..%Source%MODEL%model_functions.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/%..%..%Source%MODEL%model_functions.f index 0a5f1443ac..232e1b1ab3 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/%..%..%Source%MODEL%model_functions.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/%..%..%Source%MODEL%model_functions.f @@ -546,7 +546,7 @@ COMPLEX*32 FUNCTION MP_RECMS(CONDITION,EXPR) IF(CONDITION)THEN MP_RECMS=EXPR ELSE - MP_RECMS=CMPLX(REAL(EXPR),KIND=16) + MP_RECMS=CMPLX(REAL(EXPR,KIND=16),KIND=16) ENDIF END @@ -555,16 +555,16 @@ COMPLEX*32 FUNCTION MP_REGLOG(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16)) THEN MP_REGLOG=(0.0E0_16,0.0E0_16) @@ -577,16 +577,16 @@ COMPLEX*32 FUNCTION MP_REGLOGP(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGP=(0.0E0_16,0.0E0_16) @@ -604,16 +604,16 @@ COMPLEX*32 FUNCTION MP_REGLOGM(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGM=(0.0E0_16,0.0E0_16) @@ -633,10 +633,10 @@ COMPLEX*32 FUNCTION MP_REGSQRT(ARG_IN) COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF MP_REGSQRT=SQRT(ARG) END @@ -645,7 +645,7 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 EXPR1_IN,EXPR2_IN COMPLEX*32 EXPR1,EXPR2 @@ -655,16 +655,16 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) EXPR1=EXPR1_IN EXPR2=EXPR2_IN IF(ABS(IMAGPART(EXPR1)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16) + EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR1,KIND=16)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1)) + EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1),KIND=16) ENDIF IF(ABS(IMAGPART(EXPR2)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16) + EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR2,KIND=16)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2)) + EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2),KIND=16) ENDIF IF(EXPR1.EQ.(0.0E0_16,0.0E0_16))THEN MP_GRREGLOG=(0.0E0_16,0.0E0_16) @@ -795,7 +795,7 @@ COMPLEX*32 FUNCTION MP_B0F(P2,M12,M22) COMPLEX*32 ZERO,TWOPII PARAMETER (ZERO=(0.0E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) REAL*16 M,M2,GA,GA2 REAL*16 TINY @@ -898,7 +898,7 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) GA=-IMAGPART(P2)/M ENDIF GAMMA0=ONE+M12/P2-M22/P2 - GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2 + GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY)/P2 IF(ABS(GA).EQ.0.0E0_16)THEN MP_SQRT_TRAJECTORY=SQRT(GAMMA0**2-4.0E0_16*GAMMA1) RETURN @@ -907,15 +907,17 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG PREFACTOR=1.0E0_16 GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGIM1=GAMMA0I**2-4.0E0_16*GAMMA1I DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGI=GAMMA0I**2-4.0E0_16*GAMMA1I IF(IMAGPART(ARGI)*IMAGPART(ARGIM1).LT.0.0E0_16)THEN INTERSECTION=IMAGPART(ARGIM1)*(REAL(ARGI,KIND=16) @@ -941,7 +943,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) PARAMETER (ZERO=(0.0E0_16,0.0E0_16),ONE=(1.0E0_16,0.0E0_16)) PARAMETER (HALF=(0.5E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 GAMMA0,GAMMAP,GAMMAM,SQRTTERM REAL*16 M,GA,DGA,GA_START @@ -978,7 +980,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG ADDFACTOR(1:4)=ZERO GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) @@ -989,7 +991,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) ARGIM1(4)=(GAMMAMI-ONE)/GAMMAMI DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/loop_matrix.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/loop_matrix.f index b0330d86b0..76a868737a 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/loop_matrix.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/loop_matrix.f @@ -437,6 +437,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANSRETURNED) STOP 1 ENDIF ENDIF +C The non-optimized output uses CutTools regardless of the +C requested chain. + IF(LOOPPOLEMODE.GT.0) THEN + WRITE(*,*) 'LoopPoleMode=1, 2 or 3 requires optimized MadLoop' + $ //' output with NinjaRS or COLLIER.' + WRITE(*,*) 'Regenerate with loop_optimized_output enabled and' + $ //' MLReductionLib=8 or 7.' + STOP 1 + ENDIF IF (LOCAL_ML_INIT) THEN C Setup the file paths CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/ddx_ttx/loop_matrix.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/ddx_ttx/loop_matrix.f index 857cc31483..cdfb275d87 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/ddx_ttx/loop_matrix.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/ddx_ttx/loop_matrix.f @@ -439,6 +439,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANSRETURNED) STOP 1 ENDIF ENDIF +C The non-optimized output uses CutTools regardless of the +C requested chain. + IF(LOOPPOLEMODE.GT.0) THEN + WRITE(*,*) 'LoopPoleMode=1, 2 or 3 requires optimized MadLoop' + $ //' output with NinjaRS or COLLIER.' + WRITE(*,*) 'Regenerate with loop_optimized_output enabled and' + $ //' MLReductionLib=8 or 7.' + STOP 1 + ENDIF IF (LOCAL_ML_INIT) THEN C Setup the file paths CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%model_functions.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%model_functions.f index 0a5f1443ac..232e1b1ab3 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%model_functions.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%model_functions.f @@ -546,7 +546,7 @@ COMPLEX*32 FUNCTION MP_RECMS(CONDITION,EXPR) IF(CONDITION)THEN MP_RECMS=EXPR ELSE - MP_RECMS=CMPLX(REAL(EXPR),KIND=16) + MP_RECMS=CMPLX(REAL(EXPR,KIND=16),KIND=16) ENDIF END @@ -555,16 +555,16 @@ COMPLEX*32 FUNCTION MP_REGLOG(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16)) THEN MP_REGLOG=(0.0E0_16,0.0E0_16) @@ -577,16 +577,16 @@ COMPLEX*32 FUNCTION MP_REGLOGP(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGP=(0.0E0_16,0.0E0_16) @@ -604,16 +604,16 @@ COMPLEX*32 FUNCTION MP_REGLOGM(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGM=(0.0E0_16,0.0E0_16) @@ -633,10 +633,10 @@ COMPLEX*32 FUNCTION MP_REGSQRT(ARG_IN) COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF MP_REGSQRT=SQRT(ARG) END @@ -645,7 +645,7 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 EXPR1_IN,EXPR2_IN COMPLEX*32 EXPR1,EXPR2 @@ -655,16 +655,16 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) EXPR1=EXPR1_IN EXPR2=EXPR2_IN IF(ABS(IMAGPART(EXPR1)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16) + EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR1,KIND=16)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1)) + EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1),KIND=16) ENDIF IF(ABS(IMAGPART(EXPR2)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16) + EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR2,KIND=16)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2)) + EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2),KIND=16) ENDIF IF(EXPR1.EQ.(0.0E0_16,0.0E0_16))THEN MP_GRREGLOG=(0.0E0_16,0.0E0_16) @@ -795,7 +795,7 @@ COMPLEX*32 FUNCTION MP_B0F(P2,M12,M22) COMPLEX*32 ZERO,TWOPII PARAMETER (ZERO=(0.0E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) REAL*16 M,M2,GA,GA2 REAL*16 TINY @@ -898,7 +898,7 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) GA=-IMAGPART(P2)/M ENDIF GAMMA0=ONE+M12/P2-M22/P2 - GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2 + GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY)/P2 IF(ABS(GA).EQ.0.0E0_16)THEN MP_SQRT_TRAJECTORY=SQRT(GAMMA0**2-4.0E0_16*GAMMA1) RETURN @@ -907,15 +907,17 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG PREFACTOR=1.0E0_16 GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGIM1=GAMMA0I**2-4.0E0_16*GAMMA1I DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGI=GAMMA0I**2-4.0E0_16*GAMMA1I IF(IMAGPART(ARGI)*IMAGPART(ARGIM1).LT.0.0E0_16)THEN INTERSECTION=IMAGPART(ARGIM1)*(REAL(ARGI,KIND=16) @@ -941,7 +943,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) PARAMETER (ZERO=(0.0E0_16,0.0E0_16),ONE=(1.0E0_16,0.0E0_16)) PARAMETER (HALF=(0.5E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 GAMMA0,GAMMAP,GAMMAM,SQRTTERM REAL*16 M,GA,DGA,GA_START @@ -978,7 +980,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG ADDFACTOR(1:4)=ZERO GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) @@ -989,7 +991,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) ARGIM1(4)=(GAMMAMI-ONE)/GAMMAMI DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/loop_matrix.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/loop_matrix.f index 740c88a718..73b0039501 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/loop_matrix.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/loop_matrix.f @@ -439,6 +439,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANSRETURNED) STOP 1 ENDIF ENDIF +C The non-optimized output uses CutTools regardless of the +C requested chain. + IF(LOOPPOLEMODE.GT.0) THEN + WRITE(*,*) 'LoopPoleMode=1, 2 or 3 requires optimized MadLoop' + $ //' output with NinjaRS or COLLIER.' + WRITE(*,*) 'Regenerate with loop_optimized_output enabled and' + $ //' MLReductionLib=8 or 7.' + STOP 1 + ENDIF IF (LOCAL_ML_INIT) THEN C Setup the file paths CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/CT_interface.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/CT_interface.f index c2b27e67c6..456bb25d6a 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/CT_interface.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/CT_interface.f @@ -327,6 +327,7 @@ SUBROUTINE ML5_0_MP_BUILD_KINEMATIC_MATRIX(NLOOPLINE,P_LOOP,M2L + SUBROUTINE ML5_0_LOOP_2(W1, W2, M1, M2, RANK, SQUAREDSOINDEX, $ LOOPNUM) USE ALOHA_OBJECT diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/TIR_interface.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/TIR_interface.f index c537d9cf2e..a9980927aa 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/TIR_interface.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/TIR_interface.f @@ -52,6 +52,10 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -83,8 +87,38 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL ML5_0_CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -360,9 +394,10 @@ SUBROUTINE ML5_0_CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=8) C diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/loop_matrix.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/loop_matrix.f index ce42c10474..964ad10dfd 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/loop_matrix.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/loop_matrix.f @@ -79,13 +79,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -193,7 +195,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -246,23 +248,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE./ + $ ,.FALSE.,.FALSE.,.FALSE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -471,6 +474,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -507,10 +511,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -749,7 +772,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -775,7 +798,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -801,7 +824,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1092,8 +1115,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1659,7 +1682,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2377,6 +2400,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2748,7 +2780,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2758,7 +2791,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/mp_coef_construction_1.f index 02c1304572..ba915222bf 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -87,7 +89,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_VVV1L2P0_1(PL(0,0),W(5),GC_4,ZERO,ZERO,PL(0,1),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,1)) CALL MP_VVV1L2P0_1(PL(0,1),W(6),GC_4,ZERO,ZERO,PL(0,2),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,2),2,4,1,2,1,30,H) C Coefficient construction for loop diagram with ID 3 CALL MP_FFV1L3_1(PL(0,0),W(3),GC_5,MDL_MT,MDL_WT,PL(0,3),COEFS) @@ -95,7 +99,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L2P0_3(PL(0,3),W(4),GC_5,ZERO,ZERO,PL(0,4),COEFS) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,3),4,COEFS,4,4,WL(1,0,1,4)) CALL MP_VVV1L2P0_1(PL(0,4),W(5),GC_4,ZERO,ZERO,PL(0,5),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,5),2,4,2,1,1,31,H) C Coefficient construction for loop diagram with ID 4 CALL MP_FFV1L1P0_3(PL(0,0),W(3),GC_5,ZERO,ZERO,PL(0,6),COEFS) @@ -103,7 +109,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L3_2(PL(0,6),W(4),GC_5,MDL_MT,MDL_WT,PL(0,7),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7)) CALL MP_FFV1L1_2(PL(0,7),W(5),GC_5,MDL_MT,MDL_WT,PL(0,8),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,8),2,4,3,1,1,32,H) C Coefficient construction for loop diagram with ID 5 CALL MP_FFV1L2P0_3(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,9),COEFS) @@ -111,8 +119,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L3_1(PL(0,9),W(2),GC_5,ZERO,ZERO,PL(0,10),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1,10)) CALL MP_FFV1L2_1(PL(0,10),W(6),GC_5,ZERO,ZERO,PL(0,11),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,10),4,COEFS,4,4,WL(1,0,1,11) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,10),4,COEFS,4,4,WL(1,0,1 + $ ,11),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,11),2,4,4,1,1,33,H) C Coefficient construction for loop diagram with ID 6 CALL MP_FFV1L3_2(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,12),COEFS) @@ -121,52 +130,59 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,13) $ ) CALL MP_VVV1L2P0_1(PL(0,13),W(6),GC_4,ZERO,ZERO,PL(0,14),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,13),4,COEFS,4,4,WL(1,0,1,14) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,13),4,COEFS,4,4,WL(1,0,1 + $ ,14),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,14),2,4,4,1,1,34,H) C Coefficient construction for loop diagram with ID 7 CALL MP_FFV1L3_2(PL(0,13),W(4),GC_5,MDL_MT,MDL_WT,PL(0,15),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,13),4,COEFS,4,4,WL(1,0,1,15) $ ) CALL MP_FFV1L1P0_3(PL(0,15),W(3),GC_5,ZERO,ZERO,PL(0,16),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1,16) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1 + $ ,16),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,16),2,4,5,1,1,35,H) C Coefficient construction for loop diagram with ID 8 CALL MP_FFV1L3_1(PL(0,13),W(3),GC_5,MDL_MT,MDL_WT,PL(0,17),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,13),4,COEFS,4,4,WL(1,0,1,17) $ ) CALL MP_FFV1L2P0_3(PL(0,17),W(4),GC_5,ZERO,ZERO,PL(0,18),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1 + $ ,18),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,18),2,4,6,1,1,36,H) C Coefficient construction for loop diagram with ID 9 CALL MP_GHGHGL2_1(PL(0,0),W(5),GC_4,ZERO,ZERO,PL(0,19),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,19)) CALL MP_GHGHGL2_1(PL(0,19),W(6),GC_4,ZERO,ZERO,PL(0,20),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,19),1,COEFS,1,1,WL(1,0,1,20) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,19),1,COEFS,1,1,WL(1,0,1 + $ ,20),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,20),2,1,1,1,1,37,H) C Coefficient construction for loop diagram with ID 10 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,ZERO,ZERO,PL(0,21),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,21)) CALL MP_FFV1L2_1(PL(0,21),W(6),GC_5,ZERO,ZERO,PL(0,22),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1,22) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1 + $ ,22),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,22),2,4,1,1,4,38,H) C Coefficient construction for loop diagram with ID 11 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,MDL_MB,ZERO,PL(0,23),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,23)) CALL MP_FFV1L2_1(PL(0,23),W(6),GC_5,MDL_MB,ZERO,PL(0,24),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,23),4,COEFS,4,4,WL(1,0,1,24) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,23),4,COEFS,4,4,WL(1,0,1 + $ ,24),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,24),2,4,7,1,1,39,H) C Coefficient construction for loop diagram with ID 12 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,MDL_MT,MDL_WT,PL(0,25),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,25)) CALL MP_FFV1L2_1(PL(0,25),W(6),GC_5,MDL_MT,MDL_WT,PL(0,26),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,25),4,COEFS,4,4,WL(1,0,1,26) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,25),4,COEFS,4,4,WL(1,0,1 + $ ,26),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,26),2,4,8,1,1,40,H) GOTO 1001 diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/mp_compute_loop_coefs.f index 557e7d2eec..e1f6f78c62 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/mp_compute_loop_coefs.f @@ -173,7 +173,8 @@ SUBROUTINE ML5_0_MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/polynomial.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/polynomial.f index f10a5ca767..3c57bf6998 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/polynomial.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/ddx_ttx/polynomial.f @@ -338,11 +338,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -356,18 +358,94 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -388,11 +466,13 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -415,6 +495,90 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -423,11 +587,13 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -458,11 +624,13 @@ SUBROUTINE ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -475,6 +643,80 @@ SUBROUTINE ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -483,11 +725,13 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -508,11 +752,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -521,6 +767,76 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) @@ -529,11 +845,13 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -550,11 +868,13 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -578,18 +898,290 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -608,4 +1200,38 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + END diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%model_functions.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%model_functions.f index 0a5f1443ac..232e1b1ab3 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%model_functions.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%model_functions.f @@ -546,7 +546,7 @@ COMPLEX*32 FUNCTION MP_RECMS(CONDITION,EXPR) IF(CONDITION)THEN MP_RECMS=EXPR ELSE - MP_RECMS=CMPLX(REAL(EXPR),KIND=16) + MP_RECMS=CMPLX(REAL(EXPR,KIND=16),KIND=16) ENDIF END @@ -555,16 +555,16 @@ COMPLEX*32 FUNCTION MP_REGLOG(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16)) THEN MP_REGLOG=(0.0E0_16,0.0E0_16) @@ -577,16 +577,16 @@ COMPLEX*32 FUNCTION MP_REGLOGP(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGP=(0.0E0_16,0.0E0_16) @@ -604,16 +604,16 @@ COMPLEX*32 FUNCTION MP_REGLOGM(ARG_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 ARG_IN COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF IF(ARG.EQ.(0.0E0_16,0.0E0_16))THEN MP_REGLOGM=(0.0E0_16,0.0E0_16) @@ -633,10 +633,10 @@ COMPLEX*32 FUNCTION MP_REGSQRT(ARG_IN) COMPLEX*32 ARG ARG=ARG_IN IF(ABS(IMAGPART(ARG)).EQ.0.0E0_16)THEN - ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16) + ARG=CMPLX(REAL(ARG,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(ARG,KIND=16)).EQ.0.0E0_16)THEN - ARG=CMPLX(0.0E0_16,IMAGPART(ARG)) + ARG=CMPLX(0.0E0_16,IMAGPART(ARG),KIND=16) ENDIF MP_REGSQRT=SQRT(ARG) END @@ -645,7 +645,7 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) IMPLICIT NONE COMPLEX*32 TWOPII PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 EXPR1_IN,EXPR2_IN COMPLEX*32 EXPR1,EXPR2 @@ -655,16 +655,16 @@ COMPLEX*32 FUNCTION MP_GRREGLOG(LOGSW,EXPR1_IN,EXPR2_IN) EXPR1=EXPR1_IN EXPR2=EXPR2_IN IF(ABS(IMAGPART(EXPR1)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16) + EXPR1=CMPLX(REAL(EXPR1,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR1,KIND=16)).EQ.0.0E0_16)THEN - EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1)) + EXPR1=CMPLX(0.0E0_16,IMAGPART(EXPR1),KIND=16) ENDIF IF(ABS(IMAGPART(EXPR2)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16) + EXPR2=CMPLX(REAL(EXPR2,KIND=16),0.0E0_16,KIND=16) ENDIF IF(ABS(REAL(EXPR2,KIND=16)).EQ.0.0E0_16)THEN - EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2)) + EXPR2=CMPLX(0.0E0_16,IMAGPART(EXPR2),KIND=16) ENDIF IF(EXPR1.EQ.(0.0E0_16,0.0E0_16))THEN MP_GRREGLOG=(0.0E0_16,0.0E0_16) @@ -795,7 +795,7 @@ COMPLEX*32 FUNCTION MP_B0F(P2,M12,M22) COMPLEX*32 ZERO,TWOPII PARAMETER (ZERO=(0.0E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) REAL*16 M,M2,GA,GA2 REAL*16 TINY @@ -898,7 +898,7 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) GA=-IMAGPART(P2)/M ENDIF GAMMA0=ONE+M12/P2-M22/P2 - GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2 + GAMMA1=M12/P2-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY)/P2 IF(ABS(GA).EQ.0.0E0_16)THEN MP_SQRT_TRAJECTORY=SQRT(GAMMA0**2-4.0E0_16*GAMMA1) RETURN @@ -907,15 +907,17 @@ COMPLEX*32 FUNCTION MP_SQRT_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG PREFACTOR=1.0E0_16 GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGIM1=GAMMA0I**2-4.0E0_16*GAMMA1I DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) GAMMA0I=ONE+M12/P2I-M22/P2I - GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16)*ABS(TINY)/P2I + GAMMA1I=M12/P2I-CMPLX(0.0E0_16,1.0E0_16,KIND=16)*ABS(TINY) + $ /P2I ARGI=GAMMA0I**2-4.0E0_16*GAMMA1I IF(IMAGPART(ARGI)*IMAGPART(ARGIM1).LT.0.0E0_16)THEN INTERSECTION=IMAGPART(ARGIM1)*(REAL(ARGI,KIND=16) @@ -941,7 +943,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) PARAMETER (ZERO=(0.0E0_16,0.0E0_16),ONE=(1.0E0_16,0.0E0_16)) PARAMETER (HALF=(0.5E0_16,0.0E0_16)) PARAMETER (TWOPII=2.0E0_16 - $ *3.14169258478796109557151794433593750E0_16*(0.0E0_16 + $ *3.141592653589793238462643383279502884197E0_16*(0.0E0_16 $ ,1.0E0_16)) COMPLEX*32 GAMMA0,GAMMAP,GAMMAM,SQRTTERM REAL*16 M,GA,DGA,GA_START @@ -978,7 +980,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) DGA=(GA-GA_START)/N_SEG ADDFACTOR(1:4)=ZERO GAI=GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) @@ -989,7 +991,7 @@ COMPLEX*32 FUNCTION MP_LOG_TRAJECTORY(N_SEG,P2,M12,M22) ARGIM1(4)=(GAMMAMI-ONE)/GAMMAMI DO I=1,N_SEG GAI=DGA*I+GA_START - P2I=CMPLX(M**2,-GAI*M) + P2I=CMPLX(M**2,-GAI*M,KIND=16) SQRTTERMI=MP_SQRT_TRAJECTORY(N_SEG,P2I,M12,M22) GAMMA0I=ONE+M12/P2I-M22/P2I GAMMAPI=HALF*(GAMMA0I+SQRTTERMI) diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/CT_interface.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/CT_interface.f index 3173f6b2e8..7daa3c39b4 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/CT_interface.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/CT_interface.f @@ -327,6 +327,7 @@ SUBROUTINE ML5_0_MP_BUILD_KINEMATIC_MATRIX(NLOOPLINE,P_LOOP,M2L + SUBROUTINE ML5_0_LOOP_2(W1, W2, M1, M2, RANK, SQUAREDSOINDEX, $ LOOPNUM) USE ALOHA_OBJECT diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/TIR_interface.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/TIR_interface.f index 08854768c0..8157150741 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/TIR_interface.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/TIR_interface.f @@ -52,6 +52,10 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C used so as to force the reset of the TIR filter. INTEGER LAST_LIB_USED DATA LAST_LIB_USED/-1/ + INTEGER LAST_POLE_MODE + LOGICAL LAST_UV_POLES,LAST_IR_POLES,UV_POLES,IR_POLES + DATA LAST_POLE_MODE/-2/ + DATA LAST_UV_POLES,LAST_IR_POLES/.TRUE.,.TRUE./ COMPLEX*16 TIRCOEFS(0:LOOPMAXCOEFS-1,3) $ ,TIRCOEFSERRORS(0:LOOPMAXCOEFS-1,3) @@ -83,8 +87,38 @@ SUBROUTINE ML5_0_TIRLOOP(I_SQSO,I_LOOPGROUP,I_LIB,NLOOPLINE,PL C BEGIN CODE C ---------- +C Reject unavailable OPP backends which reach the TIR fallback. +C Check before +C consulting the cache so an unsupported ID can never reuse old +C coefficients. + SELECT CASE(MLREDUCTIONLIB(I_LIB)) + CASE(2,3,4,7) + CONTINUE + CASE DEFAULT + IF(MLREDUCTIONLIB(I_LIB).EQ.8) THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + ELSE + WRITE(*,*) 'ERROR:: Unsupported TIR reduction library:' + $ ,MLREDUCTIONLIB(I_LIB) + WRITE(*,*) 'Select an available MLReductionLib and' + $ //' regenerate and rebuild this process.' + ENDIF + STOP 1 + END SELECT + C Initialize for the very first time ML is called LAST_ILIB with C the first ILIB used. + CALL ML_LOOP_POLE_FLAGS(UV_POLES,IR_POLES) + IF(LAST_POLE_MODE.NE.LOOPPOLEMODE.OR.(LAST_UV_POLES.NEQV.UV_POLES) + $ .OR.(LAST_IR_POLES.NEQV.IR_POLES)) THEN + IF(LAST_POLE_MODE.NE.-2) CALL ML5_0_CLEAR_TIR_CACHE() + LAST_POLE_MODE=LOOPPOLEMODE + LAST_UV_POLES=UV_POLES + LAST_IR_POLES=IR_POLES + ENDIF IF(LAST_LIB_USED.EQ.-1) THEN LAST_LIB_USED = MLREDUCTIONLIB(LIBINDEX) ELSE @@ -360,9 +394,10 @@ SUBROUTINE ML5_0_CHOOSE_LOOPLIB(LIBINDEX,NLOOPLINE,RANK C CONSTANTS C INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) + PARAMETER (NLOOPLIB=8) INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER NLOOPGROUPS PARAMETER (NLOOPGROUPS=28) C diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/loop_matrix.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/loop_matrix.f index 014e80eadc..724774e379 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/loop_matrix.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/loop_matrix.f @@ -79,13 +79,15 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) PARAMETER (NSQUAREDSOP1=NSQUAREDSO+1) C The total number of loop reduction libraries C At present, there are only -C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja and COLLIER +C CutTools,PJFry++,IREGI,Golem95,Samurai, Ninja, COLLIER and +C NinjaRS INTEGER NLOOPLIB - PARAMETER (NLOOPLIB=7) -C Only CutTools or possibly Ninja (if installed with qp support) -C provide QP + PARAMETER (NLOOPLIB=8) +C CutTools, Ninja and NinjaRS can provide QP when installed with +C support INTEGER QP_NLOOPLIB PARAMETER (QP_NLOOPLIB=2) + INTEGER MAXSTABILITYLENGTH DATA MAXSTABILITYLENGTH/20/ COMMON/ML5_0_STABILITY_TESTS/MAXSTABILITYLENGTH @@ -193,7 +195,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) DATA NEPS/0/ C Below are variables to bypass the checkphase and insure C stability check to take place - LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED + LOGICAL OLD_CHECKPHASE, OLD_HELDOUBLECHECKED,BYPASS_FILTERS INTEGER OLD_GOODHEL(NCOMB) LOGICAL OLD_GOODAMP(NSQUAREDSO,NLOOPGROUPS) LOGICAL BYPASS_CHECK, ALWAYS_TEST_STABILITY @@ -246,23 +248,24 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C AVAILABLE OR NOT LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) DATA LOOPLIBS_AVAILABLE/.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE./ + $ ,.FALSE.,.FALSE.,.FALSE./ COMMON/ML5_0_LOOPLIBS_AV/ LOOPLIBS_AVAILABLE C A FLAG TO DENOTE WHETHER THE CORRESPONDING DIRECTION TESTS C AVAILABLE OR NOT IN THE LOOPLIBS LOGICAL LOOPLIBS_DIRECTEST(NLOOPLIB) - DATA LOOPLIBS_DIRECTEST /.TRUE.,.TRUE.,.TRUE.,.TRUE.,.TRUE. - $ ,.TRUE.,.TRUE./ + DATA LOOPLIBS_DIRECTEST /8*.TRUE./ C Specifying for which reduction tool quadruple precision is C available. C The index 0 is dummy and simply means that the corresponding C loop_library is not available C in which case neither is its quadruple precision version. - LOGICAL LOOPLIBS_QPAVAILABLE(0:7) - DATA LOOPLIBS_QPAVAILABLE /.FALSE.,.TRUE.,.FALSE.,.FALSE. - $ ,.FALSE.,.FALSE.,.TRUE.,.FALSE./ -C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT -C MODIFIED FOR THE PURPOSE OF THE STABILITY TEST + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + DATA LOOPLIBS_QPAVAILABLE(0:5)/.FALSE.,.TRUE.,4*.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(6)/.TRUE./ + DATA LOOPLIBS_QPAVAILABLE(7)/.FALSE./ + DATA LOOPLIBS_QPAVAILABLE(8)/.FALSE./ +C PS CAN POSSIBLY BE PASSED THROUGH IMPROVE_PS BUT IS NOT MODIFIED +C FOR THE PURPOSE OF THE STABILITY TEST C EVEN THOUGH THEY ARE PUT IN COMMON BLOCK, FOR NOW THEY ARE NOT C USED ANYWHERE ELSE REAL*8 PS(0:3,NEXTERNAL) @@ -471,6 +474,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CALL SETMADLOOPPATH(TMP) CALL JOINPATH(MLPATH,PARAMFNAME,PARAMFN) CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.) + CALL ML_APPLY_LOOP_POLE_MODE() IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION) THEN COLLIERCOMPUTEUVPOLES = COLLIER_UV_POLE_COMPUTATION_CHOICE ENDIF @@ -507,10 +511,29 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF +C Check every evaluation because callers may change the mode at +C runtime. + CALL ML_CHECK_LOOP_POLE_MODE() +C Learned zero and equivalent-helicity filters belong to the pole +C convention +C that produced them. Diagnostic modes must include cancelling +C UV/IR loops. + BYPASS_FILTERS=BYPASS_CHECK.OR.LOOPPOLEMODE.GE.0 + IF (LOCAL_ML_INIT) THEN LOCAL_ML_INIT = .FALSE. QP_TOOLS_AVAILABLE=.FALSE. INDEX_QP_TOOLS(1:QP_NLOOPLIB+1)=0 +C Explain an explicit NinjaRS-only request before dropping +C unavailable tools. + IF(MLREDUCTIONLIB(1).EQ.8.AND.MLREDUCTIONLIB(2) + $ .EQ.0.AND..NOT.LOOPLIBS_AVAILABLE(8))THEN + WRITE(*,*) 'NinjaRS (MLReductionLib=8) is unavailable in' + $ //' this generated process.' + WRITE(*,*) 'Run install ninjars in MadGraph, then regenerate' + $ //' and rebuild this process.' + STOP 'Requested NinjaRS backend is unavailable.' + ENDIF C SKIP THE ONES THAT NOT AVAILABLE J=1 DO I=1,NLOOPLIB @@ -749,7 +772,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) EVAL_DONE(I)=.FALSE. ENDDO - IF(.NOT.BYPASS_CHECK) THEN + IF(.NOT.BYPASS_FILTERS) THEN NTRY=NTRY+1 ENDIF @@ -775,7 +798,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) CHECKPHASE=(NTRY.LE.CHECKCYCLE).AND.(((.NOT.FOUNDLOOPFILTER) $ .AND.USELOOPFILTER).OR.(.NOT.FOUNDHELFILTER)) - IF (WRITEOUTFILTERS) THEN + IF (WRITEOUTFILTERS.AND.LOOPPOLEMODE.LT.0) THEN IF ((HELICITYFILTERLEVEL.NE.0).AND.(.NOT. CHECKPHASE) $ .AND.(.NOT.FOUNDHELFILTER)) THEN OPEN(1, FILE=HELFILTERFN, ERR=110, STATUS='NEW' @@ -801,7 +824,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) ENDIF ENDIF - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN OLD_CHECKPHASE = CHECKPHASE OLD_HELDOUBLECHECKED = HELDOUBLECHECKED CHECKPHASE = .FALSE. @@ -1092,8 +1115,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) IF (CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN IF((USERHEL.EQ.-1).OR.(USERHEL.EQ.HELPICKED)) THEN -C Make sure that no polarization constraint filters out -C this helicity +C Make sure that no polarization constraint filters out this +C helicity IF (POLARIZATIONS(0,0).EQ. $ -1.OR.ML5_0_IS_HEL_SELECTED(HELPICKED)) THEN C TO KEEP TRACK OF THE FINAL ANSWER TO BE RETURNED DURING @@ -1659,7 +1682,7 @@ SUBROUTINE ML5_0_SLOOPMATRIX(P_USER,ANS) C Reinitialize the check phase logicals and the filters if check C bypassed - IF (BYPASS_CHECK) THEN + IF (BYPASS_FILTERS) THEN CHECKPHASE = OLD_CHECKPHASE HELDOUBLECHECKED = OLD_HELDOUBLECHECKED DO I=1,NCOMB @@ -2377,6 +2400,15 @@ INTEGER FUNCTION ML5_0_ML5SOINDEX_FOR_AMPORDERS(ORDERS) C Definition of additional access routines C --=========================================-- + SUBROUTINE ML5_0_SET_LOOP_POLE_MODE(MODE) +C Select bare loop poles: -1 legacy, 0 both, 1 UV, 2 IR, 3 none. +C Counterterms and rational R2 contributions are not changed. + IMPLICIT NONE + INTEGER MODE +C All subprocesses share MadLoop's card and initialization state. + CALL ML_SET_LOOP_POLE_MODE(MODE) + END SUBROUTINE + SUBROUTINE ML5_0_COLLIER_COMPUTE_UV_POLES(ONOFF) C C This function can be called by the MadLoop user so as to chose @@ -2748,7 +2780,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 1 C Stable with CutTools in double precision. C U == 2 -C Stable with PJFry++. +C Stable with PJFry++ (H=2), or NinjaRS in quadruple precision +C (H=3). C U == 3 C Stable with IREGI. C U == 4 @@ -2758,7 +2791,8 @@ SUBROUTINE ML5_0_SLOOPMATRIX_THRES(P,ANS,PREC_ASKED,PREC_FOUND C U == 6 C Stable with Ninja in double precision C U == 8 -C Stable with Ninja in quadruple precision +C Stable with Ninja in quadruple precision (H=3), or NinjaRS in +C double precision (H=2). C U == 9 C Stable with CutTools in quadruple precision. C diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/mp_coef_construction_1.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/mp_coef_construction_1.f index e9d4644131..5207dd2e72 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/mp_coef_construction_1.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/mp_coef_construction_1.f @@ -2,6 +2,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C USE ML5_0_POLYNOMIAL_CONSTANTS USE ALOHA_OBJECT + USE, INTRINSIC :: IEEE_EXCEPTIONS IMPLICIT NONE C C CONSTANTS @@ -35,6 +36,7 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) C C LOCAL VARIABLES C + LOGICAL WL_ENTRY_INEXACT INTEGER I,J,K INTEGER FLAVOR(NEXTERNAL) DATA FLAVOR /NEXTERNAL*1/ @@ -87,7 +89,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_VVV1L2P0_1(PL(0,0),W(5),GC_4,ZERO,ZERO,PL(0,1),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,1)) CALL MP_VVV1L2P0_1(PL(0,1),W(8),GC_4,ZERO,ZERO,PL(0,2),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,WL(1,0,1,2) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,2),2,4,1,2,1,86,H) C Coefficient construction for loop diagram with ID 5 CALL MP_FFV1L3_1(PL(0,0),W(3),GC_5,MDL_MT,MDL_WT,PL(0,3),COEFS) @@ -95,7 +99,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L2P0_3(PL(0,3),W(4),GC_5,ZERO,ZERO,PL(0,4),COEFS) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,3),4,COEFS,4,4,WL(1,0,1,4)) CALL MP_VVV1L2P0_1(PL(0,4),W(5),GC_4,ZERO,ZERO,PL(0,5),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,5) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,5),2,4,2,1,1,87,H) C Coefficient construction for loop diagram with ID 6 CALL MP_FFV1L1P0_3(PL(0,0),W(3),GC_5,ZERO,ZERO,PL(0,6),COEFS) @@ -103,13 +109,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_FFV1L3_2(PL(0,6),W(4),GC_5,MDL_MT,MDL_WT,PL(0,7),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,6),4,COEFS,4,4,WL(1,0,1,7)) CALL MP_FFV1L1_2(PL(0,7),W(5),GC_5,MDL_MT,MDL_WT,PL(0,8),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,7),4,COEFS,4,4,WL(1,0,1,8) + $ ,WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,8),2,4,3,1,1,88,H) C Coefficient construction for loop diagram with ID 7 CALL MP_FFV1L1P0_3(PL(0,0),W(6),GC_5,ZERO,ZERO,PL(0,9),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,9)) CALL MP_FFV1L3_2(PL(0,9),W(9),GC_5,MDL_MT,MDL_WT,PL(0,10),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1,10)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,9),4,COEFS,4,4,WL(1,0,1 + $ ,10),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,10),1,4,4,1,1,89,H) C Coefficient construction for loop diagram with ID 8 CALL MP_VVV1L2P0_1(PL(0,0),W(2),GC_4,ZERO,ZERO,PL(0,11),COEFS) @@ -118,8 +128,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,12) $ ) CALL MP_FFV1L1P0_3(PL(0,12),W(6),GC_5,ZERO,ZERO,PL(0,13),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1,13) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,12),4,COEFS,4,4,WL(1,0,1 + $ ,13),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,13),2,4,5,1,1,90,H) C Coefficient construction for loop diagram with ID 9 CALL MP_FFV1L2_1(PL(0,0),W(2),GC_5,MDL_MT,MDL_WT,PL(0,14),COEFS) @@ -128,23 +139,26 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,14),4,COEFS,4,4,WL(1,0,1,15) $ ) CALL MP_FFV1L3_1(PL(0,15),W(6),GC_5,MDL_MT,MDL_WT,PL(0,16),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1,16) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,15),4,COEFS,4,4,WL(1,0,1 + $ ,16),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,16),2,4,6,1,1,91,H) C Coefficient construction for loop diagram with ID 10 CALL MP_FFV1L1P0_3(PL(0,0),W(10),GC_5,ZERO,ZERO,PL(0,17),COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,17)) CALL MP_FFV1L3_2(PL(0,17),W(7),GC_5,MDL_MT,MDL_WT,PL(0,18),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1,18) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,17),4,COEFS,4,4,WL(1,0,1 + $ ,18),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,18),1,4,7,1,1,92,H) C Coefficient construction for loop diagram with ID 11 CALL MP_FFV1L3_1(PL(0,11),W(3),GC_5,MDL_MT,MDL_WT,PL(0,19),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,19) $ ) CALL MP_FFV1L2P0_3(PL(0,19),W(7),GC_5,ZERO,ZERO,PL(0,20),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,19),4,COEFS,4,4,WL(1,0,1,20) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,19),4,COEFS,4,4,WL(1,0,1 + $ ,20),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,20),2,4,8,1,1,93,H) C Coefficient construction for loop diagram with ID 12 CALL MP_FFV1L1_2(PL(0,0),W(2),GC_5,MDL_MT,MDL_WT,PL(0,21),COEFS) @@ -153,8 +167,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,21),4,COEFS,4,4,WL(1,0,1,22) $ ) CALL MP_FFV1L3_2(PL(0,22),W(7),GC_5,MDL_MT,MDL_WT,PL(0,23),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,22),4,COEFS,4,4,WL(1,0,1,23) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,22),4,COEFS,4,4,WL(1,0,1 + $ ,23),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,23),2,4,9,1,1,94,H) C Coefficient construction for loop diagram with ID 13 CALL MP_VVV1L2P0_1(PL(0,0),W(1),GC_4,ZERO,ZERO,PL(0,24),COEFS) @@ -163,16 +178,18 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,25) $ ) CALL MP_FFV1L1P0_3(PL(0,25),W(10),GC_5,ZERO,ZERO,PL(0,26),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,25),4,COEFS,4,4,WL(1,0,1,26) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,25),4,COEFS,4,4,WL(1,0,1 + $ ,26),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,26),2,4,10,1,1,95,H) C Coefficient construction for loop diagram with ID 14 CALL MP_FFV1L3_1(PL(0,24),W(3),GC_5,MDL_MT,MDL_WT,PL(0,27),COEFS) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,27) $ ) CALL MP_FFV1L2P0_3(PL(0,27),W(9),GC_5,ZERO,ZERO,PL(0,28),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,28) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_0(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1 + $ ,28),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,28),2,4,11,1,1,96,H) C Coefficient construction for loop diagram with ID 15 CALL MP_VVV1L2P0_1(PL(0,24),W(2),GC_4,ZERO,ZERO,PL(0,29),COEFS) @@ -182,45 +199,53 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,30) $ ) CALL MP_FFV1L1P0_3(PL(0,30),W(3),GC_5,ZERO,ZERO,PL(0,31),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,30),4,COEFS,4,4,WL(1,0,1,31) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,30),4,COEFS,4,4,WL(1,0,1 + $ ,31),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,31),3,4,12,1,1,97,H) C Coefficient construction for loop diagram with ID 16 CALL MP_FFV1L3_1(PL(0,29),W(3),GC_5,MDL_MT,MDL_WT,PL(0,32),COEFS) CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,32) $ ) CALL MP_FFV1L2P0_3(PL(0,32),W(4),GC_5,ZERO,ZERO,PL(0,33),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1,33) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,32),4,COEFS,4,4,WL(1,0,1 + $ ,33),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,33),3,4,13,1,1,98,H) C Coefficient construction for loop diagram with ID 17 CALL MP_VVV1L2P0_1(PL(0,29),W(8),GC_4,ZERO,ZERO,PL(0,34),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1,34) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,29),4,COEFS,4,4,WL(1,0,1 + $ ,34),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,34),3,4,14,1,1,99,H) C Coefficient construction for loop diagram with ID 18 CALL MP_VVVV1L2P0_1(PL(0,24),W(8),W(2),GC_6,ZERO,ZERO,PL(0,35) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,35) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1 + $ ,35),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,24),W(8),W(2),GC_6,ZERO,ZERO,PL(0,36) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,36) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1 + $ ,36),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,24),W(8),W(2),GC_6,ZERO,ZERO,PL(0,37) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1,37) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,24),4,COEFS,4,4,WL(1,0,1 + $ ,37),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,35),1,4,15,2,1,100,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,36),1,4,15,2,1,101,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,37),1,4,15,2,1,102,H) C Coefficient construction for loop diagram with ID 19 CALL MP_FFV1L2_1(PL(0,27),W(2),GC_5,MDL_MT,MDL_WT,PL(0,38),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,27),4,COEFS,4,4,WL(1,0,1,38) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,27),4,COEFS + $ ,4,4,WL(1,0,1,38),WL_ENTRY_INEXACT) CALL MP_FFV1L2P0_3(PL(0,38),W(4),GC_5,ZERO,ZERO,PL(0,39),COEFS) - CALL MP_ML5_0_UPDATE_WL_3_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1,39) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_3_0(WL(1,0,1,38),4,COEFS,4,4,WL(1,0,1 + $ ,39),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,39),3,4,16,1,1,103,H) C Coefficient construction for loop diagram with ID 20 CALL MP_FFV1L2_1(PL(0,0),W(1),GC_5,MDL_MT,MDL_WT,PL(0,40),COEFS) @@ -230,8 +255,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ) CALL MP_FFV1L3_1(PL(0,41),W(10),GC_5,MDL_MT,MDL_WT,PL(0,42) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,41),4,COEFS,4,4,WL(1,0,1,42) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,41),4,COEFS,4,4,WL(1,0,1 + $ ,42),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,42),2,4,17,1,1,104,H) C Coefficient construction for loop diagram with ID 21 CALL MP_FFV1L1_2(PL(0,0),W(1),GC_5,MDL_MT,MDL_WT,PL(0,43),COEFS) @@ -240,22 +266,26 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,43),4,COEFS,4,4,WL(1,0,1,44) $ ) CALL MP_FFV1L3_2(PL(0,44),W(9),GC_5,MDL_MT,MDL_WT,PL(0,45),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,45) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1 + $ ,45),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,45),2,4,18,1,1,105,H) C Coefficient construction for loop diagram with ID 22 CALL MP_VVVV1L2P0_1(PL(0,11),W(8),W(1),GC_6,ZERO,ZERO,PL(0,46) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,46) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,46),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,11),W(8),W(1),GC_6,ZERO,ZERO,PL(0,47) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,47) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,47),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,11),W(8),W(1),GC_6,ZERO,ZERO,PL(0,48) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1,48) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,11),4,COEFS,4,4,WL(1,0,1 + $ ,48),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,46),1,4,19,2,1,106,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,47),1,4,19,2,1,107,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,48),1,4,19,2,1,108,H) @@ -264,8 +294,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,44),4,COEFS,4,4,WL(1,0,1,49) $ ) CALL MP_FFV1L3_2(PL(0,49),W(4),GC_5,MDL_MT,MDL_WT,PL(0,50),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,49),4,COEFS,4,4,WL(1,0,1,50) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,49),4,COEFS,4,4,WL(1,0,1 + $ ,50),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,50),3,4,20,1,1,109,H) C Coefficient construction for loop diagram with ID 24 CALL MP_FFV1L2_1(PL(0,40),W(2),GC_5,MDL_MT,MDL_WT,PL(0,51),COEFS) @@ -275,8 +306,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,51),4,COEFS,4,4,WL(1,0,1,52) $ ) CALL MP_FFV1L3_1(PL(0,52),W(3),GC_5,MDL_MT,MDL_WT,PL(0,53),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,52),4,COEFS,4,4,WL(1,0,1,53) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,52),4,COEFS,4,4,WL(1,0,1 + $ ,53),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,53),3,4,21,1,1,110,H) C Coefficient construction for loop diagram with ID 25 CALL MP_FFV1L1_2(PL(0,43),W(2),GC_5,MDL_MT,MDL_WT,PL(0,54),COEFS) @@ -286,8 +318,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_2_0(WL(1,0,1,54),4,COEFS,4,4,WL(1,0,1,55) $ ) CALL MP_FFV1L3_2(PL(0,55),W(4),GC_5,MDL_MT,MDL_WT,PL(0,56),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,55),4,COEFS,4,4,WL(1,0,1,56) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,55),4,COEFS,4,4,WL(1,0,1 + $ ,56),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,56),3,4,22,1,1,111,H) C Coefficient construction for loop diagram with ID 26 CALL MP_VVVV1L2P0_1(PL(0,0),W(2),W(1),GC_6,ZERO,ZERO,PL(0,57) @@ -300,27 +333,36 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) $ ,COEFS) CALL MP_ML5_0_UPDATE_WL_0_0(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,59)) CALL MP_VVV1L2P0_1(PL(0,57),W(8),GC_4,ZERO,ZERO,PL(0,60),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,57),4,COEFS,4,4,WL(1,0,1,60) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,57),4,COEFS,4,4,WL(1,0,1 + $ ,60),WL_ENTRY_INEXACT) CALL MP_VVV1L2P0_1(PL(0,58),W(8),GC_4,ZERO,ZERO,PL(0,61),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,58),4,COEFS,4,4,WL(1,0,1,61) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,58),4,COEFS,4,4,WL(1,0,1 + $ ,61),WL_ENTRY_INEXACT) CALL MP_VVV1L2P0_1(PL(0,59),W(8),GC_4,ZERO,ZERO,PL(0,62),COEFS) - CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,59),4,COEFS,4,4,WL(1,0,1,62) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_0_1(WL(1,0,1,59),4,COEFS,4,4,WL(1,0,1 + $ ,62),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,60),1,4,23,2,1,112,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,61),1,4,23,2,1,113,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,62),1,4,23,2,1,114,H) C Coefficient construction for loop diagram with ID 27 CALL MP_VVVV1L2P0_1(PL(0,4),W(2),W(1),GC_6,ZERO,ZERO,PL(0,63) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,63)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1 + $ ,63),WL_ENTRY_INEXACT) CALL MP_VVVV3L2P0_1(PL(0,4),W(2),W(1),GC_6,ZERO,ZERO,PL(0,64) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,64)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1 + $ ,64),WL_ENTRY_INEXACT) CALL MP_VVVV4L2P0_1(PL(0,4),W(2),W(1),GC_6,ZERO,ZERO,PL(0,65) $ ,COEFS) - CALL MP_ML5_0_UPDATE_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1,65)) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_0(WL(1,0,1,4),4,COEFS,4,4,WL(1,0,1 + $ ,65),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,63),1,4,24,1,1,115,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,64),1,4,24,1,1,116,H) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,65),1,4,24,1,1,117,H) @@ -328,8 +370,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_GHGHGL2_1(PL(0,0),W(5),GC_4,ZERO,ZERO,PL(0,66),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),1,COEFS,1,1,WL(1,0,1,66)) CALL MP_GHGHGL2_1(PL(0,66),W(8),GC_4,ZERO,ZERO,PL(0,67),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,66),1,COEFS,1,1,WL(1,0,1,67) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,66),1,COEFS,1,1,WL(1,0,1 + $ ,67),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,67),2,1,1,1,1,118,H) C Coefficient construction for loop diagram with ID 29 CALL MP_GHGHGL1_2(PL(0,0),W(1),GC_4,ZERO,ZERO,PL(0,68),COEFS) @@ -338,8 +381,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,68),1,COEFS,1,1,WL(1,0,1,69) $ ) CALL MP_GHGHGL1_2(PL(0,69),W(8),GC_4,ZERO,ZERO,PL(0,70),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,69),1,COEFS,1,1,WL(1,0,1,70) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,69),1,COEFS,1,1,WL(1,0,1 + $ ,70),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,70),3,1,14,1,1,119,H) C Coefficient construction for loop diagram with ID 30 CALL MP_GHGHGL2_1(PL(0,0),W(1),GC_4,ZERO,ZERO,PL(0,71),COEFS) @@ -348,15 +392,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,71),1,COEFS,1,1,WL(1,0,1,72) $ ) CALL MP_GHGHGL2_1(PL(0,72),W(8),GC_4,ZERO,ZERO,PL(0,73),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,72),1,COEFS,1,1,WL(1,0,1,73) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1(WL(1,0,1,72),1,COEFS,1,1,WL(1,0,1 + $ ,73),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,73),3,1,14,1,1,120,H) C Coefficient construction for loop diagram with ID 31 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,ZERO,ZERO,PL(0,74),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,74)) CALL MP_FFV1L2_1(PL(0,74),W(8),GC_5,ZERO,ZERO,PL(0,75),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,74),4,COEFS,4,4,WL(1,0,1,75) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,74),4,COEFS,4,4,WL(1,0,1 + $ ,75),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,75),2,4,1,1,4,121,H) C Coefficient construction for loop diagram with ID 32 CALL MP_FFV1L1_2(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,76),COEFS) @@ -365,8 +411,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,76),4,COEFS,4,4,WL(1,0,1,77) $ ) CALL MP_FFV1L1_2(PL(0,77),W(8),GC_5,ZERO,ZERO,PL(0,78),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,77),4,COEFS,4,4,WL(1,0,1,78) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,77),4 + $ ,COEFS,4,4,WL(1,0,1,78),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,78),3,4,14,1,4,122,H) C Coefficient construction for loop diagram with ID 33 CALL MP_FFV1L2_1(PL(0,0),W(1),GC_5,ZERO,ZERO,PL(0,79),COEFS) @@ -375,15 +422,17 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,79),4,COEFS,4,4,WL(1,0,1,80) $ ) CALL MP_FFV1L2_1(PL(0,80),W(8),GC_5,ZERO,ZERO,PL(0,81),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,80),4,COEFS,4,4,WL(1,0,1,81) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,80),4 + $ ,COEFS,4,4,WL(1,0,1,81),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,81),3,4,14,1,4,123,H) C Coefficient construction for loop diagram with ID 34 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,MDL_MB,ZERO,PL(0,82),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,82)) CALL MP_FFV1L2_1(PL(0,82),W(8),GC_5,MDL_MB,ZERO,PL(0,83),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,82),4,COEFS,4,4,WL(1,0,1,83) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,82),4,COEFS,4,4,WL(1,0,1 + $ ,83),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,83),2,4,25,1,1,124,H) C Coefficient construction for loop diagram with ID 35 CALL MP_FFV1L1_2(PL(0,0),W(1),GC_5,MDL_MB,ZERO,PL(0,84),COEFS) @@ -392,8 +441,9 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,84),4,COEFS,4,4,WL(1,0,1,85) $ ) CALL MP_FFV1L1_2(PL(0,85),W(8),GC_5,MDL_MB,ZERO,PL(0,86),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,85),4,COEFS,4,4,WL(1,0,1,86) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,85),4 + $ ,COEFS,4,4,WL(1,0,1,86),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,86),3,4,26,1,1,125,H) C Coefficient construction for loop diagram with ID 36 CALL MP_FFV1L2_1(PL(0,0),W(1),GC_5,MDL_MB,ZERO,PL(0,87),COEFS) @@ -402,25 +452,29 @@ SUBROUTINE ML5_0_MP_COEF_CONSTRUCTION_1(P,NHEL,H,IC) CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,87),4,COEFS,4,4,WL(1,0,1,88) $ ) CALL MP_FFV1L2_1(PL(0,88),W(8),GC_5,MDL_MB,ZERO,PL(0,89),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,88),4,COEFS,4,4,WL(1,0,1,89) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,88),4 + $ ,COEFS,4,4,WL(1,0,1,89),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,89),3,4,26,1,1,126,H) C Coefficient construction for loop diagram with ID 37 CALL MP_FFV1L2_1(PL(0,0),W(5),GC_5,MDL_MT,MDL_WT,PL(0,90),COEFS) CALL MP_ML5_0_UPDATE_WL_0_1(WL(1,0,1,0),4,COEFS,4,4,WL(1,0,1,90)) CALL MP_FFV1L2_1(PL(0,90),W(8),GC_5,MDL_MT,MDL_WT,PL(0,91),COEFS) - CALL MP_ML5_0_UPDATE_WL_1_1(WL(1,0,1,90),4,COEFS,4,4,WL(1,0,1,91) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_1_1(WL(1,0,1,90),4,COEFS,4,4,WL(1,0,1 + $ ,91),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,91),2,4,27,1,1,127,H) C Coefficient construction for loop diagram with ID 38 CALL MP_FFV1L1_2(PL(0,54),W(8),GC_5,MDL_MT,MDL_WT,PL(0,92),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,54),4,COEFS,4,4,WL(1,0,1,92) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(WL(1,0,1,54),4 + $ ,COEFS,4,4,WL(1,0,1,92),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,92),3,4,28,1,1,128,H) C Coefficient construction for loop diagram with ID 39 CALL MP_FFV1L2_1(PL(0,51),W(8),GC_5,MDL_MT,MDL_WT,PL(0,93),COEFS) - CALL MP_ML5_0_UPDATE_WL_2_1(WL(1,0,1,51),4,COEFS,4,4,WL(1,0,1,93) - $ ) + CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT) + CALL MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(WL(1,0,1,51),4 + $ ,COEFS,4,4,WL(1,0,1,93),WL_ENTRY_INEXACT) CALL MP_ML5_0_CREATE_LOOP_COEFS(WL(1,0,1,93),3,4,28,1,1,129,H) GOTO 1001 diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/mp_compute_loop_coefs.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/mp_compute_loop_coefs.f index bea682a5cc..6e4a381bdd 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/mp_compute_loop_coefs.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/mp_compute_loop_coefs.f @@ -173,7 +173,8 @@ SUBROUTINE ML5_0_MP_COMPUTE_LOOP_COEFS(PS,ANSDP) C computation in the quadruple precision variables. COMPUTE_INTEGRAND_IN_QP = ((MLREDUCTIONLIB(LIBINDEX) $ .EQ.6.AND.USEQPINTEGRANDFORNINJA) .OR. (MLREDUCTIONLIB(LIBINDEX) - $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS)) + $ .EQ.1.AND.USEQPINTEGRANDFORCUTTOOLS) .OR. + $ (MLREDUCTIONLIB(LIBINDEX).EQ.8.AND.USEQPINTEGRANDFORNINJARS)) C To be on the safe side, we always update the MP params here. C It can be redundant as this routine can be called a couple of diff --git a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/polynomial.f b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/polynomial.f index 60fc3c9977..78e5e9138a 100644 --- a/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/polynomial.f +++ b/tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/polynomial.f @@ -379,11 +379,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -397,18 +399,94 @@ SUBROUTINE ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) @@ -429,11 +507,13 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -457,18 +537,104 @@ SUBROUTINE ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_1_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) @@ -499,11 +665,13 @@ SUBROUTINE ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -517,18 +685,94 @@ SUBROUTINE ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:4 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,4 + DO K=0,4 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_1_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -549,11 +793,13 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -563,18 +809,90 @@ SUBROUTINE ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_0_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE,0:0 + $ ,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,0 + DO K=0,0 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_0_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,0 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) ENDDO ENDDO @@ -591,11 +909,13 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=(0.0D0,0.0D0) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -619,18 +939,105 @@ SUBROUTINE ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC INTEGER I,J,K COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,14 + DO K=0,14 + DO J=1,OUT_SIZE OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) ENDDO - DO K=1,IN_SIZE + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) @@ -670,9 +1077,9 @@ SUBROUTINE ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE DO K=1,IN_SIZE UPDATER_COEF = B(J,M,K) IF (UPDATER_COEF.EQ.(0.0D0,0.0D0)) CYCLE - DO L=0,14 - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION = COMB_COEF_POS(L,M) OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) $ *UPDATER_COEF ENDDO @@ -686,25 +1093,62 @@ SUBROUTINE ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE SUBROUTINE MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE $ ,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC IMPLICIT NONE INTEGER I,J,K,L,M COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L INTEGER NEW_POSITION COMPLEX*32 UPDATER_COEF C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) DO J=1,OUT_SIZE DO M=0,4 DO K=1,IN_SIZE UPDATER_COEF = B(J,M,K) IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE - DO L=0,14 - NEW_POSITION = COMB_COEF_POS(L,M) - DO I=1,LCUT_SIZE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) $ *UPDATER_COEF ENDDO @@ -713,79 +1157,2363 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + END - SUBROUTINE ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) USE ML5_0_POLYNOMIAL_CONSTANTS - INTEGER I,J,K - COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) - COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF - DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 - OUT(J,K,I)=(0.0D0,0.0D0) - ENDDO +C Welcome to the computational heart of MadLoop... + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 DO K=1,IN_SIZE - OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) - OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) - OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) - OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) - OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) - OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) - OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) - OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) - OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) - OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) - OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) - OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) - OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) - OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) - OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) - OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) - OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) - OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) - OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) - OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) - OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) - OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) - OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) - OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) - OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) - OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) - OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) - OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) - OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) - OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) - OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) - OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) - OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) - OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) - OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO ENDDO ENDDO ENDDO + END - SUBROUTINE MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE - $ ,OUT) + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L1_2(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) USE ML5_0_POLYNOMIAL_CONSTANTS - INTEGER I,J,K + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF - DO I=1,LCUT_SIZE - DO J=1,OUT_SIZE - DO K=0,34 - OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) - ENDDO - DO K=1,IN_SIZE - OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_2_1_FACTOR_FFV1L2_1(A,LCUT_SIZE,B + $ ,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + LOGICAL WL_ENTRY_INEXACT + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=1,LCUT_SIZE + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*16 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*16 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=(0.0D0,0.0D0) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + IF(.NOT.WL_NEAREST.OR..NOT.ALL(WL_IS_FINITE(REAL(A(1:IN_SIZE + $ ,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_IS_FINITE(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_IS_FINITE(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_IS_FINITE(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:34,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:34,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_UPDATE_WL_3_0_DENSE(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT) + USE ML5_0_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + OUT(J,15,I)=OUT(J,15,I)+A(K,15,I)*B(J,0,K) + OUT(J,16,I)=OUT(J,16,I)+A(K,16,I)*B(J,0,K) + OUT(J,17,I)=OUT(J,17,I)+A(K,17,I)*B(J,0,K) + OUT(J,18,I)=OUT(J,18,I)+A(K,18,I)*B(J,0,K) + OUT(J,19,I)=OUT(J,19,I)+A(K,19,I)*B(J,0,K) + OUT(J,20,I)=OUT(J,20,I)+A(K,20,I)*B(J,0,K) + OUT(J,21,I)=OUT(J,21,I)+A(K,21,I)*B(J,0,K) + OUT(J,22,I)=OUT(J,22,I)+A(K,22,I)*B(J,0,K) + OUT(J,23,I)=OUT(J,23,I)+A(K,23,I)*B(J,0,K) + OUT(J,24,I)=OUT(J,24,I)+A(K,24,I)*B(J,0,K) + OUT(J,25,I)=OUT(J,25,I)+A(K,25,I)*B(J,0,K) + OUT(J,26,I)=OUT(J,26,I)+A(K,26,I)*B(J,0,K) + OUT(J,27,I)=OUT(J,27,I)+A(K,27,I)*B(J,0,K) + OUT(J,28,I)=OUT(J,28,I)+A(K,28,I)*B(J,0,K) + OUT(J,29,I)=OUT(J,29,I)+A(K,29,I)*B(J,0,K) + OUT(J,30,I)=OUT(J,30,I)+A(K,30,I)*B(J,0,K) + OUT(J,31,I)=OUT(J,31,I)+A(K,31,I)*B(J,0,K) + OUT(J,32,I)=OUT(J,32,I)+A(K,32,I)*B(J,0,K) + OUT(J,33,I)=OUT(J,33,I)+A(K,33,I)*B(J,0,K) + OUT(J,34,I)=OUT(J,34,I)+A(K,34,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_0_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.1.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:0,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:0,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_0_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:0,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:0,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_1_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.1.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,4 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_1_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.5.GT.65536.OR.5.GT.65536.OR..NOT. + $ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:4,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:4,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:4,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:4,1:LCUT_SIZE))))) THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:4,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:4,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:4,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:14,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:14,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,5,I)*B(J,0,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,6,I)*B(J,0,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,7,I)*B(J,0,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,8,I)*B(J,0,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,9,I)*B(J,0,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,10,I)*B(J,0,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,11,I)*B(J,0,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,12,I)*B(J,0,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,13,I)*B(J,0,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,14,I)*B(J,0,K) + ENDDO + ENDDO + ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L1_2(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.(-B(1,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(1,L,I)) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_2_1_FACTOR_FFV1L2_1(A,LCUT_SIZE + $ ,B,IN_SIZE,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + IMPLICIT NONE + INTEGER I,J,K,L,M,R,HALT_INDEX + COMPLEX*32 U(4,0:14,MAXLWFSIZE) + LOGICAL, PARAMETER :: NEEDED(4,4)=RESHAPE((/.TRUE.,.TRUE. + $ ,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.FALSE.,.FALSE. + $ ,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE./),(/4,4/)) + LOGICAL HALT_FLAGS(SIZE(IEEE_ALL)) + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP_ZERO + LOGICAL WL_AZERO(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER WL_I,WL_K,WL_L + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Experimental derivative-row factorization; changed rounding + IF(.NOT.WL_ENTRY_INEXACT.OR.IN_SIZE.NE.4.OR.OUT_SIZE.NE.4.OR.MAXL + $WFSIZE.NE.4.OR.LCUT_SIZE.LT.0.OR.LCUT_SIZE.GT.4) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + DO HALT_INDEX=1,SIZE(IEEE_ALL) + IF(.NOT.IEEE_SUPPORT_HALTING(IEEE_ALL(HALT_INDEX))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + CALL IEEE_GET_HALTING_MODE(IEEE_ALL,HALT_FLAGS) + IF(ANY(HALT_FLAGS)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + IF(.NOT.ALL(GATHER_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE) + $ ,KIND=16))).OR..NOT.ALL(GATHER_BOUNDED(AIMAG(A(1:IN_SIZE,0:14 + $ ,1:LCUT_SIZE)))).OR..NOT.ALL(GATHER_BOUNDED(REAL(B(1:OUT_SIZE + $ ,0:4,1:IN_SIZE),KIND=16))) + $ .OR..NOT.ALL(GATHER_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4,1:IN_SIZE)))) + $ ) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.15.GT.65536.OR.5.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:14,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:14,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:4,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:4 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_AZERO(1:IN_SIZE,0:14,1:LCUT_SIZE)=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + DO WL_I=1,LCUT_SIZE + DO WL_L=0,14 + IF(WL_IS_FINITE(REAL(A(WL_K,WL_L,WL_I),KIND=16)) + $ .AND.WL_IS_FINITE(AIMAG(A(WL_K,WL_L,WL_I)))) + $ WL_AZERO(WL_K,WL_L,WL_I)=A(WL_K,WL_L,WL_I).EQ.0 + ENDDO + ENDDO + ENDDO + ENDIF + + DO K=1,4 + IF(B(1,1,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,1,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,1,K).NE.B(3,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,1,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,2,K).NE.B(2,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,2,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,2,K).NE.(-B(4,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,2,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,3,K).NE.CMPLX(-AIMAG(B(2,1,K)),REAL(B(2,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,3,K).NE.CMPLX(AIMAG(B(1,1,K)),-REAL(B(1,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,3,K).NE.CMPLX(AIMAG(B(4,1,K)),-REAL(B(4,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,3,K).NE.CMPLX(-AIMAG(B(3,1,K)),REAL(B(3,1,K),KIND=16) + $ ,KIND=16)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(1,4,K).NE.B(1,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(2,4,K).NE.(-B(2,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(3,4,K).NE.(-B(3,1,K))) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO + DO K=1,4 + IF(B(4,4,K).NE.B(4,1,K)) THEN + CALL MP_ML5_0_TERMINAL_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT,WL_ENTRY_INEXACT) + RETURN + ENDIF + ENDDO +C FACTOR_FAST_PATH + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + M=0 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + WL_SKIP_ZERO=.FALSE. + IF(WL_NEAREST) WL_SKIP_ZERO=WL_IS_FINITE(REAL(UPDATER_COEF + $ ,KIND=16)).AND.WL_IS_FINITE(AIMAG(UPDATER_COEF)) + DO I=J,MIN(J,LCUT_SIZE) + DO L=0,14 + IF(WL_SKIP_ZERO) THEN + IF(WL_AZERO(K,L,I)) CYCLE + ENDIF + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + U=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO I=1,LCUT_SIZE + DO R=1,4 + IF(.NOT.NEEDED(R,I)) CYCLE + DO K=1,IN_SIZE + UPDATER_COEF=B(R,1,K) + IF(UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO L=0,14 + IF(WL_AZERO(K,L,I)) CYCLE + U(R,L,I)=U(R,L,I)+A(K,L,I)*UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+CMPLX(-AIMAG(U(2 + $ ,L,I)),REAL(U(2,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=1,MIN(1,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(1,NEW_POSITION,I)=OUT(1,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(2,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+U(1,L,I) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+CMPLX(AIMAG(U(1 + $ ,L,I)),-REAL(U(1,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=2,MIN(2,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(2,NEW_POSITION,I)=OUT(2,NEW_POSITION,I)+(-U(2,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+U(3,L,I) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(4,L,I)) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+CMPLX(AIMAG(U(4 + $ ,L,I)),-REAL(U(4,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=3,MIN(3,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(3,NEW_POSITION,I)=OUT(3,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,1) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,2) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+(-U(3,L,I)) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,3) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+CMPLX(-AIMAG(U(3 + $ ,L,I)),REAL(U(3,L,I),KIND=16),KIND=16) + ENDDO + ENDDO + DO I=4,MIN(4,LCUT_SIZE) + DO L=0,14 + NEW_POSITION=COMB_COEF_POS(L,4) + OUT(4,NEW_POSITION,I)=OUT(4,NEW_POSITION,I)+U(4,L,I) + ENDDO + ENDDO + + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + + ELEMENTAL LOGICAL FUNCTION GATHER_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE(1).NE.0_8) + GATHER_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE(HI).NE.ISHFT(16383_8,48).OR.ONE(3-HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE)) + GATHER_BOUNDED=IBITS(WORDS(HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(HI),48,15).LE.17383_8 + IF(IBCLR(WORDS(HI),63).EQ.0_8.AND.WORDS(3-HI).EQ.0_8) + $ GATHER_BOUNDED=.TRUE. + END ASSOCIATE + END FUNCTION + + END + + SUBROUTINE MP_ML5_0_TERMINAL_WL_3_0(A,LCUT_SIZE,B,IN_SIZE + $ ,OUT_SIZE,OUT,WL_ENTRY_INEXACT) + USE ML5_0_POLYNOMIAL_CONSTANTS + USE, INTRINSIC :: IEEE_ARITHMETIC + USE, INTRINSIC :: IEEE_EXCEPTIONS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + TYPE(IEEE_ROUND_TYPE) WL_ROUNDING + LOGICAL WL_NEAREST + LOGICAL WL_SKIP(MAXLWFSIZE,MAXLWFSIZE) + INTEGER WL_J,WL_K + LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT + + CALL IEEE_GET_ROUNDING_MODE(WL_ROUNDING) + WL_NEAREST=WL_ROUNDING.EQ.IEEE_NEAREST + WL_ALREADY=WL_ENTRY_INEXACT + WL_HALT=.TRUE. + IF(IEEE_SUPPORT_HALTING(IEEE_INEXACT)) CALL + $ IEEE_GET_HALTING_MODE(IEEE_INEXACT,WL_HALT) + IF(.NOT.WL_NEAREST.OR..NOT.WL_ALREADY.OR.WL_HALT.OR.LCUT_SIZE.GT. + $OUT_SIZE.OR.MAXLWFSIZE.GT.16.OR.35.GT.65536.OR.1.GT.65536.OR..NOT + $.ALL(WL_BOUNDED(REAL(A(1:IN_SIZE,0:34,1:LCUT_SIZE),KIND=16))) + $ .OR..NOT.ALL(WL_BOUNDED(AIMAG(A(1:IN_SIZE,0:34,1:LCUT_SIZE)))) + $ .OR..NOT.ALL(WL_BOUNDED(REAL(B(1:OUT_SIZE,0:0,1:IN_SIZE) + $ ,KIND=16))).OR..NOT.ALL(WL_BOUNDED(AIMAG(B(1:OUT_SIZE,0:0 + $ ,1:IN_SIZE))))) THEN + CALL MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE,OUT) + RETURN + ENDIF + WL_SKIP=.FALSE. + IF(WL_NEAREST) THEN + DO WL_K=1,IN_SIZE + IF(ALL(WL_IS_FINITE(REAL(A(WL_K,0:34,1:LCUT_SIZE),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(A(WL_K,0:34,1:LCUT_SIZE))))) + $ THEN + DO WL_J=1,OUT_SIZE + IF(ALL(WL_IS_FINITE(REAL(B(WL_J,0:0,WL_K),KIND=16))) + $ .AND.ALL(WL_IS_FINITE(AIMAG(B(WL_J,0:0,WL_K))))) + $ WL_SKIP(WL_J,WL_K)=ALL(B(WL_J,0:0,WL_K).EQ.0) + ENDDO + ENDIF + ENDDO + ENDIF + + DO I=1,LCUT_SIZE + DO K=0,34 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=I,I + IF(WL_SKIP(J,K)) CYCLE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) OUT(J,1,I)=OUT(J,1,I)+A(K,1,I)*B(J,0,K) OUT(J,2,I)=OUT(J,2,I)+A(K,2,I)*B(J,0,K) OUT(J,3,I)=OUT(J,3,I)+A(K,3,I)*B(J,0,K) @@ -823,4 +3551,38 @@ SUBROUTINE MP_ML5_0_UPDATE_WL_3_0(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE ENDDO ENDDO ENDDO + CONTAINS + ELEMENTAL LOGICAL FUNCTION WL_IS_FINITE(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: ONE_WORDS(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: HI=MERGE(1,2,ONE_WORDS(1).NE.0_8) + WL_IS_FINITE=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(ONE_WORDS(HI).NE.ISHFT(16383_8,48).OR.ONE_WORDS(3-HI).NE.0_8) + $ RETURN + ASSOCIATE(WORDS=>TRANSFER(X,ONE_WORDS)) + WL_IS_FINITE=IBITS(WORDS(HI),48,15).NE.32767_8 + END ASSOCIATE + END FUNCTION + ELEMENTAL LOGICAL FUNCTION WL_BOUNDED(X) + REAL*16, INTENT(IN) :: X + INTEGER*8, PARAMETER :: BOUND_ONE(2)=TRANSFER(1.0_16,(/0_8,0_8/)) + INTEGER, PARAMETER :: BOUND_HI=MERGE(1,2,BOUND_ONE(1).NE.0_8) + WL_BOUNDED=.FALSE. + IF(STORAGE_SIZE(X).NE.128.OR.DIGITS(X).NE.113.OR.RADIX(X) + $ .NE.2.OR.MAXEXPONENT(X).NE.16384) RETURN + IF(BOUND_ONE(BOUND_HI).NE.ISHFT(16383_8,48).OR.BOUND_ONE(3 + $ -BOUND_HI).NE.0_8) RETURN + ASSOCIATE(WORDS=>TRANSFER(X,BOUND_ONE)) + IF(IBCLR(WORDS(BOUND_HI),63).EQ.0_8.AND.WORDS(3-BOUND_HI).EQ.0_8) + $ THEN + WL_BOUNDED=.TRUE. + ELSE + WL_BOUNDED=IBITS(WORDS(BOUND_HI),48,15) + $ .GE.15383_8.AND.IBITS(WORDS(BOUND_HI),48,15).LE.17383_8 + ENDIF + END ASSOCIATE + END FUNCTION + END diff --git a/tests/input_files/ninjars_profile_timing_legacy.py b/tests/input_files/ninjars_profile_timing_legacy.py new file mode 100644 index 0000000000..d8a401773b --- /dev/null +++ b/tests/input_files/ninjars_profile_timing_legacy.py @@ -0,0 +1,187 @@ +"""Pre-metadata timer method fixture for mocked call/float regression checks. + +Exact method source from the audited pre-metadata v2 timing implementation. +Only definitions are compiled by the unit tests; no compiler/physics is invoked. +""" +class LoopMatrixElementTimer: + def skip_loop_evaluation_setup(self, dir_name, skip=True): + """ Edit loop_matrix.f in order to skip the loop evaluation phase. + Notice this only affects the double precision evaluation which is + normally fine as we do not make the timing check on mp.""" + + file = open(pjoin(dir_name,'loop_matrix.f'), 'r') + loop_matrix = file.read() + file.close() + + file = open(pjoin(dir_name,'loop_matrix.f'), 'w') + loop_matrix = re.sub(r"SKIPLOOPEVAL=\S+\)","SKIPLOOPEVAL=%s)"%('.TRUE.' + if skip else '.FALSE.'), loop_matrix) + file.write(loop_matrix) + file.close() + + def boot_time_setup(self, dir_name, bootandstop=True): + """ Edit loop_matrix.f in order to set the flag which stops the + execution after booting the program (i.e. reading the color data).""" + + file = open(pjoin(dir_name,'loop_matrix.f'), 'r') + loop_matrix = file.read() + file.close() + + file = open(pjoin(dir_name,'loop_matrix.f'), 'w') + loop_matrix = re.sub(r"BOOTANDSTOP=\S+\)","BOOTANDSTOP=%s)"%('.TRUE.' + if bootandstop else '.FALSE.'), loop_matrix) + file.write(loop_matrix) + file.close() + + def time_matrix_element(self, matrix_element, reusing = False, + param_card = None, keep_folder = False, options=None, + MLOptions = {}): + """ Output the matrix_element in argument and give detail information + about the timing for its output and running""" + + # If True, then force three PS points only and skip the test on + # unpolarized PS point + make_it_quick=False + + if options and 'split_orders' in list(options.keys()): + split_orders = options['split_orders'] + else: + split_orders = -1 + + assert ((not reusing and isinstance(matrix_element, \ + helas_objects.HelasMatrixElement)) or (reusing and + isinstance(matrix_element, base_objects.Process))) + if not reusing: + proc_name = matrix_element['processes'][0].shell_string()[2:] + else: + proc_name = matrix_element.shell_string()[2:] + + export_dir=pjoin(self.output_path,('SAVED' if keep_folder else '')+\ + temp_dir_prefix+"_%s"%proc_name) + + res_timings = self.setup_process(matrix_element,export_dir, \ + reusing, param_card,MLOptions = MLOptions,clean=True) + + if res_timings == None: + return None + dir_name=res_timings['dir_path'] + + def check_disk_usage(path): + return subprocess.check_output( + [f"du -shc {path}"], shell=True, encoding="utf8" + ).split()[-2] + + res_timings['du_source']=check_disk_usage(pjoin(\ + export_dir,'Source','*','*.f')) + res_timings['du_process']=check_disk_usage(pjoin(dir_name,'*.f')) + res_timings['du_color']=check_disk_usage(pjoin(dir_name, + 'MadLoop5_resources','*.dat')) + res_timings['du_exe']=check_disk_usage(pjoin(dir_name,'check')) + + if not res_timings['Initialization']==None: + time_per_ps_estimate = (res_timings['Initialization']/4.0)/2.0 + elif make_it_quick: + time_per_ps_estimate = -1.0 + else: + # We cannot estimate from the initialization, so we run just a 3 + # PS point run to evaluate it. + MadLoopInitializer.fix_PSPoint_in_check(pjoin(export_dir,'SubProcesses'), + read_ps = False, npoints = 3, hel_config = -1, + split_orders=split_orders) + compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + time_per_ps_estimate = run_time/3.0 + + self.boot_time_setup(dir_name,bootandstop=True) + compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + res_timings['Booting_time'] = run_time + self.boot_time_setup(dir_name,bootandstop=False) + + # Detect one contributing helicity + contributing_hel=0 + n_contrib_hel=0 + proc_prefix_file = open(pjoin(dir_name,'proc_prefix.txt'),'r') + proc_prefix = proc_prefix_file.read() + proc_prefix_file.close() + helicities = open(pjoin(dir_name,'MadLoop5_resources', + '%sHelFilter.dat'%proc_prefix)).read().split() + for i, hel in enumerate(helicities): + if (self.loop_optimized_output and int(hel)>-10000) or hel=='T': + if contributing_hel==0: + contributing_hel=i+1 + n_contrib_hel += 1 + + if contributing_hel==0: + logger.error("Could not find a contributing helicity "+\ + "configuration for process %s."%proc_name) + return None + + res_timings['n_contrib_hel']=n_contrib_hel + res_timings['n_tot_hel']=len(helicities) + + # We aim at a 30 sec run + if not make_it_quick: + target_pspoints_number = max(int(30.0/time_per_ps_estimate)+1,50) + else: + target_pspoints_number = 10 + + logger.info("Checking timing for process %s "%proc_name+\ + "with %d PS points."%target_pspoints_number) + + MadLoopInitializer.fix_PSPoint_in_check(pjoin(export_dir,'SubProcesses'), + read_ps = False, npoints = target_pspoints_number*2, \ + hel_config = contributing_hel, split_orders=split_orders) + compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + + if compile_time == None: return None + + res_timings['run_polarized_total']=\ + (run_time-res_timings['Booting_time'])/(target_pspoints_number*2) + + if make_it_quick: + res_timings['run_unpolarized_total'] = 1.0 + res_timings['ram_usage'] = 0.0 + else: + MadLoopInitializer.fix_PSPoint_in_check(pjoin(export_dir,'SubProcesses'), + read_ps = False, npoints = target_pspoints_number, hel_config = -1, + split_orders=split_orders) + compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name, + checkRam=True) + + if compile_time == None: return None + res_timings['run_unpolarized_total']=\ + (run_time-res_timings['Booting_time'])/target_pspoints_number + res_timings['ram_usage'] = ram_usage + + if not self.loop_optimized_output: + return res_timings + + # For the loop optimized output, we also check the time spent in + # computing the coefficients of the loop numerator polynomials. + + # So we modify loop_matrix.f in order to skip the loop evaluation phase. + self.skip_loop_evaluation_setup(dir_name,skip=True) + + if make_it_quick: + res_timings['run_unpolarized_coefs'] = 1.0 + else: + MadLoopInitializer.fix_PSPoint_in_check(pjoin(export_dir,'SubProcesses'), + read_ps = False, npoints = target_pspoints_number, hel_config = -1, + split_orders=split_orders) + compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + if compile_time == None: return None + res_timings['run_unpolarized_coefs']=\ + (run_time-res_timings['Booting_time'])/target_pspoints_number + + MadLoopInitializer.fix_PSPoint_in_check(pjoin(export_dir,'SubProcesses'), + read_ps = False, npoints = target_pspoints_number*2, \ + hel_config = contributing_hel, split_orders=split_orders) + compile_time, run_time, ram_usage = MadLoopInitializer.make_and_run(dir_name) + if compile_time == None: return None + res_timings['run_polarized_coefs']=\ + (run_time-res_timings['Booting_time'])/(target_pspoints_number*2) + + # Restitute the original file. + self.skip_loop_evaluation_setup(dir_name,skip=False) + + return res_timings + diff --git a/tests/unit_tests/interface/test_madevent_loop_warnings.py b/tests/unit_tests/interface/test_madevent_loop_warnings.py new file mode 100644 index 0000000000..1e52dc04e0 --- /dev/null +++ b/tests/unit_tests/interface/test_madevent_loop_warnings.py @@ -0,0 +1,62 @@ +"""Explicit MadLoop card choices must trigger the loop-induced diagnostics.""" +from pathlib import Path +from types import SimpleNamespace +import tempfile +import unittest +from unittest import mock + +from madgraph.interface import madevent_interface + + +class TestLoopInducedCardWarnings(unittest.TestCase): + def treat_card(self, nhel, settings): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + (root / 'Cards').mkdir() + (root / 'SubProcesses' / 'MadLoop5_resources').mkdir(parents=True) + (root / 'Cards' / 'MadLoopParams.dat').write_text(''.join( + '#%s\n%s\n' % item for item in settings.items())) + owner = SimpleNamespace( + me_dir=directory, + proc_characteristics={'loop_induced': True, 'nexternal': 4}, + run_card={'nhel': nhel}, check_param_card=mock.Mock()) + with mock.patch.object(madevent_interface.logger, 'warning') as warning, \ + mock.patch.object(madevent_interface.logger, 'info') as info: + madevent_interface.MadEventCmd.do_treatcards( + owner, '', mode='loop', opt={'forbid_MadLoopInit': True}) + return owner.MadLoopparam, [str(c.args[0]) for c in warning.call_args_list], \ + [str(c.args[0]) for c in info.call_args_list] + + def test_explicit_opp_warns_for_helicity_sum_and_keeps_choice(self): + for library in ('1', '6', '8'): + with self.subTest(library=library): + card, warnings, _ = self.treat_card(0, {'MLReductionLib': library}) + self.assertEqual(card['MLReductionLib'], library) + self.assertEqual(len(warnings), 1) + self.assertIn('preferred reduction technique in MadLoop to be OPP', warnings[0]) + + def test_explicit_tir_warns_for_helicity_sampling_and_keeps_choice(self): + card, warnings, _ = self.treat_card(1, {'MLReductionLib': '7|8'}) + self.assertEqual(card['MLReductionLib'], '7|8') + self.assertEqual(len(warnings), 1) + self.assertIn('different than OPP', warnings[0]) + + def test_appropriate_choices_and_implicit_defaults_do_not_warn(self): + for nhel, settings in ((0, {}), (1, {}), (0, {'MLReductionLib': '7'}), + (1, {'MLReductionLib': '8'})): + with self.subTest(nhel=nhel, settings=settings): + card, warnings, _ = self.treat_card(nhel, settings) + self.assertEqual(warnings, []) + self.assertEqual(card['MLReductionLib'], + settings.get('MLReductionLib', '7|6|1' if nhel == 0 else '6|7|1')) + + def test_other_explicit_card_diagnostics_use_normalized_names(self): + card, warnings, info = self.treat_card(0, { + 'WriteOutFilters': '.true.', 'NRotations_QP': '1', 'MLStabThres': '1e-4'}) + self.assertEqual(len(warnings), 2) + self.assertTrue(any('lorentz rotation' in text for text in warnings)) + self.assertTrue(any('MLStabThres' in text for text in warnings)) + self.assertTrue(any('writing out filters' in text for text in info)) + self.assertTrue(card['WriteOutFilters']) + self.assertEqual(card['NRotations_QP'], 1) + self.assertEqual(card['MLStabThres'], 1e-4) diff --git a/tests/unit_tests/iolibs/test_export_fks.py b/tests/unit_tests/iolibs/test_export_fks.py index da29903d93..5099073eae 100755 --- a/tests/unit_tests/iolibs/test_export_fks.py +++ b/tests/unit_tests/iolibs/test_export_fks.py @@ -327,6 +327,7 @@ def run_cmd(cmd): opt = dict(interface.options) opt['ninja'] = None opt['collier'] = None + opt['ninjars'] = None with misc.TMP_variable(interface, 'options', opt): interface.exec_cmd(cmd, errorhandling=False, printcmd=False, precmd=True, postcmd=True) diff --git a/tests/unit_tests/iolibs/test_model_function_precision.py b/tests/unit_tests/iolibs/test_model_function_precision.py new file mode 100644 index 0000000000..a487acff12 --- /dev/null +++ b/tests/unit_tests/iolibs/test_model_function_precision.py @@ -0,0 +1,199 @@ +"""Compile exported model helpers and check their binary128 mathematics. + +These functions enter electroweak counterterms before loop reduction. A +low-precision intermediate here can invalidate an otherwise successful rescue. +""" +from pathlib import Path +import shutil +import subprocess +import tempfile +import unittest + +from madgraph.iolibs.export_v4 import UFO_model_to_mg4 +from madgraph.iolibs.ufo_expression_parsers import UFOExpressionParserMPFortran + + +DRIVER = """ +program check_helpers + implicit none + complex(16), external :: mp_reglog,mp_reglogp,mp_reglogm,mp_regsqrt + complex(16), external :: mp_grreglog,mp_recms,mp_b0f + complex(16), external :: mp_sqrt_trajectory + complex(16) :: z,w,expected,twopii,discriminant + real(16) :: x,pi,delta + integer :: i,mode,n + character(16) :: arg + call get_command_argument(1,arg) + read(arg,*) mode + pi=acos(-1.0_16) + twopii=cmplx(0.0_16,2*pi,kind=16) + x=1.234567890123456789012345678901234_16 + select case(mode) + case(1) + ! Pure real/imaginary inputs used to be rounded to default COMPLEX. + do i=1,4 + select case(i) + case(1) + z=cmplx(x,0.0_16,kind=16) + case(2) + z=cmplx(0.0_16,x,kind=16) + case(3) + z=cmplx(-x,0.0_16,kind=16) + case(4) + z=cmplx(0.0_16,-x,kind=16) + end select + call close(mp_reglog(z),log(z),11) + call close(mp_reglogp(z),log(z),12) + call close(mp_reglogm(z),log(z),13) + call close(mp_regsqrt(z),sqrt(z),14) + call close(mp_grreglog(1.0_16,z,z),log(z),15) + ! Exercise normalization of both arguments independently. + w=cmplx(x,x,kind=16) + call close(mp_grreglog(1.0_16,w,z),log(w),16) + enddo + z=cmplx(0.0_16,0.0_16,kind=16) + call close(mp_reglog(z),z,17) + call close(mp_reglogp(z),z,18) + call close(mp_reglogm(z),z,19) + call close(mp_grreglog(1.0_16,z,z),z,20) + case(2) + ! Continuation is checked against runtime ACOS, not a copied pi literal. + z=cmplx(-x,-x,kind=16) + call close(mp_reglogp(z),log(z)+twopii,21) + call close(mp_reglogm(z),log(z),22) + call close(mp_grreglog(1.0_16,z,conjg(z)),log(z)+twopii,23) + call close(mp_grreglog(-1.0_16,z,conjg(z)),log(z)-twopii,24) + z=conjg(z) + call close(mp_reglogm(z),log(z)-twopii,25) + call close(mp_reglogp(z),log(z),26) + call close(mp_grreglog(1.0_16,z,conjg(z)),log(z)-twopii,27) + call close(mp_grreglog(0.0_16,z,conjg(z)),log(z),28) + case(3) + ! Values identical in double precision must remain distinct in rescue. + delta=2.0_16**(-100) + z=cmplx(1.0_16+delta,0.0_16,kind=16) + expected=log(z) + if (real(expected,kind=16)==0.0_16) stop 31 + if (abs((mp_reglog(z)-expected)/expected)>1.e-31_16) stop 32 + w=cmplx(1.0_16+delta,x,kind=16) + if (mp_recms(.false.,w)/=z) stop 33 + if (mp_recms(.true.,w)/=w) stop 34 + if (mp_regsqrt(z)==cmplx(1.0_16,0.0_16,kind=16)) stop 35 + call close(mp_regsqrt(z),sqrt(z),36) + case(4) + ! The closed massless B0 branch has an explicit 2*pi*i continuation. + z=cmplx(9.0_16,-0.9_16,kind=16) + w=cmplx(4.0_16,-0.2_16,kind=16) + expected=(w-z)/z*log((w-z)/w)-twopii + call close(mp_b0f(z,cmplx(0.0_16,kind=16),w),expected,41) + z=cmplx(1.0_16,-0.1_16,kind=16) + expected=(w-z)/z*log((w-z)/w) + call close(mp_b0f(z,cmplx(0.0_16,kind=16),w),expected,42) + case(5) + ! A rounded trajectory can move a point across the two-particle threshold. + ! Below threshold the discriminant crosses its negative-real-axis cut, + ! so the continued root has the opposite sign to the final principal root. + w=cmplx(1.0_16,0.0_16,kind=16) + do i=-1,1,2 + z=cmplx(4.0_16+i*2.0_16**(-30),-1.0_16,kind=16) + discriminant=1.0_16-4.0_16*(w-cmplx(0.0_16,1.e-24_16,kind=16))/z + expected=sqrt(discriminant) + if(i<0) expected=-expected + do n=100,400,100 + call close(mp_sqrt_trajectory(n,z,w,w),expected,51) + enddo + enddo + case default + stop 99 + end select +contains + subroutine close(actual,reference,code) + complex(16), intent(in) :: actual,reference + integer, intent(in) :: code + if (.not.(abs(actual-reference)<=1.e-31_16*max(1.0_16,abs(reference)))) then + write(*,*) code,actual,reference + stop 1 + endif + end subroutine +end program +""" + + +@unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') +class ModelFunctionPrecisionTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.tmp = tempfile.TemporaryDirectory(prefix='model-function-precision-') + cls.addClassCleanup(cls.tmp.cleanup) + cls.work = Path(cls.tmp.name) + # No UFO expressions are needed: exercise the real exporter and writer. + exporter = UFO_model_to_mg4.__new__(UFO_model_to_mg4) + exporter.dir_path = str(cls.work) + exporter.model = {'modelpath': str(cls.work), 'functions': []} + exporter.opt = {'mp': True} + with exporter.open('model_functions.f', format='fortran') as writer: + exporter.open = lambda *args, **kwargs: writer + exporter.create_model_functions_def() + (cls.work / 'check.f90').write_text(DRIVER) + build = subprocess.run( + ['gfortran', '-O2', '-ffixed-line-length-132', '-fcheck=all', + 'model_functions.f', 'check.f90', '-o', 'check'], + cwd=cls.work, text=True, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + if build.returncode: + raise AssertionError(build.stdout) + + def check_case(self, mode): + run = subprocess.run([str(self.work / 'check'), str(mode)], + cwd=self.work, text=True, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + self.assertEqual(run.returncode, 0, run.stdout) + + def test_real_and_imaginary_axis_precision(self): + self.check_case(1) + + def test_logarithm_continuation_sheets(self): + self.check_case(2) + + def test_input_bits_beyond_double_precision(self): + self.check_case(3) + + def test_massless_b0_continuation(self): + self.check_case(4) + + def test_threshold_side_controls_continued_square_root(self): + self.check_case(5) + + def test_parsed_real_casts_preserve_real_and_complex_inputs(self): + parser = UFOExpressionParserMPFortran(None) + lines = [ + 'program parsed_precision', 'implicit none', + 'real(16) :: mp__x', 'complex(16) :: mp__z', + 'mp__x=1.234567890123456789012345678901234_16', + 'mp__z=cmplx(mp__x,0.25_16,kind=16)', + ] + for variable in ('x', 'z'): + reference = 'mp__x' + cases = [(f're({variable})', reference), + (f'{variable}.real', reference), + (f'({variable}*{variable}).real', + f'real(mp__{variable}*mp__{variable},kind=16)')] + for function in ('tan', 'atan'): + cases += [(f'{prefix}{function}({variable})', + f'{function}({reference})') + for prefix in ('', 'cmath.')] + for expression, expected in cases: + lines.append(f'if ({parser.parse(expression)}/={expected}) stop 1') + lines += ['mp__x=1.0_16+2.0_16**(-100)', + f'if ({parser.parse("x.real")}-1.0_16/=2.0_16**(-100)) stop 2', + 'end program'] + (self.work / 'parsed.f90').write_text('\n'.join(lines)+'\n') + build = subprocess.run( + ['gfortran', '-O2', 'parsed.f90', '-o', 'parsed'], + cwd=self.work, text=True, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + self.assertEqual(build.returncode, 0, build.stdout) + run = subprocess.run([str(self.work / 'parsed')], cwd=self.work, + text=True, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + self.assertEqual(run.returncode, 0, run.stdout) diff --git a/tests/unit_tests/iolibs/test_ufo_parsers.py b/tests/unit_tests/iolibs/test_ufo_parsers.py index 86c62963ba..34c414e9d6 100755 --- a/tests/unit_tests/iolibs/test_ufo_parsers.py +++ b/tests/unit_tests/iolibs/test_ufo_parsers.py @@ -222,12 +222,16 @@ def test_parse_fortran_fct_MP(self): tests = [('1j', 'CMPLX(0.000000e+00_16, 1.000000e+00_16 ,KIND=16)'), ('3+3j', '3.000000e+00_16+CMPLX(0.000000e+00_16, 3.000000e+00_16 ,KIND=16)'), ('re1j', 'mp__re1j'), - ('re(x)', 'real(mp__x)'), - ('x.real', 'real(mp__x)'), - ('(cmath.log(x)/x).real', 'real(log(mp__x)/mp__x)'), - ('3*x.real', '3.000000e+00_16*real(mp__x)'), - ('x*y.real', 'mp__x*real(mp__y)'), - ('(x*y.real)', '(mp__x*real(mp__y))'), + ('re(x)', 'real(mp__x,KIND=16)'), + ('x.real', 'real(mp__x,KIND=16)'), + ('(cmath.log(x)/x).real', 'real(log(mp__x)/mp__x,KIND=16)'), + ('3*x.real', '3.000000e+00_16*real(mp__x,KIND=16)'), + ('x*y.real', 'mp__x*real(mp__y,KIND=16)'), + ('(x*y.real)', '(mp__x*real(mp__y,KIND=16))'), + ('tan(x)', 'tan(real(mp__x,KIND=16))'), + ('cmath.tan(x)', 'tan(real(mp__x,KIND=16))'), + ('atan(x)', 'atan(real(mp__x,KIND=16))'), + ('cmath.atan(x)', 'atan(real(mp__x,KIND=16))'), ] diff --git a/tests/unit_tests/loop/test_factorized_wl_export.py b/tests/unit_tests/loop/test_factorized_wl_export.py new file mode 100644 index 0000000000..b04171908d --- /dev/null +++ b/tests/unit_tests/loop/test_factorized_wl_export.py @@ -0,0 +1,138 @@ +"""Private tensor contractions require explicit shapes and preserved consumers.""" +from pathlib import Path +import os +import shutil +import subprocess +import tempfile +import unittest + +from madgraph.loop.loop_exporters import LoopProcessOptimizedExporterFortranSA as Exporter +from tests.unit_tests.loop import test_terminal_wavefunctions as terminal_tests + + +class FactorizedWavefunctionExportTest(unittest.TestCase): + @staticmethod + def block(prefix='TEST_', mode='UPDATE', rank=2, vertex='FFV1L2_1', + origin='1', target='2', cut=4, ins=4, outs=4, flag=None): + if flag is None: + flag = mode == 'TERMINAL' + return ('CALL MP_%s(PL(0,1),V(1,1),GC_1,MDL_MT,ZERO,PL(0,2),COEFS)\n' + 'CALL MP_%s%s_WL_%d_1(WL(1,0,1,%s),%d,COEFS,%d,%d,' + 'WL(1,0,1,%s)%s)\n\n' % + (vertex, prefix, mode, rank, origin, cut, ins, outs, target, + ',WL_ENTRY_INEXACT' if flag else '')) + + def test_selected_full_and_terminal_preserve_arguments_and_line_endings(self): + for prefix in ('TEST_', ''): + for mode in ('UPDATE', 'TERMINAL'): + for vertex in ('FFV1L1_2', 'FFV1L2_1'): + with self.subTest(prefix=prefix, mode=mode, vertex=vertex): + before = self.block(prefix, mode, vertex=vertex) + after = Exporter.factorize_mp_coef_calls([before], prefix)[0] + name = 'MP_%s%s_WL_2_1' % (prefix, mode) + expected = before.replace(name+'(', name+'_FACTOR_'+vertex+'(') + if mode == 'UPDATE': + expected = expected.replace('WL(1,0,1,2))', + 'WL(1,0,1,2),WL_ENTRY_INEXACT)') + self.assertEqual(after, expected) + + def test_unknown_shapes_ranks_aliases_flags_and_vertices_keep_original(self): + controls = [dict(ins=3), dict(outs=3), dict(cut=5), dict(rank=1), + dict(rank=5), dict(origin='2'), dict(origin='02', target='2'), + dict(target='0'), dict(vertex='VVV1L2P0_1'), dict(flag=True), + dict(mode='TERMINAL', flag=False), dict(prefix='LONG_'*8)] + for options in controls: + with self.subTest(options=options): + before = self.block(**options) + self.assertEqual(Exporter.factorize_mp_coef_calls( + [before], options.get('prefix', 'TEST_')), [before]) + + def test_intervening_statement_or_separate_block_disables_selection(self): + vertex, updater = self.block().splitlines()[:2] + for middle in ('CALL OTHER(COEFS)', 'COEFS=0', 'X=1'): + before = vertex+'\n'+middle+'\n'+updater+'\n' + self.assertEqual(Exporter.factorize_mp_coef_calls([before], 'TEST_'), [before]) + blocks = [vertex+'\n', updater+'\n'] + self.assertEqual(Exporter.factorize_mp_coef_calls(blocks, 'TEST_'), blocks) + + def test_comments_between_vertex_and_updater_preserve_selection(self): + before = self.block().replace('\nCALL MP_TEST_', '\n# retained comment\nCALL MP_TEST_') + after = Exporter.factorize_mp_coef_calls([before], 'TEST_')[0] + self.assertIn('# retained comment\n', after) + self.assertIn('UPDATE_WL_2_1_FACTOR_FFV1L2_1(', after) + + @unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') + def test_factored_batches_compile_with_prefixed_and_empty_nlo_names(self): + for prefix in ('TEST_', ''): + with self.subTest(prefix=prefix), tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + (work/'batch.inc').write_text( + ' SUBROUTINE %(bunch_name)s_%(bunch_number)d()\n' + '%(terminal_ieee_use)s IMPLICIT NONE\n' + '%(terminal_ieee_declarations)s%(helas_calls)s\n END\n') + exporter = object.__new__(Exporter) + exporter.template_dir = str(work) + replacement = {'proc_prefix': prefix, + 'terminal_ieee_use': ' USE, INTRINSIC :: IEEE_EXCEPTIONS\n', + 'terminal_ieee_declarations': ' LOGICAL WL_ENTRY_INEXACT\n'} + calls = ['CALL FULL()'] + [ + 'CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT)\n' + 'CALL MP_%s%s_WL_2_1_FACTOR_FFV1L2_1(WL_ENTRY_INEXACT)' % + (prefix, mode) for mode in ('UPDATE', 'TERMINAL')] + before = os.getcwd() + try: + os.chdir(work) + exporter.split_HELASCALLS(True, replacement, 'batch.inc', '', + calls, 'entry', 'batch', n_helas=1) + finally: + os.chdir(before) + self.assertNotIn('IEEE_', (work/'batch_1.f').read_text()) + for number in (2, 3): + self.assertIn('LOGICAL WL_ENTRY_INEXACT', + (work/f'batch_{number}.f').read_text()) + built = subprocess.run(['gfortran', '-fno-automatic', + '-ffixed-line-length-132', '-c', 'batch_1.f', 'batch_2.f', + 'batch_3.f'], cwd=work, capture_output=True, text=True) + self.assertEqual(built.returncode, 0, built.stdout+built.stderr) + + def rendered_fixture(self, work): + expected = terminal_tests.RenderedTerminalGraphTest().fixture(work) + batch = work/'mp_coef_construction_1.f' + text = batch.read_text().replace('UPDATE_WL_1_1(', + 'UPDATE_WL_2_1_FACTOR_FFV1L2_1(').replace('WL(1,0,1,1))', + 'WL(1,0,1,1),WL_ENTRY_INEXACT)') + text = text.replace('TERMINAL_WL_1_1(', 'TERMINAL_WL_3_1_FACTOR_FFV1L1_2(') + batch.write_text(text) + expected[2]['loop_mother_rank'] = 3 + return expected + + def test_rendered_factored_producers_preserve_terminal_graph_proof(self): + with tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + expected = self.rendered_fixture(work) + self.assertTrue(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + batch = work/'mp_coef_construction_1.f' + with batch.open('a') as stream: + stream.write(' CALL MP_TEST_UPDATE_WL_2_1_FACTOR_FFV1L2_1(\n' + ' $ WL(1,0,1,2),4,COEFS,4,4,WL(1,0,1,3),WL_ENTRY_INEXACT)\n') + self.assertFalse(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + + def test_missing_flag_unknown_factor_and_unsupported_shape_fail_proof(self): + for change in ('flag', 'vertex', 'shape'): + with self.subTest(change=change), tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + expected = self.rendered_fixture(work) + batch = work/'mp_coef_construction_1.f' + text = batch.read_text() + if change == 'flag': + text = text.replace(',WL_ENTRY_INEXACT)', ')', 1) + elif change == 'vertex': + text = text.replace('_FACTOR_FFV1L2_1(', '_FACTOR_UNKNOWN(') + else: + text = text.replace(',4,COEFS,4,4,', ',4,COEFS,3,4,', 1) + batch.write_text(text) + self.assertFalse(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/unit_tests/loop/test_loop_poles.py b/tests/unit_tests/loop/test_loop_poles.py new file mode 100644 index 0000000000..d58a40f84f --- /dev/null +++ b/tests/unit_tests/loop/test_loop_poles.py @@ -0,0 +1,515 @@ +"""Bare-loop pole selection, legacy compatibility and cache invalidation.""" +import io +import shutil +import subprocess +import tempfile +import unittest +from pathlib import Path + +from madgraph import MG5DIR +from madgraph.iolibs.file_writers import FortranWriter +from madgraph.various.banner import MadLoopParam + +ROOT = Path(MG5DIR) +PARAMS = ROOT / 'Template/loop_material/StandAlone/SubProcesses' +TEMPLATES = ROOT / 'madgraph/iolibs/template_files/loop_optimized' + + +class LoopPoleCardTest(unittest.TestCase): + def test_card_roundtrip_and_legacy_default(self): + card = MadLoopParam() + self.assertEqual(card['LoopPoleMode'], -1) + for mode in (-1, 0, 1, 2, 3): + with self.subTest(mode=mode): + card['LoopPoleMode'] = mode + stream = io.StringIO() + card.write(stream) + parsed = MadLoopParam(stream.getvalue()) + self.assertEqual(parsed['LoopPoleMode'], mode) + self.assertTrue(parsed['COLLIERComputeUVpoles']) + self.assertTrue(parsed['COLLIERComputeIRpoles']) + + +@unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') +class LoopPoleFortranTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory(prefix='madloop-poles-') + self.work = Path(self.tmp.name) + self.addCleanup(self.tmp.cleanup) + + def run_command(self, *args, success=True): + result = subprocess.run(args, cwd=self.work, text=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + if success: + self.assertEqual(result.returncode, 0, result.stdout) + return result + + def compile(self, *sources): + self.run_command('gfortran', '-ffixed-line-length-132', '-fcheck=all', + '-I', str(PARAMS), *sources, + str(PARAMS / 'MadLoopParamReader.f'), '-o', 'check') + + def test_fortran_card_flags_and_rescue_chain_validation(self): + (self.work / 'card.dat').write_text('#LoopPoleMode\n2\n#MLReductionLib\n8|7\n') + (self.work / 'check.f').write_text(''' + PROGRAM CHECK + IMPLICIT NONE + INCLUDE 'MadLoopParams.inc' + INTEGER MODE,I,J,K + LOGICAL UV,IR + CHARACTER*1 ARG + CHARACTER*512 FILENAME + CALL DEFAULTPARAM() + IF(LoopPoleMode.NE.-1) STOP 11 + FILENAME='card.dat' + CALL MADLOOPPARAMREADER(FILENAME,.FALSE.) + IF(LoopPoleMode.NE.2) STOP 12 + CALL GET_COMMAND_ARGUMENT(1,ARG) + READ(ARG,*) MODE + IF(MODE.EQ.1) THEN + MLReductionLib(2)=6 + CALL ML_CHECK_LOOP_POLE_MODE() + STOP 13 + ENDIF + DO I=0,1 + DO J=0,1 + COLLIERComputeUVpoles=I.EQ.1 + COLLIERComputeIRpoles=J.EQ.1 + DO K=-1,3 + LoopPoleMode=K + CALL ML_CHECK_LOOP_POLE_MODE() + CALL ML_LOOP_POLE_FLAGS(UV,IR) + IF(K.EQ.-1) THEN + IF(UV.NEQV.(I.EQ.1)) STOP 14 + IF(IR.NEQV.(J.EQ.1)) STOP 15 + ELSE + IF(UV.NEQV.(K.EQ.0.OR.K.EQ.1)) STOP 16 + IF(IR.NEQV.(K.EQ.0.OR.K.EQ.2)) STOP 17 + ENDIF + IF(COLLIERComputeUVpoles.NEQV.(I.EQ.1)) STOP 18 + IF(COLLIERComputeIRpoles.NEQV.(J.EQ.1)) STOP 19 + ENDDO + ENDDO + ENDDO + DO I=-1,0 + LoopPoleMode=I + MLReductionLib(1:3)=(/6,7,1/) + CALL ML_CHECK_LOOP_POLE_MODE() + ENDDO + WRITE(*,*) 'POLE SELECTOR PASSED' + END +''') + self.compile('check.f') + result = self.run_command(str(self.work / 'check'), '0') + self.assertIn('POLE SELECTOR PASSED', result.stdout) + result = self.run_command(str(self.work / 'check'), '1', success=False) + self.assertNotEqual(result.returncode, 0) + self.assertIn('Set MLReductionLib to 8, 7 or 8|7', result.stdout) + self.assertNotIn('POLE SELECTOR PASSED', result.stdout) + + def test_partial_card_prints_effective_reduction_list(self): + (self.work / 'card.dat').write_text('#LoopPoleMode\n2\n') + (self.work / 'check.f').write_text(''' + PROGRAM CHECK + IMPLICIT NONE + INCLUDE 'MadLoopParams.inc' + INTEGER MODE,EXPECTED(9) + CHARACTER*1 ARG + CHARACTER*512 FILENAME + CALL DEFAULTPARAM() + CALL GET_COMMAND_ARGUMENT(1,ARG) + READ(ARG,*) MODE + IF(MODE.EQ.1) THEN + MLReductionLib=0 + MLReductionLib(1:2)=(/8,7/) + ENDIF + EXPECTED=MLReductionLib + IF(MODE.EQ.2) THEN + EXPECTED=0 + EXPECTED(1:2)=(/7,8/) + ENDIF + FILENAME='card.dat' + CALL MADLOOPPARAMREADER(FILENAME,.TRUE.) + IF(ANY(MLReductionLib.NE.EXPECTED)) STOP 51 + WRITE(*,*) 'REDUCTION DIAGNOSTIC PASSED' + END +''') + self.compile('check.f') + for mode, expected in ((0, '6|7|1'), (1, '8|7'), (2, '7|8')): + if mode == 2: + (self.work / 'card.dat').write_text( + '#LoopPoleMode\n2\n#MLReductionLib\n7|8\n') + with self.subTest(mode=mode): + result = self.run_command(str(self.work / 'check'), str(mode)) + displayed = next(line.split('=', 1)[1].strip() + for line in result.stdout.splitlines() + if '> MLReductionLib ' in line) + self.assertEqual(displayed, expected) + self.assertIn('REDUCTION DIAGNOSTIC PASSED', result.stdout) + + def test_collier_projection_and_mode_changes_invalidate_cached_tensors(self): + # Compile the production wrapper against a deterministic COLLIER double. + # Real-library numerical comparisons are separate integration tests. + source = (TEMPLATES / 'COLLIER_interface.inc').read_text().split( + ' SUBROUTINE %(proc_prefix)sSET_COLLIER_GLOBAL_CACHE', 1)[0] + replacements = { + 'proc_prefix': 'TEST_', 'info_lines': '', 'process_lines': '', + 'real_dp_format': 'REAL*8', 'complex_dp_format': 'COMPLEX*16', + 'mass_dp_format': 'COMPLEX*16', 'maxrank': 0, 'nloop_groups': 1, + 'include_vector': '', + 'collier_coefmap': '\n'.join( + ' DATA COEFMAP_%s/0/' % name + for name in ('ZERO', 'ONE', 'TWO', 'THREE')), + } + with FortranWriter(str(self.work / 'wrapper.f')) as writer: + writer.writelines(source % replacements, + context={'AmplitudeReduction': True}) + (self.work / 'loop_max_coefs.inc').write_text( + ' INTEGER LOOPMAXCOEFS\n PARAMETER(LOOPMAXCOEFS=1)\n') + (self.work / 'coupl.inc').write_text( + ' REAL*8 MU_R\n COMMON/TEST_COUPL/MU_R\n') + (self.work / 'unique_id.inc').write_text( + ' INTEGER UNIQUE_ID\n PARAMETER(UNIQUE_ID=1)\n') + (self.work / 'global_specs.inc').write_text( + ' INTEGER NPROCS,MAXNEXTERNAL\n' + ' PARAMETER(NPROCS=1,MAXNEXTERNAL=3)\n') + module = '''module collier +implicit none +real(8) :: uv=0,ir1=0,ir2=0 +integer :: calls=0,resets=0 +interface TNten_cll +module procedure tensor,tadpole +end interface +contains +subroutine SetDeltaUV_cll(v) +real(8) :: v +uv=v +end subroutine +subroutine SetDeltaIR_cll(v,w) +real(8) :: v,w +ir1=v +ir2=w +end subroutine +subroutine tadpole(t,u,m,n,r,e) +integer :: n,r +complex(8) :: t(0:r,0:r,0:r,0:r),u(0:r,0:r,0:r,0:r),m(n) +real(8) :: e(0:r) +t=10d0+2d0*uv+3d0*ir1+5d0*(ir2-acos(-1d0)**2/6d0) +u=2d0 +e=0d0 +calls=calls+1 +end subroutine +subroutine tensor(t,u,p,s,m,n,r,e) +integer :: n,r +complex(8) :: t(0:r,0:r,0:r,0:r),u(0:r,0:r,0:r,0:r),m(n) +complex(8) :: p(0:3,n-1),s(n*(n-1)/2) +real(8) :: e(0:r) +call tadpole(t,u,m,n,r,e) +end subroutine +subroutine INITCACHESYSTEM_CLL(n,r) +integer :: n,r +resets=resets+1 +end subroutine +''' + for name in ('SwitchOffCache_cll', 'SwitchOnCache_cll', 'InitEvent_cll'): + module += ('subroutine %s(i)\ninteger,optional :: i\n' + 'end subroutine\n') % name + for name in ('SetMuUV2_cll', 'SetMuIR2_cll'): + module += ('subroutine %s(v)\nreal(8) :: v\nend subroutine\n') % name + module += ('subroutine SwitchOffCacheSystem_cll()\nend subroutine\n' + 'end module\nsubroutine INITCOLLIER()\nend subroutine\n' + 'subroutine cite(a,b)\ncharacter(*) :: a,b\nend subroutine\n' + 'subroutine TEST_SWITCH_ORDER()\nend subroutine\n') + (self.work / 'collier.f90').write_text(module) + (self.work / 'driver.f').write_text(''' + PROGRAM CHECK + USE COLLIER + IMPLICIT NONE + INCLUDE 'MadLoopParams.inc' + REAL*8 MU_R,P(0:3,1),PDEN(0:3,0),EXPECTED(3,0:3) + COMMON/TEST_COUPL/MU_R + COMPLEX*16 M(1),T(0:0,3),E(0:0,3) + INTEGER ID,R,I,J,PREVIOUS + COMMON/TEST_LOOP/ID,R + LOGICAL CTINIT,TIRINIT,GOLEMINIT,SAMURAIINIT,NINJAINIT,CLINIT + COMMON/REDUCTIONCODEINIT/CTINIT,TIRINIT,GOLEMINIT, + &SAMURAIINIT,NINJAINIT,CLINIT + INTEGER ACTIVE,COUNTS(4),CALLS_IN_EVENT(4) + LOGICAL INIT_EVENT + COMMON/TEST_COLLIER_CACHE_STATUS/ACTIVE,COUNTS,CALLS_IN_EVENT, + &INIT_EVENT + CALL DEFAULTPARAM() + MU_R=1D0 + P=0D0 + M=1D0 + ID=1 + R=0 + CLINIT=.FALSE. + ACTIVE=1 + COUNTS=-1 + CALLS_IN_EVENT=0 + INIT_EVENT=.TRUE. + COLLIERUseCacheForPoles=.TRUE. + EXPECTED(:,0)=(/10D0,5D0,5D0/) + EXPECTED(:,1)=(/10D0,2D0,0D0/) + EXPECTED(:,2)=(/10D0,3D0,5D0/) + EXPECTED(:,3)=(/10D0,0D0,0D0/) +C Deliberately retain all caches between mode changes and CT modes. + DO J=1,2 + DO I=0,3 + LoopPoleMode=I + CALL TEST_COLLIERLOOP(1,1,0,P,PDEN,M,T,E) + IF(ANY(ABS(T(0,:)-EXPECTED(:,I)).GT.1D-12)) STOP 21 + PREVIOUS=CALLS + CALL TEST_COLLIERLOOP(2,1,0,P,PDEN,M,T,E) + IF(ANY(ABS(T(0,:)-EXPECTED(:,I)).GT.1D-12)) STOP 22 + IF(CALLS.NE.PREVIOUS) STOP 23 + ENDDO + ENDDO + IF(RESETS.NE.7) STOP 24 +C Legacy choices remain active after returning from an explicit mode. + LoopPoleMode=-1 + COLLIERComputeUVpoles=.FALSE. + CALL TEST_COLLIERLOOP(1,1,0,P,PDEN,M,T,E) + IF(ANY(ABS(T(0,:)-EXPECTED(:,2)).GT.1D-12)) STOP 25 + COLLIERComputeIRpoles=.FALSE. + CALL TEST_COLLIERLOOP(1,1,0,P,PDEN,M,T,E) + IF(ANY(ABS(T(0,:)-EXPECTED(:,3)).GT.1D-12)) STOP 26 + WRITE(*,*) 'COLLIER SELECTOR AND CACHE PASSED' + END +''') + self.compile('collier.f90', 'wrapper.f', 'driver.f') + result = self.run_command(str(self.work / 'check')) + self.assertIn('COLLIER SELECTOR AND CACHE PASSED', result.stdout) + + def test_invalid_mode_rejected_by_card_and_public_setter(self): + source = (TEMPLATES / 'loop_matrix_standalone.inc').read_text() + source = source[source.index( + ' SUBROUTINE %(proc_prefix)sSET_LOOP_POLE_MODE(MODE)'):] + source = source[:source.index( + '\t SUBROUTINE %(proc_prefix)sCOLLIER_COMPUTE_UV_POLES')] + with FortranWriter(str(self.work / 'setter.f')) as writer: + writer.writelines(source % {'proc_prefix': 'TEST_'}) + (self.work / 'invalid.f').write_text(''' + PROGRAM CHECK + IMPLICIT NONE + INTEGER MODE + CHARACTER*2 ARG + CHARACTER*512 FILENAME + CALL DEFAULTPARAM() + CALL GET_COMMAND_ARGUMENT(1,ARG) + READ(ARG,*) MODE + IF(MODE.EQ.0) THEN + FILENAME='card.dat' + CALL MADLOOPPARAMREADER(FILENAME,.FALSE.) + ELSE + CALL TEST_SET_LOOP_POLE_MODE(MODE) + ENDIF + WRITE(*,*) 'INVALID MODE ACCEPTED' + END +''') + self.compile('setter.f', 'invalid.f') + for mode in (-2, 4): + for route in ('card', 'setter'): + with self.subTest(mode=mode, route=route): + (self.work / 'card.dat').write_text( + '#LoopPoleMode\n%d\n' % mode) + result = self.run_command(str(self.work / 'check'), + '0' if route == 'card' else str(mode), + success=False) + self.assertNotEqual(result.returncode, 0) + self.assertIn('LoopPoleMode must be', result.stdout) + self.assertNotIn('INVALID MODE ACCEPTED', result.stdout) + + def test_two_subprocesses_share_pending_and_runtime_selector(self): + source = (TEMPLATES / 'loop_matrix_standalone.inc').read_text() + setter = source[source.index( + ' SUBROUTINE %(proc_prefix)sSET_LOOP_POLE_MODE(MODE)'):] + setter = setter[:setter.index( + '\t SUBROUTINE %(proc_prefix)sCOLLIER_COMPUTE_UV_POLES')] + start = source.index(' CALL MADLOOPPARAMREADER(PARAMFN,.TRUE.)') + first_read = source[start:source.index( + ' IF (FORCED_CHOICE_OF_COLLIER_UV_POLE_COMPUTATION)', start)] + # Compile two independently prefixed entry points using the production + # setter and first-card-read path, linked to one shared parameter reader. + for prefix in ('A_', 'B_'): + with FortranWriter(str(self.work / (prefix + '.f'))) as writer: + writer.writelines(setter % {'proc_prefix': prefix} + ''' + SUBROUTINE ''' + prefix + '''EVALUATE(SELECTED) + IMPLICIT NONE + INCLUDE 'MadLoopParams.inc' + INTEGER SELECTED + LOGICAL ML_INIT + COMMON/ML_INIT/ML_INIT + CHARACTER*512 PARAMFN + IF(ML_INIT) THEN + ML_INIT=.FALSE. + PARAMFN='card.dat' +''' + first_read + ''' + ENDIF + SELECTED=LoopPoleMode + END +''') + (self.work / 'card.dat').write_text('#LoopPoleMode\n2\n') + (self.work / 'two_processes.f').write_text(''' + PROGRAM CHECK + IMPLICIT NONE + INTEGER SCENARIO,SELECTED,EXPECTED + LOGICAL ML_INIT + COMMON/ML_INIT/ML_INIT + CHARACTER*1 ARG + CALL DEFAULTPARAM() + ML_INIT=.TRUE. + CALL GET_COMMAND_ARGUMENT(1,ARG) + READ(ARG,*) SCENARIO + EXPECTED=2 + IF(SCENARIO.EQ.1) THEN + CALL B_SET_LOOP_POLE_MODE(1) + EXPECTED=1 + ELSEIF(SCENARIO.EQ.2) THEN + CALL A_SET_LOOP_POLE_MODE(1) + CALL B_SET_LOOP_POLE_MODE(2) + ELSEIF(SCENARIO.EQ.3) THEN + CALL B_SET_LOOP_POLE_MODE(-1) + EXPECTED=-1 + ELSEIF(SCENARIO.EQ.4) THEN + CALL B_SET_LOOP_POLE_MODE(0) + EXPECTED=0 + ENDIF + CALL A_EVALUATE(SELECTED) + IF(SELECTED.NE.EXPECTED) STOP 41 + CALL B_EVALUATE(SELECTED) + IF(SELECTED.NE.EXPECTED) STOP 42 +C Runtime changes share the same global scope and the latest call wins. + CALL B_SET_LOOP_POLE_MODE(0) + CALL A_EVALUATE(SELECTED) + IF(SELECTED.NE.0) STOP 43 + CALL B_EVALUATE(SELECTED) + IF(SELECTED.NE.0) STOP 44 + CALL A_SET_LOOP_POLE_MODE(-1) + CALL B_EVALUATE(SELECTED) + IF(SELECTED.NE.-1) STOP 45 + CALL A_EVALUATE(SELECTED) + IF(SELECTED.NE.-1) STOP 46 + WRITE(*,*) 'SHARED POLE SELECTOR PASSED' + END +''') + self.compile('A_.f', 'B_.f', 'two_processes.f') + for scenario in range(5): + with self.subTest(scenario=scenario): + result = self.run_command(str(self.work / 'check'), str(scenario)) + self.assertIn('SHARED POLE SELECTOR PASSED', result.stdout) + + def test_nonoptimized_output_rejects_selected_poles(self): + source = (TEMPLATES.parent / 'loop/loop_matrix_standalone.inc').read_text() + guard = source[source.index( + 'C The non-optimized output uses CutTools'):] + guard = guard[:guard.index('IF (LOCAL_ML_INIT) THEN')] + with FortranWriter(str(self.work / 'nonoptimized.f')) as writer: + writer.writelines(''' + PROGRAM CHECK + IMPLICIT NONE + INCLUDE 'MadLoopParams.inc' + CHARACTER*2 ARG + CALL DEFAULTPARAM() + CALL GET_COMMAND_ARGUMENT(1,ARG) + READ(ARG,*) LoopPoleMode +''' + guard + ''' + WRITE(*,*) 'ACCEPTED' + END +''') + self.compile('nonoptimized.f') + for mode in (-1, 0): + self.assertIn('ACCEPTED', self.run_command( + str(self.work / 'check'), str(mode)).stdout) + for mode in (1, 2, 3): + result = self.run_command(str(self.work / 'check'), str(mode), + success=False) + self.assertNotEqual(result.returncode, 0) + self.assertIn('loop_optimized_output enabled', result.stdout) + + def test_diagnostic_modes_bypass_and_restore_learned_zero_filters(self): + source = (TEMPLATES / 'loop_matrix_standalone.inc').read_text() + start = source.index('IF (BYPASS_FILTERS) THEN') + bypass = source[start:source.index( + 'IF(CHECKPHASE.OR.(.NOT.HELDOUBLECHECKED)) THEN', start)] + start = source.index('IF (BYPASS_FILTERS) THEN', start + 1) + restore = source[start:source.index( + 'C Make sure that we finish by emptying caches', start)] + start = source.index('IF (WriteOutFilters.AND.') + write_filters = source[start:source.index( + 'IF (BYPASS_FILTERS) THEN', start)] + assignment = next(line for line in source.splitlines() + if line.startswith('BYPASS_FILTERS=')) + start = source.index('## if(LoopInduced) {\nC For loop-induced processes') + count_training_points = source[start:source.index( + 'IF (USER_STAB_PREC.GT.0.0d0) THEN', start)] + # Represent a saved combined-pole zero: UV and IR separately survive. + # Reading deliberately restrictive files reproduces the stale-filter + # case, without relying on a numerical library to infer a zero. + (self.work / 'saved_loops.dat').write_text('F\n') + (self.work / 'saved_helicities.dat').write_text('0\n0\n') + with FortranWriter(str(self.work / 'filters.f')) as writer: + writer.writelines(''' + PROGRAM CHECK + IMPLICIT NONE + INCLUDE 'MadLoopParams.inc' + INTEGER NCOMB,NSQUAREDSO,NLOOPGROUPS + PARAMETER(NCOMB=2,NSQUAREDSO=1,NLOOPGROUPS=1) + LOGICAL GOODAMP(1,1),OLD_GOODAMP(1,1) + INTEGER GOODHEL(2),OLD_GOODHEL(2),I,J,MODE,MODELIST(6),NTRY + LOGICAL CHECKPHASE,HELDOUBLECHECKED,BYPASS_CHECK,BYPASS_FILTERS + LOGICAL OLD_CHECKPHASE,OLD_HELDOUBLECHECKED + LOGICAL FOUNDHELFILTER,FOUNDLOOPFILTER,EXISTS + CHARACTER*32 HelFilterFN,LoopFilterFN + REAL*8 UV,IR + CALL DEFAULTPARAM() + USELOOPFILTER=.TRUE. + HelFilterFN='new_helicities.dat' + LoopFilterFN='new_loops.dat' + OPEN(1,FILE='saved_loops.dat',STATUS='OLD') + READ(1,*) GOODAMP + CLOSE(1) + OPEN(1,FILE='saved_helicities.dat',STATUS='OLD') + READ(1,*) GOODHEL(1) + READ(1,*) GOODHEL(2) + CLOSE(1) + MODELIST=(/1,2,0,3,1,2/) + NTRY=2 + BYPASS_CHECK=.FALSE. + CHECKPHASE=.FALSE. + HELDOUBLECHECKED=.TRUE. + FOUNDHELFILTER=.FALSE. + FOUNDLOOPFILTER=.FALSE. + DO MODE=1,6 + LoopPoleMode=MODELIST(MODE) +''' + assignment + '\n' + count_training_points + write_filters + bypass + ''' + IF(NTRY.NE.2) STOP 30 + IF(ANY(GOODHEL.NE.1).OR..NOT.ALL(GOODAMP)) STOP 31 + IF(CHECKPHASE.OR..NOT.HELDOUBLECHECKED) STOP 32 + UV=0D0 + IF(GOODAMP(1,1)) THEN + IF(GOODHEL(1).GT.0) UV=UV+3D0 + IF(GOODHEL(2).GT.0) UV=UV+5D0 + ENDIF + IR=-UV + IF(UV.NE.8D0.OR.IR.NE.-8D0) STOP 33 +''' + restore + ''' + IF(ANY(GOODHEL.NE.0).OR.ANY(GOODAMP)) STOP 34 + IF(CHECKPHASE.OR..NOT.HELDOUBLECHECKED) STOP 35 + IF(BYPASS_CHECK) STOP 36 + INQUIRE(FILE=HelFilterFN,EXIST=EXISTS) + IF(EXISTS) STOP 37 + INQUIRE(FILE=LoopFilterFN,EXIST=EXISTS) + IF(EXISTS) STOP 38 + ENDDO +C Returning to legacy mode restores the caller's learned filters. + LoopPoleMode=-1 +''' + assignment + '\n' + bypass + ''' + IF(BYPASS_FILTERS.OR.ANY(GOODHEL.NE.0).OR.ANY(GOODAMP)) STOP 39 + WRITE(*,*) 'DIAGNOSTIC FILTER BYPASS PASSED' + END +''', context={'LoopInduced': False}) + self.compile('filters.f') + result = self.run_command(str(self.work / 'check')) + self.assertIn('DIAGNOSTIC FILTER BYPASS PASSED', result.stdout) diff --git a/tests/unit_tests/loop/test_ninjars_default_policy.py b/tests/unit_tests/loop/test_ninjars_default_policy.py new file mode 100644 index 0000000000..cd81282090 --- /dev/null +++ b/tests/unit_tests/loop/test_ninjars_default_policy.py @@ -0,0 +1,122 @@ +"""Default backend selection and ownership of caller-supplied check options.""" + +import copy +from types import SimpleNamespace +import unittest +from unittest import mock + +from madgraph.core import base_objects +from madgraph.various import ninjars_install, process_checks + + +class TestReductionDefaults(unittest.TestCase): + def test_default_selection_returns_independent_lists(self): + with mock.patch.object(ninjars_install, 'is_available', return_value=True): + first = ninjars_install.default_reduction_library(True, 'installed') + first.append(1) + self.assertEqual( + ninjars_install.default_reduction_library(True, 'installed'), [8]) + with mock.patch.object(ninjars_install, 'is_available', return_value=False): + self.assertEqual( + ninjars_install.default_reduction_library(True, 'missing'), [6]) + with mock.patch.object(ninjars_install, 'is_available') as available: + self.assertEqual( + ninjars_install.default_reduction_library(False, 'installed'), [6]) + available.assert_not_called() + + def run_check(self, name, mloptions, has_born=True, reuse=False, + optimized=True, timing_result=None): + process = base_objects.Process({'has_born': has_born}) + matrix = process if reuse else {'processes': [process]} + timer = SimpleNamespace(loop_optimized_output=optimized, + time_matrix_element=mock.Mock(return_value=timing_result), + check_matrix_element_stability=mock.Mock(return_value={})) + with mock.patch.object(process_checks, 'generate_loop_matrix_element', + return_value=({}, matrix)), \ + mock.patch.object(process_checks, 'LoopMatrixElementTimer', + return_value=timer), \ + mock.patch.object(ninjars_install, 'is_available', return_value=True): + result = getattr(process_checks, name)( + {'model': None, 'has_born': not has_born}, + options={'reuse': reuse}, tir={'ninjars_dir': 'installed'}, + MLOptions=mloptions) + return result, timer + + def test_timing_and_profile_defaults_use_generated_born_status(self): + for name in ('check_timing', 'check_profile'): + for has_born in (True, False): + for reuse in (True, False): + for options in ({}, {'MLReductionLib': []}): + with self.subTest(name=name, born=has_born, + reuse=reuse, options=options): + original = copy.deepcopy(options) + result, timer = self.run_check(name, options, + has_born=has_born, reuse=reuse, timing_result={}) + expected = [8] if has_born else [6] + selected = timer.time_matrix_element.call_args.kwargs['MLOptions'] + self.assertEqual(selected['MLReductionLib'], expected) + self.assertEqual(options, original) + if name == 'check_profile': + self.assertEqual(timer.check_matrix_element_stability + .call_args.kwargs['MLOptions']['MLReductionLib'], expected) + + def test_explicit_selection_and_options_survive_each_check(self): + for name in ('check_timing', 'check_profile', 'check_stability'): + for has_born in (True, False): + options = {'MLReductionLib': [7, 6, 1], 'COLLIERGlobalCache': 9} + original = copy.deepcopy(options) + with self.subTest(name=name, born=has_born): + _, timer = self.run_check(name, options, + has_born=has_born, timing_result={}) + invocation = (timer.check_matrix_element_stability if name == + 'check_stability' else timer.time_matrix_element) + passed = invocation.call_args.kwargs['MLOptions'] + self.assertEqual(passed['MLReductionLib'], [7, 6, 1]) + self.assertEqual(options, original) + # Downstream per-library setup also owns its backend list. + passed['MLReductionLib'].append(8) + self.assertEqual(options, original) + + def test_stability_comparison_defaults_do_not_leak_to_next_call(self): + options = {} + _, timer = self.run_check('check_stability', options) + passed = timer.check_matrix_element_stability.call_args.kwargs['MLOptions'] + self.assertEqual(passed['MLReductionLib'], [8]) + self.assertEqual(passed['COLLIERGlobalCache'], 0) + self.assertEqual(options, {}) + _, timer = self.run_check('check_timing', options, has_born=False, + timing_result={}) + self.assertEqual(timer.time_matrix_element.call_args.kwargs + ['MLOptions']['MLReductionLib'], [6]) + self.assertEqual(options, {}) + + def test_stability_backend_setup_does_not_replace_callers_list(self): + options = {'MLReductionLib': [1, 6]} + process = base_objects.Process() + timer = SimpleNamespace(tir_dir={}, output_path='/unused', + setup_process=mock.Mock(return_value=None)) + with mock.patch.object(base_objects.Process, 'shell_string', return_value='0_test'): + result = process_checks.LoopMatrixElementTimer.check_matrix_element_stability( + timer, process, options={'reuse': True, 'npoints': 0, 'split_orders': -1}, + MLOptions=options) + self.assertIsNone(result) + self.assertEqual(timer.setup_process.call_args.args[4]['MLReductionLib'], 1) + self.assertEqual(options, {'MLReductionLib': [1, 6]}) + + def test_nonoptimized_checks_report_cuttools_without_changing_options(self): + for name in ('check_timing', 'check_profile'): + options = {'MLReductionLib': [8]} + with self.subTest(name=name): + result, timer = self.run_check(name, options, optimized=False, + timing_result={}) + timing = result[0] if name == 'check_profile' else result + self.assertEqual(timing['reduction_tool'], 1) + self.assertEqual(timer.time_matrix_element.call_args.kwargs['MLOptions'], {}) + self.assertEqual(options, {'MLReductionLib': [8]}) + + def test_profile_returns_failure_without_mutating_options(self): + options = {} + result, timer = self.run_check('check_profile', options, timing_result=None) + self.assertEqual(result, (None, None)) + timer.check_matrix_element_stability.assert_not_called() + self.assertEqual(options, {}) diff --git a/tests/unit_tests/loop/test_ninjars_defaults.py b/tests/unit_tests/loop/test_ninjars_defaults.py new file mode 100644 index 0000000000..c441173146 --- /dev/null +++ b/tests/unit_tests/loop/test_ninjars_defaults.py @@ -0,0 +1,257 @@ +"""Private default-policy regression controls; no exports, builds or reducers.""" +import ast +import copy +import importlib.util +import io +import json +import logging +import os +from pathlib import Path +import shutil +import sys +import tempfile +from types import MethodType, SimpleNamespace +import unittest +from unittest import mock + +ROOT = Path(__file__).resolve().parents[3] +sys.path.insert(0, str(ROOT)) +from madgraph.various import banner + +CANDIDATE = ROOT +spec = importlib.util.spec_from_file_location('private_default_ninjars_install', CANDIDATE / 'madgraph/various/ninjars_install.py') +install = importlib.util.module_from_spec(spec); spec.loader.exec_module(install) +export_tree = ast.parse((CANDIDATE / 'madgraph/loop/loop_exporters.py').read_text()) +export_class = next(n for n in export_tree.body if isinstance(n, ast.ClassDef) and n.name == 'LoopProcessExporterFortranSA') +methods = [n for n in export_class.body if isinstance(n, ast.FunctionDef) and n.name in ('finalize', 'set_default_reduction_library')] +optimized_class = next(n for n in export_tree.body if isinstance(n, ast.ClassDef) and n.name == 'LoopProcessOptimizedExporterFortranSA') +methods.append(next(n for n in optimized_class.body if isinstance(n, ast.FunctionDef) and n.name == 'link_TIR')) +namespace = {'ninjars_install': install, 'getattr': getattr, 'pjoin': os.path.join, 'banner_mod': banner, + 'os': os, 'logger': logging.getLogger('private-default-test'), + 'LoopProcessExporterFortranSA': object, 'super': lambda *args: SimpleNamespace(finalize=lambda *args: None)} +exec(compile(ast.Module(body=methods, type_ignores=[]), '', 'exec'), namespace) + + +class NinjaRSDefault(unittest.TestCase): + def setUp(self): + self.temp = tempfile.TemporaryDirectory(dir=ROOT, prefix='.test-nrs-default-') + self.addCleanup(self.temp.cleanup); self.root = Path(self.temp.name) + self.lib = self.root / 'installed/lib'; self.lib.mkdir(parents=True) + self.config = {'abi_version': install.ABI_VERSION, 'native_libs': ['-ldl', '-lm'], 'link_order_version': 1, + 'link_before': ['-Wl,--push-state,--no-as-needed', '-lquadmath', '-Wl,--pop-state']} + (self.lib / 'libninjars.a').write_bytes(b'!\nsynthetic archive metadata') + (self.lib / 'mninjars.mod').write_bytes(b'synthetic nonempty module') + self.write_config() + + def write_config(self): + (self.lib / 'ninjars-config.json').write_text(json.dumps(self.config)) + for name, key in (('ninjars-native-libs.txt', 'native_libs'), ('ninjars-link-before.txt', 'link_before')): + (self.lib / name).write_text(' '.join(self.config[key]) + '\n') + + def owner(self, has_loop_induced=False, available=True, directory=None): + owner = SimpleNamespace(has_loop_induced=has_loop_induced, + tir_available_dict={'ninjars': available}, ninjars_dir=str(self.lib), dir_path=str(directory or self.root / 'output')) + owner.set_default_reduction_library = MethodType(namespace['set_default_reduction_library'], owner) + return owner + + def template(self, directory=None, selection=None): + directory = directory or self.root / 'output'; (directory / 'Cards').mkdir(parents=True, exist_ok=True) + (directory / 'SubProcesses').mkdir(exist_ok=True) + text = (ROOT / 'Template/loop_material/StandAlone/Cards/MadLoopParams.dat').read_text() + if selection is not None: text = text.replace('!6|7|1\n', selection + '\n', 1) + for name in ('MadLoopParams.dat', 'MadLoopParams_default.dat'): (directory / 'Cards' / name).write_text(text) + return directory + + def test_complete_installation_and_relative_configured_path_are_usable(self): + self.assertTrue(install.is_available(self.lib)) + self.assertTrue(install.is_available(str(self.lib.relative_to(ROOT)))) + + def test_module_in_standard_include_directory_is_usable(self): + include = self.lib.parent / 'include'; include.mkdir() + (self.lib / 'mninjars.mod').rename(include / 'mninjars.mod') + self.assertTrue(install.is_available(self.lib)) + + def test_missing_disabled_or_corrupt_archive_paths_are_not_usable(self): + for path in (None, '', False, self.root / 'absent'): + with self.subTest(path=path): self.assertFalse(install.is_available(path)) + (self.lib / 'libninjars.a').write_bytes(b'not an archive') + self.assertFalse(install.is_available(self.lib)) + (self.lib / 'libninjars.a').write_bytes(b'!\n') + self.assertFalse(install.is_available(self.lib)) + + def test_archive_only_or_missing_module_is_not_an_installation(self): + (self.lib / 'ninjars-config.json').unlink(); self.assertFalse(install.is_available(self.lib)) + self.write_config(); (self.lib / 'mninjars.mod').unlink() + self.assertFalse(install.is_available(self.lib)) + + def test_invalid_abi_or_native_metadata_are_not_usable(self): + for config in ({**self.config, 'abi_version': 3}, {**self.config, 'native_libs': 'invalid'}, + {**self.config, 'link_before': []}): + (self.lib / 'ninjars-config.json').write_text(json.dumps(config)) + with self.subTest(config=config): self.assertFalse(install.is_available(self.lib)) + self.write_config(); (self.lib / 'ninjars-native-libs.txt').write_text('-ldifferent\n') + self.assertFalse(install.is_available(self.lib)) + + def test_unusable_optional_installation_is_skipped_before_export_link_setup(self): + (self.lib / 'ninjars-config.json').unlink() + owner = self.owner() + with self.assertLogs('private-default-test', level='WARNING') as logged: + self.assertEqual(namespace['link_TIR'](owner, str(self.root / 'target'), str(self.lib), + 'libninjars.a', tir_name='ninjars'), '') + self.assertFalse(owner.tir_available_dict['ninjars']) + self.assertIn('install ninjars --update', '\n'.join(logged.output)) + + def test_untouched_default_is_active_ninjars_first_with_legacy_fallbacks(self): + card = banner.MadLoopParam(); self.assertEqual(card['MLReductionLib'], '6|7|1') + self.assertTrue(self.owner().set_default_reduction_library(card)) + self.assertEqual(card['MLReductionLib'], '8|6|7|1') + stream = io.StringIO(); card.write(stream) + self.assertIn('#MLReductionLib\n8|6|7|1\n', stream.getvalue()) + + def test_explicit_backend_and_explicit_legacy_order_are_preserved(self): + for value in ('6', '8', '1|6', '6|7|1', '7|6|1'): + card = banner.MadLoopParam(); card.set('MLReductionLib', value, user=True) + with self.subTest(value=value): + self.assertFalse(self.owner().set_default_reduction_library(card)) + self.assertEqual(card['MLReductionLib'], value) + + def test_absent_or_unusable_library_and_nonoptimized_export_keep_legacy_default(self): + for owner in (self.owner(available=False), self.owner()): + owner.ninjars_dir = str(self.root / 'missing') + card = banner.MadLoopParam(); self.assertFalse(owner.set_default_reduction_library(card)) + self.assertEqual(card['MLReductionLib'], '6|7|1') + card = banner.MadLoopParam(); self.assertFalse(self.owner(available=False).set_default_reduction_library(card)) + self.assertEqual(card['MLReductionLib'], '6|7|1') + + def test_ordinary_standalone_finalization_writes_both_default_and_runtime_cards(self): + output = self.template(); owner = self.owner(directory=output) + namespace['finalize'](owner, None, None, {}, []) + for name in ('MadLoopParams.dat', 'MadLoopParams_default.dat'): + card = banner.MadLoopParam(str(output / 'Cards' / name)) + self.assertEqual(card['MLReductionLib'], '8|6|7|1') + self.assertTrue(card['COLLIERComputeUVpoles']); self.assertTrue(card['COLLIERComputeIRpoles']) + + def test_standalone_explicit_card_and_loop_induced_three_defaults_are_unchanged(self): + output = self.template(selection='6|7|1'); owner = self.owner(directory=output) + namespace['finalize'](owner, None, None, {}, []) + self.assertEqual(banner.MadLoopParam(str(output / 'Cards/MadLoopParams.dat'))['MLReductionLib'], '6|7|1') + output = self.template(directory=self.root / 'loop'); owner = self.owner(has_loop_induced=True, directory=output) + namespace['finalize'](owner, None, None, {}, []) + card = banner.MadLoopParam(str(output / 'Cards/MadLoopParams.dat')) + self.assertEqual(card['MLReductionLib'], '7|6|1') + self.assertFalse(card['COLLIERComputeUVpoles']); self.assertFalse(card['COLLIERComputeIRpoles']) + + def fks_hooks(self): + tree = ast.parse((CANDIDATE / 'madgraph/iolibs/export_fks.py').read_text()) + for cls in tree.body: + if isinstance(cls, ast.ClassDef) and cls.name in ('ProcessExporterFortranFKS', 'ProcessOptimizedExporterFortranFKS'): + method = next(n for n in cls.body if isinstance(n, ast.FunctionDef) and n.name == 'copy_fkstemplate') + blocks = [n for n in method.body if isinstance(n, ast.If) and any( + isinstance(x, ast.Assign) and any(isinstance(t, ast.Attribute) and t.attr == 'MadLoopparam' for t in x.targets) + for x in ast.walk(n))] + self.assertEqual(len(blocks), 1) + yield cls.name, blocks[0] + + def test_both_fks_card_copy_routes_propagate_default_to_all_three_cards(self): + for name, block in self.fks_hooks(): + output = self.template(directory=self.root / name); owner = self.owner(directory=output) + scope = {'self': owner, 'os': os, 'pjoin': os.path.join, 'banner_mod': banner} + exec(compile(ast.Module(body=[block], type_ignores=[]), '', 'exec'), scope) + for path in ('Cards/MadLoopParams.dat', 'Cards/MadLoopParams_default.dat', 'SubProcesses/MadLoopParams.dat'): + with self.subTest(route=name, path=path): + self.assertEqual(banner.MadLoopParam(str(output / path))['MLReductionLib'], '8|6|7|1') + + def test_both_fks_card_copy_routes_preserve_explicit_user_order(self): + for name, block in self.fks_hooks(): + output = self.template(directory=self.root / name, selection='1|6') + scope = {'self': self.owner(directory=output), 'os': os, 'pjoin': os.path.join, 'banner_mod': banner} + exec(compile(ast.Module(body=[block], type_ignores=[]), '', 'exec'), scope) + self.assertEqual(banner.MadLoopParam(str(output / 'SubProcesses/MadLoopParams.dat'))['MLReductionLib'], '1|6') + + def cli_default(self, args, has_born, selected): + tree = ast.parse((CANDIDATE / 'madgraph/interface/madgraph_interface.py').read_text()) + cls = next(n for n in tree.body if isinstance(n, ast.ClassDef) and n.name == 'MadGraphCmd') + method = next(n for n in cls.body if isinstance(n, ast.FunctionDef) and n.name == 'do_check') + assignment = next(n for n in method.body if isinstance(n, ast.Assign) and any( + isinstance(t, ast.Name) and t.id == 'automatic_reduction' for t in n.targets)) + condition = next(n for n in method.body if isinstance(n, ast.If) and 'automatic_reduction' in ast.unparse(n.test)) + scope = {'args': args, 'self': SimpleNamespace(options={'ninjars': str(self.lib)}), + 'myprocdef': {'has_born': has_born}, 'MLoptions': {'MLReductionLib': selected[:]}} + with mock.patch('madgraph.various.ninjars_install.is_available', create=True, side_effect=install.is_available): + exec(compile(ast.Module(body=[assignment, condition], type_ignores=[]), '', 'exec'), scope) + return scope['MLoptions']['MLReductionLib'] + + def test_cli_timing_profile_default_to_sole_ninjars_when_usable(self): + for mode in ('timing', 'profile'): + self.assertEqual(self.cli_default([mode, 'u u~ > z [virt=QCD]'], True, [1,3,5,6]), [8]) + (self.lib / 'ninjars-config.json').unlink() + self.assertEqual(self.cli_default(['profile', 'u u~ > z [virt=QCD]'], True, [1,3,5,6]), [6]) + + def test_cli_explicit_lists_loop_induced_and_comparison_checks_are_preserved(self): + for mode, born, args, selection in ( + ('profile', True, ['--reduction=6'], [6]), + ('timing', True, ['--reduction=8|6'], [8,6]), + ('profile', False, [], [1,3,5,6]), + ('stability', True, [], [1,3,5,6])): + with self.subTest(mode=mode, born=born, selection=selection): + self.assertEqual(self.cli_default([mode, 'process', *args], born, selection), selection) + + def test_explicit_cli_ninjars_with_invalid_metadata_is_actionable(self): + (self.lib / 'ninjars-config.json').unlink() + tree = ast.parse((CANDIDATE / 'madgraph/interface/madgraph_interface.py').read_text()) + cls = next(n for n in tree.body if isinstance(n, ast.ClassDef) and n.name == 'MadGraphCmd') + method = next(n for n in cls.body if isinstance(n, ast.FunctionDef) and n.name == 'do_check') + branch = next(n for n in method.body if isinstance(n, ast.If) and + ast.unparse(n.test).startswith("isinstance(self.options.get('ninjars'), str)")) + scope = {'self': SimpleNamespace(options={'ninjars': str(self.lib)}, InvalidCmd=ValueError), + 'MLoptions': {'MLReductionLib': [8]}, 'TIR_dir': {}} + with mock.patch('madgraph.various.ninjars_install.is_available', create=True, side_effect=install.is_available): + with self.assertRaisesRegex(ValueError, 'install ninjars --update'): + exec(compile(ast.Module(body=[branch], type_ignores=[]), '', 'exec'), scope) + self.assertEqual(scope['MLoptions']['MLReductionLib'], [8]) + + def direct_cli_selection(self, name, has_born=True, reusing=False, selected=None): + tree = ast.parse((CANDIDATE / 'madgraph/various/process_checks.py').read_text()) + function = next(n for n in tree.body if isinstance(n, ast.FunctionDef) and n.name == name) + class Process(dict): pass + process = Process(has_born=has_born) + matrix = process if reusing else {'processes': [process]} + observed = [] + class Timer: + loop_optimized_output = True + def __init__(self, **kwargs): pass + def time_matrix_element(self, *args, **kwargs): + observed.append(copy.deepcopy(kwargs['MLOptions']['MLReductionLib'])) + return {} + def check_matrix_element_stability(self, *args, **kwargs): + observed.append(copy.deepcopy(kwargs['MLOptions']['MLReductionLib'])) + return {} + scope = {'FakeInterface': lambda: None, 'base_objects': SimpleNamespace(Process=Process), + 'generate_loop_matrix_element': lambda *a, **k: ({}, matrix), + 'LoopMatrixElementTimer': Timer, 'ninjars_install': install, 'copy': copy} + exec(compile(ast.Module(body=[function], type_ignores=[]), '', 'exec'), scope) + mloptions = {} if selected is None else {'MLReductionLib': selected[:]} + scope[name]({'model': object(), 'has_born': not has_born}, options={}, + tir={'ninjars_dir': str(self.lib)}, MLOptions=mloptions) + return observed + + def test_direct_timing_and_profile_use_actual_generated_born_status_on_reuse(self): + for name in ('check_timing', 'check_profile'): + for reuse in (False, True): + with self.subTest(name=name, reuse=reuse): + self.assertTrue(all(value == [8] for value in self.direct_cli_selection(name, reusing=reuse))) + (self.lib / 'ninjars-config.json').unlink() + for name in ('check_timing', 'check_profile'): + self.assertTrue(all(value == [6] for value in self.direct_cli_selection(name))) + + def test_direct_cli_explicit_lists_and_loop_induced_timing_are_unchanged(self): + for name in ('check_timing', 'check_profile'): + for selection in ([6], [8], [6, 8], [7, 6, 1]): + with self.subTest(name=name, selection=selection): + self.assertTrue(all(value == selection for value in self.direct_cli_selection(name, selected=selection))) + self.assertTrue(all(value == [7, 6, 1] for value in self.direct_cli_selection(name, + has_born=False, selected=[7, 6, 1]))) + self.assertEqual(self.direct_cli_selection('check_timing', has_born=False), [[6]]) + + +if __name__ == '__main__': unittest.main() diff --git a/tests/unit_tests/loop/test_ninjars_fortran.py b/tests/unit_tests/loop/test_ninjars_fortran.py new file mode 100644 index 0000000000..3275a3be45 --- /dev/null +++ b/tests/unit_tests/loop/test_ninjars_fortran.py @@ -0,0 +1,525 @@ +"""Compile the actual MadLoop adapters without requiring an installed NinjaRS. + +A recording scalar backend checks the Fortran ABI, precision and conventions; +end-to-end numerical comparisons use the real libraries in the CLI benchmarks. +""" +import shutil +import subprocess +import tempfile +import unittest +from pathlib import Path + +from madgraph import MG5DIR +from madgraph.iolibs.file_writers import FortranWriter + +ROOT = Path(MG5DIR) +TEMPLATE = ROOT / 'madgraph/iolibs/template_files/loop_optimized' +PARAMS = ROOT / 'Template/loop_material/StandAlone/SubProcesses' + + +@unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') +class NinjaRSFortranTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory(prefix='ninjars-fortran-') + self.work = Path(self.tmp.name) + self.addCleanup(self.tmp.cleanup) + + def run_command(self, *args): + result = subprocess.run(args, cwd=self.work, text=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + self.assertEqual(result.returncode, 0, result.stdout) + return result.stdout + + def compile_run(self, sources): + self.run_command('gfortran', '-ffixed-line-length-132', '-fcheck=all', + '-I', str(PARAMS), *sources, '-o', 'check') + return self.run_command(str(self.work / 'check')) + + def test_legacy_and_ninjars_return_codes(self): + source = (PARAMS / 'MadLoopCommons.inc').read_text() + routine = source.split(' INTEGER FUNCTION SET_RET_CODE_U', 1)[1] + routine = routine.split(' SUBROUTINE DETECT_LOOPLIB', 1)[0] + (self.work / 'status.f').write_text( + ' INTEGER FUNCTION SET_RET_CODE_U' + routine + ''' + PROGRAM TEST_STATUS + IMPLICIT NONE + INTEGER SET_RET_CODE_U,I + DO I=1,8 + IF (SET_RET_CODE_U(I,.FALSE.,.TRUE.).NE.I) STOP 1 + IF (SET_RET_CODE_U(I,.FALSE.,.FALSE.).NE.0) STOP 2 + IF (SET_RET_CODE_U(I,.TRUE.,.FALSE.).NE.0) STOP 3 + ENDDO + IF (SET_RET_CODE_U(1,.TRUE.,.TRUE.).NE.9) STOP 4 + IF (SET_RET_CODE_U(6,.TRUE.,.TRUE.).NE.8) STOP 5 + IF (SET_RET_CODE_U(8,.TRUE.,.TRUE.).NE.2) STOP 6 + END +''') + self.compile_run(['status.f']) + + def test_card_eight_libraries_and_terminator(self): + (self.work / 'card.dat').write_text( + '#MLReductionLib\n8|7|6|5|4|3|2|1|8\n' + '#UseQPIntegrandForNinjaRS\n.FALSE.\n') + (self.work / 'card.f').write_text(''' + PROGRAM TEST_CARD + IMPLICIT NONE + INCLUDE 'MadLoopParams.inc' + CHARACTER*512 FILENAME + CALL DEFAULTPARAM() + IF(ANY(MLReductionLib(4:9).NE.0)) STOP 1 + IF(.NOT.UseQPIntegrandForNinjaRS) STOP 2 + FILENAME='card.dat' + CALL MADLOOPPARAMREADER(FILENAME,.FALSE.) + IF(ANY(MLReductionLib.NE.(/8,7,6,5,4,3,2,1,0/))) STOP 3 + IF(UseQPIntegrandForNinjaRS) STOP 4 + END +''') + self.compile_run(['card.f', str(PARAMS / 'MadLoopParamReader.f')]) + + def test_unavailable_ninjars_only_is_actionable_and_fallback_is_preserved(self): + source = (TEMPLATE / 'loop_matrix_standalone.inc').read_text() + block = source[source.index('IF (LOCAL_ML_INIT) THEN'):source.index( + 'C Setup the file paths')] + with FortranWriter(str(self.work / 'selection.f')) as writer: + writer.writelines(''' + PROGRAM TEST_SELECTION + IMPLICIT NONE + INTEGER NLOOPLIB,QP_NLOOPLIB,I,J,MODE,MLReductionLib(9) + PARAMETER (NLOOPLIB=8,QP_NLOOPLIB=3) + INTEGER INDEX_QP_TOOLS(QP_NLOOPLIB+1) + LOGICAL LOCAL_ML_INIT,QP_TOOLS_AVAILABLE + LOGICAL LOOPLIBS_AVAILABLE(NLOOPLIB) + LOGICAL LOOPLIBS_QPAVAILABLE(0:NLOOPLIB) + CHARACTER*1 ARG + CALL GET_COMMAND_ARGUMENT(1,ARG) + READ(ARG,*) MODE + LOCAL_ML_INIT=.TRUE. + LOOPLIBS_AVAILABLE=.FALSE. + LOOPLIBS_AVAILABLE(1)=.TRUE. + LOOPLIBS_AVAILABLE(6)=.TRUE. + LOOPLIBS_QPAVAILABLE=.FALSE. + LOOPLIBS_QPAVAILABLE(1)=.TRUE. + LOOPLIBS_QPAVAILABLE(6)=.TRUE. + MLReductionLib=0 + MLReductionLib(1)=8 + IF(MODE.EQ.2) MLReductionLib(2)=6 + IF(MODE.EQ.3) MLReductionLib(1:3)=(/6,7,1/) + IF(MODE.EQ.4) THEN + LOOPLIBS_AVAILABLE(8)=.TRUE. + LOOPLIBS_QPAVAILABLE(8)=.TRUE. + ENDIF +''' + block + ''' + ENDIF + IF(MODE.EQ.1) STOP 71 + IF(MODE.EQ.2) THEN + IF(ANY(MLReductionLib(1:2).NE.(/6,0/))) STOP 72 + IF(INDEX_QP_TOOLS(1).NE.1) STOP 73 + ELSEIF(MODE.EQ.3) THEN + IF(ANY(MLReductionLib(1:3).NE.(/6,1,0/))) STOP 74 + IF(ANY(INDEX_QP_TOOLS(1:2).NE.(/1,2/))) STOP 75 + ELSEIF(MODE.EQ.4) THEN + IF(ANY(MLReductionLib(1:2).NE.(/8,0/))) STOP 76 + IF(INDEX_QP_TOOLS(1).NE.1) STOP 77 + ENDIF + IF(.NOT.QP_TOOLS_AVAILABLE) STOP 78 + WRITE(*,*) 'SELECTION ACCEPTED' + END +''') + self.run_command('gfortran', '-ffixed-line-length-132', '-fcheck=all', + 'selection.f', '-o', 'selection') + output = self.run_command(str(self.work / 'selection'), '1') + self.assertIn("install ninjars", output) + self.assertIn('regenerate and rebuild', output) + self.assertNotIn('SELECTION ACCEPTED', output) + for mode in ('2', '3', '4'): + with self.subTest(mode=mode): + output = self.run_command(str(self.work / 'selection'), mode) + self.assertIn('SELECTION ACCEPTED', output) + self.assertNotIn('unavailable', output) + + def test_tensor_abi_normalization_precision_and_failures(self): + for amplitude in (False, True): + with self.subTest(amplitude_reduction=amplitude): + self.check_wrapper(amplitude) + + def test_tir_rejects_unsupported_backends_before_cache_access(self): + """Direct dispatch cannot bypass the normal unavailable-library filter.""" + source = (TEMPLATE / 'TIR_interface.inc').read_text() + source = source[:source.index( + ' SUBROUTINE %(proc_prefix)sSWITCH_ORDER')] + replacements = { + 'proc_prefix': 'TEST_', 'nloop_groups': 1, 'nSquaredSO': 1, + 'nexternal': 2, 'info_lines': '', 'process_lines': '', + 'real_dp_format': 'REAL*8', 'complex_dp_format': 'COMPLEX*16', + 'mass_dp_format': 'COMPLEX*16', 'include_vector': '', + } + (self.work / 'loop_max_coefs.inc').write_text( + ' INTEGER LOOPMAXCOEFS\n PARAMETER (LOOPMAXCOEFS=1)\n') + (self.work / 'tir_cache_size.inc').write_text( + ' PARAMETER (TIR_CACHE_SIZE=1)\n') + (self.work / 'coupl.inc').write_text( + ' REAL*8 MU_R\n COMMON/TEST_COUPL/MU_R\n') + driver = ''' + PROGRAM TEST_DISPATCH + IMPLICIT NONE + INCLUDE 'MadLoopParams.inc' + INTEGER MODE,CTMODE,LIBINDEX + REAL*8 PL(0:3,1),LSCALE,MU_R,NORMALIZATION + COMPLEX*16 MASS(1),RES(3),LOOPCOEFS(1) + LOGICAL STABLE,INIT_FLAGS(6),TIR_DONE(1,0:1) + CHARACTER*2 ARG + COMMON/TEST_CT/LSCALE,CTMODE + COMMON/TEST_I_LIB/LIBINDEX + COMMON/TEST_LCOEFS/LOOPCOEFS + COMMON/TEST_COUPL/MU_R + COMMON/TEST_TIRCACHING/TIR_DONE + COMMON/REDUCTIONCODEINIT/INIT_FLAGS + CALL GET_COMMAND_ARGUMENT(1,ARG) + READ(ARG,*) MODE + PL=0D0 + MASS=1D0 + LOOPCOEFS=1D0 + INIT_FLAGS=.FALSE. + TIR_DONE=.FALSE. + STABLE=.TRUE. + LIBINDEX=1 + CTMODE=1 + LoopPoleMode=0 + COLLIERUseInternalStabilityTest=.FALSE. + MU_R=91D0 + MLReductionLib=0 + MLReductionLib(1)=7 + IF(MODE.GE.10) THEN +C Fill a real coefficient cache with a valid reduction before switching IDs. + CALL TEST_TIRLOOP(1,1,1,1,PL,MASS,0,RES,STABLE) + ENDIF + MLReductionLib(1)=MOD(MODE,10) + CALL TEST_TIRLOOP(1,1,1,1,PL,MASS,0,RES,STABLE) + NORMALIZATION=%(factor)dD0/(16D0*3.14159265358979323846D0**2) + IF(ANY(ABS(RES-NORMALIZATION).GT.1D-15)) STOP 81 + WRITE(*,*) 'DISPATCH RETURNED' + END + SUBROUTINE TEST_INITTIR() + END + SUBROUTINE ML_LOOP_POLE_FLAGS(UV,IR) + LOGICAL UV,IR + UV=.TRUE. + IR=.TRUE. + END + SUBROUTINE TEST_CLEAR_TIR_CACHE() + LOGICAL TIR_DONE(1,0:1) + COMMON/TEST_TIRCACHING/TIR_DONE + TIR_DONE=.FALSE. + END + INTEGER FUNCTION TEST_TIRCACHE_INDEX(MODE) + INTEGER MODE + TEST_TIRCACHE_INDEX=1 + END + SUBROUTINE TEST_COLLIERLOOP(MODE,N,R,PL,PDEN,MASS,COEFS,ERRORS) + INTEGER MODE,N,R + REAL*8 PL(0:3,N),PDEN(0:3,N) + COMPLEX*16 MASS(N),COEFS(1,3),ERRORS(1,3) + COEFS=1D0 + ERRORS=0D0 + END +''' + for amplitude in (False, True): + for caching in (False, True): + with self.subTest(amplitude=amplitude, caching=caching): + with FortranWriter(str(self.work / 'tir.f')) as writer: + writer.writelines(source % replacements, context={ + 'AmplitudeReduction': amplitude, 'TIRCaching': caching, + 'collier_available': True, 'golem_available': False, + 'iregi_available': False, 'pjfry_available': False}) + (self.work / 'dispatch.f').write_text( + driver % {'factor': 1 if amplitude else 2}) + self.run_command('gfortran', '-ffixed-line-length-132', + '-fcheck=all', '-I', str(PARAMS), + 'tir.f', 'dispatch.f', '-o', 'dispatch') + for mode in (7, 17, 8, 18, 6, 16): + result = subprocess.run( + [str(self.work / 'dispatch'), str(mode)], + cwd=self.work, text=True, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + with self.subTest(mode=mode): + if mode % 10 == 7: + self.assertEqual(result.returncode, 0, result.stdout) + self.assertIn('DISPATCH RETURNED', result.stdout) + else: + self.assertNotEqual(result.returncode, 0, result.stdout) + self.assertNotIn('DISPATCH RETURNED', result.stdout) + if mode % 10 == 8: + self.assertIn('install ninjars', result.stdout) + self.assertIn('regenerate and rebuild', result.stdout) + else: + self.assertIn('Unsupported TIR reduction library', + result.stdout) + + def test_exit_cleanup_with_and_without_ninjars(self): + source = (TEMPLATE / 'loop_matrix_standalone.inc').read_text() + source = source[source.index( + '\t SUBROUTINE %(proc_prefix)sEXIT_MADLOOP()'):] + (self.work / 'cleanup.f90').write_text(''' +module mninjars +contains +subroutine ninjars_finalize(status) +integer, optional, intent(out) :: status +integer :: finalizations,color_cleanups +common /cleanup_counts/ finalizations,color_cleanups +finalizations=finalizations+1 +if (present(status)) status=0 +end subroutine +end module +''') + for available in (False, True): + for color_flows in (False, True): + with self.subTest(ninjars_available=available, + color_flows=color_flows): + with FortranWriter(str(self.work / 'exit.f')) as writer: + writer.writelines(source % {'proc_prefix': 'TEST_'}, + context={ + 'ninjars_available': available, + 'ComputeColorFlows': color_flows}) + (self.work / 'exit_driver.f90').write_text(f''' +program check_exit +integer :: finalizations,color_cleanups +common /cleanup_counts/ finalizations,color_cleanups +finalizations=0 +color_cleanups=0 +call TEST_EXIT_MADLOOP() +if (finalizations/={int(available)}) stop 1 +if (color_cleanups/={int(color_flows)}) stop 2 +end program +subroutine TEST_DEALLOCATE_COLOR_FLOWS() +integer :: finalizations,color_cleanups +common /cleanup_counts/ finalizations,color_cleanups +color_cleanups=color_cleanups+1 +end subroutine +''') + sources = ['cleanup.f90'] if available else [] + self.compile_run(sources + ['exit.f', 'exit_driver.f90']) + + def test_public_wrapper_resets_retry_on_entry_and_early_return(self): + source = (TEMPLATE / 'loop_matrix_standalone.inc').read_text() + source = source[:source.index( + ' SUBROUTINE %(proc_prefix)sSLOOPMATRIX_RETRY_IMPL(P_USER,ANS)')] + source += '## }\n' + with FortranWriter(str(self.work / 'entry.f')) as writer: + writer.writelines(source % { + 'proc_prefix': 'TEST_', 'nexternal': 3, 'real_dp_format': 'REAL*8'}, + context={'ninjars_available': True}) + (self.work / 'entry_driver.f90').write_text(''' +program entry_check +implicit none +logical :: mode,used +common /TEST_NRS_RETRY_FLAGS/ mode,used +real(8) :: p(0:3,3),ans(0:3,0:0) +integer :: i +p=0 +do i=1,2 + mode=.true. + used=.true. + call TEST_SLOOPMATRIX(p,ans) + if(mode.or..not.used.or.any(ans/=777d0)) stop 61 +enddo +end program +subroutine TEST_SLOOPMATRIX_RETRY_IMPL(p,ans) +implicit none +logical :: mode,used +common /TEST_NRS_RETRY_FLAGS/ mode,used +integer :: count,passed,failed,hard +common /TEST_NRS_RETRY_STATS/ count,passed,failed,hard +real(8) :: native_acc,comp_acc +common /TEST_NRS_RETRY_ACC/ native_acc,comp_acc +real(8) :: p(0:3,3),ans(0:3,0:0) +if(mode.or.used) stop 62 +if(count/=0.or.passed/=0.or.failed/=0.or.hard/=0) stop 63 +if(native_acc/=-1d0.or.comp_acc/=-1d0) stop 64 +ans=777 +mode=.true. +used=.true. +count=1 +failed=1 +return +end subroutine +''') + self.compile_run(['entry.f', 'entry_driver.f90']) + + def check_wrapper(self, amplitude): + replacements = { + 'proc_prefix': 'TEST_', 'nloop_groups': 2, 'nSquaredSO': 2, + 'real_dp_format': 'REAL*8', 'complex_dp_format': 'COMPLEX*16', + 'mass_dp_format': 'COMPLEX*16', 'real_mp_format': 'REAL*16', + 'complex_mp_format': 'COMPLEX*32', 'include_vector': '', + } + source = (TEMPLATE / 'NINJARS_interface.inc').read_text() + # Use the production momentum reversal and on-shell threshold helpers. + helpers = (TEMPLATE / 'CT_interface.inc').read_text() + helpers = helpers[helpers.index('\t SUBROUTINE %(proc_prefix)sBUILD_KINEMATIC_MATRIX'):] + helpers = helpers[:helpers.index('## if(samurai_available)')] + switch = (TEMPLATE / 'TIR_interface.inc').read_text() + switch = switch[switch.index(' SUBROUTINE %(proc_prefix)sSWITCH_ORDER'):] + switch = switch[:switch.index('\t SUBROUTINE %(proc_prefix)sINITTIR')] + matrix = (TEMPLATE / 'loop_matrix_standalone.inc').read_text() + setter = matrix[matrix.index( + ' SUBROUTINE %(proc_prefix)sSET_LOOP_POLE_MODE(MODE)'):] + setter = setter[:setter.index( + '\t SUBROUTINE %(proc_prefix)sCOLLIER_COMPUTE_UV_POLES')] + with FortranWriter(str(self.work / 'wrapper.f')) as writer: + writer.writelines((source + helpers + switch + setter) % replacements, + context={'ninjars_available': True, + 'ninjars_supports_quad_prec': True, + 'AmplitudeReduction': amplitude}) + (self.work / 'loop_max_coefs.inc').write_text( + ' INTEGER LOOPMAXCOEFS\n PARAMETER (LOOPMAXCOEFS=15)\n') + (self.work / 'coupl.inc').write_text( + ' REAL*8 MU_R\n COMMON/TEST_COUPL/MU_R\n') + module = '''module TEST_POLYNOMIAL_CONSTANTS +integer :: NCOEF_R(0:2)=[1,5,15] +integer :: COEFTORANK_MAP(0:14)=[0,1,1,1,1,2,2,2,2,2,2,2,2,2,2] +end module +module mninjars +use, intrinsic :: ieee_arithmetic +integer,parameter :: KI_NRS=kind(1d0),KI_QNRS=selected_real_kind(33,4931) +integer,parameter :: NINJARS_SUCCESS=0 +integer :: failure_mode=0 +logical :: seen_mp_extra=.false. +integer :: compensated_calls=0,last_pole_mode=-99 +real(8) :: last_shift(0:3),last_s +complex(8) :: last_mass +interface ninjars_tensor_evaluate +module procedure eval_dp,eval_mp +end interface +contains +''' + for precision, kind in [('dp', 'KI_NRS'), ('mp', 'KI_QNRS')]: + module += f'''subroutine eval_{precision}(c,n,r,s,p,m,mu,res,r1,status,pole_mode) +integer :: n,r,status,i +integer,optional :: pole_mode +complex({kind}) :: c(:),m(n),res(0:2),r1 +real({kind}) :: s(n,n),p(0:3,n),mu +if (.not.present(pole_mode)) stop 58 +last_pole_mode=pole_mode +if (size(c)/=(r+1)*(r+2)*(r+3)*(r+4)/24) stop 31 +if (abs(mu-49)>1.e-12_{kind}) stop 32 +last_shift=real(p(:,2),kind=8) +last_mass=cmplx(m(2),kind=8) +last_s=real(s(1,2),kind=8) +status=0 +r1=0 +''' + if precision == 'mp': + module += 'seen_mp_extra=real(c(1),kind=16)>1.0_16\n' + module += f'''do i=0,2 +res(i)=(i+1)*sum(c)*cmplx(1,1,kind={kind}) +enddo +if (failure_mode==1) status=2 +if (failure_mode==2) res(0)=ieee_value(0.0_{kind},ieee_quiet_nan) +end subroutine +''' + module += '''subroutine ninjars_tensor_evaluate_compensated(c,n,r,s,p,m,mu,res,r1,status,pole_mode) +integer :: n,r,status +integer,optional :: pole_mode +complex(KI_NRS) :: c(:),m(n),res(0:2),r1 +real(KI_NRS) :: s(n,n),p(0:3,n),mu +compensated_calls=compensated_calls+1 +call eval_dp(c,n,r,s,p,m,mu,res,r1,status,pole_mode) +end subroutine +end module +''' + (self.work / 'modules.f90').write_text(module) + shape = '(0:14,2)' if amplitude else '(0:14,2,2)' + loop_common = 'ID,R' if amplitude else 'ID,SQSOINDEX,R' + coef = 'COEF(:,1)' if amplitude else 'COEF(:,1,1)' + mpcoef = 'MPCOEF(:,1)' if amplitude else 'MPCOEF(:,1,1)' + expected = 'cmplx(-13d0,-13d0,kind=8)' if amplitude else 'cmplx(-26d0,0d0,kind=8)' + expected_mp = 'cmplx(1d0,1d0,kind=8)' if amplitude else 'cmplx(2d0,0d0,kind=8)' + driver = f'''program check_wrapper +use mninjars +implicit none +integer :: ID,SQSOINDEX,R,CTMODE,I +common/TEST_LOOP/{loop_common} +real(8) :: LSCALE,MU_R,P(0:3,3),NOR +real(16) :: MP(0:3,3) +common/TEST_CT/LSCALE,CTMODE +common/TEST_COUPL/MU_R +complex(8) :: COEF{shape},M(3),RES(3) +complex(16) :: MPCOEF{shape} +common/TEST_LCOEFS/COEF +common/TEST_MP_LCOEFS/MPCOEF +logical :: FDP,FQP,STABLE +common/TEST_FPE_IN_REDUCTION/FDP,FQP +logical :: NRS_RETRY_MODE,NRS_RETRY_USED +common/TEST_NRS_RETRY_FLAGS/NRS_RETRY_MODE,NRS_RETRY_USED +! BLOCK DATA must initialize a direct wrapper call without SLOOPMATRIX. +if (NRS_RETRY_MODE.or.NRS_RETRY_USED) stop 53 +call DEFAULTPARAM() +ID=1 +SQSOINDEX=1 +R=1 +MU_R=7 +CTMODE=1 +FDP=.false. +FQP=.false. +COEF=0 +{coef}(0:4)=[(cmplx(I+1,0,kind=8),I=0,4)] +P(:,1)=[4d0,1d0,2d0,3d0] +P(:,2)=[2d0,0d0,0d0,0d0] +P(:,3)=-P(:,1)-P(:,2) +M=[cmplx(3d0,-.5d0,8),cmplx(5d0,-.7d0,8),cmplx(7d0,-.9d0,8)] +NOR=1d0/(16d0*3.14159265358979323846d0**2) +call TEST_NINJARS_LOOP(3,P,M,R,RES,STABLE) +if (.not.STABLE.or.FDP) stop 40 +if (abs(RES(1)/NOR-{expected})>1d-12) stop 41 +if (abs(RES(2)-2*RES(1))>1d-12) stop 42 +if (abs(RES(3)-3*RES(1))>1d-12) stop 43 +if (any(abs(last_shift-P(:,1))>1d-12)) stop 44 +if (abs(last_s-2d0)>1d-12) stop 45 +if (abs(last_mass-M(2))>1d-12) stop 46 +if (compensated_calls/=0) stop 54 +NRS_RETRY_MODE=.true. +call TEST_NINJARS_LOOP(3,P,M,R,RES,STABLE) +if (compensated_calls/=1.or..not.STABLE) stop 55 +if (abs(RES(1)/NOR-{expected})>1d-12) stop 56 +NRS_RETRY_MODE=.false. +CTMODE=2 +call TEST_NINJARS_LOOP(3,P,M,R,RES,STABLE) +if (.not.STABLE.or.abs(last_shift(0)-6d0)>1d-12) stop 47 +if (abs(last_mass-cmplx(7d0,-.9d0,8))>1d-12) stop 48 +if (compensated_calls/=1) stop 57 +CTMODE=4 +MP=real(P,kind=16) +MPCOEF=0 +{mpcoef}(0:0)=cmplx(1.0_16+2.0_16**(-100),0.0_16,kind=16) +call TEST_MP_NINJARS_LOOP(3,MP,M,R,RES,STABLE) +if (.not.STABLE.or.FQP.or..not.seen_mp_extra) stop 49 +if (abs(RES(1)/NOR-{expected_mp})>1d-12) stop 50 +! Check the actual generic setter and all three precision paths. +if(last_pole_mode/=0) stop 59 +do I=-1,3 + call TEST_SET_LOOP_POLE_MODE(I) + CTMODE=1 + call TEST_NINJARS_LOOP(3,P,M,R,RES,STABLE) + if(last_pole_mode/=max(0,I).or..not.STABLE) stop 60 + NRS_RETRY_MODE=.true. + call TEST_NINJARS_LOOP(3,P,M,R,RES,STABLE) + if(last_pole_mode/=max(0,I).or..not.STABLE) stop 61 + NRS_RETRY_MODE=.false. + CTMODE=4 + call TEST_MP_NINJARS_LOOP(3,MP,M,R,RES,STABLE) + if(last_pole_mode/=max(0,I).or..not.STABLE) stop 62 +enddo +failure_mode=1 +call TEST_NINJARS_LOOP(3,P,M,R,RES,STABLE) +if (STABLE.or..not.FDP.or.any(RES/=0)) stop 51 +failure_mode=2 +call TEST_MP_NINJARS_LOOP(3,MP,M,R,RES,STABLE) +if (STABLE.or..not.FQP.or.any(RES/=0)) stop 52 +end program +''' + # Fortran permits a section of a whole array, but not two chained sections. + driver = driver.replace(coef + '(0:4)', 'COEF(0:4,1)' if amplitude else 'COEF(0:4,1,1)') + driver = driver.replace(mpcoef + '(0:0)', 'MPCOEF(0,1)' if amplitude else 'MPCOEF(0,1,1)') + (self.work / 'driver.f90').write_text(driver) + self.compile_run(['modules.f90', 'wrapper.f', 'driver.f90', + str(PARAMS / 'MadLoopParamReader.f')]) diff --git a/tests/unit_tests/loop/test_ninjars_profile_output_path.py b/tests/unit_tests/loop/test_ninjars_profile_output_path.py new file mode 100644 index 0000000000..e20cbb1165 --- /dev/null +++ b/tests/unit_tests/loop/test_ninjars_profile_output_path.py @@ -0,0 +1,118 @@ +"""Actual whole stability method plus real driver path handling; no native calls.""" +import ast +import copy +import datetime +import glob +import logging +import math +import os +from pathlib import Path +import re +import tempfile +from types import SimpleNamespace +import unittest + +ROOT = Path(__file__).resolve().parents[3] +NEW = ROOT/'madgraph/various/process_checks.py' + +class BoundaryReached(RuntimeError): + pass + +class Process: + def shell_string(self): + return 'P0uux_z' + +class Matrix(dict): + def __init__(self): + super().__init__(processes=[Process()]) + +def extract(path, classname, method): + cls = next(n for n in ast.parse(path.read_text()).body + if isinstance(n, ast.ClassDef) and n.name == classname) + node = copy.deepcopy(next(n for n in cls.body + if isinstance(n, ast.FunctionDef) and n.name == method)) + node.decorator_list = [] + return node + +class OutputPath(unittest.TestCase): + def setUp(self): + temporary = tempfile.TemporaryDirectory(prefix='mg7-profile-output-') + self.addCleanup(temporary.cleanup) + self.work = Path(temporary.name) + + def exercise(self, source, infos=True, same_root=False, reusing=False): + installation = self.work/'installation' + output = installation if same_root else self.work/'private-output' + directory = output/'SAVEDTMP_CHECK_uux_z/SubProcesses/P0_uux_z' + directory.mkdir(parents=True) + driver = directory/'check_sa.f' + driver.write_text(' PARAMETER (READPS = .FALSE.)\n' + ' PARAMETER (NPSPOINTS = 9)\n' + ' CALL ML5_0_SLOOPMATRIX_THRES(P,MATELEM,ACC)\n') + library = self.work/'ninja';library.mkdir() + (library/'libninja.a').write_text('non-native test fixture') + calls, setups = [], [] + namespace = {'os': os, 're': re, 'pjoin': os.path.join, + 'misc': SimpleNamespace(glob=lambda pattern,path:glob.glob(str(Path(path)/pattern))), + 'MadGraph5Error': ValueError} + real_node = extract(ROOT/'madgraph/interface/madevent_interface.py', + 'MadLoopInitializer','fix_PSPoint_in_check') + exec(compile(ast.Module(body=[real_node],type_ignores=[]),'','exec'),namespace) + real_fix = namespace['fix_PSPoint_in_check'] + def fix(path, **kwargs): + calls.append((path, kwargs)) + real_fix(path, **kwargs) + raise BoundaryReached('Real check_sa.f updated; stop before native compilation') + info = dict(Process_output=.1,HELAS_MODEL_compilation=.1, + Process_compilation=.1,Initialization=.01,dir_path=str(directory)) + class Timer: + mg_root = str(installation) + output_path = str(output) + loop_optimized_output = True + tir_dir = {'ninja_dir': str(library)} + def setup_process(self, matrix, export, *args): + setups.append(export) + return dict(info) + def forbidden(*args, **kwargs): + raise AssertionError('No compiler/native process is allowed in this regression') + logger = logging.getLogger('private-output-path-regression');logger.setLevel(logging.CRITICAL) + namespace = dict(os=os,re=re,copy=copy,math=math,datetime=datetime,logging=logging, + misc=SimpleNamespace(make_unique=lambda values:list(dict.fromkeys(values))), + pjoin=os.path.join,temp_dir_prefix='TMP_CHECK',logger=logger, + MadGraph5Error=ValueError,base_objects=SimpleNamespace(Process=Process), + helas_objects=SimpleNamespace(HelasMatrixElement=Matrix), + MadLoopInitializer=SimpleNamespace(fix_PSPoint_in_check=fix), + bannermod=SimpleNamespace(MadLoopParam=SimpleNamespace(_ID_reduction_tool_map={6:'Ninja'})), + subprocess=SimpleNamespace(Popen=forbidden,call=forbidden,check_call=forbidden)) + node=extract(source,'LoopMatrixElementTimer','check_matrix_element_stability') + exec(compile(ast.Module(body=[node],type_ignores=[]),str(source),'exec'),namespace) + Timer.check_matrix_element_stability=namespace['check_matrix_element_stability'] + timer=Timer() + try: + timer.check_matrix_element_stability(Process() if reusing else Matrix(), + options={'reuse':reusing,'npoints':1,'split_orders':-1,'events':False}, + infos_IN=dict(info) if infos else None,keep_folder=True, + MLOptions={'MLReductionLib':[6]}) + except BoundaryReached: + self.assertEqual(calls,[(str(output/'SAVEDTMP_CHECK_uux_z/SubProcesses'), + {'read_ps':True,'npoints':1,'hel_config':-1,'split_orders':-1})]) + self.assertIn('READPS = .TRUE.',driver.read_text()) + self.assertIn('NPSPOINTS = 1',driver.read_text()) + self.assertEqual(setups,[] if infos else [str(output/'SAVEDTMP_CHECK_uux_z')]) + return + self.fail('Expected driver boundary') + + def test_profile_reuses_existing_process_in_explicit_private_output(self): + self.exercise(NEW,reusing=True) + + def test_profile_reuses_infos_in_explicit_private_output(self): + self.exercise(NEW) + + def test_standalone_stability_exports_into_explicit_private_output(self): + self.exercise(NEW,infos=False) + + def test_default_installation_output_behavior_unchanged(self): + self.exercise(NEW,same_root=True) + +if __name__=='__main__': + unittest.main() diff --git a/tests/unit_tests/loop/test_ninjars_profile_stability_io.py b/tests/unit_tests/loop/test_ninjars_profile_stability_io.py new file mode 100644 index 0000000000..f6b1483bf8 --- /dev/null +++ b/tests/unit_tests/loop/test_ninjars_profile_stability_io.py @@ -0,0 +1,384 @@ +"""Run the complete stability/report I/O with real cards and a mocked checker.""" +import ast +import copy +import datetime +import errno +import glob +import io +import logging +import math +import os +from pathlib import Path +import re +import shutil +import sys +import tempfile +from types import SimpleNamespace +import unittest +from unittest import mock + +from madgraph.iolibs import save_load_object +from madgraph.various import banner + +ROOT = Path(__file__).resolve().parents[3] +SOURCE = ROOT / 'madgraph/various/process_checks.py' +INITIALIZER = ROOT / 'madgraph/interface/madevent_interface.py' + + +def method(path, owner, name): + tree = ast.parse(path.read_text()) + cls = next(n for n in tree.body if isinstance(n, ast.ClassDef) and n.name == owner) + node = copy.deepcopy(next(n for n in cls.body if isinstance(n, ast.FunctionDef) and n.name == name)) + node.decorator_list = [] + return node + + +def add_functions(namespace, nodes, filename): + exec(compile(ast.Module(body=nodes, type_ignores=[]), str(filename), 'exec'), namespace) + + +class Process(dict): + def __init__(self): + super().__init__(legs=[{}, {}, {}]) + + def shell_string(self): + return 'P0uux_z' + + def nice_string(self): + return 'Process: u u~ > z' + + +class Matrix(dict): + def __init__(self): + super().__init__(processes=[Process()]) + + +class Checker: + def __init__(self, values): + self.stdin = io.BytesIO() + text = ''.join(' ##TAG#RESULT_START#TAG##\nFIN %.17g\n ##TAG#RESULT_STOP#TAG##\n' % value + for value in values) + self.stdout = io.BytesIO(text.encode()) + self.stderr = io.BytesIO() + self.killed = False + + def poll(self): + return None + + def kill(self): + self.killed = True + + def wait(self): + return 0 + + +class StabilityFilesystem(unittest.TestCase): + def setUp(self): + parent = ROOT / '.ninjars-build/tmp' + parent.mkdir(parents=True, exist_ok=True) + self.temporary = tempfile.TemporaryDirectory(dir=parent, prefix='stability-io-') + self.addCleanup(self.temporary.cleanup) + self.root = Path(self.temporary.name) + self.installation = self.root / 'installation' + templates = self.installation / 'Template/loop_material/Checks' + templates.mkdir(parents=True) + for name in ('StabilityCheckDriver.f', 'StabilityCheckDriver_loop_induced.f'): + shutil.copyfile(ROOT / 'Template/loop_material/Checks' / name, templates / name) + self.logger = logging.getLogger('stability-full-io-software') + self.logger.setLevel(logging.CRITICAL) + self.namespace = dict(os=os, re=re, copy=copy, math=math, datetime=datetime, + logging=logging, io=io, file=io.FileIO, shutil=shutil, sys=sys, errno=errno, + time=SimpleNamespace(sleep=mock.Mock(side_effect=AssertionError('No retries expected'))), + random=SimpleNamespace(uniform=lambda a,b: .25), pjoin=os.path.join, + temp_dir_prefix='TMP_CHECK', logger=self.logger, MadGraph5Error=ValueError, + base_objects=SimpleNamespace(Process=Process), helas_objects=SimpleNamespace(HelasMatrixElement=Matrix), + bannermod=banner, save_load_object=save_load_object, + MatrixElementEvaluator=SimpleNamespace(pass_isolation_cuts=lambda p: True)) + self.compile_calls, self.engine_calls, self.checkers, self.setup_calls = [], [], [], [] + self.namespace['misc'] = SimpleNamespace( + make_unique=lambda values:list(dict.fromkeys(values)), + glob=lambda pattern,path:glob.glob(str(Path(path)/pattern)), compile=self.mock_compile) + self.namespace['subprocess'] = SimpleNamespace(call=self.mock_make, Popen=self.mock_popen, + PIPE=-1) + add_functions(self.namespace, [method(INITIALIZER, 'MadLoopInitializer', 'fix_PSPoint_in_check')], INITIALIZER) + self.namespace['MadLoopInitializer'] = SimpleNamespace(fix_PSPoint_in_check=self.namespace['fix_PSPoint_in_check']) + nodes = [method(SOURCE, 'LoopMatrixElementTimer', 'check_matrix_element_stability'), + method(SOURCE, 'LoopMatrixElementEvaluator', 'fix_MadLoopParamCard'), + method(SOURCE, 'LoopMatrixElementTimer', 'get_me_value'), + method(SOURCE, 'LoopMatrixElementEvaluator', 'parse_check_output')] + tree = ast.parse(SOURCE.read_text()) + names = {'boost_momenta', 'format_output', 'output_stability', 'output_timings', 'output_profile'} + nodes += [copy.deepcopy(n) for n in tree.body if isinstance(n, ast.FunctionDef) and n.name in names] + add_functions(self.namespace, nodes, SOURCE) + owner = self + class Timer: + mg_root = str(owner.installation) + loop_optimized_output = True + def setup_process(self, matrix, export, *args): + owner.setup_calls.append(export) + self.fix_MadLoopParamCard(str(owner.export / 'Cards'), mp=False, + MLOptions={'MLReductionLib': owner.backend}) + return dict(owner.info) + def get_momenta(self, process, options): + return [[45.,0.,0.,45.],[45.,0.,0.,-45.],[90.,0.,0.,0.]], 1. + for name in ('check_matrix_element_stability', 'fix_MadLoopParamCard'): + setattr(Timer, name, self.namespace[name]) + Timer.get_me_value = classmethod(self.namespace['get_me_value']) + Timer.parse_check_output = classmethod(self.namespace['parse_check_output']) + self.timer = Timer() + + def mock_make(self, command, cwd, **kwargs): + self.assertEqual(command, ['make', 'check']) + self.assertEqual(Path(cwd), self.directory) + self.compile_calls.append(('make', str(cwd))) + (self.directory / 'check').write_text('not executable') + return 0 + + def mock_compile(self, arg, cwd, **kwargs): + self.assertEqual(arg, ['StabilityCheckDriver']) + self.assertEqual(Path(cwd), self.directory) + self.compile_calls.append(('compile', str(cwd))) + self.assertIn('READPS = .TRUE.', (self.directory / 'check_sa.f').read_text()) + driver = (self.directory / 'StabilityCheckDriver.f').read_text() + self.assertIn('ML5_0_GET_ANSWER_DIMENSION', driver) + self.assertNotIn('%(proc_prefix)', driver) + (self.directory / 'StabilityCheckDriver').write_text('not executable') + + def mock_popen(self, command, cwd, **kwargs): + self.assertEqual(command, [str(self.directory / 'StabilityCheckDriver')]) + self.assertEqual(Path(cwd), self.directory) + active = banner.MadLoopParam(str(self.active_card)) + self.assertTrue(active['DoubleCheckHelicityFilter']) + self.assertFalse(active['UseLoopFilter']) + self.assertEqual(active['CTModeRun'], 1) + self.assertEqual(active['CTModeInit'], 1) + self.assertEqual(active['MLReductionLib'], str(self.backend)) + checker = Checker(self.values) + self.checkers.append(checker); self.engine_calls.append(command) + return checker + + def fixture(self, backend=8, layout='modern', default_output=False, keep=True): + self.backend = backend + output = self.installation if default_output else self.root / 'private-output' + self.export = output / (('SAVED' if keep else '') + 'TMP_CHECK_uux_z') + self.directory = self.export / 'SubProcesses/P0_uux_z'; self.directory.mkdir(parents=True) + (self.export / 'Cards').mkdir() + card = banner.MadLoopParam(str(ROOT / 'Template/loop_material/StandAlone/Cards/MadLoopParams.dat')) + card.set('MLReductionLib', str(backend)); card.set('DoubleCheckHelicityFilter', False) + card.write(str(self.export / 'Cards/MadLoopParams.dat')) + parent_card = self.export / 'SubProcesses/MadLoopParams.dat' + parent_card.symlink_to('../Cards/MadLoopParams.dat') + if layout == 'modern': + resources = self.export / 'SubProcesses/MadLoop5_resources'; resources.mkdir() + (resources / 'MadLoopParams.dat').symlink_to('../MadLoopParams.dat') + (self.directory / 'MadLoop5_resources').symlink_to('../MadLoop5_resources') + self.active_card = self.directory / 'MadLoop5_resources/MadLoopParams.dat' + else: + self.active_card = self.directory / 'MadLoopParams.dat' + self.active_card.symlink_to('../MadLoopParams.dat') + (self.directory / 'proc_prefix.txt').write_text('ML5_0_') + (self.directory / 'born_matrix.f').write_text('born fixture') + (self.directory / 'check_sa.f').write_text(' PARAMETER (READPS = .FALSE.)\n' + ' PARAMETER (NPSPOINTS = 9)\n CALL ML5_0_SLOOPMATRIX_THRES(P,MATELEM,ACC)\n') + (self.directory / 'check').write_text('old check') + (self.directory / 'check_sa.o').write_text('old object') + library = self.root / 'library'; library.mkdir() + name = 'ninja' if backend == 6 else 'ninjars' + (library / ('lib' + name + '.a')).write_text('not a native archive') + self.timer.tir_dir = {name + '_dir': str(library)} + self.timer.output_path = str(output) + self.info = dict(Process_output=.1, HELAS_MODEL_compilation=.1, Process_compilation=.1, + Initialization=.01, dir_path=str(self.directory)) + return output + + def call(self, npoints=2, reusing=True, infos=True, keep=True): + return self.timer.check_matrix_element_stability(Process() if reusing else Matrix(), + options={'reuse':reusing,'npoints':npoints,'split_orders':-1,'events':False}, + infos_IN=self.info if infos else None, keep_folder=keep, + MLOptions={'MLReductionLib':[self.backend]}) + + def report(self, result, output): + result['loop_optimized_output'] = True + timing = {key:.1 for key in ('HELAS_MODEL_compilation','HelasDiagrams_generation','Process_output', + 'Diagrams_generation','Process_compilation','Initialization','Booting_time')} + timing.update(loop_optimized_output=True,reduction_tool=self.backend, + run_unpolarized_total=.001,run_unpolarized_coefs=.0003, + run_polarized_total=.001,run_polarized_coefs=.0003, + n_contrib_hel=1,n_tot_hel=1,n_loops=1,n_loop_groups=1,n_loop_wfs=1, + loop_wfs_ranks=[1],ram_usage=1000,du_source='1',du_process='1',du_color='1',du_exe='1') + handler = logging.FileHandler(self.root / 'logging-only.log') + logger = logging.getLogger('madgraph'); logger.addHandler(handler) + try: + text = self.namespace['output_profile'](Process(), result, timing, str(output), reusing=True) + finally: + logger.removeHandler(handler); handler.close() + self.assertIn(banner.MadLoopParam._ID_reduction_tool_map[self.backend], text) + self.assertEqual((output / 'profile_optimized_P0uux_z.log').read_text(), text) + stable = (output / 'stability_optimized_P0uux_z.log').read_text() + self.assertIn('reduction=' + ('NINJA' if self.backend == 6 else 'NINJARS'), stable) + return stable + + def exercise(self, backend=8, layout='modern', default_output=False, zero=None, + reusing=True, infos=True, keep=True, cache=False, zero_mean=False, values=None): + output = self.fixture(backend, layout, default_output, keep) + self.values = ([zero] * 6 if zero is not None else [1.,1.0001,1.0002,1.,1.5,1.,1.1,1.10001,1.10002]) + if zero_mean: + self.values = [-1.,0.,1.,1.,1.,1.,1.,1.0001,1.0002] + if values is not None: + self.values = values + result = self.call(reusing=reusing, infos=infos, keep=keep) + name = banner.MadLoopParam._ID_reduction_tool_map[backend] + saved = self.directory / ('SavedStabilityRun_%s_0.pkl' % name) + loaded = save_load_object.load_from_file(str(saved)) + self.assertEqual(loaded, result['Stability'][name]) + self.assertEqual(len(loaded['DP_stability']), 2); self.assertEqual(len(loaded['QP_stability']), 2) + if zero is not None: + self.assertEqual([row['Accuracy'] for row in loaded['DP_stability']], [0.,0.]) + self.assertEqual(loaded['Unstable_PS_points'], []) + else: + self.assertEqual(len(loaded['Unstable_PS_points']), 1) + index = loaded['Unstable_PS_points'][0][0] + self.assertTrue(loaded['QP_stability'][index]) + if zero_mean: + self.assertEqual(loaded['DP_stability'][0]['Accuracy'], float('inf')) + self.assertEqual(len(self.compile_calls), 2); self.assertEqual(len(self.checkers), 1) + self.assertTrue(self.checkers[0].stdin.getvalue().endswith(b'y\n')) + self.assertFalse(self.checkers[0].killed) + self.assertTrue((self.export / 'SubProcesses/MadLoopParams.dat').is_symlink()) + self.assertTrue(self.active_card.is_symlink()) + self.assertFalse((self.export / 'SubProcesses/SubProcesses').exists()) + self.assertEqual(self.setup_calls, [] if infos else [str(self.export)]) + if cache: + contents = saved.read_bytes(); calls = (list(self.compile_calls),list(self.engine_calls)) + cached = self.call(npoints=0, reusing=True, keep=keep) + self.assertEqual(cached['Stability'][name], loaded) + self.assertEqual(saved.read_bytes(), contents) + self.assertEqual((self.compile_calls,self.engine_calls), calls) + stable = self.report(result, output) + if loaded['Unstable_PS_points']: + self.assertIn('QP Median accuracy', stable) + self.assertIn('DP vs QP stab test consistency', stable) + if zero is not None: + self.assertIn('Perfect accuracy', (output / 'profile_optimized_P0uux_z.log').read_text()) + self.assertIn('\n',1)[1].split('',1)[0] + self.assertEqual([float(line.split()[0]) for line in raw.splitlines()], [1e-320,1e308]) + plot = stable.split('\n',1)[1].split('',1)[0] + self.assertTrue(plot.splitlines()) + for line in plot.splitlines(): + threshold, fraction = map(float,line.split()) + self.assertTrue(math.isfinite(threshold)) + self.assertTrue(0. <= fraction <= 1.) + + def saved_cache(self, dp, qp): + name = banner.MadLoopParam._ID_reduction_tool_map[self.backend] + path = self.directory / ('SavedStabilityRun_%s_0.pkl' % name) + save_load_object.save_to_file(str(path), {'DP_stability':dp,'QP_stability':qp, + 'Unstable_PS_points':[],'Exceptional_PS_points':[]}) + return path + + def test_invalid_historical_pickle_records_are_rejected_before_report_output(self): + output = self.fixture(backend=8) + valid = dict(CTModeA=1.,CTModeB=1.,Rotation1=1.,Accuracy=0.) + trials = [] + for precision in ('DP_stability','QP_stability'): + for field, value in (('Accuracy',float('nan')), ('Accuracy',-.1), + ('Accuracy',float('-inf')), ('CTModeA',float('nan')), + ('CTModeA',float('inf')), ('Rotation1',float('-inf'))): + row = dict(valid); row[field] = value + trials.append((precision, field, row)) + trials.append(('DP_stability','empty',{})) + missing = dict(valid); missing.pop('Accuracy') + trials.append(('DP_stability','missingAccuracy',missing)) + for precision, field, invalid in trials: + with self.subTest(precision=precision, field=field, invalid=invalid): + dp = [invalid] if precision == 'DP_stability' else [dict(valid)] + qp = [invalid] if precision == 'QP_stability' else [{}] + cache = self.saved_cache(dp, qp); original = cache.read_bytes() + result = self.call(npoints=0) + self.assertEqual(self.compile_calls, []); self.assertEqual(self.engine_calls, []) + with self.assertRaisesRegex(ValueError, 'Invalid stability data.*'): + self.report(result, output) + self.assertEqual(cache.read_bytes(), original) + self.assertFalse((output / 'stability_optimized_P0uux_z.log').exists()) + self.assertFalse((output / 'profile_optimized_P0uux_z.log').exists()) + + def test_valid_infinite_cached_accuracy_and_empty_qp_remain_reportable(self): + output = self.fixture(backend=8) + row = dict(CTModeA=-1.,CTModeB=0.,Rotation1=1.,Accuracy=float('inf')) + cache = self.saved_cache([row], [{}]); original = cache.read_bytes() + result = self.call(npoints=0) + self.assertEqual(result['Stability']['NinjaRS']['DP_stability'], [row]) + self.assertEqual(result['Stability']['NinjaRS']['QP_stability'], [{}]) + self.assertIn('inf', self.report(result, output)) + self.assertEqual(cache.read_bytes(), original) + self.assertEqual(self.compile_calls, []); self.assertEqual(self.engine_calls, []) + + def test_valid_zero_fin_cached_record_remains_exactly_zero(self): + output = self.fixture(backend=6) + row = dict(CTModeA=0.,CTModeB=0.,Rotation1=0.,Accuracy=0.) + cache = self.saved_cache([row], [{}]); original = cache.read_bytes() + result = self.call(npoints=0) + self.assertEqual(result['Stability']['Ninja']['DP_stability'], [row]) + self.assertIn('0.0000e+00', self.report(result, output)) + self.assertEqual(cache.read_bytes(), original) + self.assertEqual(self.compile_calls, []); self.assertEqual(self.engine_calls, []) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/unit_tests/loop/test_ninjars_profile_timing_metadata.py b/tests/unit_tests/loop/test_ninjars_profile_timing_metadata.py new file mode 100644 index 0000000000..19ae683757 --- /dev/null +++ b/tests/unit_tests/loop/test_ninjars_profile_timing_metadata.py @@ -0,0 +1,316 @@ +"""Execute the live timing/profile methods with compiler and engine mocks.""" +import ast +import copy +import hashlib +import json +import logging +import os +import glob +import shutil +from pathlib import Path +import re +from types import SimpleNamespace +import unittest +import tempfile + +ROOT = Path(__file__).resolve().parents[3] +OLD = ROOT/'tests/input_files/ninjars_profile_timing_legacy.py' +NEW = ROOT/'madgraph/various/process_checks.py' + +class Process: + def get(self, key): + if key == 'has_born': + return True + raise KeyError(key) + + def shell_string(self): + return 'P0uux_z' + + def nice_string(self): + return 'Process: u u~ > z' + +class Matrix(dict): + def __init__(self): + super().__init__(processes=[Process()]) + +def actual_functions(path): + tree = ast.parse(path.read_text()) + cls = next(node for node in tree.body if isinstance(node,ast.ClassDef) and node.name=='LoopMatrixElementTimer') + names = ('time_matrix_element','boot_time_setup','skip_loop_evaluation_setup') + methods = [node for node in cls.body if isinstance(node,ast.FunctionDef) and node.name in names] + return methods + +def exercise(label, source, optimized=True, initialized=None, tool=8, failure=None, real_card=False, + mutate_runtime=None, base_root=None, physical_layout=None): + base = base_root/label + base.mkdir(parents=True,exist_ok=False) + calls = [] + count = [0] + archive_reads = [] + def observed_open(path,mode='r',*args,**kwargs): + if Path(path).name=='libninjars.a' and 'r' in mode: + archive_reads.append(str(path)) + return open(path,mode,*args,**kwargs) + card = dict(MLReductionLib=str(tool),CTModeRun=-1,CTModeInit=1, + COLLIERComputeUVpoles=True,COLLIERComputeIRpoles=True, + MLStabThres=1e-9,COLLIERRequiredAccuracy=1e-12) + if physical_layout is not None: + card['CTModeRun'] = 1 + class Initializer: + @staticmethod + def fix_PSPoint_in_check(path,**settings): + calls.append(('fix',dict(settings))) + directory = next((Path(path)).glob('P*_*')) + hel = settings.get('hel_config',-1) + call = ('CALL ML5_0_SLOOPMATRIXHEL_THRES(P,%s,MATELEM,ACC)'%hel if hel!=-1 + else 'CALL ML5_0_SLOOPMATRIX_THRES(P,MATELEM,ACC)') + (directory/'check_sa.f').write_text(' PARAMETER (NPSPOINTS = %s)\n'%settings['npoints']+ + ' PARAMETER (READPS = .FALSE.)\n SQRTS=1.0D3\n CALL ML5_0_SET_COUPLINGORDERS_TARGET(-1)\n '+call+'\n') + @staticmethod + def make_and_run(directory,checkRam=False): + directory = Path(directory) + calls.append(('make',checkRam,(directory/'check_sa.f').read_text(),(directory/'loop_matrix.f').read_text())) + count[0] += 1 + (directory/'check').write_text('mock nonexecutable build '+str(count[0])) + (directory/'result.dat').write_text('mock stage '+str(count[0])) + if mutate_runtime==count[0]: + (directory.parent.parent/'lib/libninjars.a').write_text('changed mock runtime') + if failure==count[0]: + return None,None,None + values = [0.6,0.1,2.0,3.0,1.0,0.8] if initialized is None else [0.1,2.,3.,1.,.8] + return .01,values[count[0]-1],123 if checkRam else None + class Timer: + loop_optimized_output = optimized + output_path = str(base) + @classmethod + def get_MadLoop_Params(cls,path): + if real_card: + from madgraph.various.banner import MadLoopParam + return MadLoopParam(path) + return copy.deepcopy(card) + def setup_process(self,matrix,export_dir,*args,**kwargs): + export = Path(export_dir) + directory = export/'SubProcesses/P0_uux_z' + resources = directory/'MadLoop5_resources' + resources.mkdir(parents=True) + (export/'Cards').mkdir() + for name in ('param_card.dat','MadLoopParams.dat'): + (export/'Cards'/name).write_text('mock '+name) + if real_card: + from madgraph.various.banner import MadLoopParam + actual = MadLoopParam() + for key,value in card.items(): + actual[key] = value + actual.write(str(export/'Cards/MadLoopParams.dat')) + if physical_layout is not None: + (resources/'param_card.dat').symlink_to('../../../Cards/param_card.dat') + (resources/'MadLoopParams.dat').symlink_to('../../../Cards/MadLoopParams.dat') + if physical_layout == 'flat-first': + (directory/'param_card.dat').write_text('mock param_card.dat') + (directory/'Cards').mkdir() + (directory/'Cards/param_card.dat').write_text('lower-priority decoy') + if physical_layout == 'ancestor-first': + (export/'SubProcesses/Cards').mkdir() + (export/'SubProcesses/Cards/param_card.dat').write_text('higher-priority native card') + (directory/'proc_prefix.txt').write_text('ML5_0_') + (resources/'ML5_0_HelFilter.dat').write_text('-10000 1 -10000\n' if optimized else 'F T F\n') + (resources/'ML5_0_HelConfigs.dat').write_text('1 -1 -1\n1 -1 0\n1 -1 1\n') + (directory/'loop_matrix.f').write_text(' PARAMETER(SKIPLOOPEVAL=.FALSE.)\n PARAMETER(BOOTANDSTOP=.FALSE.)\n') + (directory/'check').write_text('mock setup nonexecutable') + (export/'lib').mkdir() + (export/'lib/libninjars.a').write_text('mock archive text, not native') + (export/'lib/ninjars-config.json').write_text('{}') + (export/'Source').mkdir() + (export/'Source/make_opts').write_text('mock flags') + (export/'SubProcesses/MadLoop_makefile_definitions').write_text('mock link flags') + Initializer.fix_PSPoint_in_check(str(export/'SubProcesses'),read_ps=False,npoints=4) + return dict(dir_path=str(directory),Initialization=initialized,Process_output=.2, + HELAS_MODEL_compilation=.3,Process_compilation=.4) + ns = dict(os=os,re=re,copy=copy,glob=glob,shutil=shutil,open=observed_open, + MadGraph5Error=ValueError,pjoin=os.path.join,temp_dir_prefix='TMP_CHECK', + helas_objects=SimpleNamespace(HelasMatrixElement=Matrix),base_objects=SimpleNamespace(Process=Process), + MadLoopInitializer=Initializer,subprocess=SimpleNamespace(check_output=lambda *a,**k:'1K total\n'), + logger=logging.getLogger('mock-timing'),bannermod=SimpleNamespace(MadLoopParam=SimpleNamespace( + _ID_reduction_tool_map={6:'Ninja',8:'NinjaRS'}))) + exec(compile(ast.Module(body=actual_functions(source),type_ignores=[]),str(source),'exec'),ns) + for name in ('time_matrix_element','boot_time_setup','skip_loop_evaluation_setup'): + setattr(Timer,name,ns[name]) + result = Timer().time_matrix_element(Matrix(),MLOptions={'MLReductionLib':[tool]}) + (base/'archive-read-count.json').write_text(json.dumps(archive_reads)) + return result,calls,base + +class TimingMetadataTests(unittest.TestCase): + def setUp(self): + parent = ROOT/'.ninjars-build/tmp' + parent.mkdir(parents=True,exist_ok=True) + temporary = tempfile.TemporaryDirectory(dir=parent,prefix='mg5-profile-metadata-') + self.addCleanup(temporary.cleanup) + self.work = Path(temporary.name) + + def compare(self,name,**kwargs): + old,old_calls,_ = exercise(name+'-old',OLD,base_root=self.work,**kwargs) + new,new_calls,base = exercise(name+'-new',NEW,base_root=self.work,**kwargs) + self.assertEqual(old_calls,new_calls) + if old is None: + self.assertIsNone(new) + else: + raw = dict(new) + ref = raw.pop('timing_metadata') + old['dir_path'] = raw['dir_path'] + self.assertEqual(old,raw) + metadata = json.loads(Path(ref['path']).read_text()) + self.assertEqual(metadata['timing_result'],old) + self.assertEqual(metadata['selected_timing_helicity']['one_based_index'],2) + self.assertEqual(metadata['selected_timing_helicity']['physical_tuple'],[1,-1,0]) + self.assertEqual(metadata['selected_timing_helicity']['filter_tokens'], + ['-10000','1','-10000'] if kwargs.get('optimized',True) else ['F','T','F']) + self.assertEqual(metadata['reduction_backends'],[int(value) for value in str(kwargs.get('tool',8)).split('|')]) + self.assertFalse(metadata['per_evaluation_statuses_available']) + self.assertEqual(len(json.loads((base/'archive-read-count.json').read_text())),1) + for stage in metadata['stages']: + self.assertEqual(metadata['runtime_files']['lib/libninjars.a']['sha256'], + hashlib.sha256(b'mock archive text, not native').hexdigest()) + self.assertIn('sha256',stage['check_sa']) + self.assertIn('sha256',stage['loop_matrix']) + self.assertIn('sha256',stage['executable']) + self.assertIn('sha256',stage['raw_outputs']['result.dat']) + effective = {k.lower():v for k,v in stage['effective_madloop_parameters'].items()} + self.assertEqual(effective['mlstabthres'],1e-9) + self.assertEqual(effective['collierrequiredaccuracy'],1e-12) + self.assertFalse(stage['raw_output_freshness_verified']) + self.assertEqual(stage['runtime_files_reference'],'runtime_files') + self.assertTrue(stage['runtime_stat_unchanged']) + self.assertEqual(stage['energy_assignment_lines'],['SQRTS=1.0D3']) + self.assertEqual(stage['raw_outputs']['result.dat']['text'], + Path(stage['raw_outputs']['result.dat']['path']).read_text() if + stage is metadata['stages'][-1] else 'mock stage '+str(metadata['stages'].index(stage)+1)) + for field in ('check_sa.f','loop_matrix.f'): + record = stage['source_snapshots'][field] + self.assertEqual(hashlib.sha256(Path(record['path']).read_bytes()).hexdigest(),record['sha256']) + return metadata + + def test_optimized_native8_all_stage_calls_and_raw_floats_unchanged(self): + metadata = self.compare('optimized8') + stages = metadata['stages'] + self.assertEqual([s['name'] for s in stages],['estimate','boot','polarized_full','unpolarized_full','unpolarized_skip','polarized_skip']) + self.assertEqual([s['actual_npoints'] for s in stages],[3,3,302,151,151,302]) + self.assertEqual([s['flags'] for s in stages],[ + dict(SKIPLOOPEVAL=False,BOOTANDSTOP=False),dict(SKIPLOOPEVAL=False,BOOTANDSTOP=True), + dict(SKIPLOOPEVAL=False,BOOTANDSTOP=False),dict(SKIPLOOPEVAL=False,BOOTANDSTOP=False), + dict(SKIPLOOPEVAL=True,BOOTANDSTOP=False),dict(SKIPLOOPEVAL=True,BOOTANDSTOP=False)]) + for stage in stages[2:]: + self.assertEqual(stage['derived_seconds_per_point'],metadata['timing_result'][ + 'run_'+dict(polarized_full='polarized_total',unpolarized_full='unpolarized_total', + unpolarized_skip='unpolarized_coefs',polarized_skip='polarized_coefs')[stage['name']]]) + + def test_optimized_ninja6_same_metadata_contract(self): + self.compare('optimized6',tool=6) + + def test_real_madloopparam_string_selector_normalized_to_int_labels(self): + metadata = self.compare('realcard8',real_card=True) + self.assertEqual(metadata['reduction_backends'],[8]) + self.assertEqual(metadata['backend_labels'],['NinjaRS']) + + def test_real_madloopparam_ordered_selector_normalized(self): + metadata = self.compare('realcard86',real_card=True,tool='8|6') + self.assertEqual(metadata['reduction_backends'],[8,6]) + self.assertEqual(metadata['backend_labels'],['NinjaRS','Ninja']) + + def test_prior_initialization_omits_estimate_without_changing_calls(self): + metadata = self.compare('initialized',initialized=8.) + self.assertEqual(metadata['stages'][0]['name'],'boot') + self.assertEqual(metadata['stages'][0]['actual_npoints'],4) + + def test_unoptimized_early_return_is_recorded(self): + metadata = self.compare('unoptimized',optimized=False) + self.assertEqual([s['name'] for s in metadata['stages']],['estimate','boot','polarized_full','unpolarized_full']) + + def test_compile_failure_return_and_partial_metadata_preserved(self): + self.compare('failure',failure=3) + path = next((self.work/'failure-new').glob('*/SavedRunInfos/profile_timing_metadata.json')) + partial = json.loads(path.read_text()) + self.assertEqual(len(partial['stages']),3) + self.assertEqual(partial['stages'][-1]['name'],'polarized_full') + self.assertIsNone(partial['stages'][-1]['compile_seconds']) + + def test_runtime_mutation_rejected_after_existing_run_without_rehash(self): + with self.assertRaisesRegex(ValueError,'Timing runtime changed during measurement'): + exercise('runtime-mutated',NEW,mutate_runtime=2,base_root=self.work) + + def test_profile_merged_raw_dictionary_captured_before_stability_mutation(self): + _,_,base = exercise('profile-seed',NEW,base_root=self.work) + path = next(base.glob('*/SavedRunInfos/profile_timing_metadata.json')) + seed = json.loads(path.read_text())['timing_result'] + seed['timing_metadata'] = dict(path=str(path),schema='madloop-profile-timing-metadata-v1') + class Profiler: + loop_optimized_output = True + def __init__(self,**kwargs): pass + def time_matrix_element(self,*args,**kwargs): return copy.deepcopy(seed) + def check_matrix_element_stability(self,*args,**kwargs): + kwargs['infos_IN']['run_unpolarized_total'] = 999 + return {'Stability':{}} + proc = SimpleNamespace(get=lambda key:object()) + tree = ast.parse(NEW.read_text()) + fn = next(n for n in tree.body if isinstance(n,ast.FunctionDef) and n.name=='check_profile') + ns = dict(copy=copy,FakeInterface=lambda:None,base_objects=SimpleNamespace(Process=Process), + LoopMatrixElementTimer=Profiler,generate_loop_matrix_element=lambda *a,**k:({'Diagrams_generation':.123456789},Matrix())) + exec(compile(ast.Module(body=[fn],type_ignores=[]),str(NEW),'exec'),ns) + returned,_ = ns['check_profile'](proc,MLOptions={'MLReductionLib':[8]}) + metadata = json.loads(path.read_text()) + self.assertEqual(metadata['profile_timing_result']['run_unpolarized_total'],seed['run_unpolarized_total']) + self.assertEqual(metadata['profile_timing_result']['Diagrams_generation'],.123456789) + self.assertEqual(returned['run_unpolarized_total'],999) + + def assert_card_record(self, record, expected): + contents = expected.read_bytes() + self.assertEqual(Path(record['path']).resolve(),expected.resolve()) + self.assertEqual(record['realpath'],str(expected.resolve())) + self.assertNotEqual(record.get('available'),False) + self.assertEqual(record['bytes'],len(contents)) + self.assertEqual(record['sha256'],hashlib.sha256(contents).hexdigest()) + self.assertEqual(record['text'],contents.decode('utf-8')) + + def test_modern_resource_only_card_is_observed_by_actual_timing_method(self): + for tool in (6,8): + result,_,_ = exercise('modern-%d'%tool,NEW,tool=tool,real_card=True, + physical_layout='modern',base_root=self.work) + metadata = json.loads(Path(result['timing_metadata']['path']).read_text()) + directory = Path(metadata['subprocess_dir']) + self.assertFalse((directory/'param_card.dat').exists()) + self.assertTrue((directory/'MadLoop5_resources/param_card.dat').is_file()) + self.assertEqual(metadata['reduction_backends'],[tool]) + self.assertEqual(len(metadata['stages']),6) + expected = Path(metadata['export_dir'])/'Cards/param_card.dat' + for stage in metadata['stages']: + self.assert_card_record(stage['parameter_card'],expected) + self.assert_card_record(stage['subprocess_parameter_card'],expected) + + def test_native_flat_card_priority_beats_lower_cards_decoy(self): + result,_,_ = exercise('flat',NEW,real_card=True, + physical_layout='flat-first',base_root=self.work) + metadata = json.loads(Path(result['timing_metadata']['path']).read_text()) + expected = Path(metadata['subprocess_dir'])/'param_card.dat' + decoy = expected.parent/'Cards/param_card.dat' + self.assertNotEqual(expected.read_bytes(),decoy.read_bytes()) + for stage in metadata['stages']: + self.assertEqual(Path(stage['subprocess_parameter_card']['path']),expected) + self.assert_card_record(stage['subprocess_parameter_card'],expected) + self.assertEqual(stage['subprocess_parameter_card']['sha256'], + stage['parameter_card']['sha256']) + + def test_intervening_ancestor_card_records_different_effective_physics(self): + result,_,_ = exercise('ancestor',NEW,real_card=True, + physical_layout='ancestor-first',base_root=self.work) + metadata = json.loads(Path(result['timing_metadata']['path']).read_text()) + export = Path(metadata['export_dir']) + expected = export/'SubProcesses/Cards/param_card.dat' + canonical = export/'Cards/param_card.dat' + self.assertNotEqual(expected.read_bytes(),canonical.read_bytes()) + for stage in metadata['stages']: + self.assert_card_record(stage['parameter_card'],canonical) + self.assert_card_record(stage['subprocess_parameter_card'],expected) + self.assertNotEqual(stage['subprocess_parameter_card']['sha256'], + stage['parameter_card']['sha256']) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/unit_tests/loop/test_terminal_wavefunctions.py b/tests/unit_tests/loop/test_terminal_wavefunctions.py new file mode 100644 index 0000000000..223178cf73 --- /dev/null +++ b/tests/unit_tests/loop/test_terminal_wavefunctions.py @@ -0,0 +1,236 @@ +"""The private diagonal updater must fail closed on unknown consumers.""" +from pathlib import Path +import os +import shutil +import subprocess +import tempfile +import unittest +from unittest.mock import Mock + +from madgraph.iolibs.helas_call_writers import FortranUFOHelasCallWriterOptimized as Writer +from madgraph.loop.loop_exporters import LoopProcessOptimizedExporterFortranSA as Exporter +from madgraph.loop.loop_helas_objects import LoopHelasMatrixElement + + +class Wavefunction(dict): + def __init__(self, number, mother=None, is_loop=True): + super().__init__(number=number, me_id=number, is_loop=is_loop, + mothers=[] if mother is None else [mother]) + + def get_loop_mother(self): + return next((m for m in self['mothers'] if m['is_loop']), None) + + def get_helas_call_dict(self, **kwargs): + return dict(out=self['number'], loop_mother_number=self.get_loop_mother()['number'], + loop_mother_rank=1, vertex_rank=1, lcut_size=4, in_size=4, out_size=4) + + +def matrix(): + seed = Wavefunction(0) + first = Wavefunction(1, seed) + final = Wavefunction(2, first) + amp = Mock() + amp.get_final_loop_wavefunction.return_value = final + diagram = Mock() + diagram.get.side_effect = {'loop_wavefunctions': [first, final], 'number': 1}.get + diagram.get_loop_amplitudes.return_value = [amp] + me = Mock(spec=LoopHelasMatrixElement) + me.get_loop_diagrams.return_value = [diagram] + me.get_all_wavefunctions.return_value = [] + return me, diagram, first, final, amp + + +class TerminalWavefunctionGraphTest(unittest.TestCase): + def test_only_final_unconsumed_roots(self): + me, diagram, first, final, amp = matrix() + self.assertEqual(set(Writer.get_terminal_wavefunctions(me)), {2}) + another = Mock() + another.get_final_loop_wavefunction.return_value = first + diagram.get_loop_amplitudes.return_value.append(another) + self.assertEqual(set(Writer.get_terminal_wavefunctions(me)), {2}) + + def test_unknown_producer_alias_and_identifier_mismatch_disable(self): + for problem in ('mother', 'duplicate', 'alias', 'id', 'root'): + with self.subTest(problem=problem): + me, diagram, first, final, amp = matrix() + if problem == 'mother': + first['mothers'] = [Wavefunction(99)] + elif problem == 'duplicate': + diagram.get('loop_wavefunctions').append(final) + elif problem == 'alias': + final['mothers'] = [final] + elif problem == 'id': + final['me_id'] = 3 + else: + amp.get_final_loop_wavefunction.return_value = Wavefunction(99) + self.assertEqual(Writer.get_terminal_wavefunctions(me), {}) + + def test_non_loop_consumer_disables(self): + me, _, _, final, _ = matrix() + me.get_all_wavefunctions.return_value = [Wavefunction(5, final, False)] + self.assertEqual(Writer.get_terminal_wavefunctions(me), {}) + + def test_shared_terminal_becomes_full(self): + me, diagram, _, final, _ = matrix() + diagram.get('loop_wavefunctions').append(Wavefunction(3, final)) + self.assertEqual(Writer.get_terminal_wavefunctions(me), {}) + + def test_explicit_selection_preserves_cache_dp_and_labels(self): + me, _, first, final, amp = matrix() + me.get.side_effect = {'processes': [{'has_born': True}]}.get + born = Mock() + born.get.side_effect = {'number': 1}.get + amp.get.side_effect = {'loop_group_id': 0, 'amplitudes': [born], + 'loopsymmetryfactor': 1, 'multiplier': 1}.get + amp.get_analytic_info.return_value = 2 + amp.get_lcut_size.return_value = 4 + writer = Mock(spec=Writer) + writer.get_sqso_target_skip_code.return_value = [' 4000 CONTINUE'] + calls = {wf['number']: + ('CALL VERTEX(PL(0,{loop_mother_number}),COEFS)\n' + 'CALL %(proc_prefix)sUPDATE_WL_1_1(WL(1,0,1,{loop_mother_number}),' + '4,COEFS,4,4,WL(1,0,1,{out}))').format(**wf.get_helas_call_dict()) + for wf in (first, final)} + writer.get_wavefunction_call.side_effect = lambda wf: calls[wf['number']] + before = Writer.get_coef_construction_calls(writer, me)[0] + selected = Writer.get_coef_construction_calls(writer, me, + terminal_wavefunctions=Writer.get_terminal_wavefunctions(me))[0] + after = Writer.get_coef_construction_calls(writer, me)[0] + self.assertEqual(before, after) + self.assertEqual(sum('TERMINAL_WL_' in call for call in selected), 1) + self.assertEqual(selected[-1], ' 4000 CONTINUE') + calls[2] = calls[2].replace('CALL %(proc_prefix)sUPDATE', ' 4000 CALL %(proc_prefix)sUPDATE') + rejected = Writer.get_coef_construction_calls(writer, me, + terminal_wavefunctions=Writer.get_terminal_wavefunctions(me))[0] + self.assertFalse(any('TERMINAL_WL_' in call for call in rejected)) + + +class RenderedTerminalGraphTest(unittest.TestCase): + def write_ieee_batches(self, work, prefix): + (work/'batch.inc').write_text( + ' SUBROUTINE %(bunch_name)s_%(bunch_number)d()\n' + '%(terminal_ieee_use)s IMPLICIT NONE\n' + '%(terminal_ieee_declarations)s%(helas_calls)s\n END\n') + exporter = object.__new__(Exporter) + exporter.template_dir = str(work) + replacement = {'proc_prefix': prefix, + 'terminal_ieee_use': ' USE, INTRINSIC :: IEEE_EXCEPTIONS\n', + 'terminal_ieee_declarations': ' LOGICAL WL_ENTRY_INEXACT\n'} + before = os.getcwd() + try: + os.chdir(work) + exporter.split_HELASCALLS(True, replacement, 'batch.inc', '', + ['CALL FULL()', 'CALL IEEE_GET_FLAG(IEEE_INEXACT,WL_ENTRY_INEXACT)\n' + 'CALL MP_%sTERMINAL_WL_1_1()' % prefix, 'CALL FULL()'], + 'entry', 'batch', n_helas=1) + finally: + os.chdir(before) + + def test_ieee_boundary_only_in_batches_with_private_calls(self): + for prefix in ('TEST_', ''): + with self.subTest(prefix=prefix), tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + self.write_ieee_batches(work, prefix) + self.assertNotIn('IEEE_', (work/'batch_1.f').read_text()) + self.assertIn('IEEE_EXCEPTIONS', (work/'batch_2.f').read_text()) + self.assertIn('LOGICAL WL_ENTRY_INEXACT', (work/'batch_2.f').read_text()) + self.assertIn('CALL IEEE_GET_FLAG', (work/'batch_2.f').read_text()) + self.assertNotIn('IEEE_', (work/'batch_3.f').read_text()) + + @unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') + def test_empty_nlo_prefix_and_prefixed_batches_compile_with_static_locals(self): + for prefix in ('TEST_', ''): + with self.subTest(prefix=prefix), tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + self.write_ieee_batches(work, prefix) + built = subprocess.run(['gfortran', '-fno-automatic', + '-ffixed-line-length-132', '-c', 'batch_1.f', + 'batch_2.f', 'batch_3.f'], cwd=work, capture_output=True, text=True) + self.assertEqual(built.returncode, 0, built.stdout+built.stderr) + + def fixture(self, work): + (work/'mp_coef_construction_1.f').write_text( + ' CALL MP_TEST_UPDATE_WL_1_1(WL(1,0,1,0),4,COEFS,4,4,\n' + ' $ WL(1,0,1,1))\n' + ' CALL MP_TEST_TERMINAL_WL_1_1(WL(1,0,1,1),4,COEFS,4,4,\n' + ' $ WL(1,0,1,2),WL_ENTRY_INEXACT)\n' + ' CALL MP_TEST_CREATE_LOOP_COEFS(WL(1,0,1,2),2,4,1)\n') + (work/'polynomial.f').write_text( + ' SUBROUTINE MP_TEST_MERGE_WL(WL,R,LCUT_SIZE,CONST,OUT)\n' + ' COMPLEX*32 WL(4,0:34,4)\n' + ' OUT(J)=OUT(J)+WL(I,J,I)*CONST\n' + ' END\n' + ' SUBROUTINE MP_TEST_CREATE_LOOP_COEFS(LOOP_WF,R,LCUT)\n' + ' COMPLEX*32 LOOP_WF(4,0:34,4)\n' + ' CALL MP_TEST_MERGE_WL(LOOP_WF,R,LCUT,CONST,OUT)\n' + ' END\n') + return {2: dict(loop_mother_rank=1, vertex_rank=1, loop_mother_number=1, + lcut_size=4, in_size=4, out_size=4, out=2)} + + def test_known_diagonal_graph(self): + with tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + expected = self.fixture(work) + self.assertTrue(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + batch = work/'mp_coef_construction_1.f' + original = batch.read_text() + batch.write_text(' 4000 CONTINUE\n'+original+' 1001 CONTINUE\n') + self.assertTrue(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + self.assertEqual(batch.read_text(), ' 4000 CONTINUE\n'+original+' 1001 CONTINUE\n') + + def test_hidden_common_consumer_rejected(self): + for consumer in ('X=WL(1,0,2,2)', 'CALL HIDDEN(WL)', 'CALL HIDDEN(WL(1,0,1,2))', + 'X=WL', 'EQUIVALENCE(WL,X)'): + with self.subTest(consumer=consumer), tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + expected = self.fixture(work) + (work/'hidden.f').write_text( + ' COMMON/TEST_MP_WL/WL,PL\n '+consumer+'\n') + self.assertFalse(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + + def test_common_alias_rejected(self): + with tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + expected = self.fixture(work) + (work/'hidden.f').write_text(' COMMON/TEST_MP_WL/X,Y\n CALL HIDDEN(X)\n') + self.assertFalse(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + + def test_bare_array_batch_consumer_rejected(self): + for consumer in ('CALL HIDDEN(WL)', 'EQUIVALENCE(WL,X)'): + with self.subTest(consumer=consumer), tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + expected = self.fixture(work) + with (work/'mp_coef_construction_1.f').open('a') as stream: + stream.write(' '+consumer+'\n') + self.assertFalse(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + + def test_later_update_and_changed_merge_rejected(self): + with tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + expected = self.fixture(work) + with (work/'mp_coef_construction_1.f').open('a') as stream: + stream.write(' CALL MP_TEST_UPDATE_WL_1_1(WL(1,0,1,2),4,COEFS,4,4,\n' + ' $ WL(1,0,1,3))\n') + self.assertFalse(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + self.fixture(work) + polynomial = work/'polynomial.f' + polynomial.write_text(polynomial.read_text().replace('WL(I,J,I)', 'WL(I,J,1)')) + self.assertFalse(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) + + def test_extra_create_argument_or_replaced_consumer_rejected(self): + for substitution in ('extra', 'replace', 'merge'): + with self.subTest(substitution=substitution), tempfile.TemporaryDirectory() as tmp: + work = Path(tmp) + expected = self.fixture(work) + if substitution == 'extra': + batch = work/'mp_coef_construction_1.f' + batch.write_text(batch.read_text().replace('),2,4,1)', '),2,4,WL)')) + else: + polynomial = work/'polynomial.f' + text = polynomial.read_text() + if substitution == 'replace': + text = text.replace('CALL MP_TEST_MERGE_WL(', 'CALL HIDDEN(') + else: + text = text.replace(' OUT(J)=', ' CALL HIDDEN(WL)\n OUT(J)=') + polynomial.write_text(text) + self.assertFalse(Exporter.validate_terminal_wavefunctions(tmp, 'TEST_', expected)) diff --git a/tests/unit_tests/various/test_ninjars_install.py b/tests/unit_tests/various/test_ninjars_install.py new file mode 100644 index 0000000000..dab641c559 --- /dev/null +++ b/tests/unit_tests/various/test_ninjars_install.py @@ -0,0 +1,563 @@ +"""Installer lifecycle, source isolation, CLI dispatch and exported ABI checks.""" + +import io +import hashlib +import json +import os +from pathlib import Path +import shlex +import shutil +import tempfile +import types +import unittest +from unittest import mock + +from madgraph import MadGraph5Error +from madgraph.interface.madgraph_interface import MadGraphCmd +from madgraph.iolibs.export_fks import ProcessOptimizedExporterFortranFKS +from madgraph.loop.loop_exporters import LoopProcessOptimizedExporterFortranSA +from madgraph.various import banner, ninjars_install + + +class TestNinjaRSInstaller(unittest.TestCase): + def setUp(self): + self.temporary = tempfile.TemporaryDirectory() + self.addCleanup(self.temporary.cleanup) + self.root = Path(self.temporary.name) + self.prefix = self.root / 'HEPTools' + self.bridge = self.root / 'vendor' / 'ninjars' + self.bridge.mkdir(parents=True) + (self.bridge / 'Cargo.lock').write_text('''version = 4 +[[package]] +name = "ninjars" +version = "0.1.0" +source = "git+https://github.com/alphal00p/ninjars?rev=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +[[package]] +name = "oneloop" +version = "0.1.0" +source = "git+https://github.com/alphal00p/oneloopmaster.git?rev=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" +''') + (self.bridge / 'Cargo.toml').write_text('[package]\nname = "bridge"\n') + (self.bridge / 'smoke.f90').write_text('end\n') + + def fake_build(self, command, cwd, log, environment): + """Emulate compiler output while exercising staging/publish for real.""" + log.write_text('build and smoke log\n') + if command[0] == 'make': + prefix = Path(next(item[7:] for item in command + if item.startswith('PREFIX='))) + lib = prefix / 'lib' + lib.mkdir(parents=True) + (lib / 'libninjars.a').write_text('new working archive') + (lib / 'mninjars.mod').write_text('Fortran module') + (lib / 'ninjars-native-libs.txt').write_text('-lgmp -lmpfr -lpthread\n') + (lib / 'ninjars-link-before.txt').write_text('-lgcc_s\n') + + @staticmethod + def snapshot(directory): + """Compare symlink text and regular bytes without following links.""" + result = {} + for path in directory.rglob('*'): + name = str(path.relative_to(directory)) + if path.is_symlink(): + result[name] = ('symlink', os.readlink(path)) + elif path.is_file(): + result[name] = ('file', path.read_bytes()) + elif path.is_dir(): + result[name] = ('directory', None) + return result + + def previous_install(self): + previous = self.prefix / 'ninjars' + (previous / 'lib').mkdir(parents=True) + (previous / 'lib/libninjars.a').write_text('previous working archive') + (previous / 'lib/mninjars.mod').write_text('previous module') + (previous / 'install.log').write_text('previous validated smoke') + (previous / 'lib' / ninjars_install.CONFIG_NAME).write_text(json.dumps({ + 'abi_version':ninjars_install.ABI_VERSION, 'quad_precision':True, + 'native_libs':['-lgmp'], 'link_before':['-lgcc_s'], 'link_order_version':1})) + return previous + + def test_optional_backend_import_does_not_require_cargo_lock_parser(self): + import_module = __import__ + parser_imports = [] + + def without_tomllib(name, *args, **kwargs): + if name == 'tomllib': + parser_imports.append(name) + raise ModuleNotFoundError("No module named 'tomllib'", name=name) + return import_module(name, *args, **kwargs) + + module = types.ModuleType('ninjars_without_tomllib') + filename = ninjars_install.__file__ + with mock.patch('builtins.__import__', side_effect=without_tomllib): + exec(compile(Path(filename).read_text(), filename, 'exec'), module.__dict__) + self.assertFalse(module.is_available(None)) + self.assertIsNone(module.build_parser().parse_args([]).source) + self.assertEqual(parser_imports, []) + with self.assertRaisesRegex(ModuleNotFoundError, 'tomllib'): + module._dependency_provenance(self.bridge) + self.assertEqual(parser_imports, ['tomllib']) + + def test_publish_and_idempotent_install(self): + with mock.patch.object(ninjars_install.shutil, 'which', return_value='/bin/tool'), \ + mock.patch.object(ninjars_install, '_run', side_effect=self.fake_build) as run: + libdir = ninjars_install.install(self.root, self.prefix, jobs=2) + config = ninjars_install.read_config(libdir) + self.assertTrue(config['quad_precision']) + self.assertEqual(config['native_libs'], ['-lgmp', '-lmpfr', '-lpthread']) + self.assertEqual(config['link_before'], ['-lgcc_s']) + provenance = config['build_provenance'] + self.assertEqual(provenance['lock_sha256'], hashlib.sha256( + (self.bridge/'Cargo.lock').read_bytes()).hexdigest()) + self.assertEqual(provenance['manifest_sha256'], hashlib.sha256( + (self.bridge/'Cargo.toml').read_bytes()).hexdigest()) + self.assertEqual([item['name'] for item in provenance['git_dependencies']], + ['ninjars', 'oneloop']) + self.assertIn('#' + 'b'*40, + provenance['git_dependencies'][1]['source']) + smoke_link = run.call_args_list[1].args[0] + self.assertLess(smoke_link.index('-lgcc_s'), next( + i for i, arg in enumerate(smoke_link) if arg.endswith('/libninjars.a'))) + self.assertTrue((self.prefix / 'lib' / 'libninjars.a').is_file()) + self.assertTrue((self.prefix / 'ninjars' / 'Cargo.lock').is_file()) + self.assertTrue((self.prefix / 'ninjars' / 'install.log').is_file()) + self.assertEqual(len(run.call_args_list), 3) + self.assertEqual(run.call_args_list[0].args[3]['CARGO_BUILD_JOBS'], '2') + self.assertEqual(ninjars_install.install(self.root, self.prefix), libdir) + self.assertEqual(len(run.call_args_list), 3) + + def test_update_rebuilds_installed_backend_with_current_checkout_pins(self): + previous = self.previous_install() + # Simulate a git pull selecting a newer immutable dependency revision. + lock = self.bridge/'Cargo.lock' + lock.write_text(lock.read_text().replace('a'*40, 'c'*40)) + with mock.patch.object(ninjars_install.shutil, 'which', return_value='/bin/tool'), \ + mock.patch.object(ninjars_install, 'read_config', + side_effect=AssertionError('already-installed fast path')), \ + mock.patch.object(ninjars_install, '_run', side_effect=self.fake_build) as run: + libdir = Path(ninjars_install.install(self.root, self.prefix, ['--update'])) + self.assertEqual(libdir/'libninjars.a', previous/'lib/libninjars.a') + self.assertEqual((libdir/'libninjars.a').read_text(), 'new working archive') + self.assertEqual((previous/'Cargo.lock').read_bytes(), lock.read_bytes()) + provenance = ninjars_install.read_config(libdir)['build_provenance'] + self.assertEqual(provenance['lock_sha256'], hashlib.sha256(lock.read_bytes()).hexdigest()) + self.assertIn('#'+'c'*40, provenance['git_dependencies'][0]['source']) + self.assertEqual(len(run.call_args_list), 3) + + def test_previous_abi_requires_update_and_is_replaced_after_validation(self): + previous = self.previous_install() + metadata = previous / 'lib' / ninjars_install.CONFIG_NAME + config = json.loads(metadata.read_text()) + config['abi_version'] = 3 + metadata.write_text(json.dumps(config)) + before = self.snapshot(previous) + with mock.patch.object(ninjars_install, '_run') as run: + with self.assertRaisesRegex(MadGraph5Error, 'ABI.*install ninjars --update'): + ninjars_install.install(self.root, self.prefix) + run.assert_not_called() + self.assertEqual(self.snapshot(previous), before) + with mock.patch.object(ninjars_install.shutil, 'which', return_value='/bin/tool'), \ + mock.patch.object(ninjars_install, '_run', side_effect=self.fake_build) as run: + libdir = ninjars_install.install(self.root, self.prefix, ['--update']) + self.assertEqual(ninjars_install.read_config(libdir)['abi_version'], 4) + self.assertEqual(len(run.call_args_list), 3) + self.assertTrue(run.call_args_list[-1].args[0][0].endswith('/smoke')) + parser = ninjars_install.build_parser() + self.assertTrue(parser.parse_args(['--update']).force) + self.assertTrue(parser.parse_args(['--force']).force) + + def test_failed_update_build_or_smoke_preserves_previous_installation(self): + previous = self.previous_install() + common = self.prefix/'lib' + common.mkdir() + (common/'libninjars.a').symlink_to('../ninjars/lib/libninjars.a') + before_tree, before_aliases = self.snapshot(previous), self.snapshot(common) + for failing_step in ('make', 'smoke'): + def fail_update(command, cwd, log, environment): + if (command[0] == 'make' and failing_step == 'make') or ( + command[0].endswith('/smoke') and failing_step == 'smoke'): + raise MadGraph5Error('failed update '+failing_step) + self.fake_build(command, cwd, log, environment) + with self.subTest(failing_step=failing_step), \ + mock.patch.object(ninjars_install.shutil, 'which', return_value='/bin/tool'), \ + mock.patch.object(ninjars_install, '_run', side_effect=fail_update): + with self.assertRaisesRegex(MadGraph5Error, 'failed update '+failing_step): + ninjars_install.install(self.root, self.prefix, ['--update']) + self.assertEqual(before_tree, self.snapshot(previous)) + self.assertEqual(before_aliases, self.snapshot(common)) + + def test_failed_rebuild_preserves_previous_installation(self): + lib = self.prefix / 'ninjars' / 'lib' + lib.mkdir(parents=True) + (lib / 'libninjars.a').write_text('previous working archive') + + def fail_smoke(command, cwd, log, environment): + self.fake_build(command, cwd, log, environment) + if command[0].endswith('/smoke'): + raise MadGraph5Error('quad-precision smoke failed') + + with mock.patch.object(ninjars_install.shutil, 'which', return_value='/bin/tool'), \ + mock.patch.object(ninjars_install, '_run', side_effect=fail_smoke): + with self.assertRaisesRegex(MadGraph5Error, 'quad-precision'): + ninjars_install.install(self.root, self.prefix, ['--force']) + self.assertEqual((lib / 'libninjars.a').read_text(), 'previous working archive') + + def test_alias_publication_failure_rolls_back_previous_install_and_retry(self): + previous = self.previous_install() + common = self.prefix / 'lib' + common.mkdir() + (common / 'libninjars.a').symlink_to('../ninjars/lib/libninjars.a') + (common / 'mninjars.mod').symlink_to('../custom/old-module.mod') + (common / ninjars_install.CONFIG_NAME).symlink_to('../missing/old-metadata.json') + (common / 'ninjars-native-libs.txt').write_text('user-owned regular flags') + (common / 'ninjars-link-before.txt').symlink_to('../custom/old-runtime.txt') + sentinel = common / '.ninjars-link-before.txt.ninjars' + sentinel.write_text('user-owned hidden temporary sentinel') + before_tree, before_aliases = self.snapshot(previous), self.snapshot(common) + replace = ninjars_install.os.replace + injected = [] + def fail_alias(source, target): + if Path(target) == common / ninjars_install.CONFIG_NAME and not injected: + injected.append(True) + raise OSError('simulated alias publication failure') + return replace(source, target) + with mock.patch.object(ninjars_install.shutil,'which',return_value='/bin/tool'), \ + mock.patch.object(ninjars_install,'_run',side_effect=self.fake_build): + with mock.patch.object(ninjars_install.os,'replace',side_effect=fail_alias): + with self.assertRaisesRegex(OSError,'alias publication failure'): + ninjars_install.install(self.root,self.prefix,['--force']) + self.assertEqual(before_tree,self.snapshot(previous)) + self.assertEqual(before_aliases,self.snapshot(common)) + libdir = ninjars_install.install(self.root,self.prefix,['--force']) + self.assertEqual(injected,[True]) + self.assertEqual((Path(libdir)/'libninjars.a').read_text(),'new working archive') + self.assertEqual((common/'ninjars-native-libs.txt').read_text(),'user-owned regular flags') + self.assertEqual(sentinel.read_text(),'user-owned hidden temporary sentinel') + + def test_first_install_alias_failure_removes_publication_and_retry_succeeds(self): + common = self.prefix/'lib' + replace = ninjars_install.os.replace + injected = [] + def fail_alias(source,target): + if Path(target) == common/'mninjars.mod' and not injected: + injected.append(True) + raise OSError('first install alias publication failure') + return replace(source,target) + with mock.patch.object(ninjars_install.shutil,'which',return_value='/bin/tool'), \ + mock.patch.object(ninjars_install,'_run',side_effect=self.fake_build): + with mock.patch.object(ninjars_install.os,'replace',side_effect=fail_alias): + with self.assertRaisesRegex(OSError,'alias publication failure'): + ninjars_install.install(self.root,self.prefix) + self.assertFalse((self.prefix/'ninjars').exists()) + self.assertFalse(common.exists()) + self.assertTrue(list(self.prefix.glob('.ninjars-build-*/install.log'))) + libdir = ninjars_install.install(self.root,self.prefix) + self.assertTrue(ninjars_install.supports_quad_precision(libdir)) + self.assertEqual((common/'libninjars.a').read_text(),'new working archive') + + def test_common_lib_mkdir_failure_restores_previous_install_and_retry(self): + previous = self.previous_install() + before = self.snapshot(previous) + common = self.prefix/'lib' + mkdir = Path.mkdir + def fail_common(path,*args,**kwargs): + if path == common: + raise OSError('simulated common library mkdir failure') + return mkdir(path,*args,**kwargs) + with mock.patch.object(ninjars_install.shutil,'which',return_value='/bin/tool'), \ + mock.patch.object(ninjars_install,'_run',side_effect=self.fake_build): + with mock.patch.object(Path,'mkdir',autospec=True,side_effect=fail_common): + with self.assertRaisesRegex(OSError,'common library mkdir failure'): + ninjars_install.install(self.root,self.prefix,['--force']) + self.assertEqual(before,self.snapshot(previous)) + self.assertFalse(common.exists()) + libdir = ninjars_install.install(self.root,self.prefix,['--force']) + self.assertEqual((Path(libdir)/'libninjars.a').read_text(),'new working archive') + + def test_post_commit_cleanup_failure_keeps_success_and_recovery_diagnostic(self): + self.previous_install() + with mock.patch.object(ninjars_install.shutil,'which',return_value='/bin/tool'), \ + mock.patch.object(ninjars_install,'_run',side_effect=self.fake_build), \ + mock.patch.object(ninjars_install.shutil,'rmtree',side_effect=OSError('cleanup denied')): + with self.assertLogs('madgraph.ninjars_install',level='WARNING') as messages: + libdir = ninjars_install.install(self.root,self.prefix,['--force']) + self.assertTrue(ninjars_install.supports_quad_precision(libdir)) + self.assertEqual((self.prefix/'lib/libninjars.a').read_text(),'new working archive') + self.assertTrue(list(self.prefix.glob('.ninjars-build-*/previous/lib/libninjars.a'))) + self.assertIn('installed successfully','\n'.join(messages.output)) + self.assertIn('cleanup denied','\n'.join(messages.output)) + + def test_rollback_failure_retains_recovery_files_and_raises_clear_error(self): + previous = self.previous_install() + common = self.prefix/'lib' + common.mkdir() + (common/'libninjars.a').symlink_to('../ninjars/lib/libninjars.a') + (common/'mninjars.mod').symlink_to('../custom/previous.mod') + replace = ninjars_install.os.replace + def fail_publication_and_module_restore(source,target): + if Path(target) == common/ninjars_install.CONFIG_NAME: + raise OSError('simulated alias publication failure') + if Path(target) == common/'mninjars.mod' and Path(source).parent.name == 'previous-links': + raise OSError('simulated module restore failure') + return replace(source,target) + with mock.patch.object(ninjars_install.shutil,'which',return_value='/bin/tool'), \ + mock.patch.object(ninjars_install,'_run',side_effect=self.fake_build), \ + mock.patch.object(ninjars_install.os,'replace',side_effect=fail_publication_and_module_restore): + with self.assertRaisesRegex(MadGraph5Error,'rollback.*retained'): + ninjars_install.install(self.root,self.prefix,['--force']) + self.assertEqual((previous/'lib/libninjars.a').read_text(),'previous working archive') + recovery = list(common.glob('.ninjars-links-*/previous-links/mninjars.mod')) + self.assertEqual(len(recovery),1) + self.assertEqual(os.readlink(recovery[0]),'../custom/previous.mod') + + def test_symlinked_common_directory_keeps_user_files_and_working_aliases(self): + shared = self.root/'shared-libraries' + shared.mkdir() + self.prefix.mkdir() + common = self.prefix/'lib' + common.symlink_to('../shared-libraries') + (shared/'ninjars-native-libs.txt').write_text('user-owned link flags') + sentinel = shared/'.libninjars.a.ninjars' + sentinel.write_text('user-owned hidden file') + with mock.patch.object(ninjars_install.shutil,'which',return_value='/bin/tool'), \ + mock.patch.object(ninjars_install,'_run',side_effect=self.fake_build): + libdir = Path(ninjars_install.install(self.root,self.prefix)) + self.assertEqual(os.readlink(common),'../shared-libraries') + self.assertEqual((common/'libninjars.a').resolve(),libdir/'libninjars.a') + self.assertEqual((common/'libninjars.a').read_text(),'new working archive') + self.assertEqual((shared/'ninjars-native-libs.txt').read_text(),'user-owned link flags') + self.assertEqual(sentinel.read_text(),'user-owned hidden file') + self.assertFalse(list(shared.glob('.ninjars-links-*'))) + + def test_interrupted_alias_publication_restores_previous_state(self): + previous = self.previous_install() + common = self.prefix/'lib' + common.mkdir() + (common/'libninjars.a').symlink_to('../ninjars/lib/libninjars.a') + (common/'mninjars.mod').symlink_to('../custom/old-module.mod') + before_tree, before_aliases = self.snapshot(previous), self.snapshot(common) + replace = ninjars_install.os.replace + for interrupt_at in (previous,common/ninjars_install.CONFIG_NAME): + interrupted = [] + def interrupt_after_replace(source,target): + result = replace(source,target) + if Path(target) == interrupt_at and not interrupted: + interrupted.append(True) + raise KeyboardInterrupt('interrupted after atomic publication') + return result + with self.subTest(interrupt_at=interrupt_at), \ + mock.patch.object(ninjars_install.shutil,'which',return_value='/bin/tool'), \ + mock.patch.object(ninjars_install,'_run',side_effect=self.fake_build), \ + mock.patch.object(ninjars_install.os,'replace',side_effect=interrupt_after_replace): + with self.assertRaises(KeyboardInterrupt): + ninjars_install.install(self.root,self.prefix,['--force']) + self.assertEqual(interrupted,[True]) + self.assertEqual(before_tree,self.snapshot(previous)) + self.assertEqual(before_aliases,self.snapshot(common)) + + def test_local_sources_are_copied_and_original_is_unchanged(self): + source = self.root / 'reference' + for relative in ('Cargo.toml', 'crates/ninjars/Cargo.toml', + 'crates/ninjars-symbolica/Cargo.toml'): + target = source / relative + target.parent.mkdir(parents=True, exist_ok=True) + target.write_text('# original\n') + (source / 'target').mkdir() + (source / 'target' / 'cached.bin').write_text('do not copy') + (source / '.git').mkdir() + stage = self.root / 'stage' + stage.mkdir() + bridge = stage / 'bridge' + bridge.mkdir() + options = ninjars_install.build_parser().parse_args(['--source', str(source)]) + with mock.patch.object(ninjars_install.subprocess, 'check_output', + return_value='1234abcd\n'): + provenance = ninjars_install._prepare_overrides(bridge, stage, options) + config = (bridge / '.cargo' / 'config.toml').read_text() + self.assertIn(str(stage / 'sources' / 'ninjars'), config) + self.assertNotIn(str(source), config) + copied = stage / 'sources' / 'ninjars' + self.assertFalse((copied / 'target').exists()) + (copied / 'Cargo.toml').write_text('# changed in build\n') + self.assertEqual((source / 'Cargo.toml').read_text(), '# original\n') + self.assertEqual(provenance['ninjars']['revision'], '1234abcd') + self.assertEqual(provenance['ninjars']['source_files'], 3) + original_hash = provenance['ninjars']['source_tree_sha256'] + other = self.root/'other-copy' + with mock.patch.object(ninjars_install.subprocess, 'check_output', + return_value='1234abcd\n'): + copied_provenance = ninjars_install._copy_source(source, other, ['Cargo.toml']) + self.assertEqual(copied_provenance['source_tree_sha256'], original_hash) + (source/'Cargo.toml').write_text('# same revision, modified source\n') + with mock.patch.object(ninjars_install.subprocess, 'check_output', + return_value='1234abcd\n'): + modified = ninjars_install._copy_source(source, self.root/'modified', ['Cargo.toml']) + self.assertNotEqual(modified['source_tree_sha256'], original_hash) + + def test_source_tarball_never_inherits_enclosing_repository_revision(self): + source = self.root/'unpacked-dependency' + source.mkdir() + (source/'Cargo.toml').write_text('[package]\nname = "oneloop"\n') + with mock.patch.object(ninjars_install.subprocess, 'check_output', + return_value='a'*40+'\n') as git: + provenance = ninjars_install._copy_source( + source, self.root/'copied-tarball', ['Cargo.toml']) + git.assert_not_called() + self.assertIsNone(provenance['revision']) + self.assertEqual(provenance['source_files'], 1) + self.assertEqual(len(provenance['source_tree_sha256']), 64) + + def test_invalid_resolved_lock_never_replaces_previous_install(self): + previous = self.previous_install() + before = self.snapshot(previous) + (self.bridge/'Cargo.lock').write_text('invalid resolved lock\n') + with mock.patch.object(ninjars_install.shutil, 'which', return_value='/bin/tool'), \ + mock.patch.object(ninjars_install, '_run', side_effect=self.fake_build): + with self.assertRaisesRegex(MadGraph5Error, 'Invalid resolved NinjaRS Cargo.lock'): + ninjars_install.install(self.root, self.prefix, ['--force']) + self.assertEqual(self.snapshot(previous), before) + + def test_missing_tool_and_bad_job_count_fail_before_build(self): + with mock.patch.object(ninjars_install.shutil, 'which', return_value=None): + with self.assertRaisesRegex(MadGraph5Error, 'requires cargo'): + ninjars_install.install(self.root, self.prefix) + for jobs in (0, -2): + with self.subTest(jobs=jobs), self.assertRaisesRegex( + MadGraph5Error, 'positive'): + ninjars_install.install(self.root, self.prefix, + ['--jobs=%s' % jobs]) + self.assertFalse(self.prefix.exists()) + + def test_metadata_requires_compatible_abi(self): + lib = self.root / 'lib' + lib.mkdir() + config = lib / ninjars_install.CONFIG_NAME + for version in (1, 2, 3, 99): + config.write_text(json.dumps({'abi_version': version, 'native_libs': []})) + with self.subTest(version=version), self.assertRaisesRegex( + MadGraph5Error, 'ABI.*install ninjars --update'): + ninjars_install.read_config(lib) + config.write_text(json.dumps({'abi_version': ninjars_install.ABI_VERSION, + 'native_libs': 'bad'})) + with self.assertRaisesRegex(MadGraph5Error, 'link metadata'): + ninjars_install.read_config(lib) + config.write_text(json.dumps({'abi_version': ninjars_install.ABI_VERSION, + 'native_libs': []})) + with self.assertRaisesRegex(MadGraph5Error, 'compiler-runtime.*metadata'): + ninjars_install.read_config(lib) + self.assertFalse(ninjars_install.supports_quad_precision(lib)) + + def test_cli_dispatch_is_local_and_saves_only_after_success(self): + cmd = types.SimpleNamespace( + options={'heptools_install_dir': str(self.prefix), + 'fortran_compiler': 'gfortran', 'nb_core': 2}, + split_arg=shlex.split, + check_install=lambda args: {'options_for_HEPToolsInstaller': args[1:]}, + heptools_install_target=lambda prefix: (prefix, 'config.txt'), + exec_cmd=mock.Mock()) + with mock.patch.object(ninjars_install, 'install', + return_value='/installed/lib') as install: + MadGraphCmd.do_install(cmd, 'ninjars --update --jobs=3') + self.assertEqual(cmd.options['ninjars'], '/installed/lib') + self.assertEqual(install.call_args.kwargs['arguments'], ['--update', '--jobs=3']) + cmd.exec_cmd.assert_called_once_with('save options config.txt ninjars', + printcmd=False, log=False) + cmd.exec_cmd.reset_mock() + with mock.patch.object(ninjars_install, 'install', + side_effect=MadGraph5Error('failed')): + with self.assertRaises(MadGraph5Error): + MadGraphCmd.do_install(cmd, 'ninjars --update') + cmd.exec_cmd.assert_not_called() + + def test_exporter_skips_incomplete_optional_library_and_copies_valid_install(self): + lib = self.root / 'lib' + lib.mkdir() + (lib / 'libninjars.a').write_bytes(b'!\nsynthetic archive metadata') + (lib / ninjars_install.CONFIG_NAME).write_text(json.dumps( + {'abi_version': ninjars_install.ABI_VERSION, 'native_libs': ['-lgmp'], + 'link_before': ['-lgcc_s'], 'link_order_version': 1, + 'quad_precision': True})) + exporter = object.__new__(LoopProcessOptimizedExporterFortranSA) + exporter.tir_available_dict = {'ninjars': True} + exporter.dependencies = 'external' + (lib / 'ninjars-native-libs.txt').write_text('-lgmp\n') + (lib / 'ninjars-link-before.txt').write_text('-lgcc_s\n') + with self.assertLogs('madgraph.loop_exporter', level='WARNING') as logged: + self.assertEqual(exporter.link_TIR(str(self.root), str(lib), 'libninjars.a', 'ninjars'), '') + self.assertFalse(exporter.tir_available_dict['ninjars']) + self.assertIn('install ninjars --update', '\n'.join(logged.output)) + (lib / 'mninjars.mod').write_text('module') + exporter.tir_available_dict['ninjars'] = True + self.assertEqual(exporter.link_TIR( + str(self.root), str(lib), 'libninjars.a', 'ninjars'), str(lib)) + exporter.dependencies = 'internal' + (lib / 'ninjars-native-libs.txt').write_text('-lgmp\n') + (lib / 'ninjars-link-before.txt').write_text('-lgcc_s\n') + include = self.root / 'include' + include.mkdir() + (include / 'ninjars.h').write_text('/* header */\n') + (include / 'mninjars.f90').write_text('module mninjars\nend module\n') + copied = self.root / 'export' / 'lib' + self.assertEqual(exporter.link_TIR( + str(copied), str(lib), 'libninjars.a', 'ninjars'), str(copied)) + fks = object.__new__(ProcessOptimizedExporterFortranFKS) + fks.tir_available_dict = {'ninjars': True} + fks.dependencies = 'internal' + fks_copied = self.root / 'export-fks' / 'lib' + self.assertEqual(fks.link_TIR( + str(fks_copied), str(lib), 'libninjars.a', 'ninjars'), str(fks_copied)) + shutil.rmtree(lib) + shutil.rmtree(include) + for exported in (copied, fks_copied): + with self.subTest(exported=exported): + self.assertTrue(ninjars_install.is_available(exported)) + self.assertTrue(ninjars_install.supports_quad_precision(exported)) + self.assertEqual(ninjars_install.read_config(exported)['abi_version'], 4) + for name in ('libninjars.a', 'mninjars.mod', 'ninjars-config.json', + 'ninjars-native-libs.txt', 'ninjars-link-before.txt', + 'ninjars.h', 'mninjars.f90'): + self.assertTrue((exported / name).is_file(), name) + self.assertFalse((exported / name).is_symlink(), name) + + def test_standalone_and_fks_exports_reject_previous_abi_before_copy_or_link(self): + lib = self.root / 'previous-abi' + lib.mkdir() + (lib / 'libninjars.a').write_bytes(b'!\nprevious archive metadata') + (lib / 'mninjars.mod').write_bytes(b'previous Fortran module') + (lib / ninjars_install.CONFIG_NAME).write_text(json.dumps({ + 'abi_version': 3, 'native_libs': ['-lgmp'], + 'link_before': ['-lgcc_s'], 'link_order_version': 1, + 'quad_precision': True})) + (lib / 'ninjars-native-libs.txt').write_text('-lgmp\n') + (lib / 'ninjars-link-before.txt').write_text('-lgcc_s\n') + self.assertFalse(ninjars_install.is_available(lib)) + for exporter_type in (LoopProcessOptimizedExporterFortranSA, + ProcessOptimizedExporterFortranFKS): + for dependencies in ('external', 'internal'): + with self.subTest(exporter=exporter_type.__name__, dependencies=dependencies): + exporter = object.__new__(exporter_type) + exporter.tir_available_dict = {'ninjars': True} + exporter.dependencies = dependencies + target = self.root / exporter_type.__name__ / dependencies + with self.assertLogs('madgraph.loop_exporter', level='WARNING') as logged: + self.assertEqual(exporter.link_TIR( + str(target), str(lib), 'libninjars.a', 'ninjars'), '') + self.assertFalse(exporter.tir_available_dict['ninjars']) + self.assertFalse(target.exists()) + self.assertIn('install ninjars --update', '\n'.join(logged.output)) + + def test_madloop_card_round_trip_keeps_id8_and_qp_option(self): + card = banner.MadLoopParam() + card['MLReductionLib'] = '8|6|1' + card['UseQPIntegrandForNinjaRS'] = False + stream = io.StringIO() + card.write(stream) + reread = banner.MadLoopParam(stream.getvalue()) + self.assertEqual(reread['MLReductionLib'], '8|6|1') + self.assertFalse(reread['UseQPIntegrandForNinjaRS']) + self.assertEqual(card._ID_reduction_tool_map[8], 'NinjaRS') + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/unit_tests/various/test_ninjars_integration_boundaries.py b/tests/unit_tests/various/test_ninjars_integration_boundaries.py new file mode 100644 index 0000000000..6eea8ebb50 --- /dev/null +++ b/tests/unit_tests/various/test_ninjars_integration_boundaries.py @@ -0,0 +1,239 @@ +"""Failure/precision boundaries across installed capability, export and reports. + +These exercise publication rollback and consumer behavior without compiling or +calling a reduction engine. Numerical ABI/precision tests live in the existing +Fortran and Rust suites. +""" +import json +from pathlib import Path +import tempfile +import unittest +from unittest import mock +from xml.dom.minidom import parseString + +from madgraph import MadGraph5Error +from madgraph.core import base_objects +from madgraph.loop import loop_exporters +from madgraph.madevent.sum_html import RunStatistics +from madgraph.various import ninjars_install, process_checks + + +class TestNinjaRSIntegrationBoundaries(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.addCleanup(self.tmp.cleanup) + self.work = Path(self.tmp.name) + self.lib = self.work/'installed/lib' + self.lib.mkdir(parents=True) + self.config = {'abi_version':ninjars_install.ABI_VERSION, + 'native_libs':['-lgmp','-lmpfr'], 'link_before':['-lgcc_s'], + 'link_order_version':1, 'quad_precision':True} + + def metadata(self, **changes): + config = dict(self.config, **changes) + (self.lib/ninjars_install.CONFIG_NAME).write_text(json.dumps(config)) + return config + + def exporter(self, available): + exporter = object.__new__(loop_exporters.LoopProcessOptimizedExporterFortranSA) + exporter.tir_available_dict = dict.fromkeys(exporter.all_tir,False) + exporter.tir_available_dict['ninjars'] = available + exporter.ninjars_dir = str(self.lib) + return exporter + + def context(self, exporter): + with mock.patch.object(loop_exporters.LoopProcessExporterFortranSA, + 'get_context',return_value={'caller_setting':17}): + return exporter.get_context(None) + + def test_absent_backend_does_not_read_stale_precision_metadata(self): + (self.lib/ninjars_install.CONFIG_NAME).write_text('{broken JSON') + exporter = self.exporter(False) + with mock.patch.object(ninjars_install,'read_config',side_effect=AssertionError('absent backend read')): + context = self.context(exporter) + self.assertFalse(context['ninjars_available']) + self.assertFalse(context['ninjars_supports_quad_prec']) + self.assertEqual(context['caller_setting'],17) + + def test_export_requires_literal_quad_capability_and_archive(self): + exporter = self.exporter(True) + for advertised, expected in [(True,True),(False,False),('true',False),(1,False),(None,False)]: + self.metadata(quad_precision=advertised) + (self.lib/'libninjars.a').write_bytes(b'archive') + with self.subTest(advertised=advertised): + self.assertEqual(self.context(exporter)['ninjars_supports_quad_prec'],expected) + (self.lib/'libninjars.a').unlink() + self.metadata() + self.assertFalse(self.context(exporter)['ninjars_supports_quad_prec']) + + def test_available_backend_rejects_incompatible_metadata_instead_of_claiming_qp(self): + (self.lib/'libninjars.a').write_bytes(b'archive') + for changes in ({'abi_version':2}, {'abi_version':3}, {'native_libs':['-lgmp\nBAD=1']}, + {'link_before':[]}, {'link_before':['-lgcc_s\rBAD=1']}, + {'link_order_version':0}): + self.metadata(**changes) + with self.subTest(changes=changes), self.assertRaises(MadGraph5Error): + self.context(self.exporter(True)) + + def test_publication_failure_restores_complete_previous_install(self): + prefix = self.work/'HEPTools' + previous = prefix/'ninjars' + (previous/'lib').mkdir(parents=True) + (previous/'lib/libninjars.a').write_bytes(b'old archive') + (previous/'lib/mninjars.mod').write_bytes(b'old module') + (previous/'install.log').write_bytes(b'old validated log') + before = {str(p.relative_to(previous)):p.read_bytes() for p in previous.rglob('*') if p.is_file()} + bridge = self.work/'vendor/ninjars' + bridge.mkdir(parents=True) + for name in ('Cargo.lock','Cargo.toml','smoke.f90'): + (bridge/name).write_text('fixture\n') + (bridge/'Cargo.lock').write_text('version = 4\npackage = []\n') + calls = [] + def build(command,cwd,log,environment): + calls.append(command) + log.write_text('build and smoke successful\n') + if command[0] == 'make': + installed = Path(next(x[7:] for x in command if x.startswith('PREFIX='))) + (installed/'lib').mkdir(parents=True) + for name,content in {'libninjars.a':'new archive','mninjars.mod':'new module', + 'ninjars-native-libs.txt':'-lgmp -lmpfr','ninjars-link-before.txt':'-lgcc_s'}.items(): + (installed/'lib'/name).write_text(content) + replace = ninjars_install.os.replace + def fail_publish(source,destination): + if Path(source).name == 'install' and Path(destination) == previous: + raise OSError('simulated publication failure') + return replace(source,destination) + with mock.patch.object(ninjars_install.shutil,'which',return_value='/bin/tool'), \ + mock.patch.object(ninjars_install,'_run',side_effect=build), \ + mock.patch.object(ninjars_install.os,'replace',side_effect=fail_publish): + with self.assertRaisesRegex(OSError,'publication failure'): + ninjars_install.install(self.work,prefix,['--force']) + self.assertEqual(len(calls),3) # Both compilation and installed smoke ran. + self.assertEqual(before,{str(p.relative_to(previous)):p.read_bytes() for p in previous.rglob('*') if p.is_file()}) + self.assertFalse((prefix/'lib').exists()) + + def test_partial_existing_install_requires_update_without_starting_build(self): + prefix = self.work/'HEPTools' + directory = prefix/'ninjars/lib' + directory.mkdir(parents=True) + (directory/ninjars_install.CONFIG_NAME).write_text(json.dumps(self.config)) + (directory/'libninjars.a').write_bytes(b'existing archive without module') + with mock.patch.object(ninjars_install,'_run') as run: + with self.assertRaisesRegex(MadGraph5Error,'Incomplete.*--update'): + ninjars_install.install(self.work,prefix) + run.assert_not_called() + self.assertEqual((directory/'libninjars.a').read_bytes(),b'existing archive without module') + + def test_explicit_unavailable_backend_has_actionable_error_before_generation(self): + evaluator = object.__new__(process_checks.LoopMatrixElementTimer) + options = {'reuse':True, 'npoints':1, 'split_orders':-1} + configurations = ({}, {'ninjars_dir':None}, + {'ninjars_dir':str(self.work/'missing')}, + {'ninjars_dir':str(self.lib)}) + for configuration in configurations: + evaluator.tir_dir = configuration + selection = {'MLReductionLib':[8]} + with self.subTest(configuration=configuration), self.assertRaisesRegex( + MadGraph5Error, "NinjaRS.*unavailable.*install ninjars"): + evaluator.check_matrix_element_stability( + base_objects.Process(), options=options, MLOptions=selection) + self.assertEqual(selection['MLReductionLib'],[8]) + + def test_failed_smoke_then_retry_publishes_only_validated_install(self): + prefix = self.work/'HEPTools' + bridge = self.work/'vendor/ninjars' + bridge.mkdir(parents=True) + for name in ('Cargo.lock','Cargo.toml','smoke.f90'): + (bridge/name).write_text('fixture\n') + (bridge/'Cargo.lock').write_text('version = 4\npackage = []\n') + smoke_attempts, build_directories = [], [] + def build(command,cwd,log,environment): + log.write_text('retained installer attempt\n') + if command[0] == 'make': + build_directories.append(Path(cwd)) + installed = Path(next(x[7:] for x in command if x.startswith('PREFIX='))) + (installed/'lib').mkdir(parents=True) + for name,content in {'libninjars.a':'validated archive','mninjars.mod':'module', + 'ninjars-native-libs.txt':'-lgmp -lmpfr','ninjars-link-before.txt':'-lgcc_s'}.items(): + (installed/'lib'/name).write_text(content) + elif command[0].endswith('/smoke'): + smoke_attempts.append(command[0]) + if len(smoke_attempts) == 1: + raise MadGraph5Error('first installed precision smoke failed') + with mock.patch.object(ninjars_install.shutil,'which',return_value='/bin/tool'), \ + mock.patch.object(ninjars_install,'_run',side_effect=build): + with self.assertRaisesRegex(MadGraph5Error,'precision smoke failed'): + ninjars_install.install(self.work,prefix) + self.assertFalse((prefix/'ninjars').exists()) + self.assertFalse((prefix/'lib').exists()) + failed_stage = build_directories[0].parent + self.assertTrue((failed_stage/'install.log').is_file()) + result = ninjars_install.install(self.work,prefix) + self.assertEqual(len(smoke_attempts),2) + self.assertNotEqual(build_directories[0],build_directories[1]) + self.assertTrue(failed_stage.exists()) # Failure diagnostics survive retry. + self.assertFalse(build_directories[1].parent.exists()) + self.assertEqual(result,str(prefix/'ninjars/lib')) + self.assertTrue(ninjars_install.supports_quad_precision(result)) + self.assertEqual((prefix/'lib/libninjars.a').read_text(),'validated archive') + + def test_combined_source_overrides_are_isolated_before_cargo_resolution(self): + ninja, masters = self.work/'ninja-source', self.work/'masters-source' + for root, names in ((ninja,('Cargo.toml','crates/ninjars/Cargo.toml', + 'crates/ninjars-symbolica/Cargo.toml')), + (masters,('Cargo.toml',))): + for name in names: + path = root/name + path.parent.mkdir(parents=True,exist_ok=True) + path.write_text('original '+name+'\n') + (root/'target').mkdir() + (root/'target/cached').write_text('never copy') + (root/'.git').mkdir() + before = {str(path):path.read_bytes() for root in (ninja,masters) + for path in root.rglob('*') if path.is_file()} + stage = self.work/'stage' + bridge = stage/'bridge' + bridge.mkdir(parents=True) + options = ninjars_install.build_parser().parse_args( + ['--source',str(ninja),'--oneloop-source',str(masters)]) + with mock.patch.object(ninjars_install.subprocess,'check_output', + side_effect=['1'*40+'\n','2'*40+'\n']): + provenance = ninjars_install._prepare_overrides(bridge,stage,options) + config = (bridge/'.cargo/config.toml').read_text() + self.assertIn('[patch."https://github.com/alphal00p/ninjars"]',config) + self.assertIn('[patch."https://github.com/alphal00p/oneloopmaster.git"]',config) + for name in ('ninjars','oneloopmaster'): + copied = stage/'sources'/name + self.assertIn(str(copied),config) + self.assertFalse((copied/'target').exists()) + (copied/'Cargo.toml').write_text('changed only in isolated build\n') + self.assertEqual(provenance['ninjars']['revision'],'1'*40) + self.assertEqual(provenance['oneloopmaster']['revision'],'2'*40) + self.assertEqual(before,{path:Path(path).read_bytes() for path in before}) + + @staticmethod + def statistics(pjfry,ninja_qp,nrs_dp,nrs_qp,legacy=False): + count = pjfry+ninja_qp+nrs_dp+nrs_qp + extra = '' if legacy else '%s%s' % (nrs_dp,nrs_qp) + xml = '''0,0,%s,0,0,0,0,0,%s,0 + 0,%s,%s,0,00,0,%s,%s,0 + 0.001%s + 1e-81e-12%s%s''' % ( + pjfry+nrs_qp,ninja_qp+nrs_dp,pjfry+nrs_dp,ninja_qp+nrs_qp, + pjfry+nrs_dp,ninja_qp+nrs_qp,count*.001,count,extra) + value = RunStatistics() + value.load_statistics(parseString(xml).documentElement) + return value + + def test_mixed_legacy_and_contextual_status_aggregation_is_order_independent(self): + shards = [(9,5,0,0,True),(0,0,12,4,False),(3,2,7,6,False)] + keys = ['PJFry_usage','Ninja_QP_usage','NinjaRS_DP_usage','NinjaRS_QP_usage'] + for order in (shards,list(reversed(shards)),[shards[1],shards[0],shards[2]]): + total = self.statistics(*order[0]) + for shard in order[1:]: + total.aggregate_statistics(self.statistics(*shard)) + self.assertEqual([total[key] for key in keys],[12,7,19,10]) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/unit_tests/various/test_ninjars_report.py b/tests/unit_tests/various/test_ninjars_report.py new file mode 100644 index 0000000000..e7af77baf5 --- /dev/null +++ b/tests/unit_tests/various/test_ninjars_report.py @@ -0,0 +1,84 @@ +"""The optional report download must never install unverified binary inputs.""" +import hashlib +import importlib.util +import io +from pathlib import Path +import tempfile +import unittest +from unittest import mock + + +ROOT = Path(__file__).resolve().parents[3] +SPEC = importlib.util.spec_from_file_location( + "ninjars_report_artifacts", ROOT / "doc/benchmarkfolder/fetch_artifacts.py") +ARTIFACTS = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(ARTIFACTS) + + +class TestReportArtifacts(unittest.TestCase): + def setUp(self): + self.directory = tempfile.TemporaryDirectory() + self.addCleanup(self.directory.cleanup) + self.root = Path(self.directory.name) + self.name = "final-report-v1/fonts/example.otf" + self.data = b"frozen report font" + self.manifest = {"files": {self.name: { + "bytes": len(self.data), + "sha256": hashlib.sha256(self.data).hexdigest()}}} + self.patch = mock.patch.object(ARTIFACTS, "ARTIFACTS", (self.name,)) + self.patch.start() + self.addCleanup(self.patch.stop) + + def test_verified_download_and_offline_retry(self): + with mock.patch.object(ARTIFACTS.urllib.request, "urlopen", + return_value=io.BytesIO(self.data)) as download: + result = ARTIFACTS.fetch_artifacts(self.root, self.manifest) + self.assertEqual(result["downloaded"], 1) + self.assertEqual((self.root / self.name).read_bytes(), self.data) + download.assert_called_once_with(ARTIFACTS.BASE_URL + self.name, timeout=60) + with mock.patch.object(ARTIFACTS.urllib.request, "urlopen") as download: + result = ARTIFACTS.fetch_artifacts(self.root, self.manifest) + self.assertEqual(result["downloaded"], 0) + download.assert_not_called() + + def test_wrong_hash_and_partial_download_are_not_installed(self): + for data in (b"x" * len(self.data), self.data[:-1], self.data + b"extra"): + with self.subTest(data=data): + with mock.patch.object(ARTIFACTS.urllib.request, "urlopen", + return_value=io.BytesIO(data)): + with self.assertRaisesRegex(ValueError, "failed checksum"): + ARTIFACTS.fetch_artifacts(self.root, self.manifest) + self.assertEqual(list(self.root.rglob("*")), []) + + def test_changed_file_is_not_overwritten(self): + target = self.root / self.name + target.parent.mkdir(parents=True) + target.write_bytes(b"user-modified") + with mock.patch.object(ARTIFACTS.urllib.request, "urlopen") as download: + with self.assertRaisesRegex(ValueError, "move it aside first"): + ARTIFACTS.fetch_artifacts(self.root, self.manifest) + download.assert_not_called() + self.assertEqual(target.read_bytes(), b"user-modified") + + def test_failed_atomic_install_cleans_temporary_file(self): + with mock.patch.object(ARTIFACTS.urllib.request, "urlopen", + return_value=io.BytesIO(self.data)): + with mock.patch.object(Path, "replace", side_effect=OSError("full")): + with self.assertRaisesRegex(OSError, "full"): + ARTIFACTS.fetch_artifacts(self.root, self.manifest) + self.assertEqual(list((self.root / self.name).parent.iterdir()), []) + + def test_symlink_cannot_escape_output_root(self): + outside = self.root / "outside" + output = self.root / "output" + outside.mkdir() + output.mkdir() + (output / "final-report-v1").symlink_to(outside, target_is_directory=True) + with mock.patch.object(ARTIFACTS.urllib.request, "urlopen") as download: + with self.assertRaisesRegex(ValueError, "escapes output directory"): + ARTIFACTS.fetch_artifacts(output, self.manifest) + download.assert_not_called() + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/unit_tests/various/test_ninjars_statistics.py b/tests/unit_tests/various/test_ninjars_statistics.py new file mode 100644 index 0000000000..6e8830cf9e --- /dev/null +++ b/tests/unit_tests/various/test_ninjars_statistics.py @@ -0,0 +1,227 @@ +"""Legacy and contextual MadLoop backend statistics remain distinguishable.""" + +import re +import shutil +import subprocess +import tempfile +import unittest +from pathlib import Path +from types import SimpleNamespace +from xml.dom.minidom import parseString + +from madgraph import MG5DIR +from madgraph.iolibs.file_writers import FortranWriter +from madgraph.madevent.sum_html import RunStatistics, decode_madloop_backend_usage +from madgraph.interface.amcatnlo_run_interface import aMCatNLOCmd + + +class TestNinjaRSStatistics(unittest.TestCase): + @staticmethod + def xml(extra=""): + return parseString(""" + 0,0,7,0,0,0,0,0,11,0 + 0,10,8,0,0 + 0,0,10,8,0 + 0.001 + 0.018 + 1e-81e-12 + 18%s""" % extra).documentElement + + def test_old_xml_is_unchanged(self): + stats = RunStatistics() + stats.load_statistics(self.xml()) + self.assertEqual(stats["PJFry_usage"], 7) + self.assertEqual(stats["Ninja_QP_usage"], 11) + self.assertEqual(stats["NinjaRS_DP_usage"], 0) + self.assertEqual(stats["NinjaRS_QP_usage"], 0) + + def test_mixed_xml_and_aggregation(self): + stats = RunStatistics() + stats.load_statistics(self.xml( + "9" + "5")) + self.assertEqual(stats["PJFry_usage"], 2) + self.assertEqual(stats["Ninja_QP_usage"], 2) + self.assertEqual(stats["NinjaRS_DP_usage"], 9) + self.assertEqual(stats["NinjaRS_QP_usage"], 5) + self.assertIn("NinjaRS_DP", stats.nice_output("test")) + old = RunStatistics() + old.load_statistics(self.xml()) + stats.aggregate_statistics(old) + self.assertEqual(stats["PJFry_usage"], 9) + self.assertEqual(stats["Ninja_QP_usage"], 13) + self.assertEqual(stats["NinjaRS_DP_usage"], 9) + + def test_optional_counters_and_non_mutating_decoder(self): + units = [0, 0, 7, 0, 0, 0, 0, 0, 11, 0] + for _ in range(2): + usage = decode_madloop_backend_usage(units, 9, 5) + self.assertEqual(usage['Ninja_QP'], 2) + self.assertEqual(usage['PJFry'], 2) + self.assertEqual(sum(usage.values()), sum(units)) + self.assertEqual(units[8], 11) + self.assertEqual(units[2], 7) + stats = RunStatistics() + for extra, expected in [ + ('9', (2, 7, 9, 0)), + ('5', (11, 2, 0, 5)), + ('', (11, 7, 0, 0))]: + # Reusing the reader must also clear optional counters absent from + # the next file, without altering the old-file interpretation. + stats.load_statistics(self.xml(extra)) + self.assertEqual(tuple(stats[key] for key in ( + 'Ninja_QP_usage', 'PJFry_usage', 'NinjaRS_DP_usage', + 'NinjaRS_QP_usage')), expected) + + def test_nlo_logs_old_and_mixed(self): + log = """Satistics from MadLoop: + Total points tried: 18 + Stability unknown: 0 + Stable PS point: 18 + Unstable PS point (and rescued): 0 + Exceptional PS point (unstable and not rescued): 0 + Double precision used: 10 + Quadruple precision used: 8 + Initialization phase-space points: 0 + Unknown return code (100): 0 + Unknown return code (10): 0 + #Unit 2 = 7 + #Unit 8 = 11 +""" + with tempfile.TemporaryDirectory() as directory: + path = Path(directory) / "log.txt" + for extra, expected in [ + ("", False), + ("#NinjaRS DP = 9\n#NinjaRS QP = 5\n", True), + ]: + path.write_text(log + extra) + _, report = aMCatNLOCmd.compile_advanced_stats( + SimpleNamespace(me_dir=directory), + [str(path)], [], "") + self.assertEqual("NinjaRS (double precision)" in report, expected) + self.assertEqual("NinjaRS (quadruple precision)" in report, expected) + if expected: + self.assertRegex(report, r"PJFry\+\+\s+2(?:\n|$)") + self.assertRegex(report, r"Ninja \(quadruple precision\)\s+2(?:\n|$)") + + +@unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') +class TestMadLoopStatisticsRoundTrip(unittest.TestCase): + """Run actual Fortran tally/writer blocks through both Python readers.""" + + # Every legacy units bucket plus ordinary and initialization NinjaRS calls. + # Unequal counts expose alias swaps and accidental double counting. + samples = [(100, 1), (211, 2), (212, 3), (213, 4), (214, 5), + (215, 6), (216, 7), (217, 8), (328, 9), (329, 10), + (218, 11), (238, 12), (322, 13), (342, 14)] + expected = {'CutTools_DP': 2, 'PJFry': 3, 'IREGI': 4, 'Golem': 5, + 'Samurai': 6, 'Ninja': 7, 'COLLIER': 8, 'Ninja_QP': 9, + 'CutTools_QP': 10, 'NinjaRS_DP': 23, 'NinjaRS_QP': 27} + + def run_producer(self, work, tally, writer): + codes = [code for code, count in self.samples for _ in range(count)] + source = """ + program test_statistics + implicit none + integer i,j,u,t,h,return_code,ret_code,outUnit + integer NINJARS_DP_USAGE,NINJARS_QP_USAGE + integer U_RETURN_CODES(0:9),T_RETURN_CODES(0:9) + integer H_RETURN_CODES(0:9),n1(0:9) + integer ntot,nsun,nsps,nups,neps,nddp,nqdp,nini,n100,n10 + NINJARS_DP_USAGE=0 + NINJARS_QP_USAGE=0 + U_RETURN_CODES=0 + T_RETURN_CODES=0 + H_RETURN_CODES=0 + n1=0 + ntot=0 + nsun=0 + nsps=0 + nups=0 + neps=0 + nddp=0 + nqdp=0 + nini=0 + n100=0 + n10=0 + outUnit=6 + do i=1,%d + read(*,*) return_code + ret_code=return_code +""" % len(codes) + source += tally + '\n enddo\n' + writer + '\n end\n' + with FortranWriter(str(work / 'statistics.f')) as output: + output.writelines(source) + compiled = subprocess.run( + ['gfortran', '-ffixed-line-length-132', '-fcheck=all', + 'statistics.f', '-o', 'statistics'], cwd=work, + text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + self.assertEqual(compiled.returncode, 0, compiled.stdout) + run = subprocess.run([str(work / 'statistics')], cwd=work, + input='\n'.join(map(str, codes)) + '\n', text=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + self.assertEqual(run.returncode, 0, run.stdout) + return run.stdout + + def test_lo_grouped_and_ungrouped_xml_round_trip(self): + root = Path(MG5DIR) + source = (root / 'Template/LO/Source/dsample.f').read_text() + writer = source[source.index(" write(outUnit,33) ''"): + source.index(" write(outUnit,33) ''")] + writer += source[source.index('33 FORMAT('):source.index( + ' end subroutine', source.index('33 FORMAT('))] + with tempfile.TemporaryDirectory() as directory: + work = Path(directory) + for name in ('matrix_loop_induced_madevent.inc', + 'matrix_loop_induced_madevent_group.inc'): + with self.subTest(producer=name): + source = (root / 'madgraph/iolibs/template_files' / name).read_text() + tally = source[source.index('\tU = mod(RETURN_CODE,10)'): + source.index('\tMAX_PREC = max(PREC, MAX_PREC)')] + output = self.run_producer(work, tally, writer) + # All backend data comes from the production Fortran writer; + # unrelated timing/stability fields use the existing fixture. + xml = TestNinjaRSStatistics.xml() + old = xml.getElementsByTagName('u_return_code')[0] + xml.removeChild(old) + generated = parseString('' + output + '') + for node in list(generated.documentElement.childNodes): + xml.appendChild(node) + stats = RunStatistics() + stats.load_statistics(xml) + self.assertEqual({key: stats[key + '_usage'] + for key in self.expected}, self.expected) + + def test_nlo_fixed_order_and_matched_log_round_trip(self): + root = Path(MG5DIR) / 'Template/NLO/SubProcesses' + source = (root / 'BinothLHA.f').read_text() + tally = source[source.index('c Update the statistics using the MadLoop return code'): + source.index('c Write out the unstable, non-rescued')] + with tempfile.TemporaryDirectory() as directory: + work = Path(directory) + for name in ('driver_mintFO.f', 'driver_mintMC.f'): + with self.subTest(producer=name): + source = (root / name).read_text() + start = source.index(' if (ntot.ne.0) then') + writer = source[start:source.index( + " write (*,*) 'counters for the granny resonances'", start)] + output = self.run_producer(work, tally, writer) + path = work / 'log.txt' + path.write_text(output) + _, report = aMCatNLOCmd.compile_advanced_stats( + SimpleNamespace(me_dir=directory), [str(path)], [], '') + for label, count in [ + ('Not identified (CTModeRun != -1)', 1), + ('CutTools (double precision)', 2), ('PJFry++', 3), + ('IREGI', 4), ('Golem95', 5), ('Samurai', 6), + ('Ninja (double precision)', 7), ('COLLIER', 8), + ('Ninja (quadruple precision)', 9), + ('CutTools (quadruple precision)', 10), + ('NinjaRS (double precision)', 23), + ('NinjaRS (quadruple precision)', 27)]: + self.assertRegex(report, re.escape(label) + + r'\s+' + str(count) + r'(?:\n|$)') + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/unit_tests/various/test_ninjars_upstream.py b/tests/unit_tests/various/test_ninjars_upstream.py new file mode 100644 index 0000000000..a3d83fafac --- /dev/null +++ b/tests/unit_tests/various/test_ninjars_upstream.py @@ -0,0 +1,165 @@ +"""Upstream checks report changes without moving or concealing source pins.""" +import contextlib +import importlib.util +import io +import json +from pathlib import Path +import subprocess +import sys +import tempfile +import unittest +from unittest import mock + +ROOT = Path(__file__).resolve().parents[3] +SPEC = importlib.util.spec_from_file_location('ninjars_upstream',ROOT/'tools/ninjars_upstream.py') +upstream = None +if sys.version_info >= (3, 11): + upstream = importlib.util.module_from_spec(SPEC) + SPEC.loader.exec_module(upstream) + + +class TestNinjaRSUpstreamImport(unittest.TestCase): + def test_optional_checker_import_and_ref_parser_do_not_require_tomllib(self): + import_module = __import__ + parser_imports = [] + + def without_tomllib(name, *args, **kwargs): + if name == 'tomllib': + parser_imports.append(name) + raise ModuleNotFoundError("No module named 'tomllib'", name=name) + return import_module(name, *args, **kwargs) + + spec = importlib.util.spec_from_file_location( + 'ninjars_upstream_without_tomllib', ROOT/'tools/ninjars_upstream.py') + module = importlib.util.module_from_spec(spec) + with mock.patch('builtins.__import__', side_effect=without_tomllib): + spec.loader.exec_module(module) + pin = '1'*40 + remote = module.parse_remote( + 'ref: refs/heads/main\tHEAD\n%s\tHEAD\n%s\trefs/heads/main\n' % (pin,pin)) + self.assertEqual(remote['main'], pin) + self.assertEqual(parser_imports, []) + with self.assertRaisesRegex(ModuleNotFoundError, 'tomllib'): + module.read_pins('unread-manifest', 'unread-lock') + with self.assertRaisesRegex(ModuleNotFoundError, 'tomllib'): + module.check('unread-manifest', 'unread-lock') + self.assertEqual(parser_imports, ['tomllib', 'tomllib']) + + +@unittest.skipIf(upstream is None, 'The optional upstream checker requires Python 3.11+') +class TestNinjaRSUpstream(unittest.TestCase): + def setUp(self): + temporary = tempfile.TemporaryDirectory() + self.addCleanup(temporary.cleanup) + self.work = Path(temporary.name) + self.manifest, self.lock = self.work/'Cargo.toml', self.work/'Cargo.lock' + self.pin, self.master = '1'*40, '2'*40 + self.manifest.write_text('[dependencies]\n'+''.join( + '%s = {git="https://github.com/alphal00p/ninjars", rev="%s"}\n' % (name,self.pin) + for name in ('ninjars','ninjars-symbolica'))) + self.lock.write_text('version = 4\n'+''.join( + '\n[[package]]\nname = "%s"\nversion = "0.1.0"\nsource = "git+%s?rev=%s#%s"\n' % (name,url,pin,pin) + for name,url,pin in [('ninjars',upstream.REPOSITORIES['ninjars'],self.pin), + ('ninjars-symbolica',upstream.REPOSITORIES['ninjars'],self.pin), + ('oneloop',upstream.REPOSITORIES['oneloopmaster']+'.git',self.master)])) + + def remote(self,pin): + return upstream.parse_remote('ref: refs/heads/main\tHEAD\n%s\tHEAD\n%s\trefs/heads/main\n' % (pin,pin)) + + def test_current_and_pending_main_preserve_both_inputs(self): + before = (self.manifest.read_bytes(),self.lock.read_bytes()) + def query(url): + return self.remote(self.pin if url.endswith('/ninjars') else '3'*40) + result = upstream.check(self.manifest,self.lock,query) + self.assertTrue(result['update_pending']) + self.assertFalse(result['repositories']['ninjars']['update_pending']) + self.assertTrue(result['repositories']['oneloopmaster']['update_pending']) + self.assertEqual(before,(self.manifest.read_bytes(),self.lock.read_bytes())) + + def test_manifest_disagreement_rejected_before_network(self): + self.manifest.write_text(self.manifest.read_text().replace( + 'rev="'+self.pin+'"','rev="'+'3'*40+'"',1)) + query = mock.Mock() + with self.assertRaisesRegex(ValueError,'pins disagree'): + upstream.check(self.manifest,self.lock,query) + query.assert_not_called() + + def test_lock_resolution_and_missing_or_duplicate_packages_reject(self): + valid = self.lock.read_text() + for changed in (valid.replace('#'+self.pin,'#'+'3'*40,1), + valid.replace('name = "oneloop"','name = "absent"'), + valid+valid[valid.rfind('[[package]]'):], + 'version = 4\npackage = "bad"\n'): + self.lock.write_text(changed) + with self.subTest(lock=changed), self.assertRaises(ValueError): + upstream.read_pins(self.manifest,self.lock) + + def test_lock_and_manifest_mismatch_and_unknown_repository_reject(self): + valid = self.lock.read_text() + self.lock.write_text(valid.replace(self.pin,'3'*40)) + with self.assertRaisesRegex(ValueError,'disagree'): + upstream.read_pins(self.manifest,self.lock) + self.lock.write_text(valid.replace('/oneloopmaster.git','/different.git')) + with self.assertRaisesRegex(ValueError,'Unexpected oneloopmaster'): + upstream.read_pins(self.manifest,self.lock) + + def test_annotated_tag_is_inventory_not_release_order(self): + text = 'ref: refs/heads/main\tHEAD\n'+self.pin+'\tHEAD\n'+self.pin+'\trefs/heads/main\n' + text += '3'*40+'\trefs/tags/v2\n'+'4'*40+'\trefs/tags/v2^{}\n' + data = upstream.parse_remote(text) + self.assertEqual(data['tags']['v2'],{'object':'3'*40,'commit':'4'*40}) + with self.assertRaisesRegex(ValueError,'no tag object'): + upstream.parse_remote(text.replace('3'*40+'\trefs/tags/v2\n','')) + with self.assertRaisesRegex(ValueError,'Duplicate'): + upstream.parse_remote(text+self.pin+'\tHEAD\n') + + def test_query_is_read_only_and_bounded(self): + output = 'ref: refs/heads/main\tHEAD\n'+self.pin+'\tHEAD\n'+self.pin+'\trefs/heads/main\n' + with mock.patch.object(upstream.subprocess,'run',return_value=mock.Mock(stdout=output)) as run: + upstream.query(upstream.REPOSITORIES['ninjars']) + self.assertEqual(run.call_args.args[0],['git','ls-remote','--symref',upstream.REPOSITORIES['ninjars'], + 'HEAD','refs/heads/main','refs/tags/*']) + self.assertEqual(run.call_args.kwargs['timeout'],30) + + def test_failure_is_structured_and_snapshot_is_never_overwritten(self): + target = self.work/'checkpoint.json' + args = ['--manifest',str(self.manifest),'--lockfile',str(self.lock),'--output',str(target)] + with mock.patch.object(upstream,'check',side_effect=subprocess.TimeoutExpired(['git'],30)), contextlib.redirect_stdout(io.StringIO()): + self.assertEqual(upstream.main(args),2) + self.assertFalse(json.loads(target.read_text())['complete']) + before = target.read_bytes() + with mock.patch.object(upstream,'check') as check, contextlib.redirect_stdout(io.StringIO()): + self.assertEqual(upstream.main(args),2) + check.assert_not_called() + self.assertEqual(target.read_bytes(),before) + + def test_repository_pins_parse_without_network(self): + pins = upstream.read_pins(ROOT/'vendor/ninjars/Cargo.toml',ROOT/'vendor/ninjars/Cargo.lock') + self.assertEqual(set(pins),{'ninjars','oneloopmaster'}) + self.assertTrue(all(upstream.SHA.fullmatch(pin) for pin in pins.values())) + + def test_transitive_git_sources_require_explicit_matching_full_revisions(self): + valid = self.lock.read_text() + for query, resolved in [('branch=main', '4'*40), ('rev=abcd', '4'*40), + ('rev='+'4'*40, '5'*40), + ('rev='+'4'*40+'&branch=main', '4'*40)]: + self.lock.write_text(valid + '\n[[package]]\nname="transitive"\nversion="1.0.0"\n' + 'source="git+https://example.invalid/dependency?%s#%s"\n' % (query,resolved)) + query_remote = mock.Mock() + with self.subTest(query=query), self.assertRaises(ValueError): + upstream.check(self.manifest,self.lock,query_remote) + query_remote.assert_not_called() + + def test_transitive_inventory_retains_repository_revision_and_package_names(self): + result = upstream.check(self.manifest,self.lock, + lambda url: self.remote(self.pin if url.endswith('/ninjars') else self.master)) + self.assertFalse(result['update_pending']) + self.assertEqual(result['git_dependencies'],[ + {'repository':upstream.REPOSITORIES['ninjars'], 'revision':self.pin, + 'packages':['ninjars','ninjars-symbolica']}, + {'repository':upstream.REPOSITORIES['oneloopmaster'], 'revision':self.master, + 'packages':['oneloop']}]) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/unit_tests/various/test_q_polynomial_compiled.py b/tests/unit_tests/various/test_q_polynomial_compiled.py new file mode 100644 index 0000000000..79adc2b41e --- /dev/null +++ b/tests/unit_tests/various/test_q_polynomial_compiled.py @@ -0,0 +1,601 @@ +"""Numerical regression for the generated wavefunction update kernels.""" +from pathlib import Path +import shutil +import subprocess +import tempfile +import unittest + +from madgraph.iolibs.file_writers import FortranWriter +from madgraph.various.q_polynomial import ( + FortranPolynomialRoutines, get_number_of_coefs_for_rank) + + +@unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') +class CompactWavefunctionUpdateTest(unittest.TestCase): + """Compare optimized kernels with the legacy accumulation order in DP/QP.""" + + def test_exact_legacy_results_across_ranks_shapes_and_sparsity(self): + with tempfile.TemporaryDirectory(prefix='madloop-polynomial-') as tmp: + work = Path(tmp) + (work / 'coef_specs.inc').write_text( + ' INTEGER MAXLWFSIZE,VERTEXMAXCOEFS\n' + ' PARAMETER(MAXLWFSIZE=4,VERTEXMAXCOEFS=15)\n') + (work / 'loop_max_coefs.inc').write_text( + ' INTEGER LOOPMAXCOEFS\n' + ' PARAMETER(LOOPMAXCOEFS=210)\n') + generator = FortranPolynomialRoutines( + 6, updater_max_rank=2, proc_prefix='TEST_', sub_prefix='TEST_') + with FortranWriter(str(work / 'constants.f')) as writer: + writer.writelines(generator.write_polynomial_constant_module()) + for kind in (8, 16): + with self.subTest(kind=kind): + self.check_precision(work, kind) + + def check_precision(self, work, kind): + generated, calls = [], [] + generator = FortranPolynomialRoutines( + 6, updater_max_rank=2, proc_prefix='TEST_', sub_prefix='TEST_', + coef_format='complex*%d' % (2 * kind)) + for left in range(5): + for right in range(3): + generated.append(generator.write_compact_wl_updater(left, right)) + calls.append(""" +call TEST_UPDATE_WL_{left}_{right}(a,ls,b,ins,outs,actual) +call legacy_update(a,ls,b,ins,outs,{nleft},{nright},expected) +if (any(actual/=expected)) then + write(*,*) 'MISMATCH', {left},{right},ls,ins,outs,trial + stop 1 +endif +checks=checks+1 +""".format(left=left, right=right, + nleft=get_number_of_coefs_for_rank(left), + nright=get_number_of_coefs_for_rank(right))) + with FortranWriter(str(work / 'generated.f')) as writer: + writer.writelines('\n'.join(generated)) + # The reference keeps the old L,I order and accepts the rank counts at + # runtime, independently of the production generator's loop layout. + (work / 'driver.f90').write_text(""" +program check +use TEST_POLYNOMIAL_CONSTANTS +implicit none +complex({kind}) :: a(4,0:209,4),b(4,0:14,4) +complex({kind}) :: expected(4,0:209,4),actual(4,0:209,4) +real({kind}) :: scale +integer :: i,j,k,ls,ins,outs,trial,checks +checks=0 +do trial=1,3 + do k=1,4 + do j=0,209 + do i=1,4 + scale=1.0_{kind} + if(trial==2.and.mod(j,3)==0) scale=1.e20_{kind} + if(trial==2.and.mod(j,3)==1) scale=1.e-20_{kind} + a(i,j,k)=cmplx(real(mod(17*i+31*j+13*k,43)-21,kind={kind})/7, & + real(mod(37*i+11*j+7*k,31)-15,kind={kind})/13,kind={kind})*scale + enddo + enddo + do j=0,14 + do i=1,4 + b(i,j,k)=cmplx(real(mod(19*i+29*j+3*k,17)-8,kind={kind})/3, & + real(mod(11*i+17*j+13*k,23)-11,kind={kind})/11,kind={kind}) + if(trial==3.and.mod(i+j+k,3)/=0) b(i,j,k)=0 + enddo + enddo + enddo + do ls=1,4 + do ins=1,4 + do outs=1,4 +{calls} + enddo + enddo + enddo +enddo +if(checks/=2880) stop 2 +write(*,*) 'PASS', checks +contains +subroutine legacy_update(a,ls,b,ins,outs,nleft,nright,out) + integer, intent(in) :: ls,ins,outs,nleft,nright + complex({kind}), intent(in) :: a(4,0:209,4),b(4,0:14,4) + complex({kind}), intent(out) :: out(4,0:209,4) + complex({kind}) :: updater + integer :: i,j,k,l,m,position + out=0 + do j=1,outs + do m=0,nright-1 + do k=1,ins + updater=b(j,m,k) + if(updater==0) cycle + do l=0,nleft-1 + position=COMB_COEF_POS(l,m) + do i=1,ls + out(j,position,i)=out(j,position,i)+a(k,l,i)*updater + enddo + enddo + enddo + enddo + enddo +end subroutine +end program +""".format(kind=kind, calls=''.join(calls))) + result = subprocess.run( + ['gfortran', '-O3', '-fcheck=all', '-ffixed-line-length-132', + 'constants.f', 'generated.f', 'driver.f90', '-o', 'check'], + cwd=work, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) + self.assertEqual(result.returncode, 0, result.stdout) + result = subprocess.run( + [str(work / 'check')], cwd=work, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) + self.assertEqual(result.returncode, 0, result.stdout) + self.assertIn('PASS', result.stdout) + + +@unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') +class ExpandedWavefunctionUpdateTest(unittest.TestCase): + """Check full bit patterns against the legacy per-output accumulation.""" + + def test_exact_legacy_results_including_inactive_regions_and_signed_zero(self): + with tempfile.TemporaryDirectory(prefix='madloop-expanded-') as tmp: + work = Path(tmp) + (work / 'coef_specs.inc').write_text( + ' INTEGER MAXLWFSIZE,VERTEXMAXCOEFS\n' + ' PARAMETER(MAXLWFSIZE=4,VERTEXMAXCOEFS=15)\n') + (work / 'loop_max_coefs.inc').write_text( + ' INTEGER LOOPMAXCOEFS\n' + ' PARAMETER(LOOPMAXCOEFS=210)\n') + generator = FortranPolynomialRoutines( + 6, updater_max_rank=2, proc_prefix='TEST_', sub_prefix='TEST_') + with FortranWriter(str(work / 'constants.f')) as writer: + writer.writelines(generator.write_polynomial_constant_module()) + for kind in (8, 16): + with self.subTest(kind=kind): + self.check_precision(work, kind) + + def check_precision(self, work, kind): + generator = FortranPolynomialRoutines( + 6, updater_max_rank=2, proc_prefix='TEST_', sub_prefix='TEST_', + coef_format='complex*%d' % (2 * kind)) + generated, calls = [], [] + for left in range(5): + for right in range(3): + generated.append(generator.write_expanded_wl_updater(left, right)) + calls.append(""" +expected=sentinel +actual=sentinel +call legacy_update(a,ls,b,ins,outs,{nleft},{nright},{nout},expected) +call TEST_UPDATE_WL_{left}_{right}(a,ls,b,ins,outs,actual) +old_bits=transfer(expected,old_bits) +new_bits=transfer(actual,new_bits) +if(any(old_bits/=new_bits)) then + write(*,*) 'BIT MISMATCH', {left},{right},ls,ins,outs,trial + stop 1 +endif +if(any(a/=saved_a).or.any(b/=saved_b)) stop 3 +checks=checks+1 +""".format(left=left, right=right, + nleft=get_number_of_coefs_for_rank(left), + nright=get_number_of_coefs_for_rank(right), + nout=get_number_of_coefs_for_rank(left+right))) + with FortranWriter(str(work / 'generated.f')) as writer: + writer.writelines('\n'.join(generated)) + # This runtime convolution is independent of the expanded generator. + # For each fixed output, the historical routine adds terms in K,L,M + # order. It clears only active outputs, unlike the compact routines. + (work / 'driver.f90').write_text(""" +program check +use iso_fortran_env, only: int64 +use TEST_POLYNOMIAL_CONSTANTS +implicit none +complex({kind}) :: a(4,0:209,4),b(4,0:14,4) +complex({kind}) :: saved_a(4,0:209,4),saved_b(4,0:14,4) +complex({kind}) :: expected(4,0:209,4),actual(4,0:209,4),sentinel +real({kind}) :: scale +integer(int64) :: old_bits({nbits}),new_bits({nbits}) +integer :: i,j,k,ls,ins,outs,trial,checks +sentinel=cmplx(-123.25_{kind},456.125_{kind},kind={kind}) +checks=0 +do trial=1,6 + do k=1,4 + do j=0,209 + do i=1,4 + scale=1.0_{kind} + if(trial==3.and.mod(j,3)==0) scale=1.e100_{kind} + if(trial==3.and.mod(j,3)==1) scale=1.e-100_{kind} + a(i,j,k)=cmplx(real(mod(17*i+31*j+13*k,43)-21,kind={kind})/7, & + real(mod(37*i+11*j+7*k,31)-15,kind={kind})/13,kind={kind})*scale + if(trial==2.and.mod(i+j+k,3)/=0) a(i,j,k)=0 + if(trial==4) a(i,j,k)=0 + if(trial==5) a(i,j,k)=cmplx((-1.0_{kind})**i, & + (-1.0_{kind})**(i+1),kind={kind}) + if(trial==6.and.mod(i+j+k,2)==0) a(i,j,k)=cmplx(-0.0_{kind},0.0_{kind},kind={kind}) + enddo + enddo + do j=0,14 + do i=1,4 + b(i,j,k)=cmplx(real(mod(19*i+29*j+3*k,17)-8,kind={kind})/3, & + real(mod(11*i+17*j+13*k,23)-11,kind={kind})/11,kind={kind}) + if(trial==2.and.mod(i+j+k,3)/=0) b(i,j,k)=0 + if(trial==4) b(i,j,k)=0 + if(trial==5) b(i,j,k)=cmplx(1.0_{kind},-1.0_{kind},kind={kind}) + if(trial==6.and.mod(i+j+k,2)==1) b(i,j,k)=cmplx(0.0_{kind},-0.0_{kind},kind={kind}) + enddo + enddo + enddo + saved_a=a + saved_b=b + do ls=0,4 + do ins=0,4 + do outs=0,4 +{calls} + enddo + enddo + enddo +enddo +if(checks/=11250) stop 2 +write(*,*) 'PASS',checks +contains +subroutine legacy_update(a,ls,b,ins,outs,nleft,nright,nout,out) + integer,intent(in) :: ls,ins,outs,nleft,nright,nout + complex({kind}),intent(in) :: a(4,0:209,4),b(4,0:14,4) + complex({kind}),intent(inout) :: out(4,0:209,4) + integer :: i,j,k,l,m,position + do i=1,ls + do j=1,outs + out(j,0:nout-1,i)=0 + do k=1,ins + do l=0,nleft-1 + do m=0,nright-1 + position=COMB_COEF_POS(l,m) + out(j,position,i)=out(j,position,i)+a(k,l,i)*b(j,m,k) + enddo + enddo + enddo + enddo + enddo +end subroutine +end program +""".format(kind=kind, nbits=2*kind//8*4*210*4, calls=''.join(calls))) + compiled = subprocess.run( + ['gfortran', '-O3', '-fcheck=all', '-ffixed-line-length-132', + 'constants.f', 'generated.f', 'driver.f90', '-o', 'check'], + cwd=work, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) + self.assertEqual(compiled.returncode, 0, compiled.stdout) + checked = subprocess.run([str(work / 'check')], cwd=work, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) + self.assertEqual(checked.returncode, 0, checked.stdout) + self.assertIn('PASS', checked.stdout) + + +# Independent dense routines captured before sparse generation was introduced. +_SPARSE_DENSE_REFERENCES = { + 'expanded': r""" SUBROUTINE MP_OLD_UPDATE_WL_1_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE TEST_POLYNOMIAL_CONSTANTS + INTEGER I,J,K + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + + DO I=1,LCUT_SIZE + DO K=0,14 + DO J=1,OUT_SIZE + OUT(J,K,I)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + ENDDO + ENDDO + DO K=1,IN_SIZE + DO J=1,OUT_SIZE + OUT(J,0,I)=OUT(J,0,I)+A(K,0,I)*B(J,0,K) + OUT(J,1,I)=OUT(J,1,I)+A(K,0,I)*B(J,1,K)+A(K,1,I)*B(J,0,K) + OUT(J,2,I)=OUT(J,2,I)+A(K,0,I)*B(J,2,K)+A(K,2,I)*B(J,0,K) + OUT(J,3,I)=OUT(J,3,I)+A(K,0,I)*B(J,3,K)+A(K,3,I)*B(J,0,K) + OUT(J,4,I)=OUT(J,4,I)+A(K,0,I)*B(J,4,K)+A(K,4,I)*B(J,0,K) + OUT(J,5,I)=OUT(J,5,I)+A(K,1,I)*B(J,1,K) + OUT(J,6,I)=OUT(J,6,I)+A(K,1,I)*B(J,2,K)+A(K,2,I)*B(J,1,K) + OUT(J,7,I)=OUT(J,7,I)+A(K,2,I)*B(J,2,K) + OUT(J,8,I)=OUT(J,8,I)+A(K,1,I)*B(J,3,K)+A(K,3,I)*B(J,1,K) + OUT(J,9,I)=OUT(J,9,I)+A(K,2,I)*B(J,3,K)+A(K,3,I)*B(J,2,K) + OUT(J,10,I)=OUT(J,10,I)+A(K,3,I)*B(J,3,K) + OUT(J,11,I)=OUT(J,11,I)+A(K,1,I)*B(J,4,K)+A(K,4,I)*B(J,1,K) + OUT(J,12,I)=OUT(J,12,I)+A(K,2,I)*B(J,4,K)+A(K,4,I)*B(J,2,K) + OUT(J,13,I)=OUT(J,13,I)+A(K,3,I)*B(J,4,K)+A(K,4,I)*B(J,3,K) + OUT(J,14,I)=OUT(J,14,I)+A(K,4,I)*B(J,4,K) + ENDDO + ENDDO + ENDDO + END +""", + 'compact': r""" SUBROUTINE MP_OLD_UPDATE_WL_2_1(A,LCUT_SIZE,B,IN_SIZE,OUT_SIZE + $ ,OUT) + USE TEST_POLYNOMIAL_CONSTANTS + IMPLICIT NONE + INTEGER I,J,K,L,M + COMPLEX*32 A(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 B(MAXLWFSIZE,0:VERTEXMAXCOEFS-1,MAXLWFSIZE) + COMPLEX*32 OUT(MAXLWFSIZE,0:LOOPMAXCOEFS-1,MAXLWFSIZE) + INTEGER LCUT_SIZE,IN_SIZE,OUT_SIZE + INTEGER NEW_POSITION + COMPLEX*32 UPDATER_COEF + +C Welcome to the computational heart of MadLoop... + OUT(:,:,:)=CMPLX(0.0E0_16,0.0E0_16,KIND=16) + DO J=1,OUT_SIZE + DO M=0,4 + DO K=1,IN_SIZE + UPDATER_COEF = B(J,M,K) + IF (UPDATER_COEF.EQ.CMPLX(0.0E0_16,0.0E0_16,KIND=16)) CYCLE + DO I=1,LCUT_SIZE + DO L=0,14 + NEW_POSITION = COMB_COEF_POS(L,M) + OUT(J,NEW_POSITION,I)=OUT(J,NEW_POSITION,I) + A(K,L,I) + $ *UPDATER_COEF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + + END +""", +} + +_SPARSE_DRIVER = r""" +program exact_sparse +use iso_fortran_env, only: int64 +use, intrinsic :: ieee_arithmetic +use, intrinsic :: ieee_exceptions +use TEST_POLYNOMIAL_CONSTANTS +implicit none +complex(16) :: a(4,0:209,4),b(4,0:14,4),expected(4,0:209,4),actual(4,0:209,4) +complex(16) :: sentinel +integer(int64) :: old_bits(4*4*210*4),new_bits(4*4*210*4),saved_a(4*4*210*4) +integer(int64) :: b_bits(4*4*15*4),saved_b(4*4*15*4) +real(16) :: scale,inf,nan,snan,small +logical :: old_flags(size(ieee_all)),new_flags(size(ieee_all)) +type(ieee_round_type) :: modes(4) +integer :: i,j,k,ls,ins,outs,trial,rounding,checks +modes=[ieee_nearest,ieee_up,ieee_down,ieee_to_zero] +sentinel=cmplx(-123.25_16,456.125_16,kind=16) +inf=ieee_value(0.0_16,ieee_positive_inf) +nan=ieee_value(0.0_16,ieee_quiet_nan) +snan=ieee_value(0.0_16,ieee_signaling_nan) +small=nearest(0.0_16,1.0_16) +checks=0 +do rounding=1,4 + call ieee_set_rounding_mode(modes(rounding)) + do trial=1,12 + do k=1,4 + do j=0,209 + do i=1,4 + scale=1.0_16 + if(trial==3.and.mod(j,3)==0) scale=1.e2000_16 + if(trial==3.and.mod(j,3)==1) scale=1.e-2000_16 + a(i,j,k)=cmplx(real(mod(17*i+31*j+13*k,43)-21,kind=16)/7, & + real(mod(37*i+11*j+7*k,31)-15,kind=16)/13,kind=16)*scale + if(trial==2.and.mod(i+j+k,3)/=0) a(i,j,k)=0 + if(trial==4) a(i,j,k)=0 + if(trial==5) a(i,j,k)=cmplx((-1.0_16)**i,(-1.0_16)**(i+1),kind=16) + if(trial==6.and.mod(i+j+k,2)==0) a(i,j,k)=cmplx(-0.0_16,0.0_16,kind=16) + if(trial==7) a(i,j,k)=cmplx(0.0_16,-0.0_16,kind=16) + if(trial==7.and.mod(i+j+k,5)==0) a(i,j,k)=cmplx(inf,nan,kind=16) + if(trial==8.and.mod(i+j+k,3)/=0) a(i,j,k)=0 + if(trial==9) a(i,j,k)=cmplx(small,-small,kind=16) + if(trial==10.and.mod(i+j+k,2)==0) a(i,j,k)=0 + if(trial==10.and.mod(i+j+k,2)==1) a(i,j,k)=cmplx(huge(scale),-huge(scale),kind=16) + if(trial==11) a(i,j,k)=cmplx(snan,0.0_16,kind=16) + if(trial==12) a(i,j,k)=0 + enddo + enddo + do j=0,14 + do i=1,4 + b(i,j,k)=cmplx(real(mod(19*i+29*j+3*k,17)-8,kind=16)/3, & + real(mod(11*i+17*j+13*k,23)-11,kind=16)/11,kind=16) + if(trial==2.and.mod(i+j+k,3)/=0) b(i,j,k)=0 + if(trial==4.or.trial==7) b(i,j,k)=0 + if(trial==5) b(i,j,k)=cmplx(1.0_16,-1.0_16,kind=16) + if(trial==6.and.mod(i+j+k,2)==1) b(i,j,k)=cmplx(0.0_16,-0.0_16,kind=16) + if(trial==8.and.mod(i+j+k,5)==0) b(i,j,k)=cmplx(inf,nan,kind=16) + if(trial==9) b(i,j,k)=cmplx(0.25_16,-0.25_16,kind=16) + if(trial==10.and.mod(i+j+k,2)==1) b(i,j,k)=0 + if(trial==11) b(i,j,k)=0 + if(trial==12) b(i,j,k)=cmplx(snan,0.0_16,kind=16) + enddo + enddo + enddo + saved_a=transfer(a,saved_a) + saved_b=transfer(b,saved_b) + do ls=0,4 + do ins=0,4 + do outs=0,4 + +expected=sentinel +actual=sentinel +call ieee_set_flag(ieee_all,.false.) +call OLD_ROUTINE(a,ls,b,ins,outs,expected) +call ieee_get_flag(ieee_all,old_flags) +call ieee_set_flag(ieee_all,.false.) +call NEW_ROUTINE(a,ls,b,ins,outs,actual) +call ieee_get_flag(ieee_all,new_flags) +old_bits=transfer(expected,old_bits) +new_bits=transfer(actual,new_bits) +if(any(old_bits/=new_bits)) then + write(*,*) 'BIT MISMATCH', 1,1,ls,ins,outs,trial,rounding + stop 1 +endif +if(any(old_flags.neqv.new_flags)) then + write(*,*) 'FLAGS MISMATCH', 1,1,ls,ins,outs,trial,rounding + write(*,*) old_flags,new_flags + stop 2 +endif +if(any(transfer(a,old_bits)/=saved_a).or.any(transfer(b,b_bits)/=saved_b)) stop 3 +checks=checks+1 + + enddo + enddo + enddo + enddo +enddo +call ieee_set_rounding_mode(ieee_nearest) +if(checks/=6000) stop 4 +write(*,*) 'PASS',checks +end program +""" + +@unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') +class SparseQPWavefunctionUpdateTest(unittest.TestCase): + """Preserve output bits, input bits and IEEE flags, including empty calls.""" + + def check_kernel(self, mode, rounding_math=False, reject_layout=False, + no_automatic=False): + left, right = (1, 1) if mode == 'expanded' else (2, 1) + with tempfile.TemporaryDirectory(prefix='madloop-sparse-qp-') as tmp: + work = Path(tmp) + (work / 'coef_specs.inc').write_text( + ' INTEGER MAXLWFSIZE,VERTEXMAXCOEFS\n' + ' PARAMETER(MAXLWFSIZE=4,VERTEXMAXCOEFS=15)\n') + (work / 'loop_max_coefs.inc').write_text( + ' INTEGER LOOPMAXCOEFS\n' + ' PARAMETER(LOOPMAXCOEFS=210)\n') + generator = FortranPolynomialRoutines( + 6, updater_max_rank=2, proc_prefix='TEST_', sub_prefix='MP_NEW_', + coef_format='complex*32') + constants = FortranPolynomialRoutines(6, updater_max_rank=2, + sub_prefix='TEST_') + with FortranWriter(str(work / 'constants.f')) as writer: + writer.writelines(constants.write_polynomial_constant_module()) + source = getattr(generator, 'write_%s_wl_updater' % mode)(left, right) + if reject_layout: + # Simulate an unrecognized representation without floating-point + # classification: every update must reach the untouched oracle. + old = 'TRANSFER(1.0_16,(/0_8,0_8/))' + self.assertEqual(source.count(old), 1) + source = source.replace(old, '(/0_8,0_8/)') + with FortranWriter(str(work / 'new.f')) as writer: + writer.writelines(source) + (work / 'old.f').write_text(_SPARSE_DENSE_REFERENCES[mode]) + suffix = 'UPDATE_WL_%d_%d' % (left, right) + (work / 'driver.f90').write_text( + _SPARSE_DRIVER.replace('OLD_ROUTINE', 'MP_OLD_'+suffix) + .replace('NEW_ROUTINE', 'MP_NEW_'+suffix)) + flags = ['-O3', '-fcheck=all', '-ffixed-line-length-132'] + if rounding_math: + flags.append('-frounding-math') + if no_automatic: + flags.append('-fno-automatic') + build = subprocess.run( + ['gfortran', *flags, 'constants.f', 'old.f', 'new.f', + 'driver.f90', '-o', 'check'], cwd=work, text=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + self.assertEqual(build.returncode, 0, build.stdout) + run = subprocess.run([str(work/'check')], cwd=work, text=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + self.assertEqual(run.returncode, 0, run.stdout) + self.assertIn('PASS', run.stdout) + self.assertIn('6000', run.stdout) + + def test_sparse_binary128_preserves_bits_and_exception_flags(self): + for mode in ('expanded', 'compact'): + for rounding_math in (False, True): + with self.subTest(mode=mode, rounding_math=rounding_math): + self.check_kernel(mode, rounding_math) + + def test_unrecognized_binary128_layout_uses_original_arithmetic(self): + self.check_kernel('expanded', reject_layout=True) + + def test_nlo_static_locals_preserve_bits_and_exception_flags(self): + # FKS compiles polynomial.f with -fno-automatic. A local scratch array + # in the implicitly PURE elemental classifier would acquire SAVE and + # fail compilation; exercise actual updates under those build flags. + for mode in ('expanded', 'compact'): + with self.subTest(mode=mode): + self.check_kernel(mode, rounding_math=True, no_automatic=True) + + +def _terminal_driver(left, right): + """Independent full-kernel oracle, including the private guard boundaries.""" + driver = _SPARSE_DRIVER.replace('OLD_ROUTINE', 'MP_OLD_UPDATE_WL_%d_%d' % (left, right)) + name = 'MP_NEW_TERMINAL_WL_%d_%d' % (left, right) + driver = driver.replace('NEW_ROUTINE', name) + driver = driver.replace('integer :: i,j,k,ls,ins,outs,trial,rounding,checks', + 'integer :: i,j,k,ls,ins,outs,trial,rounding,checks,flagstate,before_fast\n' + 'integer :: fast,fallback\ncommon/TRACE_COUNTS/fast,fallback') + driver = driver.replace('checks=0\n', 'checks=0\nfast=0\nfallback=0\ndo flagstate=0,1\n') + driver = driver.replace('call ieee_set_flag(ieee_all,.false.)', + 'call ieee_set_flag(ieee_all,.false.)\n' + 'if(flagstate==1) call ieee_set_flag(ieee_inexact,.true.)') + driver = driver.replace('call '+name+'(a,ls,b,ins,outs,actual)', + 'before_fast=fast\ncall '+name+'(a,ls,b,ins,outs,actual,flagstate==1)') + driver = driver.replace('if(any(old_bits/=new_bits)) then', + 'if(fast>before_fast) then\n' + ' do i=1,4\n' + ' if(any(transfer(expected(i,:,i),old_bits,210*4)/= &\n' + ' transfer(actual(i,:,i),new_bits,210*4))) stop 6\n' + ' enddo\n' + 'else if(any(old_bits/=new_bits)) then') + driver = driver.replace('call ieee_set_rounding_mode(ieee_nearest)\nif(checks/=6000)', + 'enddo\ncall ieee_set_rounding_mode(ieee_nearest)\nif(checks/=18000)') + driver = driver.replace("write(*,*) 'PASS',checks", + "if(fast==0.or.fallback==0) stop 7\nwrite(*,*) 'PASS',checks,fast,fallback") + driver = driver.replace('do trial=1,12', 'do trial=1,18') + driver = driver.replace('if(trial==12) a(i,j,k)=0', """if(trial==12) a(i,j,k)=0 + if(trial==13) a(i,j,k)=cmplx(2.0_16**1000,-2.0_16**1000,kind=16) + if(trial==14) a(i,j,k)=cmplx(2.0_16**(-1000),2.0_16**(-1000),kind=16) + if(trial==15) a(i,j,k)=cmplx(2.0_16**1001,0.0_16,kind=16) + if(trial==16) a(i,j,k)=cmplx(2.0_16**(-1001),0.0_16,kind=16) + if(trial==17) a(i,j,k)=cmplx(2.0_16**1000,2.0_16**1000,kind=16) + if(trial==18) a(i,j,k)=cmplx(nearest(2.0_16**1001,-1.0_16), & + -nearest(2.0_16**1001,-1.0_16),kind=16)""") + driver = driver.replace('if(trial==12) b(i,j,k)=cmplx(snan,0.0_16,kind=16)', + """if(trial==12) b(i,j,k)=cmplx(snan,0.0_16,kind=16) + if(trial==13) b(i,j,k)=cmplx(2.0_16**1000,2.0_16**1000,kind=16) + if(trial==14.or.trial==17) b(i,j,k)=cmplx(2.0_16**(-1000), & + -2.0_16**(-1000),kind=16) + if(trial==15.or.trial==16) b(i,j,k)=cmplx(1.0_16,0.0_16,kind=16) + if(trial==18) b(i,j,k)=cmplx(nearest(2.0_16**1001,-1.0_16), & + nearest(2.0_16**1001,-1.0_16),kind=16)""") + return driver + + +@unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') +class TerminalQPWavefunctionUpdateTest(unittest.TestCase): + def test_consumed_bits_inputs_and_flags_with_full_fallback(self): + for mode in ('expanded', 'compact'): + for flags in ([], ['-frounding-math'], + ['-frounding-math', '-fno-automatic']): + with self.subTest(mode=mode, flags=flags): + self.check_kernel(mode, flags) + + def check_kernel(self, mode, flags): + left, right = (1, 1) if mode == 'expanded' else (2, 1) + with tempfile.TemporaryDirectory(prefix='madloop-terminal-qp-') as tmp: + work = Path(tmp) + (work/'coef_specs.inc').write_text( + ' INTEGER MAXLWFSIZE,VERTEXMAXCOEFS\n' + ' PARAMETER(MAXLWFSIZE=4,VERTEXMAXCOEFS=15)\n') + (work/'loop_max_coefs.inc').write_text( + ' INTEGER LOOPMAXCOEFS\n PARAMETER(LOOPMAXCOEFS=210)\n') + generator = FortranPolynomialRoutines(6, updater_max_rank=2, + proc_prefix='TEST_', sub_prefix='MP_NEW_', coef_format='complex*32') + constants = FortranPolynomialRoutines(6, updater_max_rank=2, sub_prefix='TEST_') + with FortranWriter(str(work/'constants.f')) as writer: + writer.writelines(constants.write_polynomial_constant_module()) + method = getattr(generator, 'write_'+mode+'_wl_updater') + private = method(left, right, terminal=True) + # Only counters are added; both admission paths must actually run. + private = private.replace(' LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT\n', + ' LOGICAL WL_ALREADY,WL_HALT,WL_ENTRY_INEXACT\n' + ' INTEGER FAST,FALLBACK\n COMMON/TRACE_COUNTS/FAST,FALLBACK\n') + private = private.replace(' CALL MP_NEW_UPDATE_WL_%d_%d(' % (left, right), + ' FALLBACK=FALLBACK+1\n CALL MP_NEW_UPDATE_WL_%d_%d(' % (left, right), 1) + private = private.replace(' RETURN\nENDIF\n', + ' RETURN\nENDIF\nFAST=FAST+1\n', 1) + with FortranWriter(str(work/'generated.f')) as writer: + writer.writelines(method(left, right)+'\n'+private) + (work/'old.f').write_text(_SPARSE_DENSE_REFERENCES[mode]) + (work/'driver.f90').write_text(_terminal_driver(left, right)) + command = ['gfortran', '-O3', '-fcheck=all', '-ffixed-line-length-132', + *flags, 'constants.f', 'old.f', 'generated.f', 'driver.f90', '-o', 'check'] + built = subprocess.run(command, cwd=work, capture_output=True, text=True) + self.assertEqual(built.returncode, 0, built.stdout+built.stderr) + result = subprocess.run([str(work/'check')], cwd=work, capture_output=True, text=True) + self.assertEqual(result.returncode, 0, result.stdout+result.stderr) + self.assertIn('18000', result.stdout) diff --git a/tests/unit_tests/various/test_q_polynomial_factorized.py b/tests/unit_tests/various/test_q_polynomial_factorized.py new file mode 100644 index 0000000000..215669d364 --- /dev/null +++ b/tests/unit_tests/various/test_q_polynomial_factorized.py @@ -0,0 +1,245 @@ +"""Contract and IEEE regressions for private generated QP FFV contractions.""" +from pathlib import Path +import re +import shutil +import subprocess +import tempfile +import unittest + +from madgraph.iolibs.file_writers import FortranWriter +from madgraph.various.q_polynomial import FortranPolynomialRoutines, PolynomialError + + +def generator(precision='complex*32'): + return FortranPolynomialRoutines( + 6, updater_max_rank=2, proc_prefix='TEST_', sub_prefix='TEST_', + coef_format=precision) + + +def instrument(source): + source = source.replace(' implicit none', ' implicit none\n' + ' INTEGER FAST,FALLBACK\n COMMON/FACTOR_TEST/FAST,FALLBACK', 1) + source = source.replace('C FACTOR_FAST_PATH', + 'C FACTOR_FAST_PATH\nFAST=FAST+1', 1) + source, count = re.subn( + r'(?m)^(\s*CALL TEST_(?:UPDATE|TERMINAL)_WL_\d_1(?:_DENSE)?\(.*)$', + r' FALLBACK=FALLBACK+1\n\1', source) + assert count >= 5 + return source + + +class FactorizedWavefunctionUpdateTest(unittest.TestCase): + def test_supported_private_names_and_rejected_domains(self): + gen = generator() + for rank in (2, 3, 4): + for vertex in ('FFV1L1_2', 'FFV1L2_1'): + for terminal in (False, True): + with self.subTest(rank=rank, vertex=vertex, terminal=terminal): + name = 'TEST_%s_WL_%d_1_FACTOR_%s' % ( + 'TERMINAL' if terminal else 'UPDATE', rank, vertex) + source = gen.write_factorized_wl_updater(rank, vertex, terminal) + self.assertTrue(source.startswith('SUBROUTINE ' + name + '(')) + self.assertEqual(source, gen.write_factorized_wl_updater( + rank, 'MP_' + vertex, terminal)) + for rank, vertex, precision in ( + (1, 'FFV1L1_2', 'complex*32'), + (5, 'FFV1L2_1', 'complex*32'), + (2, 'FFS1L1_2', 'complex*32'), + (2, 'FFV1L1_2', 'complex*16')): + with self.assertRaises(PolynomialError): + generator(precision).write_factorized_wl_updater(rank, vertex) + gen.sub_prefix = 'A' * 63 + with self.assertRaises(PolynomialError): + gen.write_factorized_wl_updater(2, 'FFV1L1_2') + + @unittest.skipUnless(shutil.which('gfortran'), 'gfortran is required') + def test_fast_paths_fallback_bits_flags_and_enabled_traps(self): + gen = generator() + sources = [] + old_calls, new_calls, selectors = [], [], [] + index = 0 + for rank in (2, 3, 4): + sources.append(gen.write_compact_wl_updater(rank, 1)) + sources.append(gen.write_compact_wl_updater(rank, 1, terminal=True)) + for vertex in ('FFV1L1_2', 'FFV1L2_1'): + for terminal in (False, True): + index += 1 + public = 'TEST_%s_WL_%d_1' % ( + 'TERMINAL' if terminal else 'UPDATE', rank) + private = public + '_FACTOR_' + vertex + sources.append(instrument(gen.write_factorized_wl_updater( + rank, vertex, terminal))) + old_calls.append('case(%d)\n call %s(a,ls,b,ins,outs,old%s)' % + (index, public, ',entry' if terminal else '')) + new_calls.append('case(%d)\n call %s(a,ls,b,ins,outs,new,entry)' % + (index, private)) + selectors.append('case(%d)\n flip=%d' % + (index, 1 if vertex == 'FFV1L1_2' else -1)) + driver = _DRIVER.replace('OLD_CALLS', '\n'.join(old_calls)) + driver = driver.replace('NEW_CALLS', '\n'.join(new_calls)) + driver = driver.replace('SELECT_ORIENTATION', '\n'.join(selectors)) + with tempfile.TemporaryDirectory(prefix='madloop-factor-') as tmp: + work = Path(tmp) + (work / 'coef_specs.inc').write_text( + ' INTEGER MAXLWFSIZE,VERTEXMAXCOEFS\n' + ' PARAMETER(MAXLWFSIZE=4,VERTEXMAXCOEFS=15)\n') + (work / 'loop_max_coefs.inc').write_text( + ' INTEGER LOOPMAXCOEFS\n PARAMETER(LOOPMAXCOEFS=210)\n') + for name, text in ( + ('constants.f', gen.write_polynomial_constant_module()), + ('kernels.f', '\n\n'.join(sources))): + with FortranWriter(str(work / name)) as writer: + writer.writelines(text) + (work / 'driver.f90').write_text(driver) + for flags in ([], ['-fno-automatic']): + with self.subTest(flags=flags): + compiled = subprocess.run( + ['gfortran', '-O3', '-w', '-fPIC', '-ffixed-line-length-132', + *flags, 'constants.f', 'kernels.f', 'driver.f90', '-o', 'check'], + cwd=work, capture_output=True, text=True, timeout=180) + self.assertEqual(compiled.returncode, 0, compiled.stdout + compiled.stderr) + checked = subprocess.run([str(work / 'check')], cwd=work, + capture_output=True, text=True, timeout=30) + self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr) + self.assertEqual(checked.stdout.split(), ['PASS', '204']) + + +_DRIVER = r""" +program check +use, intrinsic :: ieee_arithmetic +use, intrinsic :: ieee_exceptions +implicit none +complex(16) a(4,0:209,4),b(4,0:14,4),old(4,0:209,4),new(4,0:209,4) +complex(16) h(4,4),ci +integer*8 saved_a(4*4*210*4),saved_b(4*4*15*4) +integer*8 oldbits(4*4*210*4),newbits(4*4*210*4) +integer kernel,trial,i,j,k,l,ls,ins,outs,flip,flag,checks,fast,fallback +common/FACTOR_TEST/fast,fallback +logical entry,oldflags(size(ieee_all)),newflags(size(ieee_all)),wantfast +ci=cmplx(0.0_16,1.0_16,16) +checks=0 +call ieee_set_halting_mode(ieee_all,.false.) +do kernel=1,12 + select case(kernel) + SELECT_ORIENTATION + end select + do trial=1,12 + call ieee_set_rounding_mode(ieee_nearest) + a=0 + b=0 + do i=1,4 + do l=0,209 + do k=1,4 + a(k,l,i)=cmplx(real(mod(17*k+7*l+11*i,31)-15,16)/8, & + real(mod(13*k+3*l+5*i,23)-11,16)/16,16) + enddo + enddo + enddo + do k=1,4 + do j=1,4 + h(j,k)=cmplx(real(2*j-k,16)/8,real(j+3*k,16)/16,16) + b(j,0,k)=cmplx(real(3*j-k,16)/8,real(2*j-k,16)/16,16) + enddo + enddo + if(trial==11) then + a(:,0:209:2,:)=0 + h(:,2)=0 + endif + if(trial==12) then + h(1,:)=cmplx(real(h(1,:),16),-0.0_16,16) + h(3,:)=cmplx(-0.0_16,aimag(h(3,:)),16) + endif + b(:,1,:)=h + b(1,2,:)=-flip*h(2,:) + b(2,2,:)=-flip*h(1,:) + b(3,2,:)=flip*h(4,:) + b(4,2,:)=flip*h(3,:) + b(1,3,:)=ci*h(2,:) + b(2,3,:)=-ci*h(1,:) + b(3,3,:)=-ci*h(4,:) + b(4,3,:)=ci*h(3,:) + b(1,4,:)=-flip*h(1,:) + b(2,4,:)=flip*h(2,:) + b(3,4,:)=flip*h(3,:) + b(4,4,:)=-flip*h(4,:) + entry=.true. + ls=4 + ins=4 + outs=4 + select case(trial) + case(2) + entry=.false. + case(3) + b(1,2,1)=b(1,2,1)+1 + case(4) + a(1,0,1)=cmplx(scale(1.0_16,1001),0.0_16,16) + case(5) + call ieee_set_rounding_mode(ieee_up) + case(6) + ls=0 + case(7) + a(1,0,1)=cmplx(ieee_value(0.0_16,ieee_signaling_nan),0.0_16,16) + case(8) + b(1,0,1)=cmplx(ieee_value(0.0_16,ieee_signaling_nan),0.0_16,16) + case(9) + outs=3 + case(10) + b(1,0,1)=cmplx(nearest(0.0_16,1.0_16),0.0_16,16) + end select + saved_a=transfer(a,saved_a) + saved_b=transfer(b,saved_b) + call ieee_set_flag(ieee_all,.false.) + call ieee_set_flag(ieee_inexact,entry) + select case(kernel) + OLD_CALLS + end select + call ieee_get_flag(ieee_all,oldflags) + fast=0 + fallback=0 + call ieee_set_flag(ieee_all,.false.) + call ieee_set_flag(ieee_inexact,entry) + select case(kernel) + NEW_CALLS + end select + call ieee_get_flag(ieee_all,newflags) + wantfast=trial==1.or.trial==6.or.trial==11.or.trial==12 + if(wantfast) then + if(fast/=1.or.fallback/=0) stop 10 + if(any(abs(old-new)>1.e-30_16*max(1.0_16,maxval(abs(old))))) stop 11 + else + if(fast/=0.or.fallback/=1) stop 12 + oldbits=transfer(old,oldbits) + newbits=transfer(new,newbits) + if(any(oldbits/=newbits)) stop 13 + endif + if(any(oldflags.neqv.newflags)) stop 14 + if(any(saved_a/=transfer(a,saved_a))) stop 15 + if(any(saved_b/=transfer(b,saved_b))) stop 16 + checks=checks+1 + enddo + call ieee_set_rounding_mode(ieee_nearest) + do flag=1,size(ieee_all) + if(.not.ieee_support_halting(ieee_all(flag))) stop 17 + a=0 + b=0 + ls=4 + ins=4 + outs=4 + entry=.true. + fast=0 + fallback=0 + call ieee_set_flag(ieee_all,.false.) + call ieee_set_halting_mode(ieee_all(flag),.true.) + select case(kernel) + NEW_CALLS + end select + call ieee_set_halting_mode(ieee_all,.false.) + call ieee_get_flag(ieee_all,newflags) + if(fast/=0.or.fallback/=1.or.any(newflags).or.any(new/=0)) stop 18 + checks=checks+1 + enddo +enddo +if(checks/=204) stop 19 +write(*,*) 'PASS',checks +end program +""" diff --git a/tools/ninjars_upstream.py b/tools/ninjars_upstream.py new file mode 100644 index 0000000000..1ce8fc8a21 --- /dev/null +++ b/tools/ninjars_upstream.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 +"""Read-only upstream checkpoint. Exit 0=current, 1=update, 2=invalid/unavailable. + +Requires Python 3.11+. This never fetches, changes a pin, modifies a reference +clone, or creates a PR. An explicit --output creates a new JSON snapshot only. +""" +import argparse +import datetime +import hashlib +import json +from pathlib import Path +import re +import subprocess +from urllib.parse import parse_qs, urlsplit + +ROOT = Path(__file__).resolve().parents[1] +REPOSITORIES = { + 'ninjars': 'https://github.com/alphal00p/ninjars', + 'oneloopmaster': 'https://github.com/alphal00p/oneloopmaster', +} +SHA = re.compile(r'[0-9a-f]{40}\Z') + + +def canonical_url(url): + if not isinstance(url, str): + raise ValueError('Git URL must be a string') + return url.removesuffix('.git') + + +def revision(value, label): + if not isinstance(value, str) or not SHA.fullmatch(value): + raise ValueError('%s must pin a full 40-character commit' % label) + return value + + +def lock_source(package): + source = package.get('source', '') + if not isinstance(source, str) or not source.startswith('git+'): + raise ValueError('%s has no pinned Git lock source' % package.get('name')) + parsed = urlsplit(source[4:]) + query = parse_qs(parsed.query, strict_parsing=True) + if set(query) != {'rev'} or len(query['rev']) != 1: + raise ValueError('Lock Git source must use one explicit rev') + pin = revision(query['rev'][0], 'lock rev') + if revision(parsed.fragment, 'resolved lock revision') != pin: + raise ValueError('Lock rev differs from resolved commit') + return canonical_url(parsed._replace(query='', fragment='').geturl()), pin + + +def git_dependencies(packages): + """Inventory and validate every transitive Git source, including overrides.""" + sources = {} + for package in packages: + source = package.get('source', '') if isinstance(package, dict) else '' + if isinstance(source, str) and source.startswith('git+'): + url, pin = lock_source(package) + sources.setdefault((url, pin), []).append(package['name']) + return [dict(repository=url, revision=pin, packages=sorted(names)) + for (url, pin), names in sorted(sources.items())] + + +def read_pins(manifest, lockfile): + import tomllib + + manifest = Path(manifest) + lockfile = Path(lockfile) + cargo = tomllib.loads(manifest.read_text()) + lock = tomllib.loads(lockfile.read_text()) + dependencies = cargo.get('dependencies', {}) + explicit = [] + for name in ('ninjars', 'ninjars-symbolica'): + dependency = dependencies.get(name) + if not isinstance(dependency, dict): + raise ValueError('Missing explicit dependency %s' % name) + if canonical_url(dependency.get('git')) != REPOSITORIES['ninjars']: + raise ValueError('Unexpected %s repository' % name) + explicit.append(revision(dependency.get('rev'), name)) + if explicit[0] != explicit[1]: + raise ValueError('ninjars and ninjars-symbolica pins disagree') + packages = lock.get('package') + if not isinstance(packages, list): + raise ValueError('Cargo.lock must contain a package array') + git_dependencies(packages) # No unnoticed floating transitive Git source. + found = {} + for name in ('ninjars', 'ninjars-symbolica', 'oneloop'): + matches = [p for p in packages if isinstance(p, dict) and p.get('name') == name] + if len(matches) != 1: + raise ValueError('Cargo.lock must contain exactly one %s package' % name) + found[name] = lock_source(matches[0]) + for name in ('ninjars', 'ninjars-symbolica'): + if found[name] != (REPOSITORIES['ninjars'], explicit[0]): + raise ValueError('Cargo.toml and Cargo.lock disagree for %s' % name) + # Other crates from the same NinjaRS repository must not silently diverge. + for package in packages: + source = package.get('source', '') if isinstance(package, dict) else '' + if isinstance(source, str) and source.startswith('git+'): + url = canonical_url(urlsplit(source[4:])._replace(query='', fragment='').geturl()) + if url == REPOSITORIES['ninjars'] and lock_source(package)[1] != explicit[0]: + raise ValueError('A locked NinjaRS workspace package has a different pin') + if found['oneloop'][0] != REPOSITORIES['oneloopmaster']: + raise ValueError('Unexpected oneloopmaster repository') + return {'ninjars': explicit[0], 'oneloopmaster': found['oneloop'][1]} + + +def parse_remote(text): + refs, default = {}, None + for line in text.splitlines(): + fields = line.split() + if fields[:1] == ['ref:']: + if len(fields) != 3 or fields[2] != 'HEAD' or not fields[1].startswith('refs/heads/') or default is not None: + raise ValueError('Malformed or duplicate symbolic HEAD') + default = fields[1] + continue + if len(fields) != 2: + raise ValueError('Malformed ls-remote output') + commit, name = fields + revision(commit, 'remote ref') + if name not in ('HEAD', 'refs/heads/main') and not name.startswith('refs/tags/'): + raise ValueError('Unexpected remote ref %s' % name) + if name in refs: + raise ValueError('Duplicate remote ref %s' % name) + refs[name] = commit + if default is None or 'HEAD' not in refs or 'refs/heads/main' not in refs: + raise ValueError('Upstream must advertise symbolic HEAD and main') + if default == 'refs/heads/main' and refs['HEAD'] != refs['refs/heads/main']: + raise ValueError('Inconsistent main/HEAD advertisement') + tags = {} + for name, object_id in refs.items(): + if name.startswith('refs/tags/') and not name.endswith('^{}'): + tags[name[10:]] = {'object': object_id, 'commit': refs.get(name+'^{}', object_id)} + if any(name.endswith('^{}') and name[:-3] not in refs for name in refs): + raise ValueError('Annotated tag peeled ref has no tag object') + return {'default_branch': default, 'default_head': refs['HEAD'], + 'main': refs['refs/heads/main'], 'tags': dict(sorted(tags.items()))} + + +def query(url, timeout=30): + command = ['git', 'ls-remote', '--symref', url, 'HEAD', 'refs/heads/main', 'refs/tags/*'] + process = subprocess.run(command, check=True, text=True, capture_output=True, timeout=timeout) + return parse_remote(process.stdout) + + +def check(manifest, lockfile, query_remote=query): + import tomllib + + pins = read_pins(manifest, lockfile) # Reject local inconsistency before network. + results = {} + for name, url in REPOSITORIES.items(): + remote = query_remote(url) + results[name] = dict(repository=url, pinned=pins[name], **remote, + update_pending=remote['main'] != pins[name], + default_head_differs_from_pin=remote['default_head'] != pins[name]) + return {'schema':'ninjars-upstream-check-v1', 'checked_utc':datetime.datetime.now(datetime.timezone.utc).isoformat(), + 'complete':True, 'update_pending':any(r['update_pending'] for r in results.values()), + 'inputs':{str(Path(p)):hashlib.sha256(Path(p).read_bytes()).hexdigest() for p in (manifest,lockfile)}, + 'git_dependencies':git_dependencies(tomllib.loads(Path(lockfile).read_text())['package']), + 'repositories':results, + 'policy':'main commits determine pending updates; tags are a complete observed inventory, not ordered releases. No pin or reference clone is changed.'} + + +def main(argv=None): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--manifest',type=Path,default=ROOT/'vendor/ninjars/Cargo.toml') + parser.add_argument('--lockfile',type=Path,default=ROOT/'vendor/ninjars/Cargo.lock') + parser.add_argument('--output',type=Path,help='Create a new snapshot; existing files are never overwritten.') + args = parser.parse_args(argv) + try: + if args.output is not None and args.output.exists(): + raise ValueError('Snapshot already exists: %s' % args.output) + result = check(args.manifest,args.lockfile) + code = int(result['update_pending']) + except (OSError, ValueError, KeyError, TypeError, subprocess.SubprocessError) as error: + result = {'schema':'ninjars-upstream-check-v1','complete':False,'error':str(error)} + code = 2 + serialized = json.dumps(result,indent=2,sort_keys=True)+'\n' + if args.output is not None and not args.output.exists(): + try: + with args.output.open('x') as stream: + stream.write(serialized) + except OSError as error: + result = {'schema':'ninjars-upstream-check-v1','complete':False,'error':str(error)} + serialized = json.dumps(result,indent=2,sort_keys=True)+'\n' + code = 2 + print(serialized,end='') + return code + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/vendor/ninjars/.gitignore b/vendor/ninjars/.gitignore new file mode 100644 index 0000000000..269b7cbd6d --- /dev/null +++ b/vendor/ninjars/.gitignore @@ -0,0 +1,9 @@ +/target/ +/.cargo/ +/install/ +/build.log +/*.o +/*.mod +/libninjars.a +/ninjars-native-libs.txt +/smoke diff --git a/vendor/ninjars/Cargo.lock b/vendor/ninjars/Cargo.lock new file mode 100644 index 0000000000..cc885981f7 --- /dev/null +++ b/vendor/ninjars/Cargo.lock @@ -0,0 +1,3109 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "const-random", + "getrandom 0.3.4", + "once_cell", + "serde", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "append-only-vec" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed0f3c900b0e6025b120d0ad9b054c4056604dfd5729484aa6b5a7aba1fafd2" + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayvec" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" + +[[package]] +name = "astro-float" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cf6ecd69dd6fbe3763187ff2fa2b0e475b79f04ed86f631a7bc6b04ede0355e" +dependencies = [ + "astro-float-macro", + "astro-float-num", +] + +[[package]] +name = "astro-float-macro" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c007205ae7076600c8a59022866990afac02ff186f9031839f67ecce4df2146" +dependencies = [ + "astro-float-num", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "astro-float-num" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7f6a0312e8f5845f84241b21bd2394d49940b6bc333c6a84f992e6dc9ebb85" +dependencies = [ + "itertools 0.10.5", + "lazy_static", + "serde", +] + +[[package]] +name = "atomic" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "az" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" + +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "bincode_derive", + "serde", + "unty", +] + +[[package]] +name = "bincode-trait-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1f425dc6064b77d777fdecf6d1b374ae29e0be056b5ba8308a798d381e82632" +dependencies = [ + "bincode", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" +dependencies = [ + "serde_core", +] + +[[package]] +name = "bitvec" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" +dependencies = [ + "funty", + "radium", + "serde", + "tap", + "wyz", +] + +[[package]] +name = "blake3" +version = "1.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" +dependencies = [ + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "cpufeatures", +] + +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "brotli" +version = "8.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb31b46c14244e20ee9984b11bf5c992b91fb6939fea616e3512c8baecdbe5f" +dependencies = [ + "memchr", + "serde_core", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytecount" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "cc" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877bf67ac8e52449eb2f9e98a344ea163beb70dd1f9eebe3cc5357dcfeaee4df" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", + "terminal_size", + "unicase", + "unicode-width", +] + +[[package]] +name = "clap_derive" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "clap_lex" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "colored" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "console" +version = "0.16.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96a4956774c13c126a8b5af4daa79384f4d826534c95a02d76afb39e2ab64e3" +dependencies = [ + "encode_unicode", + "libc", + "unicode-width", + "windows-sys 0.61.2", +] + +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + +[[package]] +name = "constcat" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4938185353434999ef52c81753c8cca8955ed38042fc29913db3751916f3b7ab" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "corosensei" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6886a0c0f263965933c438626e7179139a62b978a33aa18281cbf0cd5a975f34" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "scopeguard", + "windows-sys 0.59.0", +] + +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" + +[[package]] +name = "crossterm" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +dependencies = [ + "bitflags 2.13.2", + "crossterm_winapi", + "derive_more 2.1.1", + "document-features", + "mio", + "parking_lot", + "rustix", + "serde", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "data-encoding" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" + +[[package]] +name = "defmt" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a0795ac740cb54d7b3775c9c17345f6aaecf884c01733b39d6017738e0e3e1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "840bb056bd99c495c9188198a258ab787c79f306d864db3e6e8451442d6d8366" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "defmt-parser" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71958f69fb2de856c5dd51ac9377e986ca1aa5919f931bf5395a807277f889a0" +dependencies = [ + "thiserror", +] + +[[package]] +name = "delegate" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e018fccbeeb50ff26562ece792ed06659b9c2dae79ece77c4456bb10d9bf79b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "deranged" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9de72ce2ad1f90dc62fa25f0f430ef85eb4b0d8fa0be4f30373bc40a21d28e" + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.119", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "convert_case 0.10.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.119", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", +] + +[[package]] +name = "directories" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "dot-parser" +version = "0.5.1" +source = "git+https://github.com/alphal00p/gammaloop.git?rev=d1904bf2bd5bf4f26969a73b415095e941a55610#d1904bf2bd5bf4f26969a73b415095e941a55610" +dependencies = [ + "either", + "pest", + "pest_derive", +] + +[[package]] +name = "duplicate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de78e66ac9061e030587b2a2e75cc88f22304913c907b11307bca737141230cb" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", +] + +[[package]] +name = "duplicate" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e92f10a49176cbffacaedabfaa11d51db1ea0f80a83c26e1873b43cd1742c24" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "proc-macro2-diagnostics", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ed25519-compact" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1454db4f2edb7f0e8fe0c5b375b0c978fc63244cc9f010d160e417eb10139aa8" + +[[package]] +name = "either" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "enum-try-as-inner" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c448fc2753338b04aa344ead5a6bdda26f2df2dcd85b65c86dd15b16819369e" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "env_filter" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "eyre" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08309dbcc659c5549a24ddb9b27027640641b282ef5768267c7e675558986a3" +dependencies = [ + "autocfg", + "indenter", + "once_cell", +] + +[[package]] +name = "features" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83072b3c84e55f9d0c0ff36a4575d0fd2e543ae4a56e04e7f5a9222188d574e3" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "feynkit-kinematics" +version = "0.1.0" +source = "git+https://github.com/alphal00p/gammaloop.git?rev=d1904bf2bd5bf4f26969a73b415095e941a55610#d1904bf2bd5bf4f26969a73b415095e941a55610" +dependencies = [ + "linnet", + "numerica", + "serde", + "spenso", + "symbolica", + "thiserror", +] + +[[package]] +name = "figment" +version = "0.10.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" +dependencies = [ + "atomic", + "serde", + "uncased", + "version_check", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gammaloop-workspace-hack" +version = "0.1.0" +source = "git+https://github.com/alphal00p/gammaloop.git?rev=d1904bf2bd5bf4f26969a73b415095e941a55610#d1904bf2bd5bf4f26969a73b415095e941a55610" +dependencies = [ + "ahash", + "arrayvec", + "bincode", + "bitflags 2.13.2", + "chrono", + "clap", + "clap_builder", + "console", + "crossterm", + "either", + "hashbrown 0.17.1", + "indenter", + "indexmap", + "libc", + "log", + "matrixmultiply", + "memchr", + "num-bigint", + "num-complex", + "num-integer", + "num-traits", + "numerica", + "proc-macro2", + "quote", + "rand 0.8.8", + "regex", + "regex-automata", + "regex-syntax", + "rust-embed-utils", + "rustix", + "serde", + "serde_core", + "serde_json", + "serde_spanned", + "smallvec", + "smartstring", + "symbolica", + "syn 2.0.119", + "time", + "toml_datetime", + "toml_parser", + "toml_writer", + "tracing", + "tracing-subscriber", + "winnow 0.7.15", + "winnow 1.0.4", + "zerocopy", +] + +[[package]] +name = "gat-lending-iterator" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "750117b6c895c40a8feee97fc95da9b5eb4b531ad772af2640a810ea1e4d2102" + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "globset" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c34a9410465b45bd9787443bc7370f37735bad04b0f0cd57ff1a3186c98988" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "gmp-mpfr-sys" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7db155b537cb791b133341f99f68371d86ee7fa4c79aacfbc376d72d23c70531" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "graphica" +version = "3.0.1" +source = "git+https://github.com/alphal00p/symbolica.git?rev=9cdc2949cdb153478c1eca0d40690dc0abfc616e#9cdc2949cdb153478c1eca0d40690dc0abfc616e" +dependencies = [ + "ahash", + "dyn-clone", + "numerica", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hugepage-rs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da5c9051569a6ff2f501fb927a7d994af9232e4bff255352811d7b87afc50603" +dependencies = [ + "libc", +] + +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "typenum", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "indenter" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "inventory" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6928282826c822ad91bf1c9a1cb90a30ba1c26770749929b4656cd6be829cd7c" +dependencies = [ + "rustversion", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jiff" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b005715dcbeb0089a3c0dab99f2ff1cc3b2525323552703d648585d342a383" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +dependencies = [ + "defmt", + "log", +] + +[[package]] +name = "jiff-static" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc9817253cf7c7ee4684451bd327e88d6f3658014e54a29198625590650695c" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "js-sys" +version = "0.3.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "libloading" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" +dependencies = [ + "libc", +] + +[[package]] +name = "linnet" +version = "0.17.0" +source = "git+https://github.com/alphal00p/gammaloop.git?rev=d1904bf2bd5bf4f26969a73b415095e941a55610#d1904bf2bd5bf4f26969a73b415095e941a55610" +dependencies = [ + "ahash", + "bincode", + "bincode-trait-derive", + "bitvec", + "dot-parser", + "duplicate 2.0.1", + "figment", + "gammaloop-workspace-hack", + "getrandom 0.2.17", + "indenter", + "indexmap", + "itertools 0.14.0", + "paste", + "rand 0.8.8", + "serde", + "serde_repr", + "symbolica", + "symbolica-utils", + "thiserror", +] + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litrs" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4744e383959f0db86ede514b809b1c53251889093803c05267acc7d4e7030d70" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +dependencies = [ + "libc", +] + +[[package]] +name = "madloop-ninjars" +version = "0.1.0" +dependencies = [ + "cc", + "ninjars", + "ninjars-symbolica", + "serde_json", + "symbolica", +] + +[[package]] +name = "malachite-base" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a52349e41ad66905fd33a8dc8736c554d71cfe56b81e2c499abec7f0168725" +dependencies = [ + "hashbrown 0.16.1", + "itertools 0.14.0", + "libm", + "ryu", +] + +[[package]] +name = "malachite-nz" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3069312201645d5257b0c34b8d506933f9d5ea82133b14b9c76be2ce5bb41a6" +dependencies = [ + "itertools 0.14.0", + "libm", + "malachite-base", + "serde", + "wide 0.8.3", +] + +[[package]] +name = "malachite-q" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2549764c0d9756d0396cf0c7fb47aee5df4da8a771ac5bfc616bb53ac344c9c" +dependencies = [ + "itertools 0.14.0", + "malachite-base", + "malachite-nz", + "serde", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f607c237553f086e7043417a51df26b2eb899d3caff94e6a67592ff992fedc7" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "mio" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "ninjars" +version = "0.1.0" +source = "git+https://github.com/alphal00p/ninjars?rev=41a4c00e7635e3ab188fc26bacf0aae6941e8082#41a4c00e7635e3ab188fc26bacf0aae6941e8082" +dependencies = [ + "feynkit-kinematics", + "symbolica", + "thiserror", +] + +[[package]] +name = "ninjars-positional" +version = "0.1.0" +source = "git+https://github.com/alphal00p/ninjars?rev=41a4c00e7635e3ab188fc26bacf0aae6941e8082#41a4c00e7635e3ab188fc26bacf0aae6941e8082" +dependencies = [ + "symbolica", + "thiserror", +] + +[[package]] +name = "ninjars-symbolica" +version = "0.1.0" +source = "git+https://github.com/alphal00p/ninjars?rev=41a4c00e7635e3ab188fc26bacf0aae6941e8082#41a4c00e7635e3ab188fc26bacf0aae6941e8082" +dependencies = [ + "ninjars", + "ninjars-positional", + "oneloop", + "symbolica", + "symbolica-utils", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-integer" +version = "0.1.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "numerica" +version = "3.0.1" +source = "git+https://github.com/alphal00p/symbolica.git?rev=9cdc2949cdb153478c1eca0d40690dc0abfc616e#9cdc2949cdb153478c1eca0d40690dc0abfc616e" +dependencies = [ + "ahash", + "astro-float", + "bincode", + "bincode-trait-derive", + "colored", + "dyn-clone", + "gmp-mpfr-sys", + "itertools 0.14.0", + "malachite-nz", + "malachite-q", + "num-traits", + "rand 0.9.5", + "rand_core 0.9.5", + "rayon", + "rug", + "serde", + "simba", + "smallvec", + "wide 1.7.1", + "xprec", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "oneloop" +version = "0.1.0" +source = "git+https://github.com/alphal00p/oneloopmaster.git?rev=5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5#5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5" +dependencies = [ + "bincode", + "symbolica", + "symjit", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "papergrid" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0984e668274d34691bc2b262ef0d115de5fa9973bcdee7ae32213f93099153e" +dependencies = [ + "bytecount", + "fnv", + "unicode-width", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pest" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd47a460a9cbc3b3429c7e22bf0d76653e779319bae45a499ca010c9a990bb23" +dependencies = [ + "memchr", + "psm", + "stacker", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "203e46697708f7519ab1608393cf89239cafb46b8e6d08a8ffe359359b11ef44" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e84ae6340a458d3d6cfc73cf328cf3cfe90b2484cd0de25eb66aa954615ed4d5" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "pest_meta" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b57f92f32b3dbce6598fd8f5cdf1f06a6072570b8103fa21728fa9036923e710" +dependencies = [ + "pest", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "portable-atomic-util" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "powerfmt" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6394b9e965e73d0a289ee54f589087e2c676aedf60885baf52c76b771e4958" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "version_check", +] + +[[package]] +name = "psm" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" +dependencies = [ + "cc", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "redox_users" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0" +dependencies = [ + "libredox", + "thiserror", +] + +[[package]] +name = "ref-ops" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a743269eaa4c6f18021903a3627f6031b4ae3e2dddda3c5ab8d7a8c7e723d103" + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "region" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7" +dependencies = [ + "bitflags 1.3.2", + "libc", + "mach2", + "windows-sys 0.52.0", +] + +[[package]] +name = "rug" +version = "1.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07a8857882aec59d27254b02481c709327c13de6fad1da60bfc4f9783eaaa61e" +dependencies = [ + "az", + "gmp-mpfr-sys", + "libc", + "libm", + "serde", +] + +[[package]] +name = "rust-embed-utils" +version = "8.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d84e8ba78bd384263e5922f084cbe1b081c3b7e69add59c8fb097b879ba968a" +dependencies = [ + "globset", + "sha2", + "walkdir", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "safe_arch" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "safe_arch" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629516c85c29fe757770fa03f2074cf1eac43d44c02a3de9fc2ef7b0e207dfdd" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "safe_arch" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42c6efa15875e6ecb39ca61fb0b0c1a40b84fac5a5ffe71eef7d1000c8eb3f5f" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "self_cell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813" + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_repr" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "sha2" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d7069beb7d6ac7b9acd1039986e73443f24234f41074da099d6f994ac9ad19" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "simba" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide 0.7.33", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" +dependencies = [ + "serde", +] + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "serde", + "static_assertions", + "version_check", +] + +[[package]] +name = "spec_math" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02ef091d4e8b981dbaa4cc17789d00b53d5d2c001ae689f14e6093f30c529036" + +[[package]] +name = "spenso" +version = "0.6.0" +source = "git+https://github.com/alphal00p/gammaloop.git?rev=d1904bf2bd5bf4f26969a73b415095e941a55610#d1904bf2bd5bf4f26969a73b415095e941a55610" +dependencies = [ + "ahash", + "append-only-vec", + "bincode", + "bincode-trait-derive", + "bitvec", + "colored", + "constcat", + "delegate", + "derive_more 0.99.20", + "duplicate 1.0.0", + "dyn-clone", + "enum-try-as-inner", + "env_logger", + "eyre", + "features", + "gat-lending-iterator", + "indexmap", + "itertools 0.14.0", + "linnet", + "log", + "nu-ansi-term", + "num", + "once_cell", + "rand 0.9.5", + "rand_xoshiro", + "rayon", + "ref-ops", + "serde", + "serde_json", + "spenso-macros", + "symbolica", + "symbolica-typst-plugin", + "symbolica-utils", + "tabled", + "thiserror", + "tracing", +] + +[[package]] +name = "spenso-macros" +version = "0.3.2" +source = "git+https://github.com/alphal00p/gammaloop.git?rev=d1904bf2bd5bf4f26969a73b415095e941a55610#d1904bf2bd5bf4f26969a73b415095e941a55610" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "stacker" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707f49d46706bacf8a2b00d51dace3f9de527c13eec3778f570c411f89e69967" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.61.2", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "symbolica" +version = "3.0.1" +source = "git+https://github.com/alphal00p/symbolica.git?rev=9cdc2949cdb153478c1eca0d40690dc0abfc616e#9cdc2949cdb153478c1eca0d40690dc0abfc616e" +dependencies = [ + "ahash", + "append-only-vec", + "bincode", + "bincode-trait-derive", + "brotli", + "byteorder", + "bytes", + "data-encoding", + "directories", + "dyn-clone", + "ed25519-compact", + "graphica", + "inventory", + "libloading", + "numerica", + "once_cell", + "rand 0.9.5", + "rayon", + "rug", + "self_cell", + "serde", + "smallvec", + "smartstring", + "symjit", + "tinyjson", + "tracing", + "tracing-subscriber", + "wide 1.7.1", +] + +[[package]] +name = "symbolica-typst-plugin" +version = "0.1.0" +source = "git+https://github.com/symbolica-dev/symbolica-typst-plugin?rev=57b7455b37c30f4f87353c0073e49f5225e937ab#57b7455b37c30f4f87353c0073e49f5225e937ab" +dependencies = [ + "blake3", + "ciborium", + "symbolica", +] + +[[package]] +name = "symbolica-utils" +version = "0.1.0" +source = "git+https://github.com/alphal00p/gammaloop.git?rev=d1904bf2bd5bf4f26969a73b415095e941a55610#d1904bf2bd5bf4f26969a73b415095e941a55610" +dependencies = [ + "bincode", + "bincode-trait-derive", + "itertools 0.14.0", + "serde", + "symbolica", +] + +[[package]] +name = "symjit" +version = "2.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5297d2ef25e396f984747fd0e480aaabb08e40e424f9cd07811efc6b20c140" +dependencies = [ + "ahash", + "anyhow", + "corosensei", + "hashbrown 0.16.1", + "hugepage-rs", + "lazy_static", + "libc", + "num-complex", + "num-rational", + "num-traits", + "rand 0.9.5", + "rayon", + "region", + "serde", + "serde_json", + "spec_math", + "toml", + "wasmtime-jit-icache-coherence", + "wide 1.7.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tabled" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2596a104db1900b943f97d793a6c99addca918c4525c999f751a0f17d472eb" +dependencies = [ + "papergrid", + "tabled_derive", + "testing_table", +] + +[[package]] +name = "tabled_derive" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dca1937322a1e892b1a65f6a6736183bb0a29d3b4234d1d53bc436dff9beb76" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "terminal_size" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" +dependencies = [ + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "testing_table" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f8daae29995a24f65619e19d8d31dea5b389f3d853d8bf297bbf607cd0014cc" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyjson" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab95735ea2c8fd51154d01e39cf13912a78071c2d89abc49a7ef102a7dd725a" + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow 1.0.4", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow 1.0.4", +] + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "time", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uncased" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicase" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357cc3acc6a036009fd6c973ed009037c732d60d0b4f6c673e9041497482a28f" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 3.0.9", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea6b740d1a35f2cebfe88e013ac8a4a84ff8dabc3a392df920abf554e871cf2" +dependencies = [ + "anyhow", + "cfg-if", + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "wide" +version = "0.7.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" +dependencies = [ + "bytemuck", + "safe_arch 0.7.4", +] + +[[package]] +name = "wide" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13ca908d26e4786149c48efcf6c0ea09ab0e06d1fe3c17dc1b4b0f1ca4a7e788" +dependencies = [ + "bytemuck", + "safe_arch 0.9.3", +] + +[[package]] +name = "wide" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d920ac99c3c8edce110cb8d07dbb324d6d026011dce85b1e9355b70f0adacc4f" +dependencies = [ + "bytemuck", + "safe_arch 1.2.0", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "xprec" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e736c2312fb577875c99665eae274f51a6b33489f00114602b69cf224f48a7c" +dependencies = [ + "approx", + "libm", + "num-traits", + "simba", +] + +[[package]] +name = "zerocopy" +version = "0.8.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5fe1f8f1b06191a00962174c61aa5005e0bb391a6d80d07e24d115c01a92ed8" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863ad3ac83293fb4d740aedbfdc9240dd8d1a50c1099acd76ce80ce7c7230c7f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/vendor/ninjars/Cargo.toml b/vendor/ninjars/Cargo.toml new file mode 100644 index 0000000000..a7b71d7844 --- /dev/null +++ b/vendor/ninjars/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "madloop-ninjars" +version = "0.1.0" +edition = "2024" +rust-version = "1.96" +license = "GPL-3.0-or-later" +publish = false + +[workspace] + +[lib] +name = "madloop_ninjars" +crate-type = ["staticlib", "rlib"] + +[dependencies] +ninjars = { git = "https://github.com/alphal00p/ninjars", rev = "41a4c00e7635e3ab188fc26bacf0aae6941e8082" } +ninjars-symbolica = { git = "https://github.com/alphal00p/ninjars", rev = "41a4c00e7635e3ab188fc26bacf0aae6941e8082", features = ["native-masters"] } +symbolica = { version = "3.0.1", default-features = false, features = ["integer-gmp", "float-mpfr", "bincode", "serde", "tracing_max_level_info"] } + +[patch.crates-io] +symbolica = { git = "https://github.com/alphal00p/symbolica.git", rev = "9cdc2949cdb153478c1eca0d40690dc0abfc616e" } +numerica = { git = "https://github.com/alphal00p/symbolica.git", rev = "9cdc2949cdb153478c1eca0d40690dc0abfc616e" } +graphica = { git = "https://github.com/alphal00p/symbolica.git", rev = "9cdc2949cdb153478c1eca0d40690dc0abfc616e" } +symbolica-typst-plugin = { git = "https://github.com/symbolica-dev/symbolica-typst-plugin", rev = "57b7455b37c30f4f87353c0073e49f5225e937ab" } + +[profile.release] +lto = "thin" +codegen-units = 1 + +[dev-dependencies] +serde_json = {version="1",features=["float_roundtrip"]} + +[build-dependencies] +cc = "1" + +[features] +fenv-test-support = [] diff --git a/vendor/ninjars/Makefile b/vendor/ninjars/Makefile new file mode 100644 index 0000000000..17f745072a --- /dev/null +++ b/vendor/ninjars/Makefile @@ -0,0 +1,40 @@ +SHELL := bash +FC = gfortran +AR ?= ar +CARGO ?= cargo +PREFIX ?= $(CURDIR)/install +CARGO_TARGET_DIR ?= $(CURDIR)/target +export CARGO_TARGET_DIR +FFLAGS ?= -O3 -fPIC + +.PHONY: all rust compiler-runtime install check clean +all: libninjars.a + +rust: + @set -o pipefail; $(CARGO) rustc --release --locked --lib -- --print native-static-libs 2>&1 | tee build.log + @sed -n 's/^.*native-static-libs: //p' build.log | tail -n 1 > ninjars-native-libs.txt + @test -s ninjars-native-libs.txt || { echo 'Rust did not report its required native linker flags'; exit 1; } + +mninjars.o: mninjars.f90 + $(FC) $(FFLAGS) -c $< -o $@ + +compiler-runtime: + @$(FC) --version | head -n 1 | grep -q 'GNU Fortran' || { echo 'NinjaRS currently validates compiler-runtime isolation with GNU Fortran on Linux'; exit 1; } + @case "$$($(FC) -dumpmachine)" in *-linux-*) printf '%s\n' '-lgcc_s' > ninjars-link-before.txt ;; *) echo 'NinjaRS compiler-runtime isolation is currently validated on Linux'; exit 1 ;; esac + +libninjars.a: rust mninjars.o compiler-runtime + cp "$(CARGO_TARGET_DIR)/release/libmadloop_ninjars.a" $@ + $(AR) rcs $@ mninjars.o + +install: libninjars.a + mkdir -p "$(PREFIX)/lib" "$(PREFIX)/include" + cp libninjars.a mninjars.mod ninjars-native-libs.txt ninjars-link-before.txt "$(PREFIX)/lib/" + cp ninjars.h mninjars.f90 "$(PREFIX)/include/" + +check: libninjars.a + $(CARGO) test --locked --features fenv-test-support -- --test-threads=1 + $(FC) $(FFLAGS) smoke.f90 -I. $$(cat ninjars-link-before.txt) -L. -lninjars $$(cat ninjars-native-libs.txt) -o smoke + ./smoke + +clean: + rm -f mninjars.o mninjars.mod libninjars.a smoke build.log ninjars-native-libs.txt ninjars-link-before.txt diff --git a/vendor/ninjars/UPSTREAM.md b/vendor/ninjars/UPSTREAM.md new file mode 100644 index 0000000000..895927672f --- /dev/null +++ b/vendor/ninjars/UPSTREAM.md @@ -0,0 +1,89 @@ +The bridge uses the pinned NinjaRS and Symbolica revisions in `Cargo.toml` and +`Cargo.lock`. NinjaRS is GPL-3.0-or-later; this bridge uses the same license. + +The final dependency cohort pins NinjaRS +`41a4c00e7635e3ab188fc26bacf0aae6941e8082`, oneloopmaster +`5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5`, and the coupled +Symbolica/numerica/graphica revision +`9cdc2949cdb153478c1eca0d40690dc0abfc616e`. The consuming bridge owns the +Symbolica patches because Cargo does not inherit dependency workspace patches. +NinjaRS's transitive gammaloop kinematics and Symbolica helpers are locked at +`d1904bf2bd5bf4f26969a73b415095e941a55610`; this also advances their earlier +`1e8063a763d3aa515749c33616ee59aa827705be` source revision. +Both native binary64 masters and generic higher-precision masters come from +this oneloopmaster revision. NinjaRS includes the matching generic soft-box +relabelling and precision-provider changes; a pin-only oneloopmaster update +against the earlier NinjaRS revision is not equivalent. +The benchmark report retains its original measured dependency cohort; this +upstream pole-selection update is qualified separately in `tests/poles`. + +Every new installation records its exact manifest and resolved lock hashes and +all transitive Git sources in `lib/ninjars-config.json`, alongside copies of +`Cargo.toml` and `Cargo.lock`. Explicit local overrides additionally record the +source revision and a digest of the copied source files, so a modified checkout +is distinguished from the same clean revision. Reference checkouts are copied +before building. The pole-selector interface requires bridge ABI 4; older +ABI-3 installations are rejected before export or linking. After updating the +MadGraph checkout with `git pull`, run +`install ninjars --update` to rebuild an older installation with that checkout's +current pins. This uses the committed dependency revisions and lockfile; +it does not select unpinned upstream `main` revisions. The installer validates +the replacement before publishing it and preserves the previous installation +if the build or numerical smoke test fails. `--force` remains an equivalent +backward-compatible alias. + +When a usable NinjaRS installation is configured, ordinary optimized one-loop +standalone and NLO exports start with `MLReductionLib=8|6|7|1`. Without it, +the default remains `6|7|1`. Ordinary `check timing` and `check profile` select +NinjaRS by default, or Ninja when NinjaRS is unavailable. Explicit reduction +options such as `--reduction=6` and active parameter-card choices take +precedence. Loop-induced exports retain their existing `7|6|1` selection and +scalar-integral pole settings. + +`LoopPoleMode` selects the poles of the bare loop contribution through a common +card option: `0` returns both origins, `1` UV poles, `2` IR poles, +and `3` no poles. Its default, `-1`, preserves the existing backend behavior, +including `COLLIERComputeUVpoles` and `COLLIERComputeIRpoles` for COLLIER. +Modes `1`, `2`, and `3` require a reduction/rescue list containing only NinjaRS +and/or COLLIER; other backends cannot provide the requested pole selection. +Finite coefficients and rational terms are unchanged; model counterterms are +outside this selection. MadLoop forwards the selection to the upstream +NinjaRS master providers, which use oneloopmaster's public pole-selection API +before contraction with the reduction coefficients. The bridge retains only +ABI mode validation, with no local numerical pole-projection formulas. +UV-only and IR-only modes use the generic NinjaRS +engine in both double precision and higher-precision rescue, retaining the +scaleless-bubble coefficients whose UV and IR residues cancel in the combined +result. Their compensated-DP entry uses the same generic DP path, without the +fast-engine compensated numerator callback; higher-precision rescue remains +available. Combined-pole and no-pole DP calculations retain the fast engine. +All explicit modes (`0`–`3`) bypass existing helicity/loop-filter decisions so +that cancelled combined-pole contributions remain available for separation; +default mode `-1` keeps the usual filtering policy. Explicit modes can +therefore incur additional numerator and reduction costs. The committed +dependency revisions and lockfile include the upstream pole-selection APIs. +See [Selecting UV and IR poles in MadLoop](../../doc/loop-pole-selection.md) +for card examples, the Fortran setter, and the scope of the returned poles. + +`src/guarded.rs` adapts the tensor indexing and transposed recurrence traversal +from NinjaRS commit `0d0d7e7a8033431b60a8580731084742e0655cda`, +`crates/ninjars/src/fast/{tensor.rs,tensor_layout.rs,tensor_jets.rs}`. Its added +FMA product residuals and compensated sums apply only to the explicitly +requested DP retry. This is not a universal correctly-rounded polynomial +guarantee. Unsupported layouts, exponent ranges and floating-point environments +use the original callback, and MadLoop retains independent stability checks and +genuine higher-precision rescue. + +`tests/data/compensated` contains six generated MadLoop QCD3 tensor requests, +their actual Float256 callback references, and compensated full-reduction +results. They were captured during the retained point-67 diagnosis. Complete +commands, input provenance, independent Ninja comparisons and sealed hashes +are preserved in the [immutable measurement archive](https://github.com/MadGraphTeam/MadGraph7/tree/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/experiments) +under `qcd3-point67-{dp,masters,t3}` and `t3-dp-retry`. These fixtures do not +require sibling reference clones. The final measured report and its offline +reproduction instructions are in [`doc/benchmarkfolder`](../../doc/benchmarkfolder/README.md). + +The `fenv-test-support` Cargo feature compiles test-only floating-point flag and +rounding mutators. Normal installation leaves this feature disabled and builds +only the environment observer. `make check` enables it for the serial test +suite. diff --git a/vendor/ninjars/build.rs b/vendor/ninjars/build.rs new file mode 100644 index 0000000000..a4f196c664 --- /dev/null +++ b/vendor/ninjars/build.rs @@ -0,0 +1,8 @@ +fn main() { + println!("cargo:rerun-if-changed=src/guarded_fenv.c"); + cc::Build::new().file("src/guarded_fenv.c").compile("ninjars_t3_fenv"); + if std::env::var_os("CARGO_FEATURE_FENV_TEST_SUPPORT").is_some() { + println!("cargo:rerun-if-changed=tests/fenv_helpers.c"); + cc::Build::new().file("tests/fenv_helpers.c").compile("ninjars_test_fenv"); + } +} diff --git a/vendor/ninjars/examples/replay.rs b/vendor/ninjars/examples/replay.rs new file mode 100644 index 0000000000..971fb34716 --- /dev/null +++ b/vendor/ninjars/examples/replay.rs @@ -0,0 +1,173 @@ +//! Replay an archived MadLoop tensor call against its original-Ninja result. +//! Usage: cargo run --release --example replay -- CASE.json REFERENCE.json [--mp] +use madloop_ninjars::{ + ninjars_context_create, ninjars_context_destroy, ninjars_evaluate_dp, ninjars_evaluate_mp, + ninjars_last_error, +}; +use ninjars::fast::C64; +use serde_json::{Value, json}; + +fn number(v: &Value) -> f64 { + v.as_f64().expect("numeric fixture") +} +fn complex(v: &Value) -> C64 { + C64::new(number(&v[0]), number(&v[1])) +} + +fn main() { + let args: Vec<_> = std::env::args().collect(); + assert!( + args.len() == 3 || (args.len() == 4 && args[3] == "--mp"), + "expected CASE.json REFERENCE.json [--mp]" + ); + let mp = args.len() == 4; + let case: Value = serde_json::from_str(&std::fs::read_to_string(&args[1]).unwrap()).unwrap(); + let reference: Value = + serde_json::from_str(&std::fs::read_to_string(&args[2]).unwrap()).unwrap(); + let mut worst: f64 = 0.; + let mut rational_split_difference: f64 = 0.; + let mut context = std::ptr::null_mut(); + assert_eq!(unsafe { ninjars_context_create(3, &mut context) }, 0); + let lanes = case["lanes"].as_array().unwrap(); + for lane in lanes { + let expected = reference["lanes"] + .as_array() + .unwrap() + .iter() + .find(|r| r["id"] == lane["id"]) + .expect("reference lane"); + let tensor: Vec<_> = lane["tensor"] + .as_array() + .unwrap() + .iter() + .map(complex) + .collect(); + let masses: Vec<_> = lane["masses_squared"] + .as_array() + .unwrap() + .iter() + .map(complex) + .collect(); + let flatten = |key| { + lane[key] + .as_array() + .unwrap() + .iter() + .flat_map(|r| r.as_array().unwrap().iter().map(number)) + .collect::>() + }; + let momenta = flatten("shifts"); + let matrix = flatten("s_matrix"); + let mut result = [C64::ZERO; 3]; + let mut rational = C64::ZERO; + let status = if mp { + let records = |values: &[f64]| { + values + .iter() + .flat_map(|value| { + let mut record = [b' '; 64]; + let text = format!("{value:.39e}"); + record[..text.len()].copy_from_slice(text.as_bytes()); + record + }) + .collect::>() + }; + let ct = records(&tensor.iter().flat_map(|z| [z.re, z.im]).collect::>()); + let mt = records(&masses.iter().flat_map(|z| [z.re, z.im]).collect::>()); + let st = records(&matrix); + let pt = records(&momenta); + let scale = records(&[number(&lane["mu_squared"])]); + let mut output = [b' '; 512]; + let status = unsafe { + ninjars_evaluate_mp( + context, + case["n"].as_i64().unwrap() as i32, + case["rank"].as_i64().unwrap() as i32, + tensor.len(), + ct.as_ptr(), + ct.len(), + st.as_ptr(), + st.len(), + pt.as_ptr(), + pt.len(), + mt.as_ptr(), + mt.len(), + scale.as_ptr(), + scale.len(), + output.as_mut_ptr(), + output.len(), + ) + }; + if status == 0 { + let component = |i| { + std::str::from_utf8(&output[i * 64..(i + 1) * 64]) + .unwrap() + .trim() + .parse() + .unwrap() + }; + for i in 0..3 { + result[i] = C64::new(component(2 * i), component(2 * i + 1)); + } + rational = C64::new(component(6), component(7)); + } + status + } else { + unsafe { + ninjars_evaluate_dp( + context, + case["n"].as_i64().unwrap() as i32, + case["rank"].as_i64().unwrap() as i32, + tensor.len(), + tensor.as_ptr(), + matrix.as_ptr(), + matrix.len(), + momenta.as_ptr(), + momenta.len(), + masses.as_ptr(), + masses.len(), + number(&lane["mu_squared"]), + result.as_mut_ptr(), + result.len(), + &mut rational, + 1, + ) + } + }; + if status != 0 { + let mut error = [0; 1024]; + unsafe { + ninjars_last_error(error.as_mut_ptr(), error.len()); + } + panic!( + "lane {} status {status}: {}", + lane["id"], + String::from_utf8_lossy(&error) + ); + } + for (value, key) in result + .into_iter() + .chain([rational]) + .zip(["eps0", "eps_m1", "eps_m2", "rational"]) + { + let expected = complex(&expected[key]); + let error = (value - expected).abs() / expected.abs().max(1.); + if key == "rational" { + rational_split_difference = rational_split_difference.max(error); + // The generic engine conditions its bubble basis differently. + // Its CC/rational split is basis dependent; full Laurent + // coefficients are invariant (upstream fast_parity.rs). + if mp { + continue; + } + } + worst = worst.max(error); + assert!(error <= 1e-9, "lane {} {key}: error {error}", lane["id"]); + } + } + assert_eq!(unsafe { ninjars_context_destroy(context) }, 0); + println!( + "{}", + json!({"case": case["name"], "precision": if mp {"Float(256)"} else {"f64"}, "lanes": lanes.len(), "max_scaled_error": worst, "rational_compared": !mp, "rational_split_max_scaled_difference": rational_split_difference, "passed": true}) + ); +} diff --git a/vendor/ninjars/mninjars.f90 b/vendor/ninjars/mninjars.f90 new file mode 100644 index 0000000000..477bc83bea --- /dev/null +++ b/vendor/ninjars/mninjars.f90 @@ -0,0 +1,228 @@ +! ISO C interface to the pinned NinjaRS bridge. No compiler-specific quad ABI. +! res(0) contains the complete finite result. r1 is an engine-basis diagnostic; +! the generic engine (MP and selected-pole DP) may use a different rational/CC split. +! Optional pole_mode: 0 combined (default), 1 UV, 2 IR, 3 neither. +module mninjars + use, intrinsic :: iso_c_binding + implicit none + private + integer, parameter, public :: KI_NRS = c_double + integer, parameter, public :: KI_QNRS = selected_real_kind(33,4931) + integer, parameter, public :: NINJARS_SUCCESS = 0 + integer, parameter, public :: NINJARS_UNSTABLE_KINEMATICS = 1 + integer, parameter, public :: NINJARS_ERROR = 2 + integer, parameter, public :: NINJARS_POLES_BOTH = 0 + integer, parameter, public :: NINJARS_POLES_UV = 1 + integer, parameter, public :: NINJARS_POLES_IR = 2 + integer, parameter, public :: NINJARS_POLES_NONE = 3 + integer, parameter :: record_size = 64 + type(c_ptr), save :: context = c_null_ptr + public :: ninjars_tensor_evaluate_compensated + public :: ninjars_tensor_evaluate, ninjars_error_message, ninjars_finalize + + interface ninjars_tensor_evaluate + module procedure tensor_dp, tensor_mp + end interface + interface + function create_context(version,handle) bind(C,name="ninjars_context_create") result(status) + import + integer(c_int), value :: version + type(c_ptr), intent(out) :: handle + integer(c_int) :: status + end function + function destroy_context(handle) bind(C,name="ninjars_context_destroy") result(status) + import + type(c_ptr), value :: handle + integer(c_int) :: status + end function + function evaluate_dp(handle,n,r,count,coeff,s,slen,p,plen,m,mlen,mu2,res,reslen,r1,r1len,pole_mode) & + bind(C,name="ninjars_evaluate_dp_with_poles") result(status) + import + type(c_ptr), value :: handle + integer(c_int), value :: n,r,pole_mode + integer(c_size_t), value :: count,slen,plen,mlen,reslen,r1len + complex(c_double_complex), intent(in) :: coeff(*),m(*) + real(c_double), intent(in) :: s(*),p(*) + real(c_double), value :: mu2 + complex(c_double_complex), intent(out) :: res(*),r1 + integer(c_int) :: status + end function + function evaluate_dp_compensated(handle,n,r,count,coeff,s,slen,p,plen,m,mlen,mu2,res,reslen,r1,r1len,pole_mode) & + bind(C,name="ninjars_evaluate_dp_compensated_with_poles") result(status) + import + type(c_ptr), value :: handle + integer(c_int), value :: n,r,pole_mode + integer(c_size_t), value :: count,slen,plen,mlen,reslen,r1len + complex(c_double_complex), intent(in) :: coeff(*),m(*) + real(c_double), intent(in) :: s(*),p(*) + real(c_double), value :: mu2 + complex(c_double_complex), intent(out) :: res(*),r1 + integer(c_int) :: status + end function + function evaluate_mp(handle,n,r,count,coeff,clen,s,slen,p,plen,m,mlen,mu2,scalelen,res,reslen,pole_mode) & + bind(C,name="ninjars_evaluate_mp_with_poles") result(status) + import + type(c_ptr), value :: handle + integer(c_int), value :: n,r,pole_mode + integer(c_size_t), value :: count,clen,slen,plen,mlen,scalelen,reslen + character(c_char), intent(in) :: coeff(*),s(*),p(*),m(*),mu2(*) + character(c_char), intent(out) :: res(*) + integer(c_int) :: status + end function + function last_error(message,capacity) bind(C,name="ninjars_last_error") result(required) + import + character(c_char), intent(out) :: message(*) + integer(c_size_t), value :: capacity + integer(c_size_t) :: required + end function + end interface +contains + subroutine ensure_context(status) + integer, intent(out) :: status + status = NINJARS_SUCCESS + if (.not.c_associated(context)) status = create_context(4_c_int,context) + end subroutine + + subroutine ninjars_finalize(status) + integer, intent(out), optional :: status + integer :: result + result = destroy_context(context) + if (result == NINJARS_SUCCESS) context = c_null_ptr + if (present(status)) status = result + end subroutine + + pure integer function coefficient_count(rank) result(count) + integer, intent(in) :: rank + count = (rank+1)*(rank+2)*(rank+3)*(rank+4)/24 + end function + + subroutine tensor_dp(coeff,n,rank,s,p,m,mu2,res,r1,status,pole_mode) + integer, intent(in) :: n,rank + complex(KI_NRS), intent(in) :: coeff(coefficient_count(rank)),m(n) + real(KI_NRS), intent(in) :: s(n,n),p(0:3,n),mu2 + complex(KI_NRS), intent(out) :: res(0:2),r1 + integer, intent(out) :: status + integer, intent(in), optional :: pole_mode + integer(c_int) :: selected_poles + res = cmplx(0,0,kind=KI_NRS) + r1 = cmplx(0,0,kind=KI_NRS) + selected_poles = 0_c_int + if (present(pole_mode)) selected_poles = int(pole_mode,c_int) + call ensure_context(status) + if (status /= NINJARS_SUCCESS) return + status = evaluate_dp(context,int(n,c_int),int(rank,c_int), & + int(coefficient_count(rank),c_size_t),coeff, & + s,size(s,kind=c_size_t),p,size(p,kind=c_size_t), & + m,size(m,kind=c_size_t),mu2,res,3_c_size_t,r1,1_c_size_t,selected_poles) + end subroutine + + subroutine ninjars_tensor_evaluate_compensated(coeff,n,rank,s,p,m,mu2,res,r1,status,pole_mode) + integer, intent(in) :: n,rank + complex(KI_NRS), intent(in) :: coeff(coefficient_count(rank)),m(n) + real(KI_NRS), intent(in) :: s(n,n),p(0:3,n),mu2 + complex(KI_NRS), intent(out) :: res(0:2),r1 + integer, intent(out) :: status + integer, intent(in), optional :: pole_mode + integer(c_int) :: selected_poles + res = cmplx(0,0,kind=KI_NRS) + r1 = cmplx(0,0,kind=KI_NRS) + selected_poles = 0_c_int + if (present(pole_mode)) selected_poles = int(pole_mode,c_int) + call ensure_context(status) + if (status /= NINJARS_SUCCESS) return + status = evaluate_dp_compensated(context,int(n,c_int),int(rank,c_int), & + int(coefficient_count(rank),c_size_t),coeff, & + s,size(s,kind=c_size_t),p,size(p,kind=c_size_t), & + m,size(m,kind=c_size_t),mu2,res,3_c_size_t,r1,1_c_size_t,selected_poles) + end subroutine + + subroutine pack(value,record) + real(KI_QNRS), intent(in) :: value + character(c_char), intent(out) :: record(record_size) + character(len=record_size) :: text + integer :: k + write(text,'(ES64.39E4)') value + do k=1,record_size + record(k) = text(k:k) + enddo + end subroutine + + subroutine unpack(record,value,io_status) + character(c_char), intent(in) :: record(record_size) + real(KI_QNRS), intent(out) :: value + integer, intent(out) :: io_status + character(len=record_size) :: text + integer :: k + do k=1,record_size + text(k:k) = record(k) + enddo + read(text,*,iostat=io_status) value + end subroutine + + subroutine tensor_mp(coeff,n,rank,s,p,m,mu2,res,r1,status,pole_mode) + integer, intent(in) :: n,rank + complex(KI_QNRS), intent(in) :: coeff(coefficient_count(rank)),m(n) + real(KI_QNRS), intent(in) :: s(n,n),p(0:3,n),mu2 + complex(KI_QNRS), intent(out) :: res(0:2),r1 + integer, intent(out) :: status + integer, intent(in), optional :: pole_mode + integer(c_int) :: selected_poles + character(c_char) :: coeff_text(record_size,2*coefficient_count(rank)) + character(c_char) :: s_text(record_size,n*n),p_text(record_size,4*n) + character(c_char) :: m_text(record_size,2*n),scale_text(record_size),output(record_size,8) + real(KI_QNRS) :: values(8) + integer :: i,j,k,ios + res = cmplx(0,0,kind=KI_QNRS) + r1 = cmplx(0,0,kind=KI_QNRS) + status = NINJARS_ERROR + if (radix(mu2) /= 2 .or. digits(mu2) /= 113) return + selected_poles = 0_c_int + if (present(pole_mode)) selected_poles = int(pole_mode,c_int) + call ensure_context(status) + if (status /= NINJARS_SUCCESS) return + do i=1,coefficient_count(rank) + call pack(real(coeff(i),kind=KI_QNRS),coeff_text(:,2*i-1)) + call pack(aimag(coeff(i)),coeff_text(:,2*i)) + enddo + do i=1,n + call pack(real(m(i),kind=KI_QNRS),m_text(:,2*i-1)) + call pack(aimag(m(i)),m_text(:,2*i)) + do j=0,3 + call pack(p(j,i),p_text(:,4*(i-1)+j+1)) + enddo + do j=1,n + call pack(s(j,i),s_text(:,n*(i-1)+j)) + enddo + enddo + call pack(mu2,scale_text) + status = evaluate_mp(context,int(n,c_int),int(rank,c_int),int(coefficient_count(rank),c_size_t), & + coeff_text,size(coeff_text,kind=c_size_t),s_text,size(s_text,kind=c_size_t), & + p_text,size(p_text,kind=c_size_t),m_text,size(m_text,kind=c_size_t), & + scale_text,size(scale_text,kind=c_size_t),output,size(output,kind=c_size_t),selected_poles) + if (status /= NINJARS_SUCCESS) return + do k=1,8 + call unpack(output(:,k),values(k),ios) + if (ios /= 0) then + status = NINJARS_ERROR + return + endif + enddo + do k=0,2 + res(k) = cmplx(values(2*k+1),values(2*k+2),kind=KI_QNRS) + enddo + r1 = cmplx(values(7),values(8),kind=KI_QNRS) + end subroutine + + subroutine ninjars_error_message(message) + character(len=*), intent(out) :: message + character(c_char) :: buffer(len(message)+1) + integer(c_size_t) :: required + integer :: k + required = last_error(buffer,int(size(buffer),c_size_t)) + message = '' + do k=1,len(message) + if (buffer(k) == c_null_char) exit + message(k:k) = buffer(k) + enddo + end subroutine +end module mninjars diff --git a/vendor/ninjars/ninjars.h b/vendor/ninjars/ninjars.h new file mode 100644 index 0000000000..d2d841f319 --- /dev/null +++ b/vendor/ninjars/ninjars.h @@ -0,0 +1,100 @@ +#ifndef MADLOOP_NINJARS_H +#define MADLOOP_NINJARS_H +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +typedef struct { double re, im; } ninjars_complex; +typedef struct ninjars_context ninjars_context; +#define NINJARS_ABI_VERSION 4 +enum { NINJARS_POLES_BOTH = 0, NINJARS_POLES_UV = 1, NINJARS_POLES_IR = 2, NINJARS_POLES_NONE = 3 }; +enum { NINJARS_SUCCESS = 0, NINJARS_UNSTABLE_KINEMATICS = 1, NINJARS_ERROR = 2 }; +uint32_t ninjars_abi_version(void); +int32_t ninjars_context_create(uint32_t version, ninjars_context **output); +/* Destroy only after outstanding calls complete; NULL is a no-op. */ +int32_t ninjars_context_destroy(ninjars_context *context); +/* + * One numerator, rank <= n+2. count=(rank+1)...(rank+4)/24. + * Coefficients use Ninja/MadLoop tensor order. momenta[4*n] stores (E,x,y,z) + * per propagator; s_matrix[n*n] is symmetric and masses[n] are squared. + * scale_squared is positive mu_R^2. Results: finite, single, double pole. + * Inputs and outputs must be valid and mutually disjoint for the entire call. + * Each DP length counts elements (real or complex as declared), not bytes. + * All lengths must exactly match the dimensions; mismatch is rejected before + * reading or writing any numeric buffer. count is the coefficients length. + * On failure output buffers remain unchanged. No exception crosses this ABI. + */ +int32_t ninjars_evaluate_dp(ninjars_context *context, int32_t n, int32_t rank, size_t count, + const ninjars_complex *coefficients, const double *s_matrix, size_t s_length, + const double *momenta, size_t p_length, const ninjars_complex *masses, size_t m_length, + double scale_squared, ninjars_complex *laurent, size_t laurent_length, + ninjars_complex *rational, size_t rational_length); +/* Explicit pole selection. Finite terms are unchanged; the selector is per call. + * UV/IR DP uses the generic binary64 engine on the shared Symbolica worker + * so scaleless-bubble coefficients remain available. Its rational/CC split + * can differ from the fast engine; the complete finite term is equivalent. + * Invalid modes fail. */ +int32_t ninjars_evaluate_dp_with_poles(ninjars_context *context, int32_t n, int32_t rank, size_t count, + const ninjars_complex *coefficients, const double *s_matrix, size_t s_length, + const double *momenta, size_t p_length, const ninjars_complex *masses, size_t m_length, + double scale_squared, ninjars_complex *laurent, size_t laurent_length, + ninjars_complex *rational, size_t rational_length, int32_t pole_mode); + +/* Explicit compensated DP retry. Same buffer and transactional contract as + * ninjars_evaluate_dp; owns separate lazy state. The caller controls stability + * checks and fallback. Ordinary DP calls never enable this path implicitly. */ +int32_t ninjars_evaluate_dp_compensated(ninjars_context *context, int32_t n, int32_t rank, size_t count, + const ninjars_complex *coefficients, const double *s_matrix, size_t s_length, + const double *momenta, size_t p_length, const ninjars_complex *masses, size_t m_length, + double scale_squared, ninjars_complex *laurent, size_t laurent_length, + ninjars_complex *rational, size_t rational_length); +/* Selected UV/IR retries use the same generic binary64 engine as the ordinary + * selected call, without the fast engine's compensated tensor callback. + * Combined/no-pole retries retain that callback. Invalid modes fail. */ +int32_t ninjars_evaluate_dp_compensated_with_poles(ninjars_context *context, int32_t n, int32_t rank, size_t count, + const ninjars_complex *coefficients, const double *s_matrix, size_t s_length, + const double *momenta, size_t p_length, const ninjars_complex *masses, size_t m_length, + double scale_squared, ninjars_complex *laurent, size_t laurent_length, + ninjars_complex *rational, size_t rational_length, int32_t pole_mode); +/* + * MP records are 64-byte space-padded ASCII, 40 significant decimal digits, + * with E exponent. Each number originated in binary128 (113 mantissa bits). + * Counts in records: coefficients=2*count, matrix=n*n, momenta=4*n, + * masses=2*n, scale=1. Complex records are real followed by imaginary. + * output has 8 records: three Laurent complex values then the rational term. + * Every MP buffer length is in bytes, not records; count is still the number + * of complex tensor coefficients. All byte lengths must match exactly. + * The complete reduction uses 256-bit arithmetic. All contexts share one + * worker, with independent retained numerical state; last destroy joins it. + * The last complex value is the generic engine's basis-dependent rational + * diagnostic. Its split from the cut-constructible part can differ from DP + * and original Ninja; the complete finite Laurent value includes both. + * Symbolica licensing applies to MP and selected UV/IR DP execution. + * Its restricted mode permits + * one active Symbolica thread per user across all processes; concurrent MP + * processes need a suitable license. Permit/license failures in upstream + * Symbolica can terminate the process rather than return an ABI status. + */ +int32_t ninjars_evaluate_mp(ninjars_context *context, int32_t n, int32_t rank, size_t count, + const unsigned char *coefficients, size_t coefficient_bytes, + const unsigned char *s_matrix, size_t s_bytes, + const unsigned char *momenta, size_t p_bytes, + const unsigned char *masses, size_t m_bytes, + const unsigned char *scale_squared, size_t scale_bytes, + unsigned char *output, size_t output_bytes); +/* Explicit pole selection in the generic 256-bit engine. Finite terms and + * the binary128 record contract are unchanged. Invalid modes fail. */ +int32_t ninjars_evaluate_mp_with_poles(ninjars_context *context, int32_t n, int32_t rank, size_t count, + const unsigned char *coefficients, size_t coefficient_bytes, + const unsigned char *s_matrix, size_t s_bytes, + const unsigned char *momenta, size_t p_bytes, + const unsigned char *masses, size_t m_bytes, + const unsigned char *scale_squared, size_t scale_bytes, + unsigned char *output, size_t output_bytes, int32_t pole_mode); +/* Required length includes NUL; NULL/zero queries it. Error is calling-thread local. */ +size_t ninjars_last_error(unsigned char *output, size_t capacity); +#ifdef __cplusplus +} +#endif +#endif diff --git a/vendor/ninjars/smoke.f90 b/vendor/ninjars/smoke.f90 new file mode 100644 index 0000000000..e8e610aff2 --- /dev/null +++ b/vendor/ninjars/smoke.f90 @@ -0,0 +1,87 @@ +program smoke + use mninjars + use, intrinsic :: ieee_arithmetic + implicit none + complex(KI_NRS) :: c(1),m(1),r(0:2),r1 + real(KI_NRS) :: p(0:3,1),s(1,1) + complex(KI_QNRS) :: qc(1),qm(1),qr(0:2),qr1 + real(KI_QNRS) :: qp(0:3,1),qs(1,1),delta + complex(KI_NRS) :: bm(2) + real(KI_NRS) :: bp(0:3,2),bs(2,2),pole_sign + complex(KI_QNRS) :: qbm(2) + real(KI_QNRS) :: qbp(0:3,2),qbs(2,2) + integer :: status,pole_mode + real(KI_QNRS), volatile :: rounding_x,rounding_y,rounding_sum + type(ieee_round_type) :: original_rounding + character(len=512) :: message + ! Rust staticlib compiler_builtins must not replace the Fortran runtime: + ! those helpers ignore the caller's directed IEEE rounding mode. + call ieee_get_rounding_mode(original_rounding) + rounding_x=1.0_KI_QNRS + rounding_y=2.0_KI_QNRS**(-114) + call ieee_set_rounding_mode(ieee_up) + rounding_sum=rounding_x+rounding_y + call ieee_set_rounding_mode(original_rounding) + if (rounding_sum /= nearest(1.0_KI_QNRS,1.0_KI_QNRS)) stop 8 + c = cmplx(1,0,kind=KI_NRS) + m = cmplx(4,0,kind=KI_NRS) + p = 0 + s = 0 + call ninjars_tensor_evaluate(c,1,0,s,p,m,4.0_KI_NRS,r,r1,status) + if (status /= NINJARS_SUCCESS) then + call ninjars_error_message(message) + print *, trim(message) + stop 1 + endif + if (abs(r(0)-4)>1e-12_KI_NRS .or. abs(r(1)-4)>1e-12_KI_NRS .or. abs(r(2))>1e-12_KI_NRS) stop 2 + call ninjars_tensor_evaluate_compensated(c,1,0,s,p,m,4.0_KI_NRS,r,r1,status) + if (status /= NINJARS_SUCCESS) stop 9 + if (abs(r(0)-4)>1e-12_KI_NRS .or. abs(r(1)-4)>1e-12_KI_NRS .or. abs(r(2))>1e-12_KI_NRS) stop 10 + ! Returning to the ordinary entry must not retain compensated mode. + call ninjars_tensor_evaluate(c,1,0,s,p,m,4.0_KI_NRS,r,r1,status) + if (status /= NINJARS_SUCCESS) stop 11 + if (abs(r(0)-4)>1e-12_KI_NRS .or. abs(r(1)-4)>1e-12_KI_NRS .or. abs(r(2))>1e-12_KI_NRS) stop 12 + delta = 2.0_KI_QNRS**(-100) + qc = cmplx(1.0_KI_QNRS+delta,0.0_KI_QNRS,kind=KI_QNRS) + qm = cmplx(4,0,kind=KI_QNRS) + qp = 0 + qs = 0 + call ninjars_tensor_evaluate(qc,1,0,qs,qp,qm,4.0_KI_QNRS,qr,qr1,status) + if (status /= NINJARS_SUCCESS) then + call ninjars_error_message(message) + print *, trim(message) + stop 3 + endif + if (abs(qr(1)-4.0_KI_QNRS*(1.0_KI_QNRS+delta))>1e-32_KI_QNRS) stop 4 + if (real(qr(1),kind=KI_QNRS) == 4.0_KI_QNRS) stop 5 + if (abs(qr(2))>1e-32_KI_QNRS .or. abs(qr1)>1e-32_KI_QNRS) stop 6 + ! A lightlike scaleless bubble vanishes only after UV and IR cancel. + ! Exercise the installed optional selector in both numerical domains and + ! preserve the input's binary128 information in its separated residues. + bm = cmplx(0,0,kind=KI_NRS) + bp = 0 + bp(0,2) = 2 + bp(3,2) = 2 + bs = 0 + qbm = cmplx(0,0,kind=KI_QNRS) + qbp = real(bp,kind=KI_QNRS) + qbs = 0 + do pole_mode=NINJARS_POLES_UV,NINJARS_POLES_IR + pole_sign = 3-2*pole_mode + call ninjars_tensor_evaluate(c,2,0,bs,bp,bm,4.0_KI_NRS,r,r1,status,pole_mode=pole_mode) + if (status /= NINJARS_SUCCESS) stop 13 + if (abs(r(0))>1e-12_KI_NRS .or. abs(r(1)-pole_sign)>1e-12_KI_NRS .or. abs(r(2))>1e-12_KI_NRS) stop 14 + call ninjars_tensor_evaluate(qc,2,0,qbs,qbp,qbm,4.0_KI_QNRS,qr,qr1,status,pole_mode=pole_mode) + if (status /= NINJARS_SUCCESS) stop 15 + if (abs(qr(1)-real(pole_sign,KI_QNRS)*(1.0_KI_QNRS+delta))>1e-32_KI_QNRS) stop 16 + if (abs(qr(0))>1e-32_KI_QNRS .or. abs(qr(2))>1e-32_KI_QNRS) stop 17 + enddo + ! The omitted selector must restore combined poles on a reused context. + call ninjars_tensor_evaluate(c,2,0,bs,bp,bm,4.0_KI_NRS,r,r1,status) + if (status /= NINJARS_SUCCESS .or. any(abs(r)>1e-12_KI_NRS)) stop 18 + call ninjars_tensor_evaluate(qc,2,0,qbs,qbp,qbm,4.0_KI_QNRS,qr,qr1,status) + if (status /= NINJARS_SUCCESS .or. any(abs(qr)>1e-32_KI_QNRS)) stop 19 + call ninjars_finalize(status) + if (status /= NINJARS_SUCCESS) stop 7 + print *, 'NinjaRS ABI4 DP, binary128-input rescue and separated UV/IR poles passed' +end program diff --git a/vendor/ninjars/src/final_precision_tests.rs b/vendor/ninjars/src/final_precision_tests.rs new file mode 100644 index 0000000000..83ebbced98 --- /dev/null +++ b/vendor/ninjars/src/final_precision_tests.rs @@ -0,0 +1,391 @@ +//! Final-source single-backend MP controls, adapted from the retained study. +//! This module contains no backend selector and never changes production policy. +use super::*; +use serde_json::{Value, json}; +use std::io::Write; + +fn pack(values: &Value) -> Vec { + values.as_array().unwrap().iter().flat_map(|value| { + let text = value.as_str().unwrap().as_bytes(); + assert!(text.len() <= RECORD); + let mut record = [b' '; RECORD]; + record[..text.len()].copy_from_slice(text); + record + }).collect() +} + +fn request(input: &Value) -> MpRequest { + let (reply, _) = mpsc::sync_channel(1); + MpRequest { + selection: PoleSelection::BOTH, + context_id: 0, + n: input["n"].as_u64().unwrap() as usize, + rank: input["rank"].as_u64().unwrap() as usize, + coefficients: pack(&input["coefficients"]), + s_matrix: pack(&input["s_matrix"]), + momenta: pack(&input["momenta"]), + masses: pack(&input["masses"]), + scale: pack(&input["scale"]), reply, + } +} + +fn input_bytes(r: &MpRequest) -> Vec> { + [&r.coefficients, &r.s_matrix, &r.momenta, &r.masses, &r.scale] + .into_iter().cloned().collect() +} + +fn represented(value: &Float) -> Value { + if !value.is_finite() { + return json!({"finite": false, "display": format!("{value}"), + "precision": value.prec(), "negative": value.is_sign_negative()}); + } + let rational = value.to_rational(); + json!({"finite": true, "numerator": rational.numerator().to_string(), + "denominator": rational.denominator().to_string(), + "precision": value.prec(), "negative": value.is_sign_negative()}) +} + +struct Observation { + json: Value, + raw: Option>, +} + +fn observe(state: &mut MpState, r: &MpRequest) -> Observation { + let before = input_bytes(r); + let precision = state.precision; + let result = catch_unwind(AssertUnwindSafe(|| state.evaluate(r))); + let mut raw = None; + let mut value = match result { + Ok(Ok((status, output))) => { + let fields: Vec<_> = output.chunks_exact(RECORD) + .map(|field| std::str::from_utf8(field).unwrap().trim().to_owned()).collect(); + if status == SUCCESS { + raw = state.entries.get(&(r.n, r.rank)).map(|entry| + entry.amplitude.results()[0].iter().flat_map(|z| [&z.re, &z.im]) + .cloned().collect::>()); + } + json!({"status": status, "output": fields, "output_bytes": output.len(), + "raw": raw.as_ref().map(|values| values.iter().map(represented).collect::>())}) + } + Ok(Err(error)) => json!({"status": ERROR, "error": error, "output": [], "raw": null}), + Err(payload) => { + let message = payload.downcast_ref::().cloned() + .or_else(|| payload.downcast_ref::<&str>().map(|text| (*text).to_owned())) + .unwrap_or_else(|| "non-string panic payload".to_owned()); + // Retain the panic explicitly before replacing damaged private test + // state. Returned-error controls below forbid this replacement. + *state = MpState::with_precision(precision).unwrap(); + json!({"status": ERROR, "panic": true, "panic_message": message, + "output": [], "raw": null}) + } + }; + value["working_bits"] = json!(precision); + value["input_unchanged"] = json!(input_bytes(r) == before); + Observation { json: value, raw } +} + +fn successful(value: &Observation) -> bool { + value.json["status"] == SUCCESS && value.json["input_unchanged"] == true + && value.json["output"].as_array().is_some_and(|fields| fields.len() == 8) + && value.raw.as_ref().is_some_and(|raw| raw.len() == 10 && raw.iter().all(Float::is_finite)) +} + +fn binary128_outputs_equal(actual: &Value, expected: &Value) -> bool { + let (Some(actual), Some(expected)) = (actual.as_array(), expected.as_array()) else { return false; }; + if actual.len() != 8 || expected.len() != 8 { return false; } + actual.iter().zip(expected).all(|(a, b)| { + let parsed_a = parse_records(&pack(&json!([a])), 113); + let parsed_b = parse_records(&pack(&json!([b])), 113); + match (parsed_a, parsed_b) { + (Ok(a), Ok(b)) => a[0] == b[0] && (!a[0].is_fully_zero() + || a[0].is_sign_negative() == b[0].is_sign_negative()), + _ => false, + } + }) +} + +fn emit(stream: &mut impl Write, value: &Value) { + serde_json::to_writer(&mut *stream, value).unwrap(); + stream.write_all(b"\n").unwrap(); + stream.flush().unwrap(); +} + +fn large_thread(body: impl FnOnce() + Send + 'static) { + std::thread::Builder::new().stack_size(128 * 1024 * 1024) + .spawn(body).unwrap().join().unwrap(); +} + +fn compare_precisions(low: &Observation, high: &Observation) -> Value { + if !successful(low) || !successful(high) { + return json!({"comparable": false, "passed": false}); + } + // Widen represented values exactly before comparison. Float operations + // may retain more bits than the engine's requested working precision, so + // never shrink either observation to the nominal384-bit reference size. + // The raw records retain their original precision/sign metadata; inputs + // to the evaluator remain the original recovered113-bit numbers. + let comparison_bits = low.raw.as_ref().unwrap().iter() + .chain(high.raw.as_ref().unwrap()).map(Float::prec).max().unwrap().max(384); + let at_reference = |value: &Float| { + let mut result = value.clone(); + result.set_prec(comparison_bits); + result + }; + let a: Vec<_> = low.raw.as_ref().unwrap().iter().map(at_reference).collect(); + let b: Vec<_> = high.raw.as_ref().unwrap().iter().map(at_reference).collect(); + let norm = b[..6].iter().map(|value| value.norm()) + .fold(Float::new(comparison_bits), |largest, value| if value > largest { value } else { largest }); + let bound = Float::parse("1e-31", Some(comparison_bits)).unwrap() * &norm; + let differences: Vec<_> = a.iter().zip(&b).map(|(x,y)| (x.clone()-y).norm()).collect(); + let split_bound = Float::parse("1e-60", Some(comparison_bits)).unwrap() * &norm; + let splits: Vec<_> = [&a, &b].iter().map(|values| + (0..2).map(|index| (values[index].clone() - &values[6+index] - &values[8+index]).norm()) + .collect::>()).collect(); + let laurent_passed = differences[..6].iter().all(|value| value <= &bound); + let rational_passed = differences[8..].iter().all(|value| value <= &bound); + let split_passed = splits.iter().flatten().all(|value| value <= &split_bound); + let changed_sign: Vec<_> = low.raw.as_ref().unwrap().iter().zip(high.raw.as_ref().unwrap()) + .enumerate().filter_map(|(i,(a,b))| (a.is_sign_negative() != b.is_sign_negative()).then_some(i)).collect(); + let changed_precision: Vec<_> = low.raw.as_ref().unwrap().iter().zip(high.raw.as_ref().unwrap()) + .enumerate().filter_map(|(i,(a,b))| (a.prec() != b.prec()).then_some(i)).collect(); + json!({"comparable": true, "passed": laurent_passed && rational_passed && split_passed, + "comparison_bits": comparison_bits, + "laurent_passed": laurent_passed, "rational_passed": rational_passed, + "finite_split_passed": split_passed, + "normalization": represented(&norm), "bound": represented(&bound), + "absolute_differences": differences.iter().map(represented).collect::>(), + "finite_split_absolute_defects": splits.iter().map(|values| + values.iter().map(represented).collect::>()).collect::>(), + "sign_changed_indices": changed_sign, "tracked_precision_changed_indices": changed_precision, + "automatic_sign_or_precision_difference_acceptance": false}) +} + +#[test] +#[ignore = "requires exclusive MP slot and original1392request capture; no backend selector"] +fn retained_requests_replay_and_converge() { + let input = std::fs::read_to_string(std::env::var("NINJARS_CONVERGENCE_INPUT").unwrap()).unwrap(); + let output = std::env::var("NINJARS_CONVERGENCE_OUTPUT").unwrap(); + large_thread(move || { + let records: Vec = input.lines().map(|line| serde_json::from_str(line).unwrap()).collect(); + assert_eq!(records.len(), 1392); + let mut stream = std::io::BufWriter::new(std::fs::OpenOptions::new().write(true) + .create_new(true).open(output).unwrap()); + let mut low_state = MpState::with_precision(256).unwrap(); + let mut low = Vec::with_capacity(records.len()); + let mut failed = 0usize; + let mut ascii_changed = 0usize; + for (sequence, input) in records.iter().enumerate() { + assert_eq!(input["status"], SUCCESS); + let r = request(input); + assert_eq!(r.coefficients.len(), RECORD * 2 * ninjars::fast::tensor_layout::ncoeff(r.rank)); + let observed = observe(&mut low_state, &r); + let binary128_equal = successful(&observed) + && binary128_outputs_equal(&observed.json["output"], &input["output"]); + let ascii_equal = observed.json["output"] == input["output"]; + failed += usize::from(!binary128_equal); + ascii_changed += usize::from(!ascii_equal); + emit(&mut stream, &json!({"kind": "replay", "sequence": sequence, "input": input, + "observed": observed.json, "historical_ascii_equal": ascii_equal, + "historical_binary128_values_and_zero_signs_equal": binary128_equal})); + low.push(observed); + } + // Identical full input history at both precisions avoids introducing + // a selected-subset symbol-construction history into this comparison. + let mut high_state = MpState::with_precision(384).unwrap(); + let mut convergence_failed = 0usize; + let mut sign_changed = 0usize; + for (sequence, input) in records.iter().enumerate() { + let high = observe(&mut high_state, &request(input)); + let comparison = compare_precisions(&low[sequence], &high); + convergence_failed += usize::from(comparison["passed"] != true); + sign_changed += usize::from(comparison["sign_changed_indices"].as_array() + .is_none_or(|fields| !fields.is_empty())); + emit(&mut stream, &json!({"kind": "convergence", "sequence": sequence, + "input": input, "observed_384": high.json, "comparison": comparison})); + } + let summary = json!({"kind": "summary", "complete": true, "records": records.len(), + "production_bits": 256, "reference_bits": 384, "convergence_tolerance": "1e-31", + "fields_per_precision": records.len()*8, "failed_binary128_replay_records": failed, + "historical_ascii_changed_records_retained": ascii_changed, + "failed_convergence_records": convergence_failed, + "sign_changed_convergence_records_require_review": sign_changed, + "single_production_backend_no_selector": true, "performance_claim": false}); + emit(&mut stream, &summary); + println!("NINJARS_CONVERGENCE_CAPTURE_SUMMARY {summary}"); + assert_eq!(failed, 0, "retain every historical output/status difference"); + assert_eq!(convergence_failed, 0, "retain every convergence failure without changing thresholds"); + }); +} + +fn fixture(n: usize, coefficient: &str, masses: &[&str], scale: &str) -> Value { + let (s,p) = if n == 1 { (vec!["0"],vec!["0","0","0","0"]) } + else { (vec!["0","-4","-4","0"],vec!["0","0","0","0","0","2","0","0"]) }; + json!({"n":n,"rank":0,"coefficients":[coefficient,"-0"],"s_matrix":s, + "momenta":p,"masses":masses,"scale":[scale]}) +} + +#[test] +fn analytic_poles_reuse_and_returned_shape_errors() { + large_thread(|| { + let fixtures = [ + fixture(1,"1.000000000000000000000000000000788860905",&["4","-0"],"1"), + fixture(2,"1",&["0","-0","4","-0"],"1"), + fixture(2,"2",&["4","-0","0","-0"],"9"), + fixture(1,"-3",&["9","-0.125"],"16"), + fixture(2,"-3",&["0","-0","0","-0"],"4"), + ]; + for bits in [256,384] { + let mut state = MpState::with_precision(bits).unwrap(); + for input in &fixtures { + let r = request(input); + let fresh = observe(&mut MpState::with_precision(bits).unwrap(), &r); + assert!(successful(&fresh)); + let key = (r.n,r.rank); + let before = state.entries.get(&key).map(|entry| entry as *const MpEntry as usize); + let mut wrong = request(input); + wrong.coefficients.extend(pack(&json!(["1","-0"]))); + let rejected = observe(&mut state, &wrong); + assert_eq!(rejected.json["status"], ERROR); + assert!(rejected.json["panic"].is_null()); + assert_eq!(rejected.json["output"], json!([])); + assert!(rejected.json["raw"].is_null()); + assert_eq!(rejected.json["input_unchanged"], true); + let entry = state.entries.get(&key).unwrap() as *const MpEntry as usize; + assert!(before.is_none_or(|address| address == entry)); + let recovered = observe(&mut state, &r); + assert_eq!(state.entries.get(&key).unwrap() as *const MpEntry as usize, entry); + assert_eq!(recovered.json, fresh.json); + let mut invalid = input.clone(); + invalid["masses"][1] = json!("1"); + let rejected = observe(&mut state,&request(&invalid)); + assert_eq!(rejected.json["status"], ERROR); + assert!(rejected.json["panic"].is_null()); + assert_eq!(rejected.json["output"],json!([])); + assert!(rejected.json["raw"].is_null()); + assert_eq!(observe(&mut state,&r).json,fresh.json); + let raw = fresh.raw.as_ref().unwrap(); + let coefficient = parse_records(&pack(&input["coefficients"]),bits).unwrap(); + let masses = parse_records(&pack(&input["masses"]),bits).unwrap(); + let expected = if r.n == 1 { [coefficient[0].clone()*&masses[0],coefficient[0].clone()*&masses[1]] } + else { [coefficient[0].clone(),Float::new(bits)] }; + let norm = expected[0].norm()+expected[1].norm(); + let bound = Float::parse("1e-31",Some(bits)).unwrap()*norm; + assert!((raw[2].clone()-&expected[0]).norm()<=bound); + assert!((raw[3].clone()-&expected[1]).norm()<=bound); + assert!(raw[4].is_fully_zero() && raw[5].is_fully_zero()); + } + } + }); +} + +#[test] +#[ignore = "requires exclusive MP slot; seven retained physicalfixtures in allthree modes"] +fn seven_physical_fixtures_all_modes() { + // Inputs and Ninja references are unchanged from tests/replay.py. Including + // them in this libtest target avoids a separately linked example binary. + const CASES: [(&str, &str); 7] = [ + (include_str!("../tests/data/cases/madloop-four-photon-top-box-0.json"), + include_str!("../tests/data/ninja/madloop-four-photon-top-box-0.json")), + (include_str!("../tests/data/cases/madloop-gg-hh-top-box-2.json"), + include_str!("../tests/data/ninja/madloop-gg-hh-top-box-2.json")), + (include_str!("../tests/data/cases/madloop-gg-hh-top-triangle-0.json"), + include_str!("../tests/data/ninja/madloop-gg-hh-top-triangle-0.json")), + (include_str!("../tests/data/cases/madloop-gg-hhh-top-box-8.json"), + include_str!("../tests/data/ninja/madloop-gg-hhh-top-box-8.json")), + (include_str!("../tests/data/cases/madloop-gg-hhh-top-pentagon-26.json"), + include_str!("../tests/data/ninja/madloop-gg-hhh-top-pentagon-26.json")), + (include_str!("../tests/data/cases/madloop-gg-hhh-top-triangle-0.json"), + include_str!("../tests/data/ninja/madloop-gg-hhh-top-triangle-0.json")), + (include_str!("../tests/data/cases/madloop-hgg-top-triangle-0.json"), + include_str!("../tests/data/ninja/madloop-hgg-top-triangle-0.json")), + ]; + let mut failures = 0usize; + let mut lanes = 0usize; + let mut calls = 0usize; + for (case, reference) in CASES { + let case: Value = serde_json::from_str(case).unwrap(); + let reference: Value = serde_json::from_str(reference).unwrap(); + let mut context = std::ptr::null_mut(); + assert_eq!(unsafe { ninjars_context_create(ABI_VERSION, &mut context) }, SUCCESS); + for lane in case["lanes"].as_array().unwrap() { + lanes += 1; + let expected = reference["lanes"].as_array().unwrap().iter() + .find(|row| row["id"] == lane["id"]).unwrap(); + let complex = |value: &Value| C64::new(value[0].as_f64().unwrap(), value[1].as_f64().unwrap()); + let coefficients: Vec<_> = lane["tensor"].as_array().unwrap().iter().map(complex).collect(); + let masses: Vec<_> = lane["masses_squared"].as_array().unwrap().iter().map(complex).collect(); + let flatten = |key: &str| lane[key].as_array().unwrap().iter() + .flat_map(|row| row.as_array().unwrap().iter().map(|value| value.as_f64().unwrap())).collect::>(); + let matrix = flatten("s_matrix"); + let momenta = flatten("shifts"); + for mode in 0..3 { + calls += 1; + let mut laurent = [C64::ZERO; 3]; + let mut rational = C64::ZERO; + let mut ascii = Vec::::new(); + let status = if mode < 2 { + let evaluate = if mode == 0 { ninjars_evaluate_dp } else { ninjars_evaluate_dp_compensated }; + unsafe { evaluate(context, case["n"].as_i64().unwrap() as i32, + case["rank"].as_i64().unwrap() as i32, coefficients.len(), + coefficients.as_ptr(), matrix.as_ptr(), matrix.len(), + momenta.as_ptr(), momenta.len(), masses.as_ptr(), masses.len(), + lane["mu_squared"].as_f64().unwrap(), laurent.as_mut_ptr(), + laurent.len(), &mut rational, 1) } + } else { + let records = |values: Vec| pack(&json!(values.into_iter() + .map(|value| format!("{value:.39e}")).collect::>())); + let ct = records(coefficients.iter().flat_map(|value| [value.re,value.im]).collect()); + let mt = records(masses.iter().flat_map(|value| [value.re,value.im]).collect()); + let st = records(matrix.clone()); + let pt = records(momenta.clone()); + let scale = records(vec![lane["mu_squared"].as_f64().unwrap()]); + let mut output = [b' '; 8*RECORD]; + let status = unsafe { ninjars_evaluate_mp(context, + case["n"].as_i64().unwrap() as i32, case["rank"].as_i64().unwrap() as i32, + coefficients.len(), ct.as_ptr(), ct.len(), st.as_ptr(), st.len(), + pt.as_ptr(), pt.len(), mt.as_ptr(), mt.len(), scale.as_ptr(), scale.len(), + output.as_mut_ptr(), output.len()) }; + ascii = output.chunks_exact(RECORD).map(|field| + std::str::from_utf8(field).unwrap().trim().to_owned()).collect(); + if status == SUCCESS { + let values: Vec = ascii.iter().map(|value| value.parse().unwrap()).collect(); + for index in 0..3 { laurent[index] = C64::new(values[2*index],values[2*index+1]); } + rational = C64::new(values[6],values[7]); + } + status + }; + let mut errors = Vec::new(); + let mut rational_difference = 0f64; + let mut good = status == SUCCESS; + for (index, (value,key)) in laurent.into_iter().chain([rational]) + .zip(["eps0","eps_m1","eps_m2","rational"]).enumerate() { + let expected = complex(&expected[key]); + let error = (value-expected).abs()/expected.abs().max(1.); + if index == 3 { rational_difference = error; } + // Same existing cross-basis convention as examples/replay.rs: + // compare all complete Laurent terms, report MP's basis- + // dependent rational split independently. + if index != 3 || mode != 2 { + good &= error.is_finite() && error <= 1e-9; + errors.push(error); + } + } + failures += usize::from(!good); + println!("NINJARS_FIXTURE_RECORD {}", json!({"case":case["name"], + "lane":lane["id"],"mode":mode,"status":status, + "laurent_and_rational":laurent.into_iter().chain([rational]) + .map(|value| [value.re,value.im]).collect::>(), + "mp_ascii":ascii,"compared_component_errors":errors, + "rational_compared":mode!=2,"basis_dependent_rational_scaled_difference":rational_difference, + "tolerance":1e-9,"passed":good})); + } + } + assert_eq!(unsafe { ninjars_context_destroy(context) }, SUCCESS); + } + assert_eq!(lanes,21); + assert_eq!(calls,63); + println!("NINJARS_FIXTURE_SUMMARY {}", json!({"fixtures":7,"lanes":lanes, + "calls":calls,"modes":["native-dp","compensated-dp","genuine256"], + "failed_calls":failures,"passed":failures==0})); + assert_eq!(failures,0,"all failed fixtures retained without changing inputs or thresholds"); +} diff --git a/vendor/ninjars/src/guarded.rs b/vendor/ninjars/src/guarded.rs new file mode 100644 index 0000000000..e72becfa07 --- /dev/null +++ b/vendor/ninjars/src/guarded.rs @@ -0,0 +1,200 @@ +//! Guarded compensated T3 expansion for an explicit DP retry. No stability threshold or status changes. +//! The supported domain is N(q), rank 2..=8, mindeg=2. Every other callback is +//! delegated verbatim to the pinned upstream tensor, including n+2 callbacks. +//! Scratch storage belongs to the retained tensor and is reused between calls. +//! Traversal/layout adapt the pinned NinjaRS fast tensor, tensor_layout and +//! tensor_jets implementations (see Cargo.lock and UPSTREAM.md). Compensation +//! carries first-order product/sum residuals; it is not a universal guarantee +//! of correctly rounded polynomial evaluation. MadLoop retains its independent +//! direction/rotation checks and genuine higher-precision fallback. +use ninjars::fast::{C64, CMom, FastNumerator, TensorNumerator}; +use ninjars::fast::tensor_layout::{block_offset, ncoeff_homogeneous}; +use ninjars::{Error, Result}; + +unsafe extern "C" { + fn ninjars_t3_standard_environment() -> i32; +} + +#[derive(Clone, Copy, Default)] +struct Sum { sum: f64, err: f64 } +impl Sum { + #[inline] + fn add(&mut self, x: f64) { + let s = self.sum + x; + self.err += if self.sum.abs() >= x.abs() { + (self.sum - s) + x + } else { + (x - s) + self.sum + }; + self.sum = s; + } + #[inline] + fn product(&mut self, a: f64, b: f64, sign: f64) { + let hi = a * b; + let lo = a.mul_add(b, -hi); + self.add(sign * hi); + self.add(sign * lo); + } + #[inline] + fn value(self) -> f64 { self.sum + self.err } +} +#[derive(Clone, Copy, Default)] +struct Acc { r: Sum, i: Sum } +impl Acc { + #[inline] + fn add(&mut self, z: C64) { self.r.add(z.re); self.i.add(z.im); } + #[inline] + fn product(&mut self, g: Self, x: C64) { + self.r.product(g.r.sum, x.re, 1.); + self.r.product(g.i.sum, x.im, -1.); + self.i.product(g.r.sum, x.im, 1.); + self.i.product(g.i.sum, x.re, 1.); + // First-order carried residual; this multiplication is rounded normally. + // This is compensation, not a correctly-rounded polynomial guarantee. + self.add(C64::new(g.r.err, g.i.err) * x); + } + #[inline] + fn value(self) -> C64 { C64::new(self.r.value(), self.i.value()) } +} + +/// Integer-only bounds on nonzero input components. `low` is the exact binary +/// lattice exponent, not a logarithmic approximation; `high` is a strict +/// magnitude upper bound. Signed zero is allowed. Subnormals and nonfinite +/// values are rejected before any floating arithmetic or output writes. +#[derive(Clone, Copy)] +struct Bounds { low: i32, high: i32 } +impl Bounds { + fn values(values: impl Iterator) -> Option { + let mut result = Self { low: 0, high: 0 }; + for z in values { + for x in [z.re, z.im] { + let b = x.to_bits() & 0x7fff_ffff_ffff_ffff; + if b == 0 { continue; } + let exponent = ((b >> 52) & 0x7ff) as i32; + if exponent == 0 || exponent == 0x7ff { return None; } + let significand = (b & 0x000f_ffff_ffff_ffff) | (1u64 << 52); + let low = exponent - 1023 - 52 + significand.trailing_zeros() as i32; + result.low = result.low.min(low); + result.high = result.high.max(exponent - 1023 + 1); + } + } + Some(result) + } +} + +/// Conservative preflight for *every intermediate*, including FMA residuals. +/// Each recurrence product increases degree by one; final param multiplication +/// adds at most one further factor. Addition/subtraction cannot refine the +/// common binary lattice. A 16-bit-per-level magnitude allowance dominates +/// the <=4 complex child contributions, all compensation operations and the +/// inserted lower coefficient. Bounds +/-900 leave >120 exponent bits spare. +/// No speculative calculation is attempted outside this domain, so fallback +/// cannot leak new exception flags produced by an abandoned correction. +fn safe(rank: usize, c: &[C64], a: &CMom, e3: &CMom, e4: &CMom, p: C64) -> bool { + let Some(c) = Bounds::values(c.iter().copied()) else { return false }; + let Some(v) = Bounds::values(a.iter().chain(e3).chain(e4).copied()) else { return false }; + let Some(p) = Bounds::values(std::iter::once(p)) else { return false }; + c.low + rank as i32 * v.low + p.low >= -900 + && c.high + rank as i32 * (v.high + 16) + p.high + 16 <= 900 +} + +pub struct GuardedTensor { + native: TensorNumerator, + work: Vec<[Acc; 4]>, + pub corrected: usize, + pub fallback: usize, +} +impl GuardedTensor { + pub fn new(rank: usize, lanes: usize) -> Self { + Self { native: TensorNumerator::new(rank, lanes), + work: vec![[Acc::default(); 4]; 2 * ncoeff_homogeneous(rank)], + corrected: 0, fallback: 0 } + } + pub fn coefficients_mut(&mut self) -> &mut [C64] { self.native.coefficients_mut() } + + fn carried(&mut self, lane: usize, a: &CMom, e3: &CMom, e4: &CMom, p: C64) -> [C64; 4] { + let rank = self.native.rank(); + let c = self.native.lane_coefficients(lane); + let level = ncoeff_homogeneous(rank); + let (mut cur, mut next) = self.work.split_at_mut(level); + cur.fill([Acc::default(); 4]); + for (g, &z) in cur.iter_mut().zip(&c[block_offset(rank)..]) { g[0].add(z); } + for d in (1..=rank).rev() { + let size = ncoeff_homogeneous(d - 1); + next[..size].fill([Acc::default(); 4]); + for (i, sums) in next[..size].iter_mut().enumerate() { + for component in [3, 2, 1, 0] { + let j = match component { + 0 if i == 0 => Some(0), + 1 if i < d => Some(1 + i), + 2 if i < d * (d + 1) / 2 => Some(1 + d + i), + 3 => Some(1 + d + d * (d + 1) / 2 + i), + _ => None, + }; + if let Some(j) = j { + let v = cur[j]; + sums[0].product(v[0], e3[component]); + sums[1].product(v[1], e3[component]); + sums[1].product(v[0], a[component]); + sums[2].product(v[2], e3[component]); + sums[2].product(v[1], a[component]); + sums[3].product(v[3], e3[component]); + sums[3].product(v[0], e4[component]); + } + } + let power = rank - d + 1; + if power <= 2 { sums[power].add(c[block_offset(d - 1) + i]); } + } + std::mem::swap(&mut cur, &mut next); + } + let jet = cur[0]; + let mut constant = jet[2]; + constant.product(jet[3], p); + [jet[0].value(), jet[1].value(), constant.value(), jet[3].value()] + } +} + +impl FastNumerator for GuardedTensor { + fn rank(&self) -> usize { self.native.rank() } + fn evaluate(&mut self, cut: &[usize], lanes: &[usize], q: &[CMom], mu: &[C64], out: &mut [C64]) -> Result<()> { + self.native.evaluate(cut, lanes, q, mu, out) + } + fn mu_expansion(&mut self, cut: &[usize], lanes: &[usize], v0: &[CMom], v1: Option<&[CMom]>, out: &mut [C64]) -> Result<()> { + self.native.mu_expansion(cut, lanes, v0, v1, out) + } + fn mu_expansion_x2(&mut self, cut: &[usize], lanes: &[usize], v0: &[CMom], v1: &[CMom], beta: &[C64], out: &mut [C64]) -> Result<()> { + self.native.mu_expansion_x2(cut, lanes, v0, v1, beta, out) + } + fn t2_expansion(&mut self, cut: &[usize], lanes: &[usize], a0: &[CMom], a1: &[CMom], e3: &[CMom], e4: &[CMom], p: &[[C64;3]], k: usize, out: &mut [C64]) -> Result<()> { + self.native.t2_expansion(cut, lanes, a0, a1, e3, e4, p, k, out) + } + fn t2_expansion_x2(&mut self, cut: &[usize], lanes: &[usize], a0: &[CMom], a1: &[CMom], e3: &[CMom], e4: &[CMom], p: &[[C64;3]], out: &mut [C64]) -> Result<()> { + self.native.t2_expansion_x2(cut, lanes, a0, a1, e3, e4, p, out) + } + fn t3_expansion_x2(&mut self, cut: &[usize], lanes: &[usize], a: &[CMom], e3: &[CMom], e4: &[CMom], p: &[C64], out: &mut [C64]) -> Result<()> { + self.fallback += lanes.len(); + self.native.t3_expansion_x2(cut, lanes, a, e3, e4, p, out) + } + fn t3_expansion(&mut self, cut: &[usize], lanes: &[usize], a: &[CMom], e3: &[CMom], e4: &[CMom], p: &[C64], k: usize, out: &mut [C64]) -> Result<()> { + let rank = self.native.rank(); + if k != 2 || !(2..=8).contains(&rank) || unsafe { ninjars_t3_standard_environment() } != 1 { + self.fallback += lanes.len(); + return self.native.t3_expansion(cut, lanes, a, e3, e4, p, k, out); + } + if out.len() != 4 * lanes.len() { + return Err(Error::Shape { name: "tensor numerator output", expected: 4 * lanes.len(), actual: out.len() }); + } + for (row, &lane) in lanes.iter().enumerate() { + if lane >= self.native.lanes() { return Err(Error::Lane { lane, lanes: self.native.lanes() }); } + let target = &mut out[4 * row..4 * row + 4]; + if safe(rank, self.native.lane_coefficients(lane), &a[row], &e3[row], &e4[row], p[row]) { + target.copy_from_slice(&self.carried(lane, &a[row], &e3[row], &e4[row], p[row])); + self.corrected += 1; + } else { + self.native.t3_expansion(cut, &[lane], &a[row..row+1], &e3[row..row+1], &e4[row..row+1], &p[row..row+1], k, target)?; + self.fallback += 1; + } + } + Ok(()) + } +} diff --git a/vendor/ninjars/src/guarded_fenv.c b/vendor/ninjars/src/guarded_fenv.c new file mode 100644 index 0000000000..3ef9017790 --- /dev/null +++ b/vendor/ninjars/src/guarded_fenv.c @@ -0,0 +1,21 @@ +#define _GNU_SOURCE +#include +#include +#if defined(__x86_64__) +#include +#endif + +/* Observation only: a rejected attempt must not change caller flags or traps. + Other platforms use the original upstream callback in this experiment. */ +int ninjars_t3_standard_environment(void) { +#if defined(__linux__) && defined(__x86_64__) + unsigned short cw; + __asm__ volatile ("fnstcw %0" : "=m"(cw)); + return fegetround() == FE_TONEAREST && fegetexcept() == 0 + && (_mm_getcsr() & ~UINT32_C(0x3f)) == UINT32_C(0x1f80) + && (cw & 0x1f3f) == 0x033f; +#else + return 0; +#endif +} + diff --git a/vendor/ninjars/src/guarded_tests.rs b/vendor/ninjars/src/guarded_tests.rs new file mode 100644 index 0000000000..09d6b147d9 --- /dev/null +++ b/vendor/ninjars/src/guarded_tests.rs @@ -0,0 +1,213 @@ +//! Compensated callback controls; run serially when enabling FENV test support. +use super::{guarded::GuardedTensor, tensor::TensorGenericNumerator}; +use ninjars::{Complex, Float, FourMomentum, Numerator, NumeratorRequest, + ExpansionKind, ExpansionRequest}; +use ninjars::fast::{C64, CMom, FastNumerator, TensorNumerator, GenericNumerator}; +use ninjars::fast::tensor_layout::ncoeff; +use symbolica::domains::float::RealLike; +use serde_json::{json, Value}; +use std::{fs, path::PathBuf}; +type Z=Complex; +fn z(v:Complex)->Z{Complex::new(Float::with_val(256,v.re),Float::with_val(256,v.im))} +fn mom(v:&FourMomentum>)->FourMomentum{let q=v.components();FourMomentum::from_args(z(*q[0]),z(*q[1]),z(*q[2]),z(*q[3]))} +struct Wide { inner: TensorGenericNumerator } +impl Numerator> for Wide { + fn rank(&self)->usize{self.inner.rank()} + fn evaluate_batch(&mut self,r:&[NumeratorRequest<'_,Complex>],out:&mut[Complex])->ninjars::Result<()> { + let q:Vec<_>=r.iter().map(|r|mom(r.q)).collect(); + let mu:Vec<_>=r.iter().map(|r|z(*r.mu_squared)).collect(); + let req:Vec<_>=r.iter().enumerate().map(|(i,r)|NumeratorRequest{id:r.id,q:&q[i],mu_squared:&mu[i],partition:r.partition}).collect(); + let mut values=vec![z(Complex::new(0.,0.));out.len()]; + self.inner.evaluate_batch(&req,&mut values)?; + for(o,v)in out.iter_mut().zip(values){*o=Complex::new(v.re.to_f64(),v.im.to_f64());}Ok(()) + } + fn expansion_batch(&mut self,k:&ExpansionKind,r:&[ExpansionRequest<'_,Complex>],out:&mut[Complex])->ninjars::Result<()>{ + let vectors:Vec>=r.iter().map(|r|r.vectors.iter().map(mom).collect()).collect(); + let params:Vec>=r.iter().map(|r|r.parameters.iter().copied().map(z).collect()).collect(); + let req:Vec<_>=r.iter().enumerate().map(|(i,r)|ExpansionRequest{id:r.id,partition:r.partition,vectors:&vectors[i],parameters:¶ms[i]}).collect(); + let mut values=vec![z(Complex::new(0.,0.));out.len()]; + self.inner.expansion_batch(k,&req,&mut values)?; + for(o,v)in out.iter_mut().zip(values){*o=Complex::new(v.re.to_f64(),v.im.to_f64());}Ok(()) + } +} +fn wide(rank:usize,c:&[C64])->GenericNumerator{ + let mut inner=TensorGenericNumerator::new(rank,0,&Float::with_val(256,0.)).unwrap(); + inner.set_coefficients(c.iter().map(|c|z(Complex::new(c.re,c.im))).collect(),1).unwrap(); + GenericNumerator::new(Wide{inner}) +} +fn bits(v:&[C64])->Vec<[u64;2]>{v.iter().map(|z|[z.re.to_bits(),z.im.to_bits()]).collect()} +fn len(k:usize)->usize{(0..=k).map(|j|1+j/2).sum()} +fn expand(t:&mut impl FastNumerator,k:usize,a:CMom,e:CMom,f:CMom,p:C64)->Vec{ + let mut out=vec![C64::ZERO;len(k)]; + if k==5{t.t3_expansion_x2(&[0,1,2],&[0],&[a],&[e],&[f],&[p],&mut out).unwrap();} + else{t.t3_expansion(&[0,1,2],&[0],&[a],&[e],&[f],&[p],k,&mut out).unwrap();} + out +} +fn doc()->PathBuf{PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/data/compensated")} +fn pairs(v:&Value)->Vec{v.as_array().unwrap().iter().map(|v|C64::new(v[0].as_f64().unwrap(),v[1].as_f64().unwrap())).collect()} + +#[test] +fn guarded_frozen_callbacks_match_all_480_oracle_components(){ + let inputs:Vec=serde_json::from_slice(&fs::read(doc().join("inputs.json")).unwrap()).unwrap(); + let refs:Vec=serde_json::from_slice(&fs::read(doc().join("expansion-results.json")).unwrap()).unwrap(); + let mut count=0; + for(v,r)in inputs.iter().zip(refs){ + let rank=v["rank"].as_u64().unwrap()as usize; + let mut t=GuardedTensor::new(rank,1);t.coefficients_mut().copy_from_slice(&pairs(&v["coefficients"])); + for cb in r["results"][0]["callbacks"].as_array().unwrap().iter().filter(|r|r["kind"]=="t3"){ + let i=&cb["inputs"];let p=pairs(&i["param"]);let mut out=Vec::new(); + for row in 0..p.len(){ + out.extend(expand(&mut t,2,pairs(&i["a"][row]).try_into().unwrap(), + pairs(&i["e3"][row]).try_into().unwrap(),pairs(&i["e4"][row]).try_into().unwrap(),p[row])); + } + assert_eq!(bits(&out),bits(&pairs(&cb["high_rounded"]))); + count+=out.len()*2; + } + assert_eq!(t.fallback,0); + } + assert_eq!(count,480); +} + +fn next(seed:&mut u64)->f64{ + *seed=seed.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407); + (f64::from_bits(0x3ff0_0000_0000_0000|(*seed>>12))-1.)*2.-1. +} +fn random(seed:&mut u64)->C64{C64::new(next(seed),next(seed))} +#[test] +fn guarded_ranks_layouts_dense_sparse_and_cancellation_oracle(){ + let mut seed=0x51f4_99a7_a21c_003du64; + let mut rows=vec![]; + for rank in 0..=8 { + // Same retained tensor repeatedly receives completely new coefficients. + let mut guarded=GuardedTensor::new(rank,1); + let mut native=TensorNumerator::new(rank,1); + for pattern in 0..4 { + let mut coeff:Vec<_>=(0..ncoeff(rank)).map(|_|random(&mut seed)).collect(); + let mut a=std::array::from_fn(|_|random(&mut seed)); + let mut e=std::array::from_fn(|_|random(&mut seed)); + let mut f=std::array::from_fn(|_|random(&mut seed)); + let mut p=random(&mut seed); + match pattern { + 1=>{for(i,c)in coeff.iter_mut().enumerate(){if i%7!=0{*c=C64::ZERO;}}}, + 2=>{ // All-integer dyadic case: independent exact arithmetic oracle. + for c in &mut coeff {c.re=(c.re*3.).round();c.im=(c.im*3.).round();} + for x in a.iter_mut().chain(&mut e).chain(&mut f){x.re=x.re.round();x.im=x.im.round();} + p=C64::new(1.,-1.); + }, + 3 if rank>=2=>{ + coeff.fill(C64::ZERO); + let off=ninjars::fast::tensor_layout::block_offset(rank); + coeff[off]=C64::real(1e16);coeff[off+1]=C64::real(1.); + coeff[off+2]=C64::real(-1e16); + a=[C64::real(1.);4];e=a;f=a;p=C64::real(1.); + }, + _=>{} + } + guarded.coefficients_mut().copy_from_slice(&coeff); + native.coefficients_mut().copy_from_slice(&coeff); + let mut high=wide(rank,&coeff); + for k in 0..=5 { + let out=expand(&mut guarded,k,a,e,f,p); + let old=expand(&mut native,k,a,e,f,p); + let reference=expand(&mut high,k,a,e,f,p); + if k!=2 || rank<2 { assert_eq!(bits(&out),bits(&old),"fallback rank={rank} k={k}"); } + let mut exact=0;let mut better=0;let mut worse=0;let mut worst=0f64; + for((o,n),h)in out.iter().zip(&old).zip(&reference){ + for(x,y,z)in [(o.re,n.re,h.re),(o.im,n.im,h.im)]{ + assert!(x.is_finite()); + exact+=usize::from(x.to_bits()==z.to_bits()); + better+=usize::from((x-z).abs()<(y-z).abs()); + worse+=usize::from((x-z).abs()>(y-z).abs()); + worst=worst.max((x-z).abs()); + } + } + if pattern==2 {assert_eq!(bits(&out),bits(&reference),"integer case rank={rank} k={k}");} + if pattern==3 && rank>=2 && k==2 { + assert_eq!(bits(&out),bits(&reference),"adversarial rank={rank}"); + } + rows.push(json!({"rank":rank,"pattern":pattern,"mindeg":k, + "components":out.len()*2,"exact":exact,"better":better,"worse":worse, + "max_absolute_error":worst, + "corrected_domain":rank>=2&&k==2})); + } + } + } + assert_eq!(rows.len(),9*4*6); + assert!(rows.iter().filter(|r|r["corrected_domain"]==true).all(|r|r["worse"]==0)); +} + +#[cfg(feature="fenv-test-support")] +unsafe extern "C" { + fn ninjars_t3_flags()->i32; + fn ninjars_t3_clear_flags()->i32; + fn ninjars_t3_bad_flags()->i32; + fn ninjars_t3_round_upward()->i32; + fn ninjars_t3_round_nearest()->i32; + fn ninjars_t3_raise_inexact()->i32; +} +#[cfg(feature="fenv-test-support")] +#[test] +fn guarded_unsafe_domains_and_rounding_use_native_flags_and_values(){ + let mut g=GuardedTensor::new(3,1);let mut n=TensorNumerator::new(3,1); + for (value,vector) in [(f64::INFINITY,2.),(f64::NAN,2.),(f64::MAX,2.), + (f64::from_bits(1),2.),(1e-250,2.),(1e250,2.),(-0.,2.), + // Finite normal inputs whose *intermediate* products under/overflow. + (0.25,1e-200),(0.25,1e200),(1e-250,1e-150)] { + let v=[C64::real(vector);4]; + let mut coeff=vec![C64::real(0.25);ncoeff(3)];coeff[2]=C64::real(value); + g.coefficients_mut().copy_from_slice(&coeff);n.coefficients_mut().copy_from_slice(&coeff); + unsafe{ninjars_t3_clear_flags();ninjars_t3_raise_inexact();} + let old=expand(&mut n,2,v,v,v,C64::real(2.));let old_flags=unsafe{ninjars_t3_flags()}; + unsafe{ninjars_t3_clear_flags();ninjars_t3_raise_inexact();} + let actual=expand(&mut g,2,v,v,v,C64::real(2.));let flags=unsafe{ninjars_t3_flags()}; + assert_eq!(bits(&actual),bits(&old),"value {value}"); + assert_eq!(flags,old_flags); + } + // Directed rounding is not supported by compensated error-free transforms. + let v=[C64::real(2.);4]; + g.coefficients_mut().fill(C64::real(0.25)); + n.coefficients_mut().fill(C64::real(0.25)); + unsafe{assert_eq!(ninjars_t3_round_upward(),0);} + let before=g.corrected; + let actual=expand(&mut g,2,v,v,v,C64::real(2.)); + let old=expand(&mut n,2,v,v,v,C64::real(2.)); + unsafe{assert_eq!(ninjars_t3_round_nearest(),0);} + assert_eq!(g.corrected,before);assert_eq!(bits(&actual),bits(&old)); + unsafe{ninjars_t3_clear_flags();} + expand(&mut g,2,v,v,v,C64::real(2.)); + assert_eq!(unsafe{ninjars_t3_bad_flags()},0); +} + +#[test] +fn guarded_preserves_non_t3_and_explicit_mu_abi_rejection(){ + let rank=4;let mut g=GuardedTensor::new(rank,1);let mut n=TensorNumerator::new(rank,1); + let c:Vec<_>=(0..ncoeff(rank)).map(|i|C64::new(i as f64/17.,-(i as f64)/31.)).collect(); + g.coefficients_mut().copy_from_slice(&c);n.coefficients_mut().copy_from_slice(&c); + let a=[C64::new(0.25,-0.125);4];let b=[C64::new(0.5,0.25);4]; + for k in 0..=3 { + let width=[1,3,7,13][k];let mut x=vec![C64::ZERO;width];let mut y=x.clone(); + g.t2_expansion(&[],&[0],&[a],&[b],&[a],&[b],&[[C64::real(1.);3]],k,&mut x).unwrap(); + n.t2_expansion(&[],&[0],&[a],&[b],&[a],&[b],&[[C64::real(1.);3]],k,&mut y).unwrap(); + assert_eq!(bits(&x),bits(&y)); + } + for width in 1..=3 { + let mut x=vec![C64::ZERO;width];let mut y=x.clone(); + if width==3 { + g.mu_expansion_x2(&[],&[0],&[a],&[b],&[C64::real(1.)],&mut x).unwrap(); + n.mu_expansion_x2(&[],&[0],&[a],&[b],&[C64::real(1.)],&mut y).unwrap(); + } else { + let bs=[b];let opt=(width==2).then_some(bs.as_slice()); + g.mu_expansion(&[],&[0],&[a],opt,&mut x).unwrap(); + n.mu_expansion(&[],&[0],&[a],opt,&mut y).unwrap(); + } + assert_eq!(bits(&x),bits(&y)); + } + let mut x=[C64::ZERO];let mut y=x; + g.evaluate(&[],&[0],&[a],&[C64::real(29.)],&mut x).unwrap(); + n.evaluate(&[],&[0],&[a],&[C64::real(29.)],&mut y).unwrap(); + assert_eq!(bits(&x),bits(&y)); + // Existing public ABI has exactly ncoeff(rank) N(q) coefficients. Extra + // explicit-mu blocks are rejected, never interpreted as N(q) coefficients. + assert!(super::dimensions(4,rank as i32,ncoeff(rank)+ncoeff(rank-2)).is_err()); + assert_eq!(g.corrected,0); +} diff --git a/vendor/ninjars/src/lib.rs b/vendor/ninjars/src/lib.rs new file mode 100644 index 0000000000..f6b79036f1 --- /dev/null +++ b/vendor/ninjars/src/lib.rs @@ -0,0 +1,1787 @@ +//! MadLoop's dimensioned C ABI for the pinned NinjaRS reduction engines. +//! +//! Combined-pole DP uses the binary64 fast engine directly. UV/IR selection +//! retains scaleless-bubble coefficients through the generic binary64 engine. +//! MP input records contain actual Fortran binary128 values; reduction uses +//! 256-bit Float. Generic kernels share one retained worker with the stack +//! required by Symbolica expression construction. + +mod guarded; +#[cfg(test)] +mod pole_bridge_tests; +mod poles; +mod tensor; + +use poles::PoleSelection; + +use ninjars::{ + Amplitude, AmplitudeInput, Complex, EvaluationStatus, Float, FloatLike, FourMomentum, Real, + SingleFloat, + fast::{C64, FastAmplitude, FastInput, FastOptions, FastResult, FastStatus, TensorNumerator}, +}; +use ninjars_symbolica::{ + OneLoopNativeMasters, SymbolicaAmplitudeKernels, SymbolicaCuts, SymbolicaHighCuts, + SymbolicaMasters, +}; +use std::{ + cell::RefCell, + collections::HashMap, + panic::{AssertUnwindSafe, catch_unwind}, + slice, + sync::{Mutex, mpsc}, +}; +use tensor::TensorGenericNumerator; + +const SUCCESS: i32 = 0; +const UNSTABLE: i32 = 1; +const ERROR: i32 = 2; +const RECORD: usize = 64; +const MP_BITS: u32 = 256; +const ABI_VERSION: u32 = 4; +type Result = std::result::Result; +type Z = Complex; +type MpAmplitude = Amplitude>; + +thread_local! { + static LAST_ERROR: RefCell = const { RefCell::new(String::new()) }; +} + +/// Opaque caller-owned context. Destroy only after all evaluations have returned. +pub struct Context { + dp: Mutex>, + mp: Mutex>, + compensated_dp: Mutex>, +} + +#[unsafe(no_mangle)] +pub extern "C" fn ninjars_abi_version() -> u32 { + ABI_VERSION +} + +/// Create an independent retained context using the requested ABI version. +/// # Safety +/// `output` is a writable pointer slot. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn ninjars_context_create(version: u32, output: *mut *mut Context) -> i32 { + guard(|| { + validate_output(output, 1)?; + if version != ABI_VERSION { + return Err(format!("unsupported NinjaRS ABI version {version}")); + } + let context = Box::new(Context { + dp: Mutex::new(None), + mp: Mutex::new(None), + compensated_dp: Mutex::new(None), + }); + unsafe { + output.write(Box::into_raw(context)); + } + Ok(SUCCESS) + }) +} + +/// Free a context's state; the last MP context joins the shared rescue worker. +/// NULL is a no-op. +/// # Safety +/// `context` is NULL or a live handle returned by create, with no active calls. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn ninjars_context_destroy(context: *mut Context) -> i32 { + guard(|| { + if !context.is_null() { + if !context.is_aligned() { + return Err("misaligned context".into()); + } + unsafe { + drop(Box::from_raw(context)); + } + } + Ok(SUCCESS) + }) +} + +unsafe fn context<'a>(ptr: *mut Context) -> Result<&'a Context> { + if ptr.is_null() || !ptr.is_aligned() { + return Err("invalid context".into()); + } + // The caller guarantees the context remains live until the call returns. + Ok(unsafe { &*ptr }) +} + +fn guard(f: impl FnOnce() -> Result) -> i32 { + let (status, message) = match catch_unwind(AssertUnwindSafe(f)) { + Ok(Ok(status)) => (status, String::new()), + Ok(Err(message)) => (ERROR, message), + Err(_) => (ERROR, "NinjaRS panic contained at the C boundary".into()), + }; + LAST_ERROR.with(|slot| *slot.borrow_mut() = message); + status +} + +fn dimensions(n: i32, rank: i32, count: usize) -> Result<(usize, usize)> { + if n < 1 || rank < 0 || rank > n.saturating_add(2) { + return Err(format!( + "unsupported topology: n={n}, rank={rank} (require 0<=rank<=n+2)" + )); + } + let (n, rank) = (n as usize, rank as usize); + // Check dimensions before either constructing slices or allocating tensors. + let expected = (1..=4) + .try_fold(1usize, |v, k| v.checked_mul(rank + k)) + .ok_or("tensor dimension overflow")? + / 24; + n.checked_mul(n) + .and_then(|v| v.checked_mul(RECORD)) + .ok_or("kinematic dimension overflow")?; + if expected != count { + return Err(format!("tensor length {count}, expected {expected}")); + } + Ok((n, rank)) +} + +fn length(label: &str, actual: usize, expected: usize) -> Result<()> { + if actual != expected { + return Err(format!("{label} length {actual}, expected {expected}")); + } + Ok(()) +} + +unsafe fn read<'a, T>(ptr: *const T, len: usize) -> Result<&'a [T]> { + if len == 0 { + return Ok(&[]); + } + if ptr.is_null() || !ptr.is_aligned() || len > isize::MAX as usize / size_of::() { + return Err("invalid input pointer or length".into()); + } + // The C caller owns readable, aligned storage for the documented length. + Ok(unsafe { slice::from_raw_parts(ptr, len) }) +} + +fn validate_output(ptr: *mut T, count: usize) -> Result> { + let bytes = count + .checked_mul(size_of::()) + .ok_or("output size overflow")?; + if ptr.is_null() || !ptr.is_aligned() || bytes > isize::MAX as usize { + return Err("invalid output pointer".into()); + } + let start = ptr as usize; + let end = start.checked_add(bytes).ok_or("output pointer overflow")?; + Ok(start..end) +} + +unsafe fn write(ptr: *mut T, values: &[T]) -> Result<()> { + validate_output(ptr, values.len())?; + // The C caller owns disjoint writable storage for the documented length. + unsafe { slice::from_raw_parts_mut(ptr, values.len()) }.copy_from_slice(values); + Ok(()) +} + +struct DpEntry { + amplitude: FastAmplitude, + tensor: TensorNumerator, + shifts: Vec<[f64; 4]>, +} +struct DpState { + entries: HashMap<(usize, usize), DpEntry>, + masters: OneLoopNativeMasters, +} +impl DpState { + fn new() -> Result { + Ok(Self { + entries: HashMap::new(), + masters: OneLoopNativeMasters::new().map_err(|e| e.to_string())?, + }) + } + fn evaluate( + &mut self, + n: usize, + rank: usize, + coeff: &[C64], + s: &[f64], + p: &[f64], + m: &[C64], + mu2: f64, + ) -> Result<(i32, FastResult)> { + if !mu2.is_finite() + || mu2 <= 0. + || p.iter().chain(s).any(|v| !v.is_finite()) + || coeff.iter().any(|v| !v.is_finite()) + || m.iter().any(|v| !v.is_finite() || v.im > 0.) + { + return Err("nonfinite input, invalid mass width, or nonpositive squared scale".into()); + } + if !self.entries.contains_key(&(n, rank)) { + self.entries.insert( + (n, rank), + DpEntry { + amplitude: FastAmplitude::new(n, rank, FastOptions::default()) + .map_err(|e| e.to_string())?, + tensor: TensorNumerator::new(rank, 1), + shifts: vec![[0.; 4]; n], + }, + ); + } + let state = self.entries.get_mut(&(n, rank)).unwrap(); + state.tensor.coefficients_mut().copy_from_slice(coeff); + for (v, values) in state.shifts.iter_mut().zip(p.chunks_exact(4)) { + v.copy_from_slice(values); + } + let mut result = [FastResult::default()]; + let mut status = [FastStatus::NotEvaluated]; + state + .amplitude + .evaluate( + &FastInput { + lanes: 1, + shifts: &state.shifts, + masses_squared: m, + scales_squared: &[mu2], + s_matrix: Some(s), + }, + &mut state.tensor, + &mut self.masters, + &mut result, + &mut status, + ) + .map_err(|e| e.to_string())?; + Ok(( + if status[0] == FastStatus::Success { + SUCCESS + } else { + UNSTABLE + }, + result[0], + )) + } +} + +struct CompensatedDpEntry { + amplitude: FastAmplitude, + tensor: guarded::GuardedTensor, + shifts: Vec<[f64; 4]>, +} +struct CompensatedDpState { + entries: HashMap<(usize, usize), CompensatedDpEntry>, + masters: OneLoopNativeMasters, +} +impl CompensatedDpState { + fn new() -> Result { + Ok(Self { + entries: HashMap::new(), + masters: OneLoopNativeMasters::new().map_err(|e| e.to_string())?, + }) + } + fn evaluate( + &mut self, + n: usize, + rank: usize, + coeff: &[C64], + s: &[f64], + p: &[f64], + m: &[C64], + mu2: f64, + ) -> Result<(i32, FastResult)> { + if !mu2.is_finite() + || mu2 <= 0. + || p.iter().chain(s).any(|v| !v.is_finite()) + || coeff.iter().any(|v| !v.is_finite()) + || m.iter().any(|v| !v.is_finite() || v.im > 0.) + { + return Err("nonfinite input, invalid mass width, or nonpositive squared scale".into()); + } + if !self.entries.contains_key(&(n, rank)) { + self.entries.insert( + (n, rank), + CompensatedDpEntry { + amplitude: FastAmplitude::new(n, rank, FastOptions::default()) + .map_err(|e| e.to_string())?, + tensor: guarded::GuardedTensor::new(rank, 1), + shifts: vec![[0.; 4]; n], + }, + ); + } + let state = self.entries.get_mut(&(n, rank)).unwrap(); + state.tensor.coefficients_mut().copy_from_slice(coeff); + for (v, values) in state.shifts.iter_mut().zip(p.chunks_exact(4)) { + v.copy_from_slice(values); + } + let mut result = [FastResult::default()]; + let mut status = [FastStatus::NotEvaluated]; + state + .amplitude + .evaluate( + &FastInput { + lanes: 1, + shifts: &state.shifts, + masses_squared: m, + scales_squared: &[mu2], + s_matrix: Some(s), + }, + &mut state.tensor, + &mut self.masters, + &mut result, + &mut status, + ) + .map_err(|e| e.to_string())?; + Ok(( + if status[0] == FastStatus::Success { + SUCCESS + } else { + UNSTABLE + }, + result[0], + )) + } +} + +/// Evaluate one DP numerator. Output is committed only on success. +/// +/// # Safety +/// Buffers have the dimensions in ninjars.h and are valid/disjoint for this call. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn ninjars_evaluate_dp( + handle: *mut Context, + n: i32, + rank: i32, + count: usize, + coefficients: *const C64, + s_matrix: *const f64, + s_length: usize, + momenta: *const f64, + p_length: usize, + masses: *const C64, + m_length: usize, + scale_squared: f64, + laurent: *mut C64, + laurent_length: usize, + rational: *mut C64, + rational_length: usize, +) -> i32 { + unsafe { + ninjars_evaluate_dp_with_poles( + handle, + n, + rank, + count, + coefficients, + s_matrix, + s_length, + momenta, + p_length, + masses, + m_length, + scale_squared, + laurent, + laurent_length, + rational, + rational_length, + 0, + ) + } +} + +/// Evaluate with an explicit pole mode: 0 combined, 1 UV, 2 IR, 3 none. +/// +/// # Safety +/// The buffer contract is identical to the corresponding combined-pole entry point. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn ninjars_evaluate_dp_with_poles( + handle: *mut Context, + n: i32, + rank: i32, + count: usize, + coefficients: *const C64, + s_matrix: *const f64, + s_length: usize, + momenta: *const f64, + p_length: usize, + masses: *const C64, + m_length: usize, + scale_squared: f64, + laurent: *mut C64, + laurent_length: usize, + rational: *mut C64, + rational_length: usize, + pole_mode: i32, +) -> i32 { + guard(|| { + let selection = poles::from_mode(pole_mode)?; + let (n, rank) = dimensions(n, rank, count)?; + length("S matrix", s_length, n * n)?; + length("momenta", p_length, n * 4)?; + length("masses", m_length, n)?; + length("Laurent output", laurent_length, 3)?; + length("rational output", rational_length, 1)?; + let a = validate_output(laurent, 3)?; + let b = validate_output(rational, 1)?; + if a.start < b.end && b.start < a.end { + return Err("overlapping output buffers".into()); + } + let context = unsafe { context(handle) }?; + let coeff = unsafe { read(coefficients, count) }?; + let s = unsafe { read(s_matrix, n * n) }?; + let p = unsafe { read(momenta, n * 4) }?; + let m = unsafe { read(masses, n) }?; + let (status, mut result) = if selection == PoleSelection::UV + || selection == PoleSelection::IR + { + evaluate_selected_dp(context, n, rank, coeff, s, p, m, scale_squared, selection)? + } else { + let mut state = context.dp.lock().map_err(|_| "DP context poisoned")?; + if state.is_none() { + *state = Some(DpState::new()?); + } + let value = state + .as_mut() + .unwrap() + .evaluate(n, rank, coeff, s, p, m, scale_squared)?; + value + }; + if selection == PoleSelection::NONE { + result.laurent[1] = C64::real(0.); + result.laurent[2] = C64::real(0.); + } + if status == SUCCESS { + unsafe { + write(laurent, &result.laurent)?; + write(rational, &[result.rational])?; + } + } + Ok(status) + }) +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn ninjars_evaluate_dp_compensated( + handle: *mut Context, + n: i32, + rank: i32, + count: usize, + coefficients: *const C64, + s_matrix: *const f64, + s_length: usize, + momenta: *const f64, + p_length: usize, + masses: *const C64, + m_length: usize, + scale_squared: f64, + laurent: *mut C64, + laurent_length: usize, + rational: *mut C64, + rational_length: usize, +) -> i32 { + unsafe { + ninjars_evaluate_dp_compensated_with_poles( + handle, + n, + rank, + count, + coefficients, + s_matrix, + s_length, + momenta, + p_length, + masses, + m_length, + scale_squared, + laurent, + laurent_length, + rational, + rational_length, + 0, + ) + } +} + +/// Evaluate with an explicit pole mode: 0 combined, 1 UV, 2 IR, 3 none. +/// +/// # Safety +/// The buffer contract is identical to the corresponding combined-pole entry point. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn ninjars_evaluate_dp_compensated_with_poles( + handle: *mut Context, + n: i32, + rank: i32, + count: usize, + coefficients: *const C64, + s_matrix: *const f64, + s_length: usize, + momenta: *const f64, + p_length: usize, + masses: *const C64, + m_length: usize, + scale_squared: f64, + laurent: *mut C64, + laurent_length: usize, + rational: *mut C64, + rational_length: usize, + pole_mode: i32, +) -> i32 { + guard(|| { + let selection = poles::from_mode(pole_mode)?; + let (n, rank) = dimensions(n, rank, count)?; + length("S matrix", s_length, n * n)?; + length("momenta", p_length, n * 4)?; + length("masses", m_length, n)?; + length("Laurent output", laurent_length, 3)?; + length("rational output", rational_length, 1)?; + let a = validate_output(laurent, 3)?; + let b = validate_output(rational, 1)?; + if a.start < b.end && b.start < a.end { + return Err("overlapping output buffers".into()); + } + let context = unsafe { context(handle) }?; + let coeff = unsafe { read(coefficients, count) }?; + let s = unsafe { read(s_matrix, n * n) }?; + let p = unsafe { read(momenta, n * 4) }?; + let m = unsafe { read(masses, n) }?; + let (status, mut result) = if selection == PoleSelection::UV + || selection == PoleSelection::IR + { + evaluate_selected_dp(context, n, rank, coeff, s, p, m, scale_squared, selection)? + } else { + let mut state = context + .compensated_dp + .lock() + .map_err(|_| "DP context poisoned")?; + if state.is_none() { + *state = Some(CompensatedDpState::new()?); + } + let value = state + .as_mut() + .unwrap() + .evaluate(n, rank, coeff, s, p, m, scale_squared)?; + value + }; + if selection == PoleSelection::NONE { + result.laurent[1] = C64::real(0.); + result.laurent[2] = C64::real(0.); + } + if status == SUCCESS { + unsafe { + write(laurent, &result.laurent)?; + write(rational, &[result.rational])?; + } + } + Ok(status) + }) +} + +#[cfg(test)] +fn parse_record(text: &[u8]) -> Result { + parse_record_at_precision(text, MP_BITS) +} +fn parse_record_at_precision(text: &[u8], precision: u32) -> Result { + let text = std::str::from_utf8(text) + .map_err(|_| "MP input is not ASCII")? + .trim(); + let mut input = Float::parse(text, Some(113)).map_err(|e| format!("invalid MP value: {e}"))?; + if !input.is_finite() { + return Err("nonfinite MP input".into()); + } + // Forty significant decimal digits round-trip binary128. First recover that + // value at 113 bits, then widen the represented value itself. A rational + // round-trip would discard the sign of zero, which selects complex branch lips. + input.set_prec(precision); + Ok(input) +} +fn parse_records(data: &[u8], precision: u32) -> Result> { + data.chunks_exact(RECORD) + .map(|record| parse_record_at_precision(record, precision)) + .collect() +} +fn pairs(values: Vec) -> Vec { + let mut values = values.into_iter(); + let mut out = Vec::with_capacity(values.len() / 2); + while let Some(re) = values.next() { + out.push(Complex::new(re, values.next().unwrap())); + } + out +} +fn real(value: Float) -> Z { + let imaginary = value.zero(); + Complex::new(value, imaginary) +} + +struct MpEntry { + amplitude: MpAmplitude, + tensor: TensorGenericNumerator, +} +struct MpState { + precision: u32, + entries: HashMap<(usize, usize), MpEntry>, + low: SymbolicaCuts, + high: SymbolicaHighCuts, + masters: SymbolicaMasters, +} +impl MpState { + fn new() -> Result { + Self::with_precision(MP_BITS) + } + fn with_precision(precision: u32) -> Result { + let prototype = Float::new(precision); + // Original Ninja QP uses 1e15 * machine epsilon; independent of the + // dimensionless MadLoop OSThres already applied to the input S-matrix. + let two = Float::with_val(precision, 2); + let threshold = Float::with_val(precision, 1_000_000_000_000_000i64) / two.pow(112); + Ok(Self { + precision, + entries: HashMap::new(), + low: SymbolicaCuts::new(prototype.clone()).map_err(|e| e.to_string())?, + high: SymbolicaHighCuts::new(prototype.clone()).map_err(|e| e.to_string())?, + masters: SymbolicaMasters::new(prototype).with_onshell_threshold(Some(threshold)), + }) + } + fn evaluate(&mut self, request: &MpRequest) -> Result<(i32, Vec)> { + self.masters.set_pole_selection(request.selection); + let precision = self.precision; + let n = request.n; + let rank = request.rank; + let coeff = pairs(parse_records(&request.coefficients, precision)?); + let shifts: Vec<_> = parse_records(&request.momenta, precision)? + .chunks_exact(4) + .map(|v| FourMomentum::from(std::array::from_fn(|k| real(v[k].clone())))) + .collect(); + let masses = pairs(parse_records(&request.masses, precision)?); + let smat: Vec<_> = parse_records(&request.s_matrix, precision)? + .into_iter() + .map(real) + .collect(); + let scale = parse_record_at_precision(&request.scale, precision)?; + if scale <= Float::new(precision) || masses.iter().any(|m| m.im > m.im.zero()) { + return Err("invalid MP squared scale or mass width".into()); + } + if !self.entries.contains_key(&(n, rank)) { + let prototype = Float::new(precision); + let kernels = SymbolicaAmplitudeKernels::new(n, rank, prototype.clone()) + .map_err(|e| e.to_string())?; + self.entries.insert( + (n, rank), + MpEntry { + amplitude: kernels.into_amplitude(1).map_err(|e| e.to_string())?, + tensor: TensorGenericNumerator::new(rank, 0, &prototype) + .map_err(|e| e.to_string())?, + }, + ); + } + let entry = self.entries.get_mut(&(n, rank)).unwrap(); + entry + .tensor + .set_coefficients(coeff, 1) + .map_err(|e| e.to_string())?; + entry.amplitude.reset_batch(1); + let scales = [real(scale)]; + // Match NinjaRS's generic tensor harness/Ninja auxiliary box scale, + // keeping the comparison and values in the rescue precision. + let sampling_scale = smat + .iter() + .chain(&masses) + .map(|value| value.re.norm()) + .fold(Float::with_val(precision, 1), |largest, value| { + if value > largest { value } else { largest } + }); + let sampling = [real(sampling_scale)]; + entry + .amplitude + .evaluate_batch_with_inputs( + AmplitudeInput { + shifts: &shifts, + masses_squared: &masses, + scales_squared: &scales, + sampling_scales: &sampling, + s_matrix: Some(&smat), + }, + &mut entry.tensor, + &mut self.low, + &mut self.high, + &mut self.masters, + ) + .map_err(|e| e.to_string())?; + if entry.amplitude.statuses()[0] != EvaluationStatus::Success { + return Ok((UNSTABLE, Vec::new())); + } + let result = &entry.amplitude.results()[0]; + let mut output = vec![b' '; 8 * RECORD]; + for (index, value) in [0, 1, 2, 4] + .into_iter() + .flat_map(|k| [&result[k].re, &result[k].im]) + .enumerate() + { + if !value.is_finite() { + return Ok((UNSTABLE, Vec::new())); + } + let text = format!("{value:.39e}"); + if text.len() > RECORD { + return Err("MP output exceeds ABI record width".into()); + } + output[index * RECORD..index * RECORD + text.len()].copy_from_slice(text.as_bytes()); + } + Ok((SUCCESS, output)) + } +} + +// Selected-pole DP needs the generic engine: its bubble coefficients survive +// even when the combined scaleless master vanishes. Keep its Symbolica kernels +// on the same worker as MP, but use actual binary64 arithmetic and independent +// cached plans. The ordinary fast path does not enter this worker. +struct SelectedDpEntry { + amplitude: Amplitude, SymbolicaAmplitudeKernels>, + tensor: TensorGenericNumerator, +} +struct SelectedDpState { + entries: HashMap<(usize, usize), SelectedDpEntry>, + low: SymbolicaCuts, + high: SymbolicaHighCuts, + masters: SymbolicaMasters, +} +struct SelectedDpRequest { + context_id: u64, + n: usize, + rank: usize, + selection: PoleSelection, + coefficients: Vec, + s_matrix: Vec, + momenta: Vec, + masses: Vec, + scale: f64, + reply: mpsc::SyncSender>, +} +impl SelectedDpState { + fn new() -> Result { + Ok(Self { + entries: HashMap::new(), + low: SymbolicaCuts::new(0.).map_err(|e| e.to_string())?, + high: SymbolicaHighCuts::new(0.).map_err(|e| e.to_string())?, + // Match OneLoopNativeMasters' default absolute threshold. + masters: SymbolicaMasters::new(0.), + }) + } + fn evaluate(&mut self, request: &SelectedDpRequest) -> Result<(i32, FastResult)> { + let n = request.n; + let rank = request.rank; + self.masters.set_pole_selection(request.selection); + if !self.entries.contains_key(&(n, rank)) { + let kernels = SymbolicaAmplitudeKernels::new(n, rank, 0.).map_err(|e| e.to_string())?; + self.entries.insert( + (n, rank), + SelectedDpEntry { + amplitude: kernels.into_amplitude(1).map_err(|e| e.to_string())?, + tensor: TensorGenericNumerator::new(rank, 0, &0.).map_err(|e| e.to_string())?, + }, + ); + } + let entry = self.entries.get_mut(&(n, rank)).unwrap(); + entry + .tensor + .set_coefficients( + request + .coefficients + .iter() + .map(|v| Complex::new(v.re, v.im)) + .collect(), + 1, + ) + .map_err(|e| e.to_string())?; + entry.amplitude.reset_batch(1); + let real = |v: f64| Complex::new(v, 0.); + let shifts: Vec<_> = request + .momenta + .chunks_exact(4) + .map(|v| FourMomentum::from(std::array::from_fn(|k| real(v[k])))) + .collect(); + let masses: Vec<_> = request + .masses + .iter() + .map(|v| Complex::new(v.re, v.im)) + .collect(); + let smat: Vec<_> = request.s_matrix.iter().map(|v| real(*v)).collect(); + let scales = [real(request.scale)]; + let sampling = [real( + request + .s_matrix + .iter() + .copied() + .chain(request.masses.iter().map(|v| v.re)) + .map(f64::abs) + .fold(1., f64::max), + )]; + entry + .amplitude + .evaluate_batch_with_inputs( + AmplitudeInput { + shifts: &shifts, + masses_squared: &masses, + scales_squared: &scales, + sampling_scales: &sampling, + s_matrix: Some(&smat), + }, + &mut entry.tensor, + &mut self.low, + &mut self.high, + &mut self.masters, + ) + .map_err(|e| e.to_string())?; + if entry.amplitude.statuses()[0] != EvaluationStatus::Success { + return Ok((UNSTABLE, FastResult::default())); + } + let values = &entry.amplitude.results()[0]; + if [0, 1, 2, 4] + .iter() + .any(|&k| !values[k].re.is_finite() || !values[k].im.is_finite()) + { + return Ok((UNSTABLE, FastResult::default())); + } + Ok(( + SUCCESS, + FastResult { + laurent: std::array::from_fn(|k| C64::new(values[k].re, values[k].im)), + cut_constructible: C64::new(values[3].re, values[3].im), + rational: C64::new(values[4].re, values[4].im), + }, + )) + } +} +fn evaluate_selected_dp( + context: &Context, + n: usize, + rank: usize, + coeff: &[C64], + s: &[f64], + p: &[f64], + m: &[C64], + scale: f64, + selection: PoleSelection, +) -> Result<(i32, FastResult)> { + if !scale.is_finite() + || scale <= 0. + || p.iter().chain(s).any(|v| !v.is_finite()) + || coeff.iter().any(|v| !v.is_finite()) + || m.iter().any(|v| !v.is_finite() || v.im > 0.) + { + return Err("nonfinite input, invalid mass width, or nonpositive squared scale".into()); + } + let (reply, receive) = mpsc::sync_channel(1); + let mut worker = context.mp.lock().map_err(|_| "MP context poisoned")?; + if worker.is_none() { + *worker = Some(MpContext::new()?); + } + let worker = worker.as_ref().unwrap(); + worker + .sender + .send(MpMessage::EvaluateDp(SelectedDpRequest { + context_id: worker.id, + n, + rank, + selection, + coefficients: coeff.to_vec(), + s_matrix: s.to_vec(), + momenta: p.to_vec(), + masses: m.to_vec(), + scale, + reply, + })) + .map_err(|_| "rescue worker disconnected")?; + receive.recv().map_err(|_| "rescue worker disconnected")? +} + +struct MpRequest { + context_id: u64, + selection: PoleSelection, + n: usize, + rank: usize, + coefficients: Vec, + s_matrix: Vec, + momenta: Vec, + masses: Vec, + scale: Vec, + reply: mpsc::SyncSender)>>, +} +// Symbolica's restricted license grants one active thread per user. Route all +// contexts through one process worker, retaining independent numerical state +// for each context. The last context's destroy joins and releases the worker. +struct MpContext { + id: u64, + sender: mpsc::Sender, +} +enum MpMessage { + Evaluate(MpRequest), + EvaluateDp(SelectedDpRequest), + Remove(u64, mpsc::SyncSender<()>), + Shutdown, +} +struct MpWorker { + sender: mpsc::Sender, + thread: Option>, +} +struct MpManager { + worker: Option, + users: usize, + next_id: u64, +} +static MP_MANAGER: Mutex = Mutex::new(MpManager { + worker: None, + users: 0, + next_id: 0, +}); +impl MpContext { + fn new() -> Result { + let mut manager = MP_MANAGER.lock().map_err(|_| "MP manager poisoned")?; + let id = manager.next_id; + manager.next_id = id.checked_add(1).ok_or("MP context ID overflow")?; + if manager.worker.is_none() { + manager.worker = Some(MpWorker::new()?); + } + manager.users += 1; + Ok(Self { + id, + sender: manager.worker.as_ref().unwrap().sender.clone(), + }) + } +} +impl Drop for MpContext { + fn drop(&mut self) { + let mut manager = MP_MANAGER.lock().unwrap_or_else(|e| e.into_inner()); + let (reply, receive) = mpsc::sync_channel(1); + if self.sender.send(MpMessage::Remove(self.id, reply)).is_ok() { + let _ = receive.recv(); + } + manager.users -= 1; + if manager.users == 0 { + // Hold the manager lock through join so another creation cannot + // start a second worker before this one's license permit is freed. + drop(manager.worker.take()); + } + } +} +impl Drop for MpWorker { + fn drop(&mut self) { + let _ = self.sender.send(MpMessage::Shutdown); + if let Some(thread) = self.thread.take() { + let _ = thread.join(); + } + } +} +impl MpWorker { + fn new() -> Result { + let (send, recv) = mpsc::channel::(); + let thread = std::thread::Builder::new() + .name("madloop-ninjars-mp".into()) + .stack_size(128 * 1024 * 1024) + .spawn(move || { + let mut states = HashMap::new(); + let mut dp_states = HashMap::new(); + while let Ok(message) = recv.recv() { + match message { + MpMessage::Evaluate(request) => { + let result = catch_unwind(AssertUnwindSafe(|| { + if !states.contains_key(&request.context_id) { + states.insert(request.context_id, MpState::new()?); + } + states + .get_mut(&request.context_id) + .unwrap() + .evaluate(&request) + })) + .unwrap_or_else(|_| { + states.remove(&request.context_id); + Err("NinjaRS MP panic contained in rescue worker".into()) + }); + let _ = request.reply.send(result); + } + MpMessage::EvaluateDp(request) => { + let result = catch_unwind(AssertUnwindSafe(|| { + if !dp_states.contains_key(&request.context_id) { + dp_states.insert(request.context_id, SelectedDpState::new()?); + } + dp_states + .get_mut(&request.context_id) + .unwrap() + .evaluate(&request) + })) + .unwrap_or_else(|_| { + dp_states.remove(&request.context_id); + Err("NinjaRS selected-pole DP panic contained in worker".into()) + }); + let _ = request.reply.send(result); + } + MpMessage::Remove(id, reply) => { + states.remove(&id); + dp_states.remove(&id); + let _ = reply.send(()); + } + MpMessage::Shutdown => break, + } + } + }) + .map_err(|e| format!("cannot start NinjaRS rescue worker: {e}"))?; + Ok(Self { + sender: send, + thread: Some(thread), + }) + } +} + +/// Evaluate actual binary128 inputs supplied as fixed-width ASCII records. +/// +/// # Safety +/// Buffers contain the number of 64-byte records specified in ninjars.h. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn ninjars_evaluate_mp( + handle: *mut Context, + n: i32, + rank: i32, + count: usize, + coefficients: *const u8, + coefficient_bytes: usize, + s_matrix: *const u8, + s_bytes: usize, + momenta: *const u8, + p_bytes: usize, + masses: *const u8, + m_bytes: usize, + scale_squared: *const u8, + scale_bytes: usize, + output: *mut u8, + output_bytes: usize, +) -> i32 { + unsafe { + ninjars_evaluate_mp_with_poles( + handle, + n, + rank, + count, + coefficients, + coefficient_bytes, + s_matrix, + s_bytes, + momenta, + p_bytes, + masses, + m_bytes, + scale_squared, + scale_bytes, + output, + output_bytes, + 0, + ) + } +} + +/// Evaluate with an explicit pole mode: 0 combined, 1 UV, 2 IR, 3 none. +/// +/// # Safety +/// The buffer contract is identical to the corresponding combined-pole entry point. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn ninjars_evaluate_mp_with_poles( + handle: *mut Context, + n: i32, + rank: i32, + count: usize, + coefficients: *const u8, + coefficient_bytes: usize, + s_matrix: *const u8, + s_bytes: usize, + momenta: *const u8, + p_bytes: usize, + masses: *const u8, + m_bytes: usize, + scale_squared: *const u8, + scale_bytes: usize, + output: *mut u8, + output_bytes: usize, + pole_mode: i32, +) -> i32 { + guard(|| { + let selection = poles::from_mode(pole_mode)?; + let (n, rank) = dimensions(n, rank, count)?; + length( + "MP coefficients", + coefficient_bytes, + count + .checked_mul(2 * RECORD) + .ok_or("coefficient byte overflow")?, + )?; + length("MP S matrix", s_bytes, n * n * RECORD)?; + length("MP momenta", p_bytes, n * 4 * RECORD)?; + length("MP masses", m_bytes, n * 2 * RECORD)?; + length("MP scale", scale_bytes, RECORD)?; + length("MP output", output_bytes, 8 * RECORD)?; + validate_output(output, 8 * RECORD)?; + let context = unsafe { context(handle) }?; + let (reply, receive) = mpsc::sync_channel(1); + let mut request = MpRequest { + context_id: 0, + selection, + n, + rank, + coefficients: unsafe { + read( + coefficients, + count + .checked_mul(2 * RECORD) + .ok_or("coefficient byte overflow")?, + ) + }? + .to_vec(), + s_matrix: unsafe { read(s_matrix, n * n * RECORD) }?.to_vec(), + momenta: unsafe { read(momenta, n * 4 * RECORD) }?.to_vec(), + masses: unsafe { read(masses, n * 2 * RECORD) }?.to_vec(), + scale: unsafe { read(scale_squared, RECORD) }?.to_vec(), + reply, + }; + let mut worker = context.mp.lock().map_err(|_| "MP context poisoned")?; + if worker.is_none() { + *worker = Some(MpContext::new()?); + } + let worker = worker.as_ref().unwrap(); + request.context_id = worker.id; + worker + .sender + .send(MpMessage::Evaluate(request)) + .map_err(|_| "rescue worker disconnected")?; + let (status, values) = receive.recv().map_err(|_| "rescue worker disconnected")??; + if status == SUCCESS { + unsafe { write(output, &values) }?; + } + Ok(status) + }) +} + +/// Copy the last calling-thread error, NUL terminated; return required bytes +/// including the terminator. Passing NULL/zero queries the required capacity. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn ninjars_last_error(output: *mut u8, capacity: usize) -> usize { + LAST_ERROR.with(|slot| { + let message = slot.borrow(); + if !output.is_null() && capacity > 0 { + let n = message.len().min(capacity - 1); + unsafe { + std::ptr::copy_nonoverlapping(message.as_ptr(), output, n); + output.add(n).write(0); + } + } + message.len() + 1 + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use ninjars::fast::tensor_layout::{monomial_index, ncoeff}; + use ninjars::{ExpansionKind, ExpansionRequest, Numerator, NumeratorRequest, SampleId}; + + struct TestContext(*mut Context); + impl TestContext { + fn new() -> Self { + let mut context = std::ptr::null_mut(); + assert_eq!( + unsafe { ninjars_context_create(ABI_VERSION, &mut context) }, + SUCCESS + ); + Self(context) + } + } + impl Drop for TestContext { + fn drop(&mut self) { + assert_eq!(unsafe { ninjars_context_destroy(self.0) }, SUCCESS); + } + } + + fn dp(context: &TestContext, c: C64, mass: C64, scale: f64) -> (i32, [C64; 3]) { + let mut out = [C64::real(991.); 3]; + let mut rational = C64::real(992.); + let status = unsafe { + ninjars_evaluate_dp( + context.0, + 1, + 0, + 1, + &c, + &[0.][0], + 1, + &[0.; 4][0], + 4, + &mass, + 1, + scale, + out.as_mut_ptr(), + out.len(), + &mut rational, + 1, + ) + }; + (status, out) + } + + #[test] + fn tadpole_rebinds_coefficients_masses_and_scale() { + let context = TestContext::new(); + let (status, result) = dp(&context, C64::real(1.), C64::real(4.), 4.); + assert_eq!(status, SUCCESS); + assert!((result[0].re - 4.).abs() < 1e-12); + assert_eq!(result[1], C64::real(4.)); + assert_eq!(result[2], C64::ZERO); + let (status, result) = dp(&context, C64::new(2., -1.), C64::real(9.), 1.); + assert_eq!(status, SUCCESS); + assert_eq!(result[1], C64::new(18., -9.)); + assert!((result[0].re - 18. * (1. - 9f64.ln())).abs() < 1e-12); + let (status, result) = dp(&context, C64::real(1.), C64::new(4., -0.5), 4.); + assert_eq!(status, SUCCESS); + assert_eq!(result[1], C64::new(4., -0.5)); + } + + #[test] + fn invalid_input_preserves_outputs_and_reports_error() { + let context = TestContext::new(); + let (status, result) = dp(&context, C64::real(1.), C64::new(4., 1.), 4.); + assert_eq!(status, ERROR); + assert_eq!(result, [C64::real(991.); 3]); + let mut error = [0; 128]; + assert!(unsafe { ninjars_last_error(error.as_mut_ptr(), error.len()) } > 1); + assert!(String::from_utf8_lossy(&error).contains("mass")); + assert!(dimensions(0, 0, 1).is_err()); + assert!(dimensions(1, 4, 70).is_err()); + assert!(dimensions(1, 0, 2).is_err()); + } + + #[test] + fn version_and_malformed_outputs_are_transactional() { + let mut invalid = std::ptr::null_mut(); + assert_eq!(unsafe { ninjars_context_create(1, &mut invalid) }, ERROR); + assert_eq!( + unsafe { ninjars_context_create(ABI_VERSION + 1, &mut invalid) }, + ERROR + ); + assert!(invalid.is_null()); + assert_eq!(ninjars_abi_version(), ABI_VERSION); + let context = TestContext::new(); + let mut out = [C64::real(991.); 3]; + let mut storage = [0u64; 4]; + // A deliberately misaligned second output must be rejected before the + // otherwise valid Laurent output receives any data. + let bad_rational = unsafe { storage.as_mut_ptr().cast::().add(1).cast::() }; + let call = |out: *mut C64, rational| unsafe { + ninjars_evaluate_dp( + context.0, + 1, + 0, + 1, + &C64::ONE, + &[0.][0], + 1, + &[0.; 4][0], + 4, + &C64::real(4.), + 1, + 4., + out, + 3, + rational, + 1, + ) + }; + assert_eq!(call(out.as_mut_ptr(), bad_rational), ERROR); + assert_eq!(out, [C64::real(991.); 3]); + assert_eq!(call(out.as_mut_ptr(), out.as_mut_ptr()), ERROR); + assert_eq!(out, [C64::real(991.); 3]); + } + + #[test] + fn every_short_buffer_is_rejected_before_access_or_output() { + let context = TestContext::new(); + let mut output = [C64::real(991.); 3]; + let mut rational = C64::real(992.); + let coefficient = C64::ONE; + let dp_matrix = [0.]; + let dp_momenta = [0.; 4]; + let mass = C64::real(4.); + for short in 0..6 { + // A zero-length buffer has no readable/writable elements. Use + // NULL for that buffer to verify length validation comes first. + let mut lengths = [1, 1, 4, 1, 3, 1]; + lengths[short] = 0; + let status = unsafe { + ninjars_evaluate_dp( + context.0, + 1, + 0, + lengths[0], + if short == 0 { + std::ptr::null() + } else { + &coefficient + }, + if short == 1 { + std::ptr::null() + } else { + dp_matrix.as_ptr() + }, + lengths[1], + if short == 2 { + std::ptr::null() + } else { + dp_momenta.as_ptr() + }, + lengths[2], + if short == 3 { std::ptr::null() } else { &mass }, + lengths[3], + 4., + if short == 4 { + std::ptr::null_mut() + } else { + output.as_mut_ptr() + }, + lengths[4], + if short == 5 { + std::ptr::null_mut() + } else { + &mut rational + }, + lengths[5], + ) + }; + assert_eq!(status, ERROR); + assert_eq!(output, [C64::real(991.); 3]); + assert_eq!(rational, C64::real(992.)); + let mut message = [0; 256]; + unsafe { + ninjars_last_error(message.as_mut_ptr(), message.len()); + } + assert!(String::from_utf8_lossy(&message).contains("length")); + } + let coefficients = [record("1"), record("0")].concat(); + let matrix = record("0"); + let momenta = matrix.repeat(4); + let masses = [record("4"), record("0")].concat(); + let scale = record("4"); + let mut output = [b'!'; 8 * RECORD]; + for short in 0..6 { + let mut lengths = [ + 2 * RECORD, + RECORD, + 4 * RECORD, + 2 * RECORD, + RECORD, + 8 * RECORD, + ]; + // A nonempty truncated ASCII record must also fail immediately. + lengths[short] -= 1; + let status = unsafe { + ninjars_evaluate_mp( + context.0, + 1, + 0, + 1, + coefficients.as_ptr(), + lengths[0], + matrix.as_ptr(), + lengths[1], + momenta.as_ptr(), + lengths[2], + masses.as_ptr(), + lengths[3], + scale.as_ptr(), + lengths[4], + output.as_mut_ptr(), + lengths[5], + ) + }; + assert_eq!(status, ERROR); + assert_eq!(output, [b'!'; 8 * RECORD]); + let mut message = [0; 256]; + unsafe { + ninjars_last_error(message.as_mut_ptr(), message.len()); + } + assert!(String::from_utf8_lossy(&message).contains("length")); + } + assert!(unsafe { &*context.0 }.mp.lock().unwrap().is_none()); + } + + fn record(text: &str) -> [u8; RECORD] { + assert!(text.len() <= RECORD); + let mut data = [b' '; RECORD]; + data[..text.len()].copy_from_slice(text.as_bytes()); + data + } + + #[test] + fn mp_transport_preserves_binary128_information() { + let input = Float::with_val(113, 1) + Float::with_val(113, 2).pow(100).inv(); + let parsed = parse_record(&record(&format!("{input:.39e}"))).unwrap(); + assert_eq!(parsed.to_rational(), input.to_rational()); + assert!(parsed > Float::with_val(MP_BITS, 1)); + assert!(parse_record(&record("not-a-number")).is_err()); + } + + #[test] + fn numerical_tensor_evaluation_and_laurent_expansion() { + let prototype = Float::new(MP_BITS); + let z = |x| real(Float::with_val(MP_BITS, x)); + let mut tensor = TensorGenericNumerator::new(2, 0, &prototype).unwrap(); + let mut coefficients = vec![z(0); ncoeff(2)]; + coefficients[0] = z(3); + coefficients[monomial_index([2, 0, 0, 0])] = z(1); + coefficients[monomial_index([0, 1, 0, 0])] = z(2); + tensor.set_coefficients(coefficients, 1).unwrap(); + let q = FourMomentum::from([z(2), z(3), z(4), z(5)]); + let mut out = [z(0)]; + tensor + .evaluate_batch( + &[NumeratorRequest { + id: SampleId { lane: 0, sample: 0 }, + q: &q, + mu_squared: &z(0), + partition: &[], + }], + &mut out, + ) + .unwrap(); + assert_eq!(out[0], z(13)); + // q = a + t e3 + (beta+mu²)e4/t: q0=1+2t, q1=3. + // N = 4t²+4t+10, independent of mu². + let vectors = [ + FourMomentum::from([z(1), z(3), z(0), z(0)]), + FourMomentum::from([z(2), z(0), z(0), z(0)]), + FourMomentum::from([z(0), z(0), z(0), z(1)]), + ]; + let mut out = [z(0), z(0), z(0), z(0)]; + tensor + .expansion_batch( + &ExpansionKind::T3 { + powers: vec![(2, 0), (1, 0), (0, 0), (0, 1)], + }, + &[ExpansionRequest { + id: SampleId { lane: 0, sample: 0 }, + partition: &[], + vectors: &vectors, + parameters: &[z(1)], + }], + &mut out, + ) + .unwrap(); + assert_eq!(out, [z(4), z(4), z(10), z(0)]); + } + + #[test] + fn complete_mp_tadpole_retains_input_precision() { + let context = TestContext::new(); + let one = Float::with_val(113, 1); + let coefficient = one + Float::with_val(113, 2).pow(100).inv(); + let mut coeff = Vec::new(); + coeff.extend(record(&format!("{coefficient:.39e}"))); + coeff.extend(record("0")); + let zero = record("0"); + let momenta: Vec<_> = zero.repeat(4); + let masses: Vec<_> = [record("4"), zero].concat(); + let mut out = [b' '; 8 * RECORD]; + let status = unsafe { + ninjars_evaluate_mp( + context.0, + 1, + 0, + 1, + coeff.as_ptr(), + coeff.len(), + zero.as_ptr(), + zero.len(), + momenta.as_ptr(), + momenta.len(), + masses.as_ptr(), + masses.len(), + record("4").as_ptr(), + RECORD, + out.as_mut_ptr(), + out.len(), + ) + }; + if status != SUCCESS { + let mut error = [0; 1024]; + unsafe { + ninjars_last_error(error.as_mut_ptr(), error.len()); + } + panic!("MP status {status}: {}", String::from_utf8_lossy(&error)); + } + let pole = parse_record(&out[2 * RECORD..3 * RECORD]).unwrap(); + assert_eq!( + pole.to_rational(), + (coefficient * Float::with_val(113, 4)).to_rational() + ); + } + + #[test] + fn mp_bubbles_cover_massless_orderings_and_context_rebinding() { + fn run(context: &TestContext, m0: f64, m1: f64, scale: f64, coefficient: f64) -> [C64; 3] { + let records = |values: &[f64]| { + values + .iter() + .flat_map(|x| record(&format!("{x:.39e}"))) + .collect::>() + }; + let coeff = records(&[coefficient, 0.]); + let matrix = records(&[0., -4., -4., 0.]); + let momenta = records(&[0., 0., 0., 0., 0., 2., 0., 0.]); + let masses = records(&[m0, 0., m1, 0.]); + let scale = records(&[scale]); + let mut output = [b' '; 8 * RECORD]; + let status = unsafe { + ninjars_evaluate_mp( + context.0, + 2, + 0, + 1, + coeff.as_ptr(), + coeff.len(), + matrix.as_ptr(), + matrix.len(), + momenta.as_ptr(), + momenta.len(), + masses.as_ptr(), + masses.len(), + scale.as_ptr(), + scale.len(), + output.as_mut_ptr(), + output.len(), + ) + }; + if status != SUCCESS { + let mut error = [0; 1024]; + unsafe { + ninjars_last_error(error.as_mut_ptr(), error.len()); + } + panic!( + "MP bubble status {status}: {}", + String::from_utf8_lossy(&error) + ); + } + std::array::from_fn(|i| { + let component = |j| { + std::str::from_utf8(&output[j * RECORD..(j + 1) * RECORD]) + .unwrap() + .trim() + .parse() + .unwrap() + }; + C64::new(component(2 * i), component(2 * i + 1)) + }) + } + let retained = TestContext::new(); + for (m0, m1, scale, coefficient) in [(0., 4., 1., 1.), (4., 0., 9., 2.), (0., 0., 4., -3.)] + { + let actual = run(&retained, m0, m1, scale, coefficient); + let fresh = run(&TestContext::new(), m0, m1, scale, coefficient); + assert_eq!(actual, fresh); + let mut dp = [C64::ZERO; 3]; + let mut rational = C64::ZERO; + assert_eq!( + unsafe { + ninjars_evaluate_dp( + retained.0, + 2, + 0, + 1, + &C64::real(coefficient), + [0., -4., -4., 0.].as_ptr(), + 4, + [0., 0., 0., 0., 0., 2., 0., 0.].as_ptr(), + 8, + [C64::real(m0), C64::real(m1)].as_ptr(), + 2, + scale, + dp.as_mut_ptr(), + dp.len(), + &mut rational, + 1, + ) + }, + SUCCESS + ); + for i in 0..3 { + assert!((actual[i] - dp[i]).abs() <= 1e-11 * dp[i].abs().max(1.)); + } + assert!((actual[1] - C64::real(coefficient)).abs() < 1e-12); + assert!(actual[2].abs() < 1e-12); + } + } + + #[test] + fn complex_mass_pentagon_converges_at_binary128_output_precision() { + // The public production ABI remains 256-bit. This independent worker + // repeats a retained physical rank-five fixture at 384 bits, with + // complex masses and numerator information below binary64 precision. + std::thread::Builder::new() + .stack_size(128 * 1024 * 1024) + .spawn(|| { + let case: serde_json::Value = serde_json::from_str(include_str!( + "../tests/data/cases/madloop-gg-hhh-top-pentagon-26.json" + )) + .unwrap(); + let lane = &case["lanes"][2]; + let numbers = |key: &str| { + lane[key] + .as_array() + .unwrap() + .iter() + .flat_map(|row| row.as_array().unwrap().iter()) + .map(|value| value.as_f64().unwrap()) + .collect::>() + }; + let tensors = numbers("tensor"); + let matrix = numbers("s_matrix"); + let momenta = numbers("shifts"); + let mut masses = numbers("masses_squared"); + for mass in masses.chunks_exact_mut(2) { + mass[1] = -299.29; + } + let scale = lane["mu_squared"].as_f64().unwrap(); + let records = |values: &[f64]| { + values + .iter() + .flat_map(|x| record(&format!("{x:.39e}"))) + .collect::>() + }; + let multiplier = Float::with_val(113, 1) + Float::with_val(113, 2).pow(100).inv(); + let coefficients: Vec<_> = tensors + .iter() + .flat_map(|x| { + let value = Float::with_val(113, *x) * &multiplier; + record(&format!("{value:.39e}")) + }) + .collect(); + let (reply, _) = mpsc::sync_channel(1); + let request = MpRequest { + context_id: 0, + selection: PoleSelection::BOTH, + n: 5, + rank: 5, + coefficients, + s_matrix: records(&matrix), + momenta: records(&momenta), + masses: records(&masses), + scale: records(&[scale]), + reply, + }; + let mut state256 = MpState::with_precision(256).unwrap(); + let (status256, output256) = state256.evaluate(&request).unwrap(); + let mut state384 = MpState::with_precision(384).unwrap(); + let (status384, output384) = state384.evaluate(&request).unwrap(); + assert_eq!(status256, SUCCESS); + assert_eq!(status384, SUCCESS); + let decode = |bytes: &[u8]| { + bytes + .chunks_exact(RECORD) + .map(|record| { + Float::parse(std::str::from_utf8(record).unwrap().trim(), Some(384)) + .unwrap() + }) + .collect::>() + }; + let values256 = decode(&output256); + let values384 = decode(&output384); + let tolerance = Float::parse("1e-31", Some(384)).unwrap(); + let normalization = values384.iter().fold(Float::new(384), |largest, value| { + let magnitude = value.norm(); + if magnitude > largest { + magnitude + } else { + largest + } + }); + assert!(normalization > Float::new(384)); + // The split is basis dependent, but each engine must retain + // its own complete finite = cut-constructible + rational. + for state in [&state256, &state384] { + let raw = &state.entries[&(5, 5)].amplitude.results()[0]; + let defect = raw[0].clone() - &raw[3] - &raw[4]; + let bound = Float::parse("1e-60", Some(384)).unwrap() * &normalization; + assert!(defect.re.norm() <= bound && defect.im.norm() <= bound); + } + let mut largest_error = Float::new(384); + for (a, b) in values256.iter().zip(&values384) { + let error = (a.clone() - b).norm(); + assert!( + error <= tolerance.clone() * &normalization, + "256/384: {a} vs {b}" + ); + if error > largest_error { + largest_error = error; + } + } + let c64 = |values: &[f64]| { + values + .chunks_exact(2) + .map(|z| C64::new(z[0], z[1])) + .collect::>() + }; + let (status, dp) = DpState::new() + .unwrap() + .evaluate( + 5, + 5, + &c64(&tensors), + &matrix, + &momenta, + &c64(&masses), + scale, + ) + .unwrap(); + assert_eq!(status, SUCCESS); + let mut dp_error: f64 = 0.; + for (index, value) in dp.laurent.into_iter().chain([dp.rational]).enumerate() { + let to_f64 = |number: &Float| format!("{number:.17e}").parse::().unwrap(); + let expected = C64::new( + to_f64(&values384[2 * index]), + to_f64(&values384[2 * index + 1]), + ); + assert!((value - expected).abs() <= 1e-10 * expected.abs().max(1.)); + dp_error = dp_error.max((value - expected).abs() / expected.abs().max(1.)); + } + let strings = |data: &[u8]| { + data.chunks_exact(RECORD).map(|record| { + std::str::from_utf8(record).unwrap().trim().to_owned() + }).collect::>() + }; + println!( + "NINJARS_CONVERGENCE {}", + serde_json::json!({ + "fixture": "cases/madloop-gg-hhh-top-pentagon-26.json", + "lane": lane["id"], + "modification": "Each squared mass gets Im=-299.29 as binary64 promoted to binary128; tensor multiplied by 1+2^-100 in binary128.", + "input": { + "n": 5, "rank": 5, "coefficients": strings(&request.coefficients), + "s_matrix": strings(&request.s_matrix), "momenta": strings(&request.momenta), + "masses_squared": strings(&request.masses), "scale_squared": strings(&request.scale), + }, + "production_bits": 256, "reference_bits": 384, + "result_256": strings(&output256), "result_384": strings(&output384), + "convergence_max_scaled_error": format!("{:.39e}", largest_error / normalization), + "convergence_tolerance": "1e-31", + "finite_split_identity_tolerance": "1e-60 times largest output component", + "dp_max_scaled_error": dp_error, "dp_tolerance": 1e-10, + "passed": true + }) + ); + }) + .unwrap() + .join() + .unwrap(); + } +} + +#[cfg(test)] +mod retry_tests; + +#[cfg(test)] +mod guarded_tests; + +#[cfg(test)] +mod transport_contract_tests; +#[cfg(test)] +mod transport_replay_tests; + +#[cfg(test)] +mod final_precision_tests; + +#[cfg(test)] +mod panic_contract_tests; + +#[cfg(test)] +mod upstream_master_tests; diff --git a/vendor/ninjars/src/panic_contract_tests.rs b/vendor/ninjars/src/panic_contract_tests.rs new file mode 100644 index 0000000000..3705cbd6c7 --- /dev/null +++ b/vendor/ninjars/src/panic_contract_tests.rs @@ -0,0 +1,38 @@ +//! Boundary recovery without creating a reducer, context, or Symbolica worker. +use super::*; + +#[test] +fn panic_is_contained_and_success_clears_calling_thread_error() { + assert_eq!(guard(|| Err("earlier rejected request".into())), ERROR); + assert_eq!(guard(|| panic!("deliberate boundary regression panic")), ERROR); + + let required = unsafe { ninjars_last_error(std::ptr::null_mut(), 0) }; + assert!(required > 1); + let mut message = vec![b'!'; required + 3]; + assert_eq!( + unsafe { ninjars_last_error(message.as_mut_ptr(), required) }, + required + ); + assert_eq!(message[required - 1], 0); + assert_eq!(&message[required..], &[b'!'; 3]); + let text = std::str::from_utf8(&message[..required - 1]).unwrap(); + assert!(text.contains("panic contained at the C boundary")); + assert!(!text.contains("earlier rejected request")); + + let mut truncated = [b'!'; 8]; + assert_eq!( + unsafe { ninjars_last_error(truncated.as_mut_ptr(), truncated.len()) }, + required + ); + assert_eq!(truncated[7], 0); + assert_eq!(&truncated[..7], &message[..7]); + + assert_eq!(guard(|| Ok(SUCCESS)), SUCCESS); + assert_eq!(unsafe { ninjars_last_error(std::ptr::null_mut(), 0) }, 1); + let mut cleared = [b'!'; 4]; + assert_eq!( + unsafe { ninjars_last_error(cleared.as_mut_ptr(), cleared.len()) }, + 1 + ); + assert_eq!(cleared, [0, b'!', b'!', b'!']); +} diff --git a/vendor/ninjars/src/pole_bridge_tests.rs b/vendor/ninjars/src/pole_bridge_tests.rs new file mode 100644 index 0000000000..3da437ab51 --- /dev/null +++ b/vendor/ninjars/src/pole_bridge_tests.rs @@ -0,0 +1,162 @@ +//! End-to-end C ABI tests of the selected-pole DP and binary128 rescue paths. +use super::*; +use ninjars::fast::tensor_layout::{monomial_index, ncoeff}; + +struct Handle(*mut Context); +impl Handle { + fn new() -> Self { + let mut pointer = std::ptr::null_mut(); + assert_eq!( + unsafe { ninjars_context_create(ABI_VERSION, &mut pointer) }, + SUCCESS + ); + Self(pointer) + } +} +impl Drop for Handle { + fn drop(&mut self) { + assert_eq!(unsafe { ninjars_context_destroy(self.0) }, SUCCESS); + } +} + +fn records(values: &[f64]) -> Vec { + values + .iter() + .flat_map(|value| { + let mut record = [b' '; RECORD]; + let text = format!("{value:.39e}"); + record[..text.len()].copy_from_slice(text.as_bytes()); + record + }) + .collect() +} +fn call( + handle: &Handle, + rank: usize, + coefficient: f64, + mode: i32, + mp: bool, + compensated: bool, +) -> (i32, [C64; 3]) { + // Exact lightlike shift: every ordinary bubble master vanishes, but the + // q0^rank numerator has UV residue (-2)^rank / (rank+1). + let mut tensor = vec![C64::ZERO; ncoeff(rank)]; + tensor[monomial_index([rank as u32, 0, 0, 0])] = C64::real(coefficient); + let matrix = [0.; 4]; + let momenta = [0., 0., 0., 0., 2., 0., 0., 2.]; + let masses = [C64::ZERO; 2]; + let mut output = [C64::real(991.); 3]; + let mut rational = C64::real(992.); + let status = if mp { + let coeff_text = records(&tensor.iter().flat_map(|z| [z.re, z.im]).collect::>()); + let matrix_text = records(&matrix); + let momenta_text = records(&momenta); + let masses_text = records(&[0.; 4]); + let scale_text = records(&[7.]); + let mut result = vec![b'?'; 8 * RECORD]; + let status = unsafe { + ninjars_evaluate_mp_with_poles( + handle.0, + 2, + rank as i32, + tensor.len(), + coeff_text.as_ptr(), + coeff_text.len(), + matrix_text.as_ptr(), + matrix_text.len(), + momenta_text.as_ptr(), + momenta_text.len(), + masses_text.as_ptr(), + masses_text.len(), + scale_text.as_ptr(), + scale_text.len(), + result.as_mut_ptr(), + result.len(), + mode, + ) + }; + if status == SUCCESS { + let values: Vec = result + .chunks_exact(RECORD) + .map(|text| std::str::from_utf8(text).unwrap().trim().parse().unwrap()) + .collect(); + for k in 0..3 { + output[k] = C64::new(values[2 * k], values[2 * k + 1]); + } + } else { + assert!(result.iter().all(|&v| v == b'?')); + } + status + } else { + let evaluate = if compensated { + ninjars_evaluate_dp_compensated_with_poles + } else { + ninjars_evaluate_dp_with_poles + }; + unsafe { + evaluate( + handle.0, + 2, + rank as i32, + tensor.len(), + tensor.as_ptr(), + matrix.as_ptr(), + matrix.len(), + momenta.as_ptr(), + momenta.len(), + masses.as_ptr(), + masses.len(), + 7., + output.as_mut_ptr(), + output.len(), + &mut rational, + 1, + mode, + ) + } + }; + (status, output) +} + +#[test] +fn selected_poles_survive_scaleless_reduction_dp_mp_and_mode_changes() { + let handle = Handle::new(); + for mp in [false, true] { + for rank in 0..=4 { + // Reuse one context across topologies, changing mode and numerator. + for (mode, coefficient, sign) in [(1, 1., 1.), (2, 3., -1.), (1, -2., 1.)] { + let (status, value) = call(&handle, rank, coefficient, mode, mp, false); + assert_eq!(status, SUCCESS, "rank={rank}, mode={mode}, mp={mp}"); + let expected = + coefficient * sign * (-2.0_f64).powi(rank as i32) / (rank + 1) as f64; + assert!(value[0].abs() < 1e-10, "finite changed: {value:?}"); + assert!( + (value[1] - C64::real(expected)).abs() < 1e-10, + "rank={rank} mode={mode} mp={mp}: {value:?}, expected {expected}" + ); + assert!(value[2].abs() < 1e-10); + } + } + // NONE and BOTH use the ordinary combined result (zero here). + for mode in [3, 0] { + let (status, result) = call(&handle, 0, 1., mode, mp, false); + assert_eq!(status, SUCCESS); + assert!(result.iter().all(|v| v.abs() < 1e-10)); + } + } + let (status, result) = call(&handle, 2, 1., 1, false, true); + assert_eq!(status, SUCCESS); + assert!((result[1] - C64::real(4. / 3.)).abs() < 1e-10); +} + +#[test] +fn invalid_pole_mode_preserves_output_buffers() { + let handle = Handle::new(); + for mp in [false, true] { + for mode in [-1, 4, i32::MAX] { + let (status, result) = call(&handle, 0, 1., mode, mp, false); + assert_eq!(status, ERROR); + assert_eq!(result, [C64::real(991.); 3]); + } + } +} diff --git a/vendor/ninjars/src/poles.rs b/vendor/ninjars/src/poles.rs new file mode 100644 index 0000000000..6e37dc8312 --- /dev/null +++ b/vendor/ninjars/src/poles.rs @@ -0,0 +1,303 @@ +//! Map the MadLoop ABI selector to the upstream master-provider option. +//! +//! Numerical UV/IR separation belongs to oneloopmaster and is forwarded by +//! NinjaRS's master providers. Keep only ABI validation in this module. + +pub(crate) use ninjars_symbolica::PoleSelection; + +pub(crate) fn from_mode(mode: i32) -> std::result::Result { + match mode { + 0 => Ok(PoleSelection::BOTH), + 1 => Ok(PoleSelection::UV), + 2 => Ok(PoleSelection::IR), + 3 => Ok(PoleSelection::NONE), + _ => Err(format!( + "invalid loop pole mode {mode}: expected 0, 1, 2, or 3" + )), + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tensor::TensorGenericNumerator; + use ninjars::{ + AmplitudeInput, Complex, EvaluationStatus, Float, FloatLike, FourMomentum, MasterFailure, + MasterIntegral, MasterProvider, MasterRequest, MasterStatus, + }; + use ninjars_symbolica::{ + SymbolicaAmplitudeKernels, SymbolicaCuts, SymbolicaHighCuts, SymbolicaMasters, + }; + + fn c(value: f64) -> Complex { + Complex::new(value, 0.) + } + + fn close(actual: Complex, expected: Complex) { + assert!( + (actual.re - expected.re).hypot(actual.im - expected.im) + < 2e-11 * (1. + expected.re.hypot(expected.im)), + "{actual:?} != {expected:?}" + ); + } + + #[test] + fn scaleless_bubble_poles_survive_the_provider_in_every_tensor_rank() { + let mut provider = SymbolicaMasters::new(0.).with_pole_selection(PoleSelection::BOTH); + for (rank, integral) in [ + MasterIntegral::B0, + MasterIntegral::B1, + MasterIntegral::B11, + MasterIntegral::B111, + MasterIntegral::B1111, + ] + .into_iter() + .enumerate() + { + let residue = (-1f64).powi(rank as i32) / (rank + 1) as f64; + for (selection, single) in [ + (PoleSelection::BOTH, 0.), + (PoleSelection::UV, residue), + (PoleSelection::IR, -residue), + (PoleSelection::NONE, 0.), + (PoleSelection::BOTH, 0.), + ] { + provider.set_pole_selection(selection); + let mut output = [[c(91.); 3]]; + provider + .evaluate( + MasterRequest { + integral, + invariants: &[c(0.)], + masses_squared: &[c(0.); 2], + scales_squared: &[c(17.)], + }, + &mut output, + ) + .unwrap(); + for (actual, expected) in output[0].into_iter().zip([0., single, 0.]) { + close(actual, c(expected)); + } + } + } + } + + #[test] + fn selected_master_poles_add_to_the_total_without_changing_finite_parts() { + let mut provider = SymbolicaMasters::new(0.).with_pole_selection(PoleSelection::BOTH); + for (integral, invariants, masses) in [ + (MasterIntegral::A0, vec![], vec![Complex::new(4., -0.2)]), + (MasterIntegral::An { rank: 2 }, vec![], vec![c(4.)]), + (MasterIntegral::An { rank: 4 }, vec![], vec![c(4.)]), + (MasterIntegral::B0, vec![c(-11.)], vec![c(4.), c(9.)]), + (MasterIntegral::B1, vec![c(-11.)], vec![c(4.), c(9.)]), + (MasterIntegral::B11, vec![c(-11.)], vec![c(4.), c(9.)]), + (MasterIntegral::B111, vec![c(-11.)], vec![c(4.), c(9.)]), + (MasterIntegral::B1111, vec![c(-11.)], vec![c(4.), c(9.)]), + ( + MasterIntegral::C0, + vec![c(0.), c(0.), c(-11.)], + vec![c(0.); 3], + ), + ( + MasterIntegral::D0, + vec![c(0.), c(0.), c(0.), c(0.), c(-11.), c(-7.)], + vec![c(0.); 4], + ), + ] { + let mut results = [[[c(0.); 3]]; 4]; + for (selection, output) in [ + PoleSelection::BOTH, + PoleSelection::UV, + PoleSelection::IR, + PoleSelection::NONE, + ] + .into_iter() + .zip(&mut results) + { + provider.set_pole_selection(selection); + provider + .evaluate( + MasterRequest { + integral, + invariants: &invariants, + masses_squared: &masses, + scales_squared: &[c(3.)], + }, + output, + ) + .unwrap(); + } + let [total, uv, ir, none] = results.map(|row| row[0]); + for selected in [uv, ir, none] { + close(selected[0], total[0]); + } + close(uv[1] + ir[1], total[1]); + close(uv[2], c(0.)); + close(ir[2], total[2]); + close(none[1], c(0.)); + close(none[2], c(0.)); + if matches!( + integral, + MasterIntegral::A0 + | MasterIntegral::An { .. } + | MasterIntegral::B0 + | MasterIntegral::B1 + | MasterIntegral::B11 + | MasterIntegral::B111 + | MasterIntegral::B1111 + ) { + close(ir[1], c(0.)); + } else { + close(uv[1], c(0.)); + } + } + } + + #[test] + fn failed_master_rows_and_structural_errors_preserve_outputs() { + let mut provider = SymbolicaMasters::new(0.).with_pole_selection(PoleSelection::UV); + let sentinel = [c(67.); 3]; + let mut output = [sentinel; 2]; + let mut statuses = [MasterStatus::Success; 2]; + provider + .evaluate_batch( + MasterRequest { + integral: MasterIntegral::B0, + invariants: &[c(-1.), c(-1.)], + masses_squared: &[c(1.), c(1.), Complex::new(1., 0.1), c(1.)], + scales_squared: &[c(1.), c(1.)], + }, + &mut output, + &mut statuses, + ) + .unwrap(); + assert_eq!( + statuses, + [ + MasterStatus::Success, + MasterStatus::Failed(MasterFailure::InvalidMass) + ] + ); + assert_eq!(output[1], sentinel); + close(output[0][1], c(1.)); + let before = output; + let before_statuses = statuses; + assert!( + provider + .evaluate_batch( + MasterRequest { + integral: MasterIntegral::B0, + invariants: &[c(-1.)], + masses_squared: &[c(1.), c(1.)], + scales_squared: &[c(1.), c(1.)], + }, + &mut output, + &mut statuses + ) + .is_err() + ); + assert_eq!(output, before); + assert_eq!(statuses, before_statuses); + assert!( + provider + .evaluate( + MasterRequest { + integral: MasterIntegral::B0, + invariants: &[c(-1.), c(-1.)], + masses_squared: &[c(1.), c(1.), Complex::new(1., 0.1), c(1.)], + scales_squared: &[c(1.), c(1.)], + }, + &mut output + ) + .is_err() + ); + assert_eq!(output, before); + } + + #[test] + fn multiprecision_scaleless_tensor_bubble_retains_exact_uv_ir_cancellation() { + let prototype = Float::new(256); + let z = Complex::new(prototype.clone(), prototype.clone()); + let one = Complex::new(Float::with_val(256, 1), prototype.clone()); + let mut provider = SymbolicaMasters::new(prototype).with_pole_selection(PoleSelection::UV); + let mut results = [std::array::from_fn::<_, 3, _>(|_| z.clone())]; + let mut poles = Vec::new(); + for selection in [PoleSelection::UV, PoleSelection::IR, PoleSelection::BOTH] { + provider.set_pole_selection(selection); + provider + .evaluate( + MasterRequest { + integral: MasterIntegral::B11, + invariants: std::slice::from_ref(&z), + masses_squared: &[z.clone(), z.clone()], + scales_squared: std::slice::from_ref(&one), + }, + &mut results, + ) + .unwrap(); + assert!(results[0][0].is_fully_zero() && results[0][2].is_fully_zero()); + poles.push(results[0][1].clone()); + } + assert!((poles[0].clone() + &poles[1]).is_fully_zero()); + assert!(!poles[0].is_fully_zero()); + assert!(poles[2].is_fully_zero()); + } + + #[test] + fn generic_reduction_keeps_lightlike_scaleless_bubble_coefficients() { + use ninjars::fast::tensor_layout::{monomial_index, ncoeff}; + let mut low = SymbolicaCuts::new(0.).unwrap(); + let mut high = SymbolicaHighCuts::new(0.).unwrap(); + let mut masters = SymbolicaMasters::new(0.).with_pole_selection(PoleSelection::BOTH); + let shifts = [ + FourMomentum::from([c(0.); 4]), + FourMomentum::from([c(2.), c(0.), c(0.), c(2.)]), + ]; + for rank in 0..=4 { + let mut amplitude = SymbolicaAmplitudeKernels::new(2, rank, 0.) + .unwrap() + .into_amplitude(1) + .unwrap(); + let mut numerator = TensorGenericNumerator::new(rank, 0, &0.).unwrap(); + let mut coefficients = vec![c(0.); ncoeff(rank)]; + coefficients[monomial_index([rank as u32, 0, 0, 0])] = c(1.); + numerator.set_coefficients(coefficients, 1).unwrap(); + // For N(q)=q0^rank and null K=(2,0,0,2), all metric coefficients + // vanish: the only UV residue is K0^rank B_{1...1}. + let uv = (-2f64).powi(rank as i32) / (rank + 1) as f64; + for (selection, expected) in [ + (PoleSelection::BOTH, 0.), + (PoleSelection::UV, uv), + (PoleSelection::IR, -uv), + ] { + amplitude.reset_batch(1); + masters.set_pole_selection(selection); + amplitude + .evaluate_batch_with_inputs( + AmplitudeInput { + shifts: &shifts, + masses_squared: &[c(0.); 2], + scales_squared: &[c(1.)], + sampling_scales: &[c(1.)], + s_matrix: Some(&[c(0.); 4]), + }, + &mut numerator, + &mut low, + &mut high, + &mut masters, + ) + .unwrap(); + assert_eq!( + amplitude.statuses()[0], + EvaluationStatus::Success, + "rank {rank}" + ); + let value = amplitude.results()[0]; + close(value[0], c(0.)); + close(value[1], c(expected)); + close(value[2], c(0.)); + } + } + } +} diff --git a/vendor/ninjars/src/retry_tests.rs b/vendor/ninjars/src/retry_tests.rs new file mode 100644 index 0000000000..c3fd72349f --- /dev/null +++ b/vendor/ninjars/src/retry_tests.rs @@ -0,0 +1,106 @@ +use super::*; +use serde_json::Value; +use std::{fs,path::PathBuf}; +fn doc()->PathBuf{PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/data/compensated")} +fn pairs(v:&Value)->Vec{v.as_array().unwrap().iter().map(|v|C64::new(v[0].as_f64().unwrap(),v[1].as_f64().unwrap())).collect()} +fn numbers(v:&Value)->Vec{v.as_array().unwrap().iter().map(|v|v.as_f64().unwrap()).collect()} +fn bits(v:&[C64])->Vec<[u64;2]>{v.iter().map(|z|[z.re.to_bits(),z.im.to_bits()]).collect()} +fn create()->*mut Context{let mut c=std::ptr::null_mut();assert_eq!(unsafe{ninjars_context_create(ABI_VERSION,&mut c)},SUCCESS);c} +fn call(ctx:*mut Context,comp:bool,v:&Value)->(i32,[C64;3]){ + let n=v["n"].as_i64().unwrap()as i32;let rank=v["rank"].as_i64().unwrap()as i32; + let c=pairs(&v["coefficients"]);let s=numbers(&v["s_matrix_column_major"]); + let p=numbers(&v["momenta_column_major"]);let m=pairs(&v["masses_squared"]); + let mut out=[C64::new(987.,654.);3];let mut rational=C64::new(987.,654.); + let f=if comp{ninjars_evaluate_dp_compensated}else{ninjars_evaluate_dp}; + let status=unsafe{f(ctx,n,rank,c.len(),c.as_ptr(),s.as_ptr(),s.len(),p.as_ptr(),p.len(), + m.as_ptr(),m.len(),v["scale_squared"].as_f64().unwrap(), + out.as_mut_ptr(),3,&mut rational,1)}; + (status,out) +} +#[test] +fn retry_native_path_is_exact_and_compensated_state_is_lazy(){ + let fixtures:Vec=serde_json::from_slice(&fs::read(doc().join( + "inputs.json")).unwrap()).unwrap(); + let corrected:Vec=serde_json::from_slice(&fs::read(doc().join( + "corrected-results.json")).unwrap()).unwrap(); + let ctx=create(); + for v in &fixtures{ + let(status,out)=call(ctx,false,v);assert_eq!(status,SUCCESS); + assert_eq!(bits(&out),bits(&pairs(&v["ninjars"]))); + } + unsafe{ + assert!((*ctx).compensated_dp.lock().unwrap().is_none()); + assert!((*ctx).mp.lock().unwrap().is_none()); + } + for v in &fixtures{ + let reference=corrected.iter().find(|r|r["loop"]==v["loop"]&&r["direction"]==v["direction"]).unwrap(); + let(status,out)=call(ctx,true,v);assert_eq!(status,SUCCESS); + assert_eq!(bits(&out),bits(&pairs(&reference["ninjars"]))); + // A subsequent ordinary call must not inherit any compensated mode. + let(status,out)=call(ctx,false,v);assert_eq!(status,SUCCESS); + assert_eq!(bits(&out),bits(&pairs(&v["ninjars"]))); + } + unsafe{ + assert!((*ctx).compensated_dp.lock().unwrap().is_some()); + assert!((*ctx).mp.lock().unwrap().is_none()); + assert_eq!(ninjars_context_destroy(ctx),SUCCESS); + } +} +#[test] +fn retry_rebinding_and_failure_preserve_explicit_call_semantics(){ + let ctx=create(); + for (coeff,mass,scale) in [(1.,2.,1.),(2.5,3.,4.),(-0.75,2.,1.)]{ + let v=serde_json::json!({"n":1,"rank":0,"coefficients":[[coeff,0.]], + "s_matrix_column_major":[0.],"momenta_column_major":[0.,0.,0.,0.], + "masses_squared":[[mass,0.]],"scale_squared":scale}); + let fresh=create();let a=call(ctx,true,&v);let b=call(fresh,true,&v);let c=call(ctx,false,&v); + assert_eq!(a.0,SUCCESS);assert_eq!(b.0,SUCCESS);assert_eq!(c.0,SUCCESS); + assert_eq!(bits(&a.1),bits(&b.1));assert_eq!(bits(&a.1),bits(&c.1)); + unsafe{ninjars_context_destroy(fresh);} + } + let c=[C64::real(f64::NAN)];let s=[0.];let p=[0.;4];let m=[C64::real(2.)]; + let sentinel=C64::new(987.,654.);let mut out=[sentinel;3];let mut r=sentinel; + let code=unsafe{ninjars_evaluate_dp_compensated(ctx,1,0,1,c.as_ptr(),s.as_ptr(),1, + p.as_ptr(),4,m.as_ptr(),1,1.,out.as_mut_ptr(),3,&mut r,1)}; + assert_eq!(code,ERROR);assert_eq!(bits(&out),bits(&[sentinel;3]));assert_eq!(bits(&[r]),bits(&[sentinel])); + // Invalid output length fails before attempting to read the null inputs. + let code=unsafe{ninjars_evaluate_dp_compensated(ctx,1,0,1,std::ptr::null(), + std::ptr::null(),1,std::ptr::null(),4,std::ptr::null(),1,1., + out.as_mut_ptr(),2,&mut r,1)}; + assert_eq!(code,ERROR);assert_eq!(bits(&out),bits(&[sentinel;3])); + unsafe{assert_eq!(ninjars_context_destroy(ctx),SUCCESS);} +} + +#[test] +fn retry_active_tensor_rebinds_masses_scale_and_native_interleaving(){ + let fixtures:Vec=serde_json::from_slice(&fs::read(doc().join( + "inputs.json")).unwrap()).unwrap(); + let ctx=create(); + // Exercise the compensated rank-2/3/4 states, including return to an older + // tensor shape and parameters after both independent DP states were used. + for (index,parameter) in [(0,0),(1,1),(2,2),(1,2),(0,1),(2,0),(0,0)]{ + let mut v=fixtures[index].clone(); + let factor=[1.,1.25,0.75][parameter]; + for c in v["coefficients"].as_array_mut().unwrap(){ + for component in c.as_array_mut().unwrap(){ + *component=serde_json::json!(component.as_f64().unwrap()*factor); + } + } + for mass in v["masses_squared"].as_array_mut().unwrap(){ + mass[0]=serde_json::json!([0.,4.,25.][parameter]); + } + v["scale_squared"]=serde_json::json!([1e6,2e6,0.5e6][parameter]); + let fresh=create(); + for comp in [false,true,false,true]{ + let current=call(ctx,comp,&v);let isolated=call(fresh,comp,&v); + assert_eq!(current.0,SUCCESS,"shape={index} parameter={parameter} compensated={comp}"); + assert_eq!(isolated.0,SUCCESS); + assert_eq!(bits(¤t.1),bits(&isolated.1)); + } + unsafe{assert_eq!(ninjars_context_destroy(fresh),SUCCESS);} + } + unsafe{ + assert!((*ctx).mp.lock().unwrap().is_none()); + assert_eq!(ninjars_context_destroy(ctx),SUCCESS); + } +} diff --git a/vendor/ninjars/src/tensor.rs b/vendor/ninjars/src/tensor.rs new file mode 100644 index 0000000000..b8fd622630 --- /dev/null +++ b/vendor/ninjars/src/tensor.rs @@ -0,0 +1,427 @@ +// Adapted from NinjaRS 0d0d7e7a8033431b60a8580731084742e0655cda, +// crates/ninjars-cli/src/case_check/harness.rs, precision-generic tensor section. +// Copyright the NinjaRS contributors; GPL-3.0-or-later. +// Keep the numerical recurrence in sync with the pinned upstream implementation. +use ninjars::fast::tensor_layout::{monomial_index, monomials, mu_block_offset, ncoeff, ncoeff_mu}; +use ninjars::{ + BatchShape, Complex, ExpansionKind, ExpansionRequest, FloatLike, FourMomentum, Numerator, + NumeratorRequest, Real, SingleFloat, +}; +type Result = std::result::Result>; +/// Shape of one Laurent expansion: `q = t F(u, x, mu^2)` with `u = 1/t`. +#[derive(Clone, Copy, PartialEq, Eq)] +enum Shape { + /// `Mu` (`beta = 0`) and `MuShifted`: `F = v0 + v1 u`, `mu^2 = t^2 (v0^2 - beta u^2)`. + Mu, + /// `F = e3 + a u + (beta + mu^2) e4 u^2`. + T3, + /// `F = e3 + (a0 + x a1) u + (b0 + b1 x + b2 x^2 + mu^2) e4 u^2`. + T2, +} + +/// A dense tensor numerator `N(q, mu^2) = sum_k (mu^2)^k T_k(q)` in the +/// `tensor_layout` (and `MuTensorNumerator` block) order for the generic +/// engine in any precision. +/// +/// Expansions are computed numerically: each monomial `q^m = t^|m| prod_c +/// F_c^(m_c)` is a truncated series in `u = 1/t` (and `x`, `mu^2` for the +/// triangle and bubble parametrisations), built from its parent monomial with +/// one multiplication by `F_c`; the requested Laurent coefficients are then +/// contracted with the lane's coefficients. Exact arithmetic would reproduce +/// [`ninjars_symbolica::PolynomialNumerator`] exactly; in floating point both +/// round differently. +pub struct TensorGenericNumerator { + rank: usize, + mu_powers: usize, + width: usize, + degrees: Vec, + /// `(parent monomial, component)` of every monomial but the constant. + parents: Vec<(usize, usize)>, + coefficients: Vec>, + lanes: usize, + zero: Complex, + one: Complex, + values_work: Vec>, + series_work: Vec>, +} + +impl TensorGenericNumerator +where + Complex: Real, +{ + pub fn new(rank: usize, mu_powers: usize, prototype: &T) -> Result { + if 2 * mu_powers > rank { + return Err("mu_powers exceeds rank / 2".into()); + } + let list = monomials(rank); + let degrees = list + .iter() + .map(|m| m.iter().sum::() as usize) + .collect(); + let parents = list + .iter() + .map(|m| { + let Some(c) = (0..4).rev().find(|&c| m[c] > 0) else { + return (0, 0); + }; + let mut parent = *m; + parent[c] -= 1; + (monomial_index(parent), c) + }) + .collect(); + let zero = Complex::new(prototype.zero(), prototype.zero()); + let one = Complex::new(prototype.one(), prototype.zero()); + Ok(Self { + rank, + mu_powers, + width: ncoeff_mu(rank, mu_powers), + degrees, + parents, + coefficients: Vec::new(), + lanes: 0, + zero, + one, + values_work: Vec::new(), + series_work: Vec::new(), + }) + } + + /// Bind lane-major coefficients (`width()` per lane). + pub fn set_coefficients(&mut self, coefficients: Vec>, lanes: usize) -> Result<()> { + if coefficients.len() != lanes * self.width { + return Err(format!( + "{} coefficients for {lanes} lanes of width {}", + coefficients.len(), + self.width + ) + .into()); + } + self.coefficients = coefficients; + self.lanes = lanes; + Ok(()) + } + + /// `(offset, size)` of the `mu^(2k)` block. + fn block(&self, k: usize) -> (usize, usize) { + (mu_block_offset(self.rank, k), ncoeff(self.rank - 2 * k)) + } + + fn lane_coefficients(&self, lane: usize) -> ninjars::Result<&[Complex]> { + if lane >= self.lanes { + return Err(ninjars::Error::Lane { + lane, + lanes: self.lanes, + }); + } + Ok(&self.coefficients[lane * self.width..(lane + 1) * self.width]) + } +} + +// Allocation-only expansion of the pinned Complex::mul expression. +// The four scalar products, operand order and two additions are unchanged. +#[inline] +fn borrowed_product(a: &Complex, b: &Complex) -> Complex { + Complex::new( + a.re.clone() * &b.re - a.im.clone() * &b.im, + a.re.clone() * &b.im + a.im.clone() * &b.re, + ) +} + +fn minkowski(a: &[Complex; 4], b: &[Complex; 4]) -> Complex +where + Complex: Real, +{ + borrowed_product(&a[0], &b[0]) - borrowed_product(&a[1], &b[1]) - borrowed_product(&a[2], &b[2]) - borrowed_product(&a[3], &b[3]) +} + +fn components(v: &FourMomentum) -> [T; 4] { + v.components().map(|x| x.clone()) +} + +impl Numerator> for TensorGenericNumerator +where + Complex: Real, +{ + fn rank(&self) -> usize { + self.rank + } + + fn evaluate_batch( + &mut self, + requests: &[NumeratorRequest<'_, Complex>], + output: &mut [Complex], + ) -> ninjars::Result<()> { + BatchShape { + rows: requests.len(), + columns: 1, + } + .validate("numerator output", output.len())?; + let count = self.degrees.len(); + let mut values = std::mem::take(&mut self.values_work); + values.resize_with(count, || self.zero.clone()); + for (request, out) in requests.iter().zip(output.iter_mut()) { + let coefficients = self.lane_coefficients(request.id.lane)?; + let q = components(request.q); + values[0].set_from(&self.one); + for i in 1..count { + let (parent, c) = self.parents[i]; + values[i] = borrowed_product(&values[parent], &q[c]); + } + let mut total = self.zero.clone(); + let mut mu_power = self.one.clone(); + for k in 0..=self.mu_powers { + let (offset, size) = self.block(k); + let mut block = self.zero.clone(); + for (c, v) in coefficients[offset..offset + size].iter().zip(&values) { + block += borrowed_product(c, v); + } + total += block * &mu_power; + mu_power *= request.mu_squared; + } + *out = total; + } + self.values_work = values; + Ok(()) + } + + fn expansion_batch( + &mut self, + kind: &ExpansionKind, + requests: &[ExpansionRequest<'_, Complex>], + output: &mut [Complex], + ) -> ninjars::Result<()> { + let columns = kind.len(); + BatchShape { + rows: requests.len(), + columns, + } + .validate("expansion output", output.len())?; + let (shape, vectors, scalars, shifted) = match kind { + ExpansionKind::Mu { .. } => (Shape::Mu, 2, 0, false), + ExpansionKind::MuShifted { .. } => (Shape::Mu, 2, 1, true), + ExpansionKind::T3 { .. } => (Shape::T3, 3, 1, false), + ExpansionKind::T2 { .. } => (Shape::T2, 4, 3, false), + }; + for request in requests { + self.lane_coefficients(request.id.lane)?; + if request.vectors.len() != vectors + && !(matches!(kind, ExpansionKind::Mu { .. }) && request.vectors.len() == 1) + { + return Err(ninjars::Error::Shape { + name: "cut vectors", + expected: vectors, + actual: request.vectors.len(), + }); + } + BatchShape { + rows: 1, + columns: scalars, + } + .validate("cut parameters", request.parameters.len())?; + } + if requests.is_empty() || columns == 0 { + return Ok(()); + } + // Requested (t power, x power, mu^2 power) per column. + let powers: Vec<(i64, usize, usize)> = match kind { + ExpansionKind::Mu { powers } | ExpansionKind::MuShifted { powers } => { + powers.iter().map(|&p| (i64::from(p), 0, 0)).collect() + } + ExpansionKind::T3 { powers } => powers + .iter() + .map(|&(p, l)| (i64::from(p), 0, usize::from(l))) + .collect(), + ExpansionKind::T2 { powers } => powers + .iter() + .map(|&(p, a, l)| (i64::from(p), usize::from(a), usize::from(l))) + .collect(), + }; + let lowest = powers.iter().map(|p| p.0).min().unwrap_or(0); + // Deepest u order any term reaches at the requested powers. + let depth = (self.rank as i64 - lowest).max(0) as usize; + let (xs, mus) = match shape { + Shape::Mu => (1, 1), + Shape::T3 => (1, depth / 2 + 1), + Shape::T2 => (depth + 1, depth / 2 + 1), + }; + let size = (depth + 1) * xs * mus; + let at = |j: usize, a: usize, l: usize| (j * xs + a) * mus + l; + let count = self.degrees.len(); + let mut series = std::mem::take(&mut self.series_work); + series.resize_with(count * size, || self.zero.clone()); + for (row, request) in requests.iter().enumerate() { + let coefficients = self.lane_coefficients(request.id.lane)?; + let v: Vec<[Complex; 4]> = request.vectors.iter().map(components).collect(); + let zero4 = || std::array::from_fn::<_, 4, _>(|_| self.zero.clone()); + // Factor coefficients per component: [1, u, u x, u^2, u^2 x, u^2 x^2, u^2 mu^2]. + let factors: Vec<[Complex; 7]> = (0..4) + .map(|c| { + let z = || self.zero.clone(); + match shape { + Shape::Mu => { + let v1 = v.get(1).cloned().unwrap_or_else(zero4); + [v[0][c].clone(), v1[c].clone(), z(), z(), z(), z(), z()] + } + Shape::T3 => { + let e4 = &v[2][c]; + [ + v[1][c].clone(), + v[0][c].clone(), + z(), + borrowed_product(&request.parameters[0], e4), + z(), + z(), + e4.clone(), + ] + } + Shape::T2 => { + let e4 = &v[3][c]; + [ + v[2][c].clone(), + v[0][c].clone(), + v[1][c].clone(), + borrowed_product(&request.parameters[0], e4), + borrowed_product(&request.parameters[1], e4), + borrowed_product(&request.parameters[2], e4), + e4.clone(), + ] + } + } + }) + .collect(); + for value in series.iter_mut() { + value.set_from(&self.zero); + } + series[at(0, 0, 0)].set_from(&self.one); + for i in 1..count { + let (parent, c) = self.parents[i]; + let f = &factors[c]; + let (head, tail) = series.split_at_mut(i * size); + let source = &head[parent * size..(parent + 1) * size]; + let target = &mut tail[..size]; + for j in 0..=depth { + for a in 0..xs.min(j + 1) { + for l in 0..mus { + if a + 2 * l > j { + break; + } + let mut acc = borrowed_product(&f[0], &source[at(j, a, l)]); + if j >= 1 { + acc += borrowed_product(&f[1], &source[at(j - 1, a, l)]); + if shape == Shape::T2 && a >= 1 { + acc += borrowed_product(&f[2], &source[at(j - 1, a - 1, l)]); + } + } + if j >= 2 && shape != Shape::Mu { + acc += borrowed_product(&f[3], &source[at(j - 2, a, l)]); + if shape == Shape::T2 { + if a >= 1 { + acc += borrowed_product(&f[4], &source[at(j - 2, a - 1, l)]); + } + if a >= 2 { + acc += borrowed_product(&f[5], &source[at(j - 2, a - 2, l)]); + } + } + if l >= 1 { + acc += borrowed_product(&f[6], &source[at(j - 2, a, l - 1)]); + } + } + target[at(j, a, l)] = acc; + } + } + } + } + let out = &mut output[row * columns..(row + 1) * columns]; + match shape { + Shape::Mu => { + // mu^2 = t^2 G(u), G = v0^2 - beta u^2; powers G^k truncated at depth. + let g0 = minkowski(&v[0], &v[0]); + let beta = if shifted { + request.parameters[0].clone() + } else { + self.zero.clone() + }; + let mut g_powers = vec![{ + let mut s = vec![self.zero.clone(); depth + 1]; + s[0] = self.one.clone(); + s + }]; + for k in 1..=self.mu_powers { + let previous = &g_powers[k - 1]; + let mut s = vec![self.zero.clone(); depth + 1]; + for j in 0..=depth { + let mut acc = borrowed_product(&g0, &previous[j]); + if j >= 2 { + acc -= borrowed_product(&beta, &previous[j - 2]); + } + s[j] = acc; + } + g_powers.push(s); + } + for (column, &(p, _, _)) in powers.iter().enumerate() { + let mut acc = self.zero.clone(); + for (k, g) in g_powers.iter().enumerate() { + let (offset, block) = self.block(k); + for i in 0..block { + let c = &coefficients[offset + i]; + if c.is_fully_zero() { + continue; + } + let j = (self.degrees[i] + 2 * k) as i64 - p; + if j < 0 || j as usize > depth { + continue; + } + let j = j as usize; + let s = &series[i * size..(i + 1) * size]; + let mut term = self.zero.clone(); + for j1 in 0..=j { + term += borrowed_product(&s[at(j1, 0, 0)], &g[j - j1]); + } + acc += term * c; + } + } + out[column] = acc; + } + } + Shape::T3 | Shape::T2 => { + for (column, &(p, a, total_mu)) in powers.iter().enumerate() { + let mut acc = self.zero.clone(); + for k in 0..=self.mu_powers.min(total_mu) { + let l = total_mu - k; + if l >= mus || a >= xs { + continue; + } + let (offset, block) = self.block(k); + for i in 0..block { + let c = &coefficients[offset + i]; + if c.is_fully_zero() { + continue; + } + let j = self.degrees[i] as i64 - p; + if j < 0 || j as usize > depth || a + 2 * l > j as usize { + continue; + } + acc += borrowed_product(&series[i * size + at(j as usize, a, l)], c); + } + } + out[column] = acc; + } + } + } + } + self.series_work = series; + Ok(()) + } +} + +#[cfg(test)] +#[path = "tensor_dense_reference.rs"] +mod dense_reference; + +#[cfg(test)] +#[path = "tensor_allocation_tests.rs"] +mod allocation_tests; + +#[cfg(test)] +#[path = "tensor_capture_tests.rs"] +mod capture_tests; diff --git a/vendor/ninjars/src/tensor_allocation_tests.rs b/vendor/ninjars/src/tensor_allocation_tests.rs new file mode 100644 index 0000000000..e306c1d695 --- /dev/null +++ b/vendor/ninjars/src/tensor_allocation_tests.rs @@ -0,0 +1,274 @@ +//! Numerical oracle is the frozen production dense source, not an algebraic +//! reimplementation. Compare full stored values, precision and signs. +use super::*; +use ninjars::{Float, SampleId}; + +fn equal_component(a: &Float, b: &Float) { + assert_eq!(a.prec(), b.prec(), "tracked precision differs"); + assert_eq!(a.is_sign_negative(), b.is_sign_negative(), "sign differs"); + assert_eq!(a.is_finite(), b.is_finite()); + if a.is_finite() { + assert_eq!( + a.to_rational(), + b.to_rational(), + "exact stored value differs" + ); + } else { + assert_eq!(format!("{a:?}"), format!("{b:?}")); + } +} + +fn equal_rows(a: &[Complex], b: &[Complex]) { + assert_eq!(a.len(), b.len()); + for (a, b) in a.iter().zip(b) { + equal_component(&a.re, &b.re); + equal_component(&a.im, &b.im); + } +} + +fn number(bits: u32, seed: usize) -> Complex { + // Different tracked precisions, signs, rounded fractions and signed zeros. + let p = [bits, bits.saturating_sub(17).max(2), bits / 2][seed % 3]; + let re = if seed % 7 == 0 { + Float::with_val(p, if seed % 2 == 0 { -0.0 } else { 0.0 }) + } else { + Float::with_val(p, seed as i64 - 11) / Float::with_val(p, 7) + }; + let im = if seed % 5 == 0 { + Float::with_val(p, -0.0) + } else { + Float::with_val(p, 3 - seed as i64) / Float::with_val(p, 13) + }; + Complex::new(re, im) +} + +fn kinds(rank: usize) -> Vec { + let r = rank as i32; + let mut t3 = Vec::new(); + let mut t2 = Vec::new(); + for p in (-1..=r).rev() { + for l in 0..=(r - p) / 2 { + t3.push((p, l as u16)); + } + for a in 0..=r - p { + for l in 0..=(r - p - a) / 2 { + t2.push((p, a as u16, l as u16)); + } + } + } + // Duplicate/reordered output columns and a deliberately empty contraction. + t3.extend([(r, 0), (r + 2, 0), (-1, 0)]); + t2.extend([(r, 0, 0), (r + 2, 0, 0), (-1, 0, 0)]); + vec![ + ExpansionKind::Mu { + powers: vec![r, 0, r - 1, -1, r], + }, + ExpansionKind::MuShifted { + powers: vec![r, 0, r - 1, -1, r], + }, + ExpansionKind::T3 { powers: t3 }, + ExpansionKind::T2 { powers: t2 }, + ] +} + +#[test] +fn allocation_tensor_matches_dense_values_precision_and_signed_zero() { + for bits in [113, 256, 384] { + for rank in 0..=6 { + for mu_powers in 0..=2.min(rank / 2) { + let prototype = Float::new(bits); + let mut planned = TensorGenericNumerator::new(rank, mu_powers, &prototype).unwrap(); + let mut dense = + dense_reference::TensorGenericNumerator::new(rank, mu_powers, &prototype) + .unwrap(); + let coefficients: Vec<_> = (0..2 * planned.width) + .map(|i| number(bits, i + 1)) + .collect(); + planned.set_coefficients(coefficients.clone(), 2).unwrap(); + dense.set_coefficients(coefficients.clone(), 2).unwrap(); + for kind in kinds(rank) { + let (vectors, scalars) = match kind { + ExpansionKind::Mu { .. } => (1, 0), + ExpansionKind::MuShifted { .. } => (2, 1), + ExpansionKind::T3 { .. } => (3, 1), + ExpansionKind::T2 { .. } => (4, 3), + }; + for lane in 0..2 { + let v: Vec<_> = (0..vectors) + .map(|i| { + FourMomentum::from(std::array::from_fn(|c| { + number(bits, i * 4 + c + lane * 9 + 1) + })) + }) + .collect(); + let p: Vec<_> = (0..scalars).map(|i| number(bits, i + lane + 2)).collect(); + let request = ExpansionRequest { + id: SampleId { lane, sample: 0 }, + partition: &[], + vectors: &v, + parameters: &p, + }; + let mut a = vec![number(bits, 99); kind.len()]; + let mut b = a.clone(); + planned.expansion_batch(&kind, &[request], &mut a).unwrap(); + // Construct the second request without requiring Clone on its type. + let request = ExpansionRequest { + id: SampleId { lane, sample: 0 }, + partition: &[], + vectors: &v, + parameters: &p, + }; + dense.expansion_batch(&kind, &[request], &mut b).unwrap(); + equal_rows(&a, &b); + } + } + // New coefficients reuse existing allocated scratch. + let rebound: Vec<_> = coefficients.into_iter().rev().collect(); + planned.set_coefficients(rebound.clone(), 2).unwrap(); + dense.set_coefficients(rebound, 2).unwrap(); + let kind = kinds(rank).pop().unwrap(); + let v0: Vec<_> = (0..4) + .map(|i| { + FourMomentum::from(std::array::from_fn(|c| number(bits, i * 4 + c + 31))) + }) + .collect(); + let v1: Vec<_> = (0..4) + .map(|i| { + FourMomentum::from(std::array::from_fn(|c| number(bits, i * 4 + c + 57))) + }) + .collect(); + let p0: Vec<_> = (0..3).map(|i| number(bits, i + 7)).collect(); + let p1: Vec<_> = (0..3).map(|i| number(bits, i + 21)).collect(); + let requests = || { + [ + ExpansionRequest { + id: SampleId { lane: 1, sample: 0 }, + partition: &[], + vectors: &v0, + parameters: &p0, + }, + ExpansionRequest { + id: SampleId { lane: 0, sample: 1 }, + partition: &[], + vectors: &v1, + parameters: &p1, + }, + ] + }; + let mut a = vec![number(bits, 99); 2 * kind.len()]; + let mut b = a.clone(); + planned.expansion_batch(&kind, &requests(), &mut a).unwrap(); + dense.expansion_batch(&kind, &requests(), &mut b).unwrap(); + equal_rows(&a, &b); + } + } + } +} + +#[test] +fn allocation_tensor_nonfinite_inputs_match_original() { + let bits = 113; + let prototype = Float::new(bits); + let mut planned = TensorGenericNumerator::new(2, 0, &prototype).unwrap(); + let mut dense = dense_reference::TensorGenericNumerator::new(2, 0, &prototype).unwrap(); + let coefficients: Vec<_> = (0..planned.width).map(|i| number(bits, i)).collect(); + planned.set_coefficients(coefficients.clone(), 1).unwrap(); + dense.set_coefficients(coefficients, 1).unwrap(); + let mut v = vec![FourMomentum::from(std::array::from_fn(|i| { + number(bits, i + 1) + }))]; + let kind = ExpansionKind::Mu { + powers: vec![2, 1, 0], + }; + v[0] = FourMomentum::from([ + Complex::new(Float::with_val(bits, f64::INFINITY), Float::new(bits)), + number(bits, 2), + number(bits, 3), + number(bits, 4), + ]); + let mut a = vec![number(bits, 8); kind.len()]; + let mut b = a.clone(); + planned + .expansion_batch( + &kind, + &[ExpansionRequest { + id: SampleId { lane: 0, sample: 0 }, + partition: &[], + vectors: &v, + parameters: &[], + }], + &mut a, + ) + .unwrap(); + dense + .expansion_batch( + &kind, + &[ExpansionRequest { + id: SampleId { lane: 0, sample: 0 }, + partition: &[], + vectors: &v, + parameters: &[], + }], + &mut b, + ) + .unwrap(); + equal_rows(&a, &b); +} + +#[test] +fn allocation_evaluation_rebinds_scratch_and_lanes_exactly() { + for bits in [113, 256, 384] { + for rank in 0..=6 { + for mu_powers in 0..=rank / 2 { + let prototype = Float::new(bits); + let mut planned = TensorGenericNumerator::new(rank, mu_powers, &prototype).unwrap(); + let mut dense = dense_reference::TensorGenericNumerator::new(rank, mu_powers, &prototype).unwrap(); + for round in 0..3 { + let coefficients: Vec<_> = (0..2 * planned.width).map(|i| number(bits, i + 17 * round)).collect(); + planned.set_coefficients(coefficients.clone(), 2).unwrap(); + dense.set_coefficients(coefficients, 2).unwrap(); + let momenta: Vec<_> = (0..4).map(|i| FourMomentum::from(std::array::from_fn(|j| number(bits, 13 * round + i * 4 + j)))).collect(); + let mu: Vec<_> = (0..4).map(|i| number(bits, round * 11 + i)).collect(); + let requests = || (0..4).map(|i| NumeratorRequest { + id: SampleId { lane: i % 2, sample: i }, partition: &[], q: &momenta[i], mu_squared: &mu[i], + }).collect::>(); + let mut a = vec![number(bits, 99); 4]; + let mut b = a.clone(); + planned.evaluate_batch(&requests(), &mut a).unwrap(); + dense.evaluate_batch(&requests(), &mut b).unwrap(); + equal_rows(&a, &b); + } + planned.evaluate_batch(&[], &mut []).unwrap(); + dense.evaluate_batch(&[], &mut []).unwrap(); + let mut a = [number(bits, 99)]; + let mut b = a.clone(); + assert_eq!(format!("{:?}", planned.evaluate_batch(&[], &mut a)), format!("{:?}", dense.evaluate_batch(&[], &mut b))); + equal_rows(&a, &b); + } + } + } +} + +#[test] +fn borrowed_product_and_actual_zero_one_resets_preserve_state() { + for bits in [2, 53, 113, 256, 384] { + let mut values: Vec<_> = (0..24).map(|i| number(bits, i)).collect(); + for exceptional in [f64::INFINITY, f64::NEG_INFINITY, f64::NAN, -0.0, 0.0] { + values.push(Complex::new(Float::with_val(bits, exceptional), Float::with_val(bits, -0.0))); + } + for a in &values { + for b in &values { + equal_rows(&[borrowed_product(a, b)], &[a.clone() * b]); + } + // Production resets only to these finite prototype zero/one values. + // Rug clone_from for an arbitrary NaN source can retain the old + // destination sign; that unrelated failure is retained separately. + for b in [Complex::new(Float::new(bits), Float::new(bits)), + Complex::new(Float::with_val(bits, 1), Float::new(bits))] { + let mut slot = a.clone(); + slot.set_from(&b); + equal_rows(&[slot], &[b.clone()]); + } + } + } +} diff --git a/vendor/ninjars/src/tensor_capture_tests.rs b/vendor/ninjars/src/tensor_capture_tests.rs new file mode 100644 index 0000000000..b0f8370953 --- /dev/null +++ b/vendor/ninjars/src/tensor_capture_tests.rs @@ -0,0 +1,235 @@ +//! Replay actual MadLoop binary128 requests, comparing every generic expansion. +use super::*; +use crate::{ + AmplitudeInput, EvaluationStatus, Float, MP_BITS, RECORD, SymbolicaAmplitudeKernels, + SymbolicaCuts, SymbolicaHighCuts, SymbolicaMasters, pairs, parse_records, real, +}; +use serde_json::Value; +use std::collections::{BTreeMap, HashSet}; + +struct Oracle { + planned: TensorGenericNumerator, + dense: dense_reference::TensorGenericNumerator, + counts: BTreeMap<&'static str, usize>, +} +fn equal_component(a: &Float, b: &Float) { + assert_eq!(a.prec(), b.prec()); + assert_eq!(a.is_sign_negative(), b.is_sign_negative()); + assert!(a.is_finite() && b.is_finite()); + assert_eq!(a.to_rational(), b.to_rational()); +} +fn equal(a: &[Complex], b: &[Complex]) { + assert_eq!(a.len(), b.len()); + for (a, b) in a.iter().zip(b) { + equal_component(&a.re, &b.re); + equal_component(&a.im, &b.im); + } +} +impl Numerator> for Oracle { + fn rank(&self) -> usize { + self.planned.rank() + } + fn evaluate_batch( + &mut self, + requests: &[NumeratorRequest<'_, Complex>], + output: &mut [Complex], + ) -> ninjars::Result<()> { + let mut reference = output.to_vec(); + self.planned.evaluate_batch(requests, output)?; + self.dense.evaluate_batch(requests, &mut reference)?; + equal(output, &reference); + *self.counts.entry("numerator_values").or_default() += output.len(); + Ok(()) + } + fn expansion_batch( + &mut self, + kind: &ExpansionKind, + requests: &[ExpansionRequest<'_, Complex>], + output: &mut [Complex], + ) -> ninjars::Result<()> { + let mut reference = output.to_vec(); + self.planned.expansion_batch(kind, requests, output)?; + self.dense.expansion_batch(kind, requests, &mut reference)?; + equal(output, &reference); + let name = match kind { + ExpansionKind::Mu { .. } => "mu", + ExpansionKind::MuShifted { .. } => "mu_shifted", + ExpansionKind::T3 { .. } => "t3", + ExpansionKind::T2 { .. } => "t2", + }; + *self.counts.entry(name).or_default() += output.len(); + Ok(()) + } +} +fn records(value: &Value) -> Vec { + let mut bytes = Vec::new(); + for string in value.as_array().unwrap() { + let text = string.as_str().unwrap().as_bytes(); + assert!(text.len() <= RECORD); + let mut record = [b' '; RECORD]; + record[..text.len()].copy_from_slice(text); + bytes.extend(record); + } + parse_records(&bytes, MP_BITS).unwrap() +} + +#[test] +#[ignore = "requires an explicit retained MadLoop request capture"] +fn actual_madloop_requests_match_dense_expansions_exactly() { + let path = std::env::var("NINJARS_TENSOR_REPLAY").expect("capture path required"); + let text = std::fs::read_to_string(path).unwrap(); + std::thread::Builder::new() + .stack_size(128 * 1024 * 1024) + .spawn(move || { + let prototype = Float::new(MP_BITS); + let mut low = SymbolicaCuts::new(prototype.clone()).unwrap(); + let mut high = SymbolicaHighCuts::new(prototype.clone()).unwrap(); + let threshold = Float::with_val(MP_BITS, 1_000_000_000_000_000i64) + / Float::with_val(MP_BITS, 2).pow(112); + let mut masters = + SymbolicaMasters::new(prototype.clone()).with_onshell_threshold(Some(threshold)); + let mut seen = HashSet::new(); + let mut total = BTreeMap::<&'static str, usize>::new(); + let mut tested = 0; + for line in text.lines() { + let record: Value = serde_json::from_str(line).unwrap(); + if record["status"] != 0 { + continue; + } + let n = record["n"].as_u64().unwrap() as usize; + let rank = record["rank"].as_u64().unwrap() as usize; + // Retain one successful actual request for every topology/rank. + // The complete capture remains available for wider replay. + if !seen.insert((n, rank)) && std::env::var_os("NINJARS_REPLAY_ALL").is_none() { + continue; + } + let coefficients = pairs(records(&record["coefficients"])); + assert_eq!(coefficients.len(), ncoeff(rank)); + assert_eq!(coefficients.len(), record["count"].as_u64().unwrap() as usize); + let shifts: Vec<_> = records(&record["momenta"]) + .chunks_exact(4) + .map(|v| FourMomentum::from(std::array::from_fn(|k| real(v[k].clone())))) + .collect(); + let masses = pairs(records(&record["masses"])); + let smat: Vec<_> = records(&record["s_matrix"]).into_iter().map(real).collect(); + let scales: Vec<_> = records(&record["scale"]).into_iter().map(real).collect(); + let sampling = [real(smat.iter().chain(&masses).map(|v| v.re.norm()).fold( + Float::with_val(MP_BITS, 1), + |a, b| if b > a { b } else { a }, + ))]; + let mut oracle = Oracle { + planned: TensorGenericNumerator::new(rank, 0, &prototype).unwrap(), + dense: dense_reference::TensorGenericNumerator::new(rank, 0, &prototype) + .unwrap(), + counts: BTreeMap::new(), + }; + oracle + .planned + .set_coefficients(coefficients.clone(), 1) + .unwrap(); + oracle.dense.set_coefficients(coefficients, 1).unwrap(); + let mut amplitude = SymbolicaAmplitudeKernels::new(n, rank, prototype.clone()) + .unwrap() + .into_amplitude(1) + .unwrap(); + amplitude.reset_batch(1); + amplitude + .evaluate_batch_with_inputs( + AmplitudeInput { + shifts: &shifts, + masses_squared: &masses, + scales_squared: &scales, + sampling_scales: &sampling, + s_matrix: Some(&smat), + }, + &mut oracle, + &mut low, + &mut high, + &mut masters, + ) + .unwrap(); + assert_eq!(amplitude.statuses()[0], EvaluationStatus::Success); + let result = &litude.results()[0]; + let formatted: Vec<_> = [0, 1, 2, 4] + .into_iter() + .flat_map(|i| [&result[i].re, &result[i].im]) + .map(|v| format!("{v:.39e}")) + .collect(); + let expected: Vec<_> = record["output"] + .as_array() + .unwrap() + .iter() + .map(|s| s.as_str().unwrap()) + .collect(); + assert_eq!(formatted, expected, "ABI output differs for ({n},{rank})"); + for (kind, count) in oracle.counts { + *total.entry(kind).or_default() += count; + } + tested += 1; + eprintln!("captured request n={n} rank={rank}: exact"); + } + assert!(tested >= 4, "expected multiple actual topology/rank shapes"); + assert!(total.get("t2").copied().unwrap_or(0) > 0); + assert!(total.get("t3").copied().unwrap_or(0) > 0); + eprintln!("captured exact requests={tested}; expansion/value counts={total:?}"); + }) + .unwrap() + .join() + .unwrap(); +} + +#[test] +#[ignore = "runs the full retained physical fixture set through Symbolica"] +fn all_golden_mp_inputs_match_original_numerator_state() { + std::thread::Builder::new().stack_size(128 * 1024 * 1024).spawn(|| { + let base = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/data/cases"); + let mut files: Vec<_> = std::fs::read_dir(base).unwrap().map(|v| v.unwrap().path()).collect(); + files.sort(); + let prototype = Float::new(MP_BITS); + let mut low = SymbolicaCuts::new(prototype.clone()).unwrap(); + let mut high = SymbolicaHighCuts::new(prototype.clone()).unwrap(); + let threshold = Float::with_val(MP_BITS, 1_000_000_000_000_000i64) / Float::with_val(MP_BITS, 2).pow(112); + let mut masters = SymbolicaMasters::new(prototype.clone()).with_onshell_threshold(Some(threshold)); + let mut total = BTreeMap::<&'static str, usize>::new(); + let mut tested = 0; + for file in files { + let case: Value = serde_json::from_str(&std::fs::read_to_string(&file).unwrap()).unwrap(); + let n = case["n"].as_u64().unwrap() as usize; + let rank = case["rank"].as_u64().unwrap() as usize; + let mut oracle = Oracle { + planned: TensorGenericNumerator::new(rank, 0, &prototype).unwrap(), + dense: dense_reference::TensorGenericNumerator::new(rank, 0, &prototype).unwrap(), + counts: BTreeMap::new(), + }; + let mut amplitude = SymbolicaAmplitudeKernels::new(n, rank, prototype.clone()).unwrap().into_amplitude(1).unwrap(); + for lane in case["lanes"].as_array().unwrap() { + let flatten = |key: &str| -> Vec { + let strings: Vec<_> = lane[key].as_array().unwrap().iter().flat_map(|v| v.as_array().unwrap()).map(|v| Value::String(format!("{:.39e}", v.as_f64().unwrap()))).collect(); + records(&Value::Array(strings)) + }; + let coefficients = pairs(flatten("tensor")); + assert_eq!(coefficients.len(), ncoeff(rank)); + oracle.planned.set_coefficients(coefficients.clone(), 1).unwrap(); + oracle.dense.set_coefficients(coefficients, 1).unwrap(); + let masses = pairs(flatten("masses_squared")); + let shifts: Vec<_> = flatten("shifts").chunks_exact(4).map(|v| FourMomentum::from(std::array::from_fn(|k| real(v[k].clone())))).collect(); + let smat: Vec<_> = flatten("s_matrix").into_iter().map(real).collect(); + let scale = records(&serde_json::json!([format!("{:.39e}", lane["mu_squared"].as_f64().unwrap())])); + let scales: Vec<_> = scale.into_iter().map(real).collect(); + let sampling = [real(smat.iter().chain(&masses).map(|v| v.re.norm()).fold(Float::with_val(MP_BITS, 1), |a,b| if b>a {b} else {a}))]; + amplitude.reset_batch(1); + amplitude.evaluate_batch_with_inputs(AmplitudeInput { + shifts: &shifts, masses_squared: &masses, scales_squared: &scales, + sampling_scales: &sampling, s_matrix: Some(&smat), + }, &mut oracle, &mut low, &mut high, &mut masters).unwrap(); + assert_eq!(amplitude.statuses()[0], EvaluationStatus::Success); + assert!(amplitude.results()[0].iter().all(|z| z.re.is_finite() && z.im.is_finite())); + tested += 1; + eprintln!("golden {} lane {}: exact original numerator values/expansions", file.file_name().unwrap().to_string_lossy(), lane["id"]); + } + for (kind, count) in oracle.counts { *total.entry(kind).or_default() += count; } + } + assert_eq!(tested, 21); + eprintln!("golden exact lanes={tested}; expansion/value counts={total:?}"); + }).unwrap().join().unwrap(); +} diff --git a/vendor/ninjars/src/tensor_dense_reference.rs b/vendor/ninjars/src/tensor_dense_reference.rs new file mode 100644 index 0000000000..acd6d02d7a --- /dev/null +++ b/vendor/ninjars/src/tensor_dense_reference.rs @@ -0,0 +1,405 @@ +// Adapted from NinjaRS 0d0d7e7a8033431b60a8580731084742e0655cda, +// crates/ninjars-cli/src/case_check/harness.rs, precision-generic tensor section. +// Copyright the NinjaRS contributors; GPL-3.0-or-later. +// Keep the numerical recurrence in sync with the pinned upstream implementation. +use ninjars::fast::tensor_layout::{monomial_index, monomials, mu_block_offset, ncoeff, ncoeff_mu}; +use ninjars::{ + BatchShape, Complex, ExpansionKind, ExpansionRequest, FloatLike, FourMomentum, Numerator, + NumeratorRequest, Real, SingleFloat, +}; +type Result = std::result::Result>; +/// Shape of one Laurent expansion: `q = t F(u, x, mu^2)` with `u = 1/t`. +#[derive(Clone, Copy, PartialEq, Eq)] +enum Shape { + /// `Mu` (`beta = 0`) and `MuShifted`: `F = v0 + v1 u`, `mu^2 = t^2 (v0^2 - beta u^2)`. + Mu, + /// `F = e3 + a u + (beta + mu^2) e4 u^2`. + T3, + /// `F = e3 + (a0 + x a1) u + (b0 + b1 x + b2 x^2 + mu^2) e4 u^2`. + T2, +} + +/// A dense tensor numerator `N(q, mu^2) = sum_k (mu^2)^k T_k(q)` in the +/// `tensor_layout` (and `MuTensorNumerator` block) order for the generic +/// engine in any precision. +/// +/// Expansions are computed numerically: each monomial `q^m = t^|m| prod_c +/// F_c^(m_c)` is a truncated series in `u = 1/t` (and `x`, `mu^2` for the +/// triangle and bubble parametrisations), built from its parent monomial with +/// one multiplication by `F_c`; the requested Laurent coefficients are then +/// contracted with the lane's coefficients. Exact arithmetic would reproduce +/// [`ninjars_symbolica::PolynomialNumerator`] exactly; in floating point both +/// round differently. +pub struct TensorGenericNumerator { + rank: usize, + mu_powers: usize, + width: usize, + degrees: Vec, + /// `(parent monomial, component)` of every monomial but the constant. + parents: Vec<(usize, usize)>, + coefficients: Vec>, + lanes: usize, + zero: Complex, + one: Complex, + values_work: Vec>, + series_work: Vec>, +} + +impl TensorGenericNumerator +where + Complex: Real, +{ + pub fn new(rank: usize, mu_powers: usize, prototype: &T) -> Result { + if 2 * mu_powers > rank { + return Err("mu_powers exceeds rank / 2".into()); + } + let list = monomials(rank); + let degrees = list + .iter() + .map(|m| m.iter().sum::() as usize) + .collect(); + let parents = list + .iter() + .map(|m| { + let Some(c) = (0..4).rev().find(|&c| m[c] > 0) else { + return (0, 0); + }; + let mut parent = *m; + parent[c] -= 1; + (monomial_index(parent), c) + }) + .collect(); + let zero = Complex::new(prototype.zero(), prototype.zero()); + let one = Complex::new(prototype.one(), prototype.zero()); + Ok(Self { + rank, + mu_powers, + width: ncoeff_mu(rank, mu_powers), + degrees, + parents, + coefficients: Vec::new(), + lanes: 0, + zero, + one, + values_work: Vec::new(), + series_work: Vec::new(), + }) + } + + /// Bind lane-major coefficients (`width()` per lane). + pub fn set_coefficients(&mut self, coefficients: Vec>, lanes: usize) -> Result<()> { + if coefficients.len() != lanes * self.width { + return Err(format!( + "{} coefficients for {lanes} lanes of width {}", + coefficients.len(), + self.width + ) + .into()); + } + self.coefficients = coefficients; + self.lanes = lanes; + Ok(()) + } + + /// `(offset, size)` of the `mu^(2k)` block. + fn block(&self, k: usize) -> (usize, usize) { + (mu_block_offset(self.rank, k), ncoeff(self.rank - 2 * k)) + } + + fn lane_coefficients(&self, lane: usize) -> ninjars::Result<&[Complex]> { + if lane >= self.lanes { + return Err(ninjars::Error::Lane { + lane, + lanes: self.lanes, + }); + } + Ok(&self.coefficients[lane * self.width..(lane + 1) * self.width]) + } +} + +fn minkowski(a: &[Complex; 4], b: &[Complex; 4]) -> Complex +where + Complex: Real, +{ + a[0].clone() * &b[0] - a[1].clone() * &b[1] - a[2].clone() * &b[2] - a[3].clone() * &b[3] +} + +fn components(v: &FourMomentum) -> [T; 4] { + v.components().map(|x| x.clone()) +} + +impl Numerator> for TensorGenericNumerator +where + Complex: Real, +{ + fn rank(&self) -> usize { + self.rank + } + + fn evaluate_batch( + &mut self, + requests: &[NumeratorRequest<'_, Complex>], + output: &mut [Complex], + ) -> ninjars::Result<()> { + BatchShape { + rows: requests.len(), + columns: 1, + } + .validate("numerator output", output.len())?; + let count = self.degrees.len(); + let mut values = std::mem::take(&mut self.values_work); + values.resize(count, self.zero.clone()); + for (request, out) in requests.iter().zip(output.iter_mut()) { + let coefficients = self.lane_coefficients(request.id.lane)?; + let q = components(request.q); + values[0] = self.one.clone(); + for i in 1..count { + let (parent, c) = self.parents[i]; + values[i] = values[parent].clone() * &q[c]; + } + let mut total = self.zero.clone(); + let mut mu_power = self.one.clone(); + for k in 0..=self.mu_powers { + let (offset, size) = self.block(k); + let mut block = self.zero.clone(); + for (c, v) in coefficients[offset..offset + size].iter().zip(&values) { + block += c.clone() * v; + } + total += block * &mu_power; + mu_power *= request.mu_squared; + } + *out = total; + } + self.values_work = values; + Ok(()) + } + + fn expansion_batch( + &mut self, + kind: &ExpansionKind, + requests: &[ExpansionRequest<'_, Complex>], + output: &mut [Complex], + ) -> ninjars::Result<()> { + let columns = kind.len(); + BatchShape { + rows: requests.len(), + columns, + } + .validate("expansion output", output.len())?; + let (shape, vectors, scalars, shifted) = match kind { + ExpansionKind::Mu { .. } => (Shape::Mu, 2, 0, false), + ExpansionKind::MuShifted { .. } => (Shape::Mu, 2, 1, true), + ExpansionKind::T3 { .. } => (Shape::T3, 3, 1, false), + ExpansionKind::T2 { .. } => (Shape::T2, 4, 3, false), + }; + for request in requests { + self.lane_coefficients(request.id.lane)?; + if request.vectors.len() != vectors + && !(matches!(kind, ExpansionKind::Mu { .. }) && request.vectors.len() == 1) + { + return Err(ninjars::Error::Shape { + name: "cut vectors", + expected: vectors, + actual: request.vectors.len(), + }); + } + BatchShape { + rows: 1, + columns: scalars, + } + .validate("cut parameters", request.parameters.len())?; + } + if requests.is_empty() || columns == 0 { + return Ok(()); + } + // Requested (t power, x power, mu^2 power) per column. + let powers: Vec<(i64, usize, usize)> = match kind { + ExpansionKind::Mu { powers } | ExpansionKind::MuShifted { powers } => { + powers.iter().map(|&p| (i64::from(p), 0, 0)).collect() + } + ExpansionKind::T3 { powers } => powers + .iter() + .map(|&(p, l)| (i64::from(p), 0, usize::from(l))) + .collect(), + ExpansionKind::T2 { powers } => powers + .iter() + .map(|&(p, a, l)| (i64::from(p), usize::from(a), usize::from(l))) + .collect(), + }; + let lowest = powers.iter().map(|p| p.0).min().unwrap_or(0); + // Deepest u order any term reaches at the requested powers. + let depth = (self.rank as i64 - lowest).max(0) as usize; + let (xs, mus) = match shape { + Shape::Mu => (1, 1), + Shape::T3 => (1, depth / 2 + 1), + Shape::T2 => (depth + 1, depth / 2 + 1), + }; + let size = (depth + 1) * xs * mus; + let at = |j: usize, a: usize, l: usize| (j * xs + a) * mus + l; + let count = self.degrees.len(); + let mut series = std::mem::take(&mut self.series_work); + series.resize(count * size, self.zero.clone()); + for (row, request) in requests.iter().enumerate() { + let coefficients = self.lane_coefficients(request.id.lane)?; + let v: Vec<[Complex; 4]> = request.vectors.iter().map(components).collect(); + let zero4 = || std::array::from_fn::<_, 4, _>(|_| self.zero.clone()); + // Factor coefficients per component: [1, u, u x, u^2, u^2 x, u^2 x^2, u^2 mu^2]. + let factors: Vec<[Complex; 7]> = (0..4) + .map(|c| { + let z = || self.zero.clone(); + match shape { + Shape::Mu => { + let v1 = v.get(1).cloned().unwrap_or_else(zero4); + [v[0][c].clone(), v1[c].clone(), z(), z(), z(), z(), z()] + } + Shape::T3 => { + let e4 = &v[2][c]; + [ + v[1][c].clone(), + v[0][c].clone(), + z(), + request.parameters[0].clone() * e4, + z(), + z(), + e4.clone(), + ] + } + Shape::T2 => { + let e4 = &v[3][c]; + [ + v[2][c].clone(), + v[0][c].clone(), + v[1][c].clone(), + request.parameters[0].clone() * e4, + request.parameters[1].clone() * e4, + request.parameters[2].clone() * e4, + e4.clone(), + ] + } + } + }) + .collect(); + for value in series.iter_mut() { + *value = self.zero.clone(); + } + series[at(0, 0, 0)] = self.one.clone(); + for i in 1..count { + let (parent, c) = self.parents[i]; + let f = &factors[c]; + let (head, tail) = series.split_at_mut(i * size); + let source = &head[parent * size..(parent + 1) * size]; + let target = &mut tail[..size]; + for j in 0..=depth { + for a in 0..xs.min(j + 1) { + for l in 0..mus { + if a + 2 * l > j { + break; + } + let mut acc = f[0].clone() * &source[at(j, a, l)]; + if j >= 1 { + acc += f[1].clone() * &source[at(j - 1, a, l)]; + if shape == Shape::T2 && a >= 1 { + acc += f[2].clone() * &source[at(j - 1, a - 1, l)]; + } + } + if j >= 2 && shape != Shape::Mu { + acc += f[3].clone() * &source[at(j - 2, a, l)]; + if shape == Shape::T2 { + if a >= 1 { + acc += f[4].clone() * &source[at(j - 2, a - 1, l)]; + } + if a >= 2 { + acc += f[5].clone() * &source[at(j - 2, a - 2, l)]; + } + } + if l >= 1 { + acc += f[6].clone() * &source[at(j - 2, a, l - 1)]; + } + } + target[at(j, a, l)] = acc; + } + } + } + } + let out = &mut output[row * columns..(row + 1) * columns]; + match shape { + Shape::Mu => { + // mu^2 = t^2 G(u), G = v0^2 - beta u^2; powers G^k truncated at depth. + let g0 = minkowski(&v[0], &v[0]); + let beta = if shifted { + request.parameters[0].clone() + } else { + self.zero.clone() + }; + let mut g_powers = vec![{ + let mut s = vec![self.zero.clone(); depth + 1]; + s[0] = self.one.clone(); + s + }]; + for k in 1..=self.mu_powers { + let previous = &g_powers[k - 1]; + let mut s = vec![self.zero.clone(); depth + 1]; + for j in 0..=depth { + let mut acc = g0.clone() * &previous[j]; + if j >= 2 { + acc -= beta.clone() * &previous[j - 2]; + } + s[j] = acc; + } + g_powers.push(s); + } + for (column, &(p, _, _)) in powers.iter().enumerate() { + let mut acc = self.zero.clone(); + for (k, g) in g_powers.iter().enumerate() { + let (offset, block) = self.block(k); + for i in 0..block { + let c = &coefficients[offset + i]; + if c.is_fully_zero() { + continue; + } + let j = (self.degrees[i] + 2 * k) as i64 - p; + if j < 0 || j as usize > depth { + continue; + } + let j = j as usize; + let s = &series[i * size..(i + 1) * size]; + let mut term = self.zero.clone(); + for j1 in 0..=j { + term += s[at(j1, 0, 0)].clone() * &g[j - j1]; + } + acc += term * c; + } + } + out[column] = acc; + } + } + Shape::T3 | Shape::T2 => { + for (column, &(p, a, total_mu)) in powers.iter().enumerate() { + let mut acc = self.zero.clone(); + for k in 0..=self.mu_powers.min(total_mu) { + let l = total_mu - k; + if l >= mus || a >= xs { + continue; + } + let (offset, block) = self.block(k); + for i in 0..block { + let c = &coefficients[offset + i]; + if c.is_fully_zero() { + continue; + } + let j = self.degrees[i] as i64 - p; + if j < 0 || j as usize > depth || a + 2 * l > j as usize { + continue; + } + acc += series[i * size + at(j as usize, a, l)].clone() * c; + } + } + out[column] = acc; + } + } + } + } + self.series_work = series; + Ok(()) + } +} diff --git a/vendor/ninjars/src/transport_contract_tests.rs b/vendor/ninjars/src/transport_contract_tests.rs new file mode 100644 index 0000000000..f7b3aff1e0 --- /dev/null +++ b/vendor/ninjars/src/transport_contract_tests.rs @@ -0,0 +1,66 @@ +use super::*; +fn record(text:&str)->[u8;RECORD] { + assert!(text.len()<=RECORD); + let mut out=[b' ';RECORD];out[..text.len()].copy_from_slice(text.as_bytes());out +} +// Proposed tests inside vendor/ninjars/src/lib.rs existing cfg(test) module. +// Expected values are exact integer dyadics; no engine/context is constructed. +#[test] +fn mp_transport_preserves_binary128_finite_dyadics_and_sign() { + use symbolica::domains::rational::Rational; + let cases: &[(&str, &str, i128, i32, bool)] = &[ + ("+zero", "0.000000000000000000000000000000000000000E+39", 0_i128, 0, false), + ("-zero", "-0.000000000000000000000000000000000000000E+39", 0_i128, 0, true), + ("+min_subnormal", "6.475175119438025110924438958227646552500E-4966", 1_i128, -16494, false), + ("-min_subnormal", "-6.475175119438025110924438958227646552500E-4966", 1_i128, -16494, true), + ("+max_subnormal", "3.362103143112093506262677817321751955081E-4932", 5192296858534827628530496329220095_i128, -16494, false), + ("-max_subnormal", "-3.362103143112093506262677817321751955081E-4932", 5192296858534827628530496329220095_i128, -16494, true), + ("+min_normal", "3.362103143112093506262677817321752602598E-4932", 1_i128, -16382, false), + ("-min_normal", "-3.362103143112093506262677817321752602598E-4932", 1_i128, -16382, true), + ("+max_finite", "1.189731495357231765085759326628007016196E+4932", 10384593717069655257060992658440191_i128, 16271, false), + ("-max_finite", "-1.189731495357231765085759326628007016196E+4932", 10384593717069655257060992658440191_i128, 16271, true), + ("+beyond_dp", "1.000000000000000000000000000000788860905E+0", 1267650600228229401496703205377_i128, -100, false), + ("-beyond_dp", "-1.000000000000000000000000000000788860905E+0", 1267650600228229401496703205377_i128, -100, true), + ("+last_binary128_bit", "1.000000000000000000000000000000000192593E+0", 5192296858534827628530496329220097_i128, -112, false), + ("-last_binary128_bit", "-1.000000000000000000000000000000000192593E+0", 5192296858534827628530496329220097_i128, -112, true), + ]; + for &(name, text, significand, exponent, negative) in cases { + let mut expected = Rational::from(significand); + let scale = Rational::from(2).pow(u64::from(exponent.unsigned_abs())); + expected = if exponent < 0 { expected / scale } else { expected * scale }; + if negative { expected = -expected; } + for precision in [256, 384] { + let parsed = parse_record_at_precision(&record(text), precision).unwrap(); + assert_eq!(parsed.prec(), precision, "{name}"); + assert_eq!(parsed.to_rational(), expected, "{name}"); + assert_eq!(parsed.is_sign_negative(), negative, "{name}"); + let formatted = format!("{parsed:.39e}"); + assert!(formatted.len() <= RECORD); + let back = Float::parse(&formatted, Some(113)).unwrap(); + assert_eq!(back.to_rational(), expected, "output {name}"); + assert_eq!(back.is_sign_negative(), negative, "output {name}"); + } + } + for precision in [256, 384] { + for text in ["NaN", "nan", "+inf", "-inf", "not-a-number"] { + assert!(parse_record_at_precision(&record(text), precision).is_err()); + } + } +} + +#[test] +fn mp_transport_preserves_complex_branch_lips() { + for precision in [256, 384] { + let real = parse_record_at_precision(&record("-1"), precision).unwrap(); + let plus = parse_record_at_precision(&record("0"), precision).unwrap(); + let minus = parse_record_at_precision(&record("-0"), precision).unwrap(); + let upper = Complex::new(real.clone(), plus); + let lower = Complex::new(real, minus); + let upper_sqrt = upper.sqrt(); + let lower_sqrt = lower.sqrt(); + assert_eq!(upper_sqrt.im, Float::with_val(precision, 1)); + assert_eq!(lower_sqrt.im, Float::with_val(precision, -1)); + assert!(!upper.log().im.is_sign_negative()); + assert!(lower.log().im.is_sign_negative()); + } +} diff --git a/vendor/ninjars/src/transport_replay_tests.rs b/vendor/ninjars/src/transport_replay_tests.rs new file mode 100644 index 0000000000..6507cce5cf --- /dev/null +++ b/vendor/ninjars/src/transport_replay_tests.rs @@ -0,0 +1,63 @@ +//! Held full replay through the isolated production MpState, retaining changes. +use super::*; +use serde_json::{Value,json}; +use std::io::Write; + +fn packed(value:&Value)->Vec { + let mut result=Vec::new(); + for value in value.as_array().unwrap() { + let text=value.as_str().unwrap().as_bytes(); + assert!(text.len()<=RECORD); + let mut record=[b' ';RECORD]; + record[..text.len()].copy_from_slice(text); + result.extend(record); + } + result +} + +#[test] +#[ignore="requires exclusive MP slot and retained 1392-request capture"] +fn all_stored_requests_retain_outputs_after_transport_fix() { + let input=std::fs::read_to_string(std::env::var("NINJARS_TRANSPORT_REPLAY").unwrap()).unwrap(); + let output=std::env::var("NINJARS_TRANSPORT_REPLAY_OUTPUT").unwrap(); + std::thread::Builder::new().stack_size(128*1024*1024).spawn(move || { + let mut stream=std::io::BufWriter::new(std::fs::OpenOptions::new().write(true).create_new(true).open(output).unwrap()); + let mut state=MpState::new().unwrap(); + let mut tested=0usize; + let mut changed_records=0usize; + let mut changed_fields=0usize; + let mut failures=0usize; + for line in input.lines() { + let record:Value=serde_json::from_str(line).unwrap(); + assert_eq!(record["status"],0); + let n=record["n"].as_u64().unwrap() as usize; + let rank=record["rank"].as_u64().unwrap() as usize; + let (reply,_)=std::sync::mpsc::sync_channel(1); + let request=MpRequest { selection: PoleSelection::BOTH, context_id:0,n,rank,coefficients:packed(&record["coefficients"]), + s_matrix:packed(&record["s_matrix"]),momenta:packed(&record["momenta"]), + masses:packed(&record["masses"]),scale:packed(&record["scale"]),reply }; + assert_eq!(request.coefficients.len(),RECORD*2*ninjars::fast::tensor_layout::ncoeff(rank)); + let expected:Vec=record["output"].as_array().unwrap().iter().map(|v|v.as_str().unwrap().to_owned()).collect(); + assert_eq!(expected.len(),8); + let result=match state.evaluate(&request) { + Ok((status,output))=> { + let actual:Vec=output.chunks_exact(RECORD).map(|row|std::str::from_utf8(row).unwrap().trim().to_owned()).collect(); + let changed:Vec=(0..8).filter(|&i|actual.get(i)!=expected.get(i)).collect(); + if status!=SUCCESS || actual.len()!=8 {failures+=1;} + if !changed.is_empty() {changed_records+=1;changed_fields+=changed.len();} + json!({"record":tested,"n":n,"rank":rank,"status":status, + "expected":expected,"actual":actual,"changed_fields":changed}) + } + Err(error)=> {failures+=1;json!({"record":tested,"n":n,"rank":rank,"error":error,"expected":expected})} + }; + serde_json::to_writer(&mut stream,&result).unwrap();stream.write_all(b"\n").unwrap();stream.flush().unwrap(); + tested+=1; + } + assert_eq!(tested,1392); + serde_json::to_writer(&mut stream,&json!({"complete":true,"records":tested, + "changed_records":changed_records,"changed_fields":changed_fields,"failures":failures})).unwrap(); + stream.write_all(b"\n").unwrap();stream.flush().unwrap(); + assert_eq!(failures,0,"retain and investigate all failure records"); + assert_eq!(changed_records,0,"retain and investigate all changed fields; never rewrite old expected outputs"); + }).unwrap().join().unwrap(); +} diff --git a/vendor/ninjars/src/upstream_master_tests.rs b/vendor/ninjars/src/upstream_master_tests.rs new file mode 100644 index 0000000000..286fa5ebb4 --- /dev/null +++ b/vendor/ninjars/src/upstream_master_tests.rs @@ -0,0 +1,194 @@ +//! Final upstream master-provider controls at MadLoop's rescue threshold. +//! +//! The soft box and its independent COLLIER/OneLOop references are from +//! NinjaRS aa6a6307 `tests/soft_box_labelling.rs`. The planar sentinels are +//! oneloopmaster 8ec256fc `STATUS.md`, ns9210 and ns11857. These controls +//! deliberately preserve upstream failures rather than accepting a finite +//! value merely because its tracked precision is large. +use super::*; +use ninjars::{Laurent, MasterFailure, MasterIntegral, MasterProvider, MasterRequest, MasterStatus}; +use ninjars_symbolica::tracked_bits; +use serde_json::json; +use symbolica::domains::float::RealLike; + +fn run(body: impl FnOnce() + Send + 'static) { + std::thread::Builder::new().stack_size(128 * 1024 * 1024) + .spawn(body).unwrap().join().unwrap(); +} + +fn provider(bits: u32) -> SymbolicaMasters { + // Exactly the production bridge threshold, independent of working bits. + let threshold = Float::with_val(bits, 1_000_000_000_000_000i64) + / Float::with_val(bits, 2).pow(112); + SymbolicaMasters::new(Float::new(bits)).with_onshell_threshold(Some(threshold)) +} + +fn recovered(text: &str, bits: u32) -> Float { + let mut record = [b' '; RECORD]; + record[..text.len()].copy_from_slice(text.as_bytes()); + parse_record_at_precision(&record, bits).unwrap() +} + +fn dyadic(value: f64, bits: u32) -> Float { + // The STATUS inputs are binary64 values. The same fixed-width transport + // used by MadLoop preserves them exactly through binary128 recovery. + recovered(&format!("{value:.39e}"), bits) +} + +fn rows(provider: &mut SymbolicaMasters, invariant_rows: &[[f64; 6]], + mass_rows: &[[(f64, f64); 4]], scales: &[f64], bits: u32) + -> (Vec>, Vec) { + let invariants: Vec<_> = invariant_rows.iter().flatten() + .map(|value| real(dyadic(*value, bits))).collect(); + let masses: Vec<_> = mass_rows.iter().flatten().map(|(re, im)| + Complex::new(dyadic(*re, bits), dyadic(*im, bits))).collect(); + let scales: Vec<_> = scales.iter().map(|value| real(dyadic(*value, bits))).collect(); + let sentinel = || real(Float::with_val(bits, 991)); + let mut output = vec![std::array::from_fn(|_| sentinel()); scales.len()]; + let mut statuses = vec![MasterStatus::Success; scales.len()]; + provider.evaluate_batch(MasterRequest {integral: MasterIntegral::D0, + invariants: &invariants, masses_squared: &masses, scales_squared: &scales}, + &mut output, &mut statuses).unwrap(); + (output, statuses) +} + +fn soft_rows() -> (Vec<[f64; 6]>, Vec<[(f64, f64); 4]>) { + // d_ij = (q_i-q_j)^2. Reorder the propagators, then read the four + // external invariants and the two channels in OneLOop's documented order. + let (h,m,a,b,s) = (15625.,29929.,1299773111931./1562500., + 976955119487./3125000.,1756052./5.); + let distance = [[0.,h,s,a],[h,0.,m,b],[s,m,0.,m],[a,b,m,0.]]; + let masses = [m,m,0.,m]; + let mut invariant_rows = Vec::new(); + let mut mass_rows = Vec::new(); + for i in 0..4 { for j in 0..4 { for k in 0..4 { for l in 0..4 { + if i == j || i == k || i == l || j == k || j == l || k == l { continue; } + invariant_rows.push([distance[i][j],distance[j][k],distance[k][l], + distance[l][i],distance[i][k],distance[j][l]]); + mass_rows.push([i,j,k,l].map(|index| (masses[index],-0.))); + }}}} + assert_eq!(invariant_rows.len(),24); + (invariant_rows,mass_rows) +} + +fn represented(values: &Laurent) -> Vec> { + values.iter().map(|z| vec![format!("{:.39e}",z.re),format!("{:.39e}",z.im)]).collect() +} + +#[test] +#[ignore = "requires exclusive MP slot; final-provider soft D0 permutations and failed-row recovery"] +fn soft_box_permutations_and_failure_recovery() { + run(|| { + let (invariants,masses) = soft_rows(); + let references: [(f64,f64);3] = [(-2.0688070109990276e-10,4.1246220036002915e-11), + (-2.6860952042523525e-11,3.9817595477722426e-11),(0.,0.)]; + for bits in [256,384] { + let mut state = provider(bits); + let (batch,statuses) = rows(&mut state,&invariants,&masses,&[1e6;24],bits); + assert!(statuses.iter().all(|status| *status == MasterStatus::Success),"{statuses:?}"); + for (index,values) in batch.iter().enumerate() { + for (value,(re,im)) in values.iter().zip(references) { + let error = (value.re.to_f64()-re).hypot(value.im.to_f64()-im); + assert!(error <= 1e-13*references[0].0.hypot(references[0].1), + "labelling{index} at{bits}bits: {value:?}"); + } + for (actual,expected) in values.iter().zip(&batch[0]) { + let delta = (actual.re.clone()-&expected.re).norm() + +(actual.im.clone()-&expected.im).norm(); + assert!(delta <= Float::parse("1e-31",Some(bits)).unwrap() + * (batch[0][0].re.norm()+batch[0][0].im.norm())); + } + println!("NINJARS_UPSTREAM_SOFT_BOX {}",json!({"working_bits":bits, + "permutation":index,"status":format!("{:?}",statuses[index]), + "output":represented(values),"laurent_and_permutation_passed":true, + "input_precision_bits":113,"threshold":"1e15*2^-112"})); + } + let mut invalid = masses[0]; invalid[0].1=1.; + let (rejected,status) = rows(&mut state,&[invariants[0]],&[invalid],&[1e6],bits); + assert_eq!(status,[MasterStatus::Failed(MasterFailure::InvalidMass)]); + assert!(rejected[0].iter().all(|value| value == &real(Float::with_val(bits,991)))); + let (recovered,status) = rows(&mut state,&[invariants[0]],&[masses[0]],&[1e6],bits); + assert_eq!(status,[MasterStatus::Success]); + assert_eq!(recovered[0],batch[0]); + } + }); +} + +#[test] +#[ignore = "requires exclusive MP slot; upstream known-tail diagnostic, success is not certification"] +fn planar_box_sentinels_retain_unconverged_successes() { + run(|| { + let cases = [ + ("ns9210",1.,[-285.2138671875,13.123821258544922,0.,-780.9905891418457, + -340.4909248352051,-104.8216438293457], + [(6.957667603777042,-4.856459427327334), + (6.957667603777042,-4.856459427327334), + (6.957667603777042,-4.856459427327334),(0.,0.)]), + ("ns11857",0.00390625,[34.35824579000473,-29.8271062374115,0., + 0.5082151293754578,0.2645418047904968,-88.81898474693298], + [(0.,0.),(1.97227437591852e-5,-8.531542965385371e-15), + (4.155059391982788e-5,0.),(0.5082151293754578,0.)]), + ]; + let mut unconverged_successes = 0; + for (name,scale,invariants,masses) in cases { + // First reproduce STATUS's positive-zero records exactly, then + // check MadLoop's negative-zero physical branch lip separately. + for negative_zero in [false,true] { + let masses = masses.map(|(re,im)| + (re,if im==0. && negative_zero {-0.} else {im})); + let mut observations = Vec::new(); + for bits in [256,512,1024] { + let (output,status) = rows(&mut provider(bits),&[invariants],&[masses],&[scale],bits); + println!("NINJARS_UPSTREAM_PLANAR_BOX {}",json!({"case":name, + "working_bits":bits,"status":format!("{:?}",status[0]), + "output":represented(&output[0]),"input_invariants":invariants, + "input_masses_squared":masses,"scale_squared":scale, + "zero_mass_imaginary_sign":if negative_zero {"negative"} else {"positive"}, + "tracked_bits":output[0].iter().map(tracked_bits).collect::>(), + "threshold":"1e15*2^-112","performance_claim":false})); + observations.push((output[0].clone(),status[0])); + } + let distance = |left: &Laurent,right: &Laurent| { + let widen = |value: &Float| {let mut value=value.clone();value.set_prec(1024);value}; + let norm = right.iter().map(|z| widen(&z.re).norm()+widen(&z.im).norm()) + .fold(Float::new(1024),|a,b| if a>b {a} else {b}); + left.iter().zip(right).map(|(a,b)| + ((widen(&a.re)-widen(&b.re)).norm()+(widen(&a.im)-widen(&b.im)).norm())/&norm) + .fold(Float::new(1024),|a,b| if a>b {a} else {b}) + }; + // A rejected production result must retain its sentinels. Higher + // precision may reject too: that does not make the production + // rejection unsafe. An accepted production result, however, needs + // two successful and mutually converged higher-precision values. + let reference_error = (observations[1].1==MasterStatus::Success + && observations[2].1==MasterStatus::Success) + .then(|| distance(&observations[1].0,&observations[2].0)); + let reference_converged = reference_error.as_ref().is_some_and(|value| + value <= &Float::parse("1e-31",Some(1024)).unwrap()); + let error = (observations[0].1==MasterStatus::Success + && observations[2].1==MasterStatus::Success) + .then(|| distance(&observations[0].0,&observations[2].0)); + let rejected_output_untouched = observations[0].0.iter() + .all(|value| value == &real(Float::with_val(256,991))); + let passed = if observations[0].1==MasterStatus::Success { + reference_converged && error.as_ref().is_some_and(|value| + value <= &Float::parse("1e-31",Some(1024)).unwrap()) + } else { rejected_output_untouched }; + unconverged_successes += usize::from(!passed); + println!("NINJARS_UPSTREAM_PLANAR_COMPARISON {}",json!({"case":name, + "production_bits":256,"reference_bits":[512,1024],"tolerance":"1e-31", + "zero_mass_imaginary_sign":if negative_zero {"negative"} else {"positive"}, + "production_status":format!("{:?}",observations[0].1), + "maximum_scaled_difference":error.map(|value|format!("{value:.39e}")), + "reference_statuses":[format!("{:?}",observations[1].1), + format!("{:?}",observations[2].1)], + "reference_maximum_scaled_difference":reference_error.map(|value|format!("{value:.39e}")), + "reference_mutually_converged":reference_converged, + "rejected_output_untouched":rejected_output_untouched, + "accepted_or_rejected_safely":passed,"performance_claim":false})); + } + } + assert_eq!(unconverged_successes,0, + "upstream finite master successes fail convergence; retain as an outstanding diagnostic"); + }); +} diff --git a/vendor/ninjars/tests/data/cases/madloop-four-photon-top-box-0.json b/vendor/ninjars/tests/data/cases/madloop-four-photon-top-box-0.json new file mode 100644 index 0000000000..861b907047 --- /dev/null +++ b/vendor/ninjars/tests/data/cases/madloop-four-photon-top-box-0.json @@ -0,0 +1 @@ +{"format": "ninjars-bench-case-v1", "name": "madloop-four-photon-top-box-0", "n": 4, "rank": 4, "description": "exact inputs MadLoop (loop_optimized_output, MLReductionLib=6) passes to ninja_tensor_evaluate for the pool points, recorded with NINJA_BENCH_DUMP", "lanes": [{"id": "four-photon-top-box-0-madloop-sqrt_s_200", "shifts": [[0, 0, 0, 0], [100, 0, 0, 100], [200, 0, 0, 0], [100, -66.66666666666667, -33.333333333333336, -66.66666666666667]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 40000, 0], [0, 0, 0, -33333.33333333334], [40000, 0, 0, 0], [0, -33333.33333333334, 0, 0]], "tensor": [[-713971.0256401731, 0], [-18882.577848411325, 0], [-33038.90523748282, -9474.924907627737], [-16519.45261874141, 18949.849815255475], [16519.45261874141, 0], [0.3363598342207581, 0], [347.4139132796838, -94.74924907627741], [8.288190562947449, 31.58308302542577], [173.7069566398419, 189.49849815255482], [125.8838523227422, -47.37462453813867], [-86.12469867910923, -31.58308302542577], [-173.70695663984193, 0], [15.455181678492124, -15.791541512712922], [7.727590839246062, 31.583083025425843], [55.21433532212501, 0], [0.947492490762774, 0], [1.737069566398419, 5.551115123125783e-17], [1.105407905889903, 0.31583083025425795], [-0.789577075635645, 0], [0.8685347831992095, -1.1102230246251565e-16], [-1.2633233210170318, -0.47374624538138665], [-0.3947885378178225, 0], [2.0529003966526767, -0.31583083025425795], [-0.789577075635645, 0], [-0.3947885378178225, 0], [-0.8685347831992095, 0], [-0.9474924907627742, -0.15791541512712895], [1.0264501983263388, 2.7755575615628914e-17], [-0.4737462453813871, 0.3158308302542579], [0.6316616605085157, -2.7755575615628914e-17], [0.552703952944952, -2.7755575615628914e-17], [-0.15791541512712892, 0], [-0.4737462453813871, -2.7755575615628914e-17], [-0.23687312269069355, 5.551115123125783e-17], [0.07895770756356449, 0], [0.0023687312269069357, 0], [0, 0], [0.0055270395294495156, 6.505213034913027e-19], [0, 0], [0, 0], [0, 0], [-0.00631661660508516, 0], [0, 0], [0, 0], [0.010264501983263384, -6.505213034913027e-19], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-0.0047374624538138715, 0], [0, 0], [-0.007895770756356451, 0], [-0.0023687312269069357, 0], [0, 0], [-0.003947885378178226, 0], [0, 0], [-0.007895770756356451, 0], [-0.003947885378178226, 0], [-0.000789577075635645, 0], [0, 0], [-0.001579154151271289, -6.505213034913027e-19], [0, 0], [0.00631661660508516, 4.336808689942018e-19], [-0.006316616605085158, 6.505213034913027e-19], [0, 0], [0.0047374624538138715, 0], [0.0023687312269069357, 0], [-0.001579154151271291, 0]]}, {"id": "four-photon-top-box-0-madloop-sqrt_s_500", "shifts": [[0, 0, 0, 0], [250, 0, 0, 250], [500, 0, 0, 0], [250, -71.42857142857143, 107.14285714285714, -214.28571428571428]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 250000, 0], [0, 0, 0, -232142.85714285716], [250000, 0, 0, 0], [0, -232142.85714285716, 0, 0]], "tensor": [[-6686425.702526007, 3.571153138330265e-11], [33065.11919639389, 3.78099197672805e-14], [68300.45544044382, 190344.47359073578], [-102450.68316066574, 126896.3157271572], [-34150.22772022192, -8.706547709741159e-14], [319.9228698471023, -7.184116676773506e-16], [978.9144356094985, 761.3778943629432], [1216.8838941266204, -108.76827062327772], [-1468.3716534142475, 507.5852629086289], [113.36612295906491, 90.64022551939843], [1169.6480095603433, 108.76827062327772], [-489.45721780474935, 1.0455570580451334e-16], [-339.5835323962441, 54.38413531163889], [509.37529859436614, 36.25609020775923], [113.1087047185897, 6.138559618728373e-16], [1.015170525817258, 1.734723475976807e-18], [1.9578288712189973, 4.440892098500626e-16], [6.018510974488027, -0.4350730824931106], [-0.9426583454017392, -1.1102230246251565e-16], [-2.936743306828496, 1.1102230246251565e-16], [1.7402923299724429, 0.362560902077592], [1.413987518102609, -5.551115123125783e-17], [5.2933891703328415, 0.4350730824931106], [-0.9426583454017392, -2.220446049250313e-16], [1.413987518102609, -5.551115123125783e-17], [-0.9789144356094989, 1.7773014338920593e-18], [-1.5952679691414047, 0.21753654124655508], [0.7613778943629439, 1.3877787807814457e-16], [2.392901953712107, 0.14502436083103692], [-0.8701461649862217, 0], [1.1239387964405363, 1.3877787807814457e-16], [-0.07251218041551855, 0], [-0.21753654124655558, 0], [0.3263048118698335, 0], [0.03625609020775933, -4.257795791525218e-20], [0.0010151705258172581, 0], [0, 0], [0.012037021948976058, -2.168404344971009e-19], [0, 0], [0, 0], [0, 0], [0.0034805846599448883, 1.734723475976807e-18], [0, 0], [0, 0], [0.010586778340665685, 2.168404344971009e-19], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-0.00319053593828281, 8.673617379884035e-19], [0, 0], [-0.0037706333816069576, 4.336808689942018e-19], [0.004785803907424214, 0], [0, 0], [0.005655950072410437, 0], [0, 0], [-0.0037706333816069576, 0], [0.005655950072410437, 0], [-0.00014502436083103703, 0], [0, 0], [-0.010151705258172578, 2.168404344971009e-19], [0, 0], [-0.0034805846599448883, -2.0599841277224584e-18], [-0.008701461649862206, -2.168404344971009e-19], [0, 0], [0.0031905359382828095, -8.673617379884035e-19], [-0.004785803907424214, 0], [-0.000870146164986221, 0]]}, {"id": "four-photon-top-box-0-madloop-sqrt_s_800", "shifts": [[0, 0, 0, 0], [400, 0, 0, 400], [800, 0, 0, 0], [400, 177.77777777777777, -177.77777777777777, -311.1111111111111]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 640000, 0], [0, 0, 0, -568888.8888888889], [640000, 0, 0, 0], [0, -568888.8888888889, 0, 0]], "tensor": [[-28833483.439799175, 0], [328643.45537601254, 0], [-665689.1337908517, -808526.9254509003], [665689.1337908517, -808526.9254509003], [-332844.5668954258, 0], [1421.462976033641, 0], [-3818.0438146292513, -2021.3173136272508], [3299.3751956450783, -449.1816252505003], [3818.0438146292513, -2021.3173136272508], [730.3187897244726, 0], [3299.3751956450783, 449.1816252505003], [-1909.0219073146254, 0], [1446.1023427943546, -224.59081262525018], [-1446.1023427943546, -224.59081262525018], [403.53670089272043, 0], [2.5266466420340636, 0], [-4.7725547682865646, 2.220446049250313e-16], [7.860678441883756, -1.1229540631262513], [2.245908126252501, 0], [4.7725547682865646, 2.220446049250313e-16], [4.491816252505006, 0], [-2.245908126252501, 0], [7.860678441883756, 1.1229540631262513], [2.245908126252501, 0], [-2.245908126252501, 0], [-2.386277384143282, 0], [3.368862189378751, -0.561477031563126], [2.245908126252501, -1.1102230246251565e-16], [-3.368862189378751, -0.561477031563126], [-2.2459081262525036, 0], [2.245908126252501, 1.1102230246251565e-16], [-0.28073851578156306, 0], [0.8422155473446891, 2.220446049250313e-16], [-0.8422155473446891, 2.220446049250313e-16], [0.14036925789078164, 0], [0.0015791541512712897, 0], [0, 0], [0.009825848052354699, -8.673617379884035e-19], [0, 0], [0, 0], [0, 0], [0.0056147703156312605, 0], [0, 0], [0, 0], [0.009825848052354699, 8.673617379884035e-19], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0.004211077736723438, -4.336808689942018e-19], [0, 0], [0.005614770315631253, 0], [-0.004211077736723438, -4.336808689942018e-19], [0, 0], [-0.005614770315631253, 0], [0, 0], [0.005614770315631253, 0], [-0.005614770315631253, 0], [-0.0003509231447269539, 0], [0, 0], [-0.007018462894539072, 8.673617379884035e-19], [0, 0], [-0.0056147703156312605, 0], [-0.007018462894539072, -8.673617379884035e-19], [0, 0], [-0.004211077736723439, 4.336808689942018e-19], [0.004211077736723439, 4.336808689942018e-19], [-0.0012282310065443358, 0]]}]} diff --git a/vendor/ninjars/tests/data/cases/madloop-gg-hh-top-box-2.json b/vendor/ninjars/tests/data/cases/madloop-gg-hh-top-box-2.json new file mode 100644 index 0000000000..a5d8a8852e --- /dev/null +++ b/vendor/ninjars/tests/data/cases/madloop-gg-hh-top-box-2.json @@ -0,0 +1 @@ +{"format": "ninjars-bench-case-v1", "name": "madloop-gg-hh-top-box-2", "n": 4, "rank": 4, "description": "exact inputs MadLoop (loop_optimized_output, MLReductionLib=6) passes to ninja_tensor_evaluate for the pool points, recorded with NINJA_BENCH_DUMP", "lanes": [{"id": "gg-hh-top-box-2-madloop-sqrt_s_312.5", "shifts": [[0, 0, 0, 0], [156.25, 0, 0, 156.25], [312.5, 0, 0, 0], [156.25, -62.5, -31.25, -62.5]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 97656.25, 15625], [0, 0, 0, -52734.375], [97656.25, 0, 0, 15625], [15625, -52734.375, 15625, 0]], "tensor": [[372523983.61792946, 0], [13404301.21176524, 0], [-2018614.8430932546, -4468100.403921748], [-1009307.4215466273, 8936200.807843495], [-59962267.72824642, 0], [328852.1897286406, 0], [114383.37034039672, -28595.84258509918], [220021.81174483322, 0], [57191.68517019836, 57191.68517019836], [0, 0], [220021.81174483322, 0], [-85787.52775529757, 0], [-57191.68517019836, 0], [-28595.84258509918, 0], [-243064.66197334306, 0], [1830.1339254463478, 0], [366.0267850892695, 0], [-915.0669627231739, 0], [0, 0], [183.01339254463474, 0], [0, 0], [0, 0], [-915.0669627231739, 0], [0, 0], [0, 0], [-274.52008881695235, 0], [0, 0], [640.5468739062217, 0], [0, 0], [0, 0], [640.5468739062217, 0], [-1830.1339254463478, 0], [-366.0267850892695, 0], [-183.01339254463474, 0], [274.5200888169522, 0], [2.9282142807141565, 0], [0, 0], [-2.9282142807141565, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-2.9282142807141565, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-5.856428561428313, 0], [0, 0], [2.9282142807141565, 0], [0, 0], [0, 0], [2.9282142807141565, 0], [0, 0], [0, 0], [0, 0], [2.9282142807141565, 0]]}, {"id": "gg-hh-top-box-2-madloop-sqrt_s_416.7", "shifts": [[0, 0, 0, 0], [208.33333333333334, 0, 0, 208.33333333333334], [416.6666666666667, 0, 0, 0], [208.33333333333334, -47.61904761904762, 71.42857142857143, -142.85714285714286]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 173611.11111111112, 15625], [0, 0, 0, -130704.36507936509], [173611.11111111112, 0, 0, 15625], [15625, -130704.36507936509, 15625, 0]], "tensor": [[3789111454.1171737, 0], [16643082.986036554, 0], [3757534.143243608, 18156090.5302217], [-5636301.214865416, 12104060.353481133], [-83936950.55607657, 0], [548313.9340126954, 0], [116198.9793934189, 87149.23454506417], [222972.17645599428, 0], [-174298.46909012835, 58099.48969670945], [0, 0], [222972.17645599428, 0], [-79886.79833297554, 0], [-58099.48969670945, 0], [87149.23454506417, 0], [-468427.13567971985, 0], [2440.1785672617966, 0], [278.87755054420535, 0], [-1220.089283630898, 0], [0, 0], [-418.31632581630805, 0], [0, 0], [0, 0], [-1220.089283630898, 0], [0, 0], [0, 0], [-191.72831599914116, 0], [0, 0], [1028.3609676317574, 0], [0, 0], [0, 0], [1028.3609676317574, 0], [-2440.1785672617966, 0], [-278.87755054420535, 0], [418.31632581630805, 0], [191.7283159991411, 0], [2.9282142807141565, 0], [0, 0], [-2.9282142807141565, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-2.9282142807141565, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-5.856428561428313, 0], [0, 0], [2.9282142807141565, 0], [0, 0], [0, 0], [2.9282142807141565, 0], [0, 0], [0, 0], [0, 0], [2.9282142807141565, 0]]}, {"id": "gg-hh-top-box-2-madloop-sqrt_s_650", "shifts": [[0, 0, 0, 0], [325, 0, 0, 325], [650, 0, 0, 0], [325, 133.33333333333334, -133.33333333333334, -233.33333333333334]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 422500, 15624.999999999993], [0, 0, 0, -347291.66666666674], [422500, 0, 0, 15624.999999999993], [15624.999999999993, -347291.66666666674, 15624.999999999993, 0]], "tensor": [[13279807299.008095, 0], [56703649.456746005, 0], [-59107762.184783675, -82478035.57344875], [59107762.184783675, -82478035.57344875], [-162600200.74913457, 0], [1324406.9173813406, 0], [-507557.1419904538, -253778.5709952269], [175679.1918428728, 0], [507557.1419904538, -253778.5709952269], [0, 0], [175679.1918428728, 0], [-174472.76755921857, 0], [253778.5709952269, 0], [-253778.5709952269, 0], [-1149934.149822122, 0], [3806.678564928404, 0], [-780.857141523775, 0], [-1903.339282464202, 0], [0, 0], [780.857141523775, 0], [0, 0], [0, 0], [-1903.339282464202, 0], [0, 0], [0, 0], [-268.41964239879803, 0], [0, 0], [1634.919640065404, 0], [0, 0], [0, 0], [1634.919640065404, 0], [-3806.678564928404, 0], [780.857141523775, 0], [-780.857141523775, 0], [268.41964239879775, 0], [2.9282142807141565, 0], [0, 0], [-2.9282142807141565, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-2.9282142807141565, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-5.856428561428313, 0], [0, 0], [2.9282142807141565, 0], [0, 0], [0, 0], [2.9282142807141565, 0], [0, 0], [0, 0], [0, 0], [2.9282142807141565, 0]]}]} diff --git a/vendor/ninjars/tests/data/cases/madloop-gg-hh-top-triangle-0.json b/vendor/ninjars/tests/data/cases/madloop-gg-hh-top-triangle-0.json new file mode 100644 index 0000000000..8d7bd288c8 --- /dev/null +++ b/vendor/ninjars/tests/data/cases/madloop-gg-hh-top-triangle-0.json @@ -0,0 +1 @@ +{"format": "ninjars-bench-case-v1", "name": "madloop-gg-hh-top-triangle-0", "n": 3, "rank": 3, "description": "exact inputs MadLoop (loop_optimized_output, MLReductionLib=6) passes to ninja_tensor_evaluate for the pool points, recorded with NINJA_BENCH_DUMP", "lanes": [{"id": "gg-hh-top-triangle-0-madloop-sqrt_s_312.5", "shifts": [[0, 0, 0, 0], [156.25, 0, 0, 156.25], [312.5, 0, 0, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 97656.25], [0, 0, 0], [97656.25, 0, 0]], "tensor": [[31623.25012457252, 0], [522.895407270385, 0], [0, 0], [0, 0], [-522.895407270385, 0], [1.673265303265232, 0], [0, 0], [1.6732653032652323, 0], [0, 0], [0, 0], [1.6732653032652323, 0], [0, 0], [0, 0], [0, 0], [-1.673265303265232, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}, {"id": "gg-hh-top-triangle-0-madloop-sqrt_s_416.7", "shifts": [[0, 0, 0, 0], [208.33333333333334, 0, 0, 208.33333333333334], [416.6666666666667, 0, 0, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 173611.11111111112], [0, 0, 0], [173611.11111111112, 0, 0]], "tensor": [[49414.967470565534, 0], [362.0045127256511, 0], [0, 0], [0, 0], [-362.0045127256511, 0], [0.8688108305415627, 0], [0, 0], [0.8688108305415628, 0], [0, 0], [0, 0], [0.8688108305415628, 0], [0, 0], [0, 0], [0, 0], [-0.8688108305415627, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}, {"id": "gg-hh-top-triangle-0-madloop-sqrt_s_650", "shifts": [[0, 0, 0, 0], [325, 0, 0, 325], [650, 0, 0, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 422500], [0, 0, 0], [422500, 0, 0]], "tensor": [[61168.97944624096, 0], [219.2787191779034, 0], [0, 0], [0, 0], [-219.2787191779034, 0], [0.33735187565831287, 0], [0, 0], [0.337351875658313, 0], [0, 0], [0, 0], [0.337351875658313, 0], [0, 0], [0, 0], [0, 0], [-0.33735187565831287, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}]} diff --git a/vendor/ninjars/tests/data/cases/madloop-gg-hhh-top-box-8.json b/vendor/ninjars/tests/data/cases/madloop-gg-hhh-top-box-8.json new file mode 100644 index 0000000000..0fb0fb35ff --- /dev/null +++ b/vendor/ninjars/tests/data/cases/madloop-gg-hhh-top-box-8.json @@ -0,0 +1 @@ +{"format": "ninjars-bench-case-v1", "name": "madloop-gg-hhh-top-box-8", "n": 4, "rank": 4, "description": "exact inputs MadLoop (loop_optimized_output, MLReductionLib=6) passes to ninja_tensor_evaluate for the pool points, recorded with NINJA_BENCH_DUMP", "lanes": [{"id": "gg-hhh-top-box-8-madloop-sqrt_s_450", "shifts": [[0, 0, 0, 0], [225, 0, 0, 225], [450, 0, 0, 0], [300, 41.4578098794425, 71.80703308172536, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 202500, 83125], [0, 0, 0, -51875], [202500, 0, 0, 15625], [83125, -51875, 15625, 0]], "tensor": [[944471.8077896647, 0], [232324.22907520676, 0], [-14172.371302247897, 60045.68032159541], [-24547.26715922445, -34667.38969734732], [-417708.64567877946, 0], [2508.6267073556405, 0], [-308.1545750875318, 266.8696903182019], [462.8013655969977, 0], [-533.7393806364038, -154.0772875437659], [0, 0], [462.8013655969977, 0], [-1114.9452032691736, 0], [154.0772875437659, 0], [266.8696903182019, 0], [-1393.6815040864667, 0], [8.052382023610697, 0], [-0.6847879446389595, 0], [-3.0970700090810377, 0], [0, 0], [-1.1860875125253416, 0], [0, 0], [0, 0], [-3.0970700090810377, 0], [0, 0], [0, 0], [-1.8582420054486226, 0], [0, 0], [1.8582420054486226, 0], [0, 0], [0, 0], [1.8582420054486226, 0], [-8.052382023610697, 0], [0.6847879446389595, 0], [1.1860875125253416, 0], [1.8582420054486226, 0], [0.008258853357549435, 0], [0, 0], [-0.008258853357549435, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-0.008258853357549435, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-0.01651770671509887, 0], [0, 0], [0.008258853357549435, 0], [0, 0], [0, 0], [0.008258853357549435, 0], [0, 0], [0, 0], [0, 0], [0.008258853357549435, 0]]}, {"id": "gg-hhh-top-box-8-madloop-sqrt_s_525", "shifts": [[0, 0, 0, 0], [262.5, 0, 0, 262.5], [525, 0, 0, 0], [350, 61.237243569579455, 106.06601717798213, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 275625, 107500], [0, 0, 0, -76250], [275625, 0, 0, 15625], [107500, -76250, 15625, 0]], "tensor": [[2907160.5876228176, 0], [276783.02300642326, 0], [-28965.6314046698, 88693.34781184272], [-50169.94526620077, -51207.1282344965], [-435683.9515237714, 0], [2508.626707355641, 0], [-390.1495484533066, 337.8794202355913], [266.0668826707572, 0], [-675.7588404711826, -195.0747742266533], [0, 0], [266.0668826707572, 0], [-1114.9452032691738, 0], [195.0747742266533, 0], [337.8794202355913, 0], [-1393.6815040864672, 0], [6.902041734523456, 0], [-0.7431419970539174, 0], [-2.654631436355176, 0], [0, 0], [-1.287159696135586, 0], [0, 0], [0, 0], [-2.654631436355176, 0], [0, 0], [0, 0], [-1.5927788618131054, 0], [0, 0], [1.5927788618131054, 0], [0, 0], [0, 0], [1.5927788618131054, 0], [-6.902041734523456, 0], [0.7431419970539174, 0], [1.287159696135586, 0], [1.5927788618131054, 0], [0.006067728997383258, 0], [0, 0], [-0.006067728997383258, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-0.006067728997383258, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-0.012135457994766516, 0], [0, 0], [0.006067728997383258, 0], [0, 0], [0, 0], [0.006067728997383258, 0], [0, 0], [0, 0], [0, 0], [0.006067728997383258, 0]]}, {"id": "gg-hhh-top-box-8-madloop-sqrt_s_600", "shifts": [[0, 0, 0, 0], [300, 0, 0, 300], [600, 0, 0, 0], [400, 78.06247497997998, 135.2081728298996, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 360000, 135625], [0, 0, 0, -104375], [360000, 0, 0, 15625], [135625, -104375, 15625, 0]], "tensor": [[4181021.0937645286, 0], [320579.7297354841, 0], [-43569.18695149456, 113062.27780461451], [-75464.04544445552, -65276.53652568643], [-459618.04218816373, 0], [2508.626707355641, 0], [-435.17691017124287, 376.874259348715], [138.37863654074528, 0], [-753.74851869743, -217.58845508562143], [0, 0], [138.37863654074528, 0], [-1114.9452032691736, 0], [217.58845508562143, 0], [376.874259348715, 0], [-1393.6815040864672, 0], [6.039286517708025, 0], [-0.7252948502854047, 0], [-2.3228025068107785, 0], [0, 0], [-1.2562475311623833, 0], [0, 0], [0, 0], [-2.3228025068107785, 0], [0, 0], [0, 0], [-1.3936815040864672, 0], [0, 0], [1.3936815040864672, 0], [0, 0], [0, 0], [1.3936815040864672, 0], [-6.039286517708025, 0], [0.7252948502854047, 0], [1.2562475311623833, 0], [1.3936815040864672, 0], [0.004645605013621557, 0], [0, 0], [-0.004645605013621557, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-0.004645605013621557, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-0.009291210027243113, 0], [0, 0], [0.004645605013621557, 0], [0, 0], [0, 0], [0.004645605013621557, 0], [0, 0], [0, 0], [0, 0], [0.004645605013621557, 0]]}]} diff --git a/vendor/ninjars/tests/data/cases/madloop-gg-hhh-top-pentagon-26.json b/vendor/ninjars/tests/data/cases/madloop-gg-hhh-top-pentagon-26.json new file mode 100644 index 0000000000..df4aadf363 --- /dev/null +++ b/vendor/ninjars/tests/data/cases/madloop-gg-hhh-top-pentagon-26.json @@ -0,0 +1 @@ +{"format": "ninjars-bench-case-v1", "name": "madloop-gg-hhh-top-pentagon-26", "n": 5, "rank": 5, "description": "exact inputs MadLoop (loop_optimized_output, MLReductionLib=6) passes to ninja_tensor_evaluate for the pool points, recorded with NINJA_BENCH_DUMP", "lanes": [{"id": "gg-hhh-top-pentagon-26-madloop-sqrt_s_450", "shifts": [[0, 0, 0, 0], [225, 0, 0, 225], [450, 0, 0, 0], [300, -82.915619758885, 0, 0], [150, -41.4578098794425, -71.80703308172536, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 202500, 83125, 15625], [0, 0, 0, -51875, -51875], [202500, 0, 0, 15625, 83125], [83125, -51875, 15625, 0, 15625], [15625, -51875, 83125, 15625, 0]], "tensor": [[736270027776.8054, -151145496420.97668], [29504428215.77043, -953652828.6120431], [4989718818.072374, -764951045.4263523], [-569630256.5878286, 5534702672.0172], [-37867976466.29997, 953652828.6120431], [281797779.5614526, -2119228.508026763], [66403859.600122124, 1.324183065825839e-10], [30659260.417485416, 2119228.508026763], [23002971.729216382, 26561543.84004885], [0, 0], [30659260.417485416, 2119228.508026763], [-144154922.35093814, 0], [-39842315.760073274, -9.313225746154785e-10], [-23002971.72921637, 0], [-137642857.2105145, 2119228.508026763], [961032.8156729212, 0], [132807.71920024423, 25558.857476907087], [-320344.2718909738, 0], [44269.23973341475, -25558.857476907087], [76676.57243072127, 14756.413244471594], [0, 0], [25558.857476907087, -14756.413244471587], [-320344.2718909738, 0], [44269.23973341475, -25558.857476907087], [25558.857476907087, -14756.413244471585], [-320344.27189097373, 0], [0, 0], [320344.27189097373, 0], [0, 0], [0, 0], [320344.27189097373, 0], [-961032.8156729212, 0], [-132807.71920024423, -25558.857476907087], [-76676.57243072127, -14756.413244471594], [320344.27189097373, 0], [1067.814239636579, 0], [0, 0], [-711.8761597577193, 0], [0, 0], [-355.9380798788597, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-711.8761597577193, 0], [0, 0], [-711.8761597577194, 0], [0, 0], [0, 0], [-355.9380798788597, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-2135.628479273158, 0], [0, 0], [711.8761597577194, 0], [0, 0], [0, 0], [711.8761597577194, 0], [0, 0], [0, 0], [0, 0], [1067.814239636579, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}, {"id": "gg-hhh-top-pentagon-26-madloop-sqrt_s_525", "shifts": [[0, 0, 0, 0], [262.5, 0, 0, 262.5], [525, 0, 0, 0], [350, -122.47448713915891, 0, 0], [175, -61.237243569579455, -106.06601717798213, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 275625, 107500, 15625], [0, 0, 0, -76250, -76250], [275625, 0, 0, 15625, 107500], [107500, -76250, 15625, 0, 15625], [15625, -76250, 107500, 15625, 0]], "tensor": [[1745161943978.2883, -498828629990.6297], [50363965824.22308, -2427479927.376109], [12151946946.312319, -1129907576.4927464], [78828127.2249937, 11363060181.445639], [-55566543667.224434, 2427479927.37611], [390247663.27454275, -4623771.29024021], [114432501.18945831, 4.783602474053623e-09], [17645274.371914603, 4623771.29024021], [39640581.21946557, 45773000.47578333], [0, 0], [17645274.371914603, 4623771.29024021], [-196210866.53322142, 0], [-68659500.71367499, 0], [-39640581.219465576, -3.725290298461914e-09], [-194036796.74132136, 4623771.29024021], [1121204.951618408, 0], [196170.0020390714, 37752.93449472912], [-373734.9838728028, 0], [65390.00067969048, -37752.93449472912], [113258.80348418735, 21796.66689323017], [0, 0], [37752.93449472912, -21796.66689323017], [-373734.9838728028, 0], [65390.000679690485, -37752.93449472912], [37752.93449472912, -21796.66689323016], [-373734.9838728027, 0], [0, 0], [373734.9838728028, 0], [0, 0], [0, 0], [373734.9838728028, 0], [-1121204.951618408, 0], [-196170.00203907143, -37752.93449472912], [-113258.80348418735, -21796.66689323017], [373734.9838728027, 0], [1067.814239636579, 0], [0, 0], [-711.8761597577193, 0], [0, 0], [-355.9380798788597, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-711.8761597577193, 0], [0, 0], [-711.8761597577194, 0], [0, 0], [0, 0], [-355.9380798788597, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-2135.628479273158, 0], [0, 0], [711.8761597577194, 0], [0, 0], [0, 0], [711.8761597577194, 0], [0, 0], [0, 0], [0, 0], [1067.814239636579, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}, {"id": "gg-hhh-top-pentagon-26-madloop-sqrt_s_600", "shifts": [[0, 0, 0, 0], [300, 0, 0, 300], [600, 0, 0, 0], [400, -156.12494995995996, 0, 0], [200, -78.06247497997998, -135.2081728298996, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 360000, 135625, 15625], [0, 0, 0, -104375, -104375], [360000, 0, 0, 15625, 135625], [135625, -104375, 15625, 0, 15625], [15625, -104375, 135625, 15625, 0]], "tensor": [[3303441616937.1904, -1127577719608.6628], [78581410927.67152, -4508177007.984204], [22523934913.885864, -1440355195.2732134], [1454022904.700779, 19173903907.85557], [-78520759078.86017, 4508177007.984204], [515382144.4819543, -7513628.346640341], [166712444.7297936, -3.725290298461914e-09], [2629136.6270251945, 7513628.346640342], [57750884.90520418, 66684977.89191745], [0, 0], [2629136.6270251945, 7513628.346640342], [-256275417.51277897, 0], [-100027466.83787617, 0], [-57750884.90520418, -3.725290298461914e-09], [-259106726.9691754, 7513628.346640341], [1281377.0875638952, 0], [250068.66709469043, 48125.73742100348], [-427125.6958546317, 0], [83356.2223648968, -48125.73742100348], [144377.21226301044, 27785.4074549656], [0, 0], [48125.73742100348, -27785.407454965607], [-427125.6958546317, 0], [83356.2223648968, -48125.73742100348], [48125.73742100348, -27785.407454965603], [-427125.6958546317, 0], [0, 0], [427125.6958546316, 0], [0, 0], [0, 0], [427125.6958546316, 0], [-1281377.0875638947, 0], [-250068.66709469043, -48125.73742100348], [-144377.21226301044, -27785.4074549656], [427125.6958546316, 0], [1067.814239636579, 0], [0, 0], [-711.8761597577193, 0], [0, 0], [-355.9380798788597, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-711.8761597577193, 0], [0, 0], [-711.8761597577194, 0], [0, 0], [0, 0], [-355.9380798788597, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [-2135.628479273158, 0], [0, 0], [711.8761597577194, 0], [0, 0], [0, 0], [711.8761597577194, 0], [0, 0], [0, 0], [0, 0], [1067.814239636579, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}]} diff --git a/vendor/ninjars/tests/data/cases/madloop-gg-hhh-top-triangle-0.json b/vendor/ninjars/tests/data/cases/madloop-gg-hhh-top-triangle-0.json new file mode 100644 index 0000000000..0c17aa43d1 --- /dev/null +++ b/vendor/ninjars/tests/data/cases/madloop-gg-hhh-top-triangle-0.json @@ -0,0 +1 @@ +{"format": "ninjars-bench-case-v1", "name": "madloop-gg-hhh-top-triangle-0", "n": 3, "rank": 3, "description": "exact inputs MadLoop (loop_optimized_output, MLReductionLib=6) passes to ninja_tensor_evaluate for the pool points, recorded with NINJA_BENCH_DUMP", "lanes": [{"id": "gg-hhh-top-triangle-0-madloop-sqrt_s_450", "shifts": [[0, 0, 0, 0], [225, 0, 0, 225], [450, 0, 0, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 202500], [0, 0, 0], [202500, 0, 0]], "tensor": [[212.75988452805544, 0], [1.3424089403909787, 0], [0, 0], [0, 0], [-1.3424089403909782, 0], [0.0029831309786466187, 0], [0, 0], [0.0029831309786466187, 0], [0, 0], [0, 0], [0.0029831309786466187, 0], [0, 0], [0, 0], [0, 0], [-0.0029831309786466187, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}, {"id": "gg-hhh-top-triangle-0-madloop-sqrt_s_525", "shifts": [[0, 0, 0, 0], [262.5, 0, 0, 262.5], [525, 0, 0, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 275625], [0, 0, 0], [275625, 0, 0]], "tensor": [[231.31575160940366, 0], [1.125665830223685, 0], [0, 0], [0, 0], [-1.125665830223685, 0], [0.002144125390902257, 0], [0, 0], [0.0021441253909022574, 0], [0, 0], [0, 0], [0.0021441253909022574, 0], [0, 0], [0, 0], [0, 0], [-0.002144125390902257, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}, {"id": "gg-hhh-top-triangle-0-madloop-sqrt_s_600", "shifts": [[0, 0, 0, 0], [300, 0, 0, 300], [600, 0, 0, 0]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0]], "mu_squared": 10000, "s_matrix": [[0, 0, 360000], [0, 0, 0], [360000, 0, 0]], "tensor": [[242.93421647885035, 0], [0.9712771280747792, 0], [0, 0], [0, 0], [-0.9712771280747792, 0], [0.0016187952134579652, 0], [0, 0], [0.0016187952134579654, 0], [0, 0], [0, 0], [0.0016187952134579654, 0], [0, 0], [0, 0], [0, 0], [-0.0016187952134579652, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}]} diff --git a/vendor/ninjars/tests/data/cases/madloop-hgg-top-triangle-0.json b/vendor/ninjars/tests/data/cases/madloop-hgg-top-triangle-0.json new file mode 100644 index 0000000000..8aab4688b9 --- /dev/null +++ b/vendor/ninjars/tests/data/cases/madloop-hgg-top-triangle-0.json @@ -0,0 +1 @@ +{"format": "ninjars-bench-case-v1", "name": "madloop-hgg-top-triangle-0", "n": 3, "rank": 3, "description": "exact inputs MadLoop (loop_optimized_output, MLReductionLib=6) passes to ninja_tensor_evaluate for the pool points, recorded with NINJA_BENCH_DUMP", "lanes": [{"id": "hgg-top-triangle-0-madloop-rest_frame", "shifts": [[0, 0, 0, 0], [125, 0, 0, 0], [62.5, -41.666666666666664, -20.833333333333332, -41.666666666666664]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0]], "mu_squared": 15625, "s_matrix": [[0, 15625, 0], [15625, 0, 0], [0, 0, 0]], "tensor": [[-15945563.131366033, 0], [90122.55064864484, 0], [60081.70043242989, -2.5900266318074857e-12], [30040.850216214945, 5.180053263614971e-12], [60081.70043242988, 0], [720.9804051891589, 0], [0, 0], [80.10893390990651, 1.4210854715202004e-14], [0, 0], [-640.8714712792527, -1.4210854715202004e-14], [560.762537369346, -1.4210854715202004e-14], [0, 0], [-1281.7429425585042, -1.4210854715202004e-14], [-640.8714712792521, 2.842170943040401e-14], [80.10893390990627, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}, {"id": "hgg-top-triangle-0-madloop-boosted_a", "shifts": [[-7.105427357601002e-15, 0, 0, 3.552713678800501e-15], [152.44006849315068, -16.37720156555773, 57.84001956947162, 63.23997064579256], [52.440068493150676, -44.9486301369863, 14.982876712328768, -22.474315068493148]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0]], "mu_squared": 15625, "s_matrix": [[0, 15625, 0], [15625, 0, 0], [0, 0, 0]], "tensor": [[-5782889.973684717, -8693151.305343835], [31197.50630008032, 46897.76977430731], [48106.22601462649, 13805.40408940645], [53442.76877187606, -3248.330373978003], [12210.24185218516, 79651.76771191874], [297.45867231423523, 447.1558783378852], [-3.944304526105059e-31, 0], [-398.117138433586, 257.45338449757026], [0, 0], [-560.0740294333107, 487.8064127322382], [321.9780422663848, 636.8583721781999], [0, 0], [-921.4121129386724, -1318.8840047945705], [-828.4966057515793, 18.066904175268157], [373.59776848143656, -447.1558783378852], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}, {"id": "hgg-top-triangle-0-madloop-boosted_b", "shifts": [[0, -8.881784197001252e-15, 3.552713678800501e-15, -1.0658141036401503e-14], [181.25, 77.08333333333333, -45.833333333333336, 95.83333333333333], [31.25, 10.416666666666657, 20.833333333333336, -20.833333333333343]], "masses_squared": [[29929, 0], [29929, 0], [29929, 0]], "mu_squared": 15625, "s_matrix": [[0, 15624.999999999993, 0], [15624.999999999993, 0, 0], [0, 0, 0]], "tensor": [[-7029283.719255499, -10153409.816702388], [21374.43964452022, 30874.19059764033], [18207.855993480196, 8708.105040360077], [-34832.42016144037, -6333.1673020800745], [6333.167302080069, 44332.171114560435], [341.99103431232356, 493.98704956224515], [0, 0], [333.54681124288373, 519.3197187705654], [0, 0], [219.54979980544243, -151.99601524992175], [-325.1025881734435, 468.6543803539248], [0, 0], [-320.8804766387233, -50.665338416640765], [1131.5258913049715, 1165.302783582732], [333.54681124288334, -493.98704956224515], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]}]} diff --git a/vendor/ninjars/tests/data/compensated/README.md b/vendor/ninjars/tests/data/compensated/README.md new file mode 100644 index 0000000000..0a353ee121 --- /dev/null +++ b/vendor/ninjars/tests/data/compensated/README.md @@ -0,0 +1,23 @@ +# Compensated callback regression fixtures + +These are fixed regression inputs and numerical oracles, not benchmark output. +The ordinary Rust suite reads them locally; tests require no downloads. + +`inputs.json` and `corrected-results.json` retain six MadLoop QCD3 requests and +their complete ordinary/compensated reduction results. `expansion-results.json` +retains the 30 `t3` callbacks exercised by +`guarded_frozen_callbacks_match_all_480_oracle_components`: all callback inputs +and all 480 real components of the Float256 reference rounded to binary64. + +The callback fixture is a lossless projection of the +[original capture](https://github.com/MadGraphTeam/MadGraph7/blob/cc6f6fe6dd344a0a767dcfe52341c147e39a193a/vendor/ninjars/tests/data/compensated/expansion-results.json) +(SHA256 `8bdf9a439db23f793ca38f774997d866d6a0fa279e00a086d81cee21a3d67b76`). +For every outer row it keeps `direction`, `loop`, and +`results[0].callbacks` with `kind == "t3"`; each callback keeps `kind`, `inputs`, +and `high_rounded`. Unused native callback outputs and other captured callback +kinds/results remain in the immutable original. Every retained numeric value, +including its binary64 bits and signed zero, is unchanged. The projection reduces +the fixture from 1,350,447 to 131,790 bytes without reducing test coverage. + +The complete commands and scientific provenance are linked in +[`UPSTREAM.md`](../../../UPSTREAM.md). diff --git a/vendor/ninjars/tests/data/compensated/corrected-results.json b/vendor/ninjars/tests/data/compensated/corrected-results.json new file mode 100644 index 0000000000..5fec07cfef --- /dev/null +++ b/vendor/ninjars/tests/data/compensated/corrected-results.json @@ -0,0 +1,110 @@ +[ + { + "loop": 3, + "direction": 1, + "ninjars": [ + [ + 0.016661532475041874, + 0.003118837753793652 + ], + [ + 0.006525657516490924, + 0.001204561338287391 + ], + [ + 0.0, + 0.0 + ] + ] + }, + { + "loop": 52, + "direction": 1, + "ninjars": [ + [ + -0.018133066770232076, + -0.003179419139975638 + ], + [ + -0.009869035562516615, + -0.0021353858344426158 + ], + [ + -0.0016981805218419133, + -0.00048776164290072123 + ] + ] + }, + { + "loop": 71, + "direction": 1, + "ninjars": [ + [ + -0.008545203672243245, + -0.004339845675765525 + ], + [ + -0.01091312687699375, + -0.002124518842363088 + ], + [ + -0.00495576644630319, + 0.0001466643346410872 + ] + ] + }, + { + "loop": 3, + "direction": 2, + "ninjars": [ + [ + 0.016661532478679852, + 0.003118837752884157 + ], + [ + 0.006525657518309913, + 0.0012045613378326436 + ], + [ + 0.0, + 0.0 + ] + ] + }, + { + "loop": 52, + "direction": 2, + "ninjars": [ + [ + -0.018133066770260386, + -0.0031794191490605514 + ], + [ + -0.00986903556251697, + -0.002135385837170778 + ], + [ + -0.0016981805218419129, + -0.0004877616429007213 + ] + ] + }, + { + "loop": 71, + "direction": 2, + "ninjars": [ + [ + -0.008545203672240606, + -0.004339845678497309 + ], + [ + -0.010913126876994087, + -0.0021245188432722955 + ], + [ + -0.004955766446303171, + 0.00014666433464095833 + ] + ] + } +] diff --git a/vendor/ninjars/tests/data/compensated/expansion-results.json b/vendor/ninjars/tests/data/compensated/expansion-results.json new file mode 100644 index 0000000000..acfdb2cf92 --- /dev/null +++ b/vendor/ninjars/tests/data/compensated/expansion-results.json @@ -0,0 +1,5102 @@ +[ + { + "direction": 1, + "loop": 3, + "results": [ + { + "callbacks": [ + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -70256.07204287549, + 0.0 + ], + [ + 33159.54319941298, + 0.0 + ], + [ + 45325.80145089835, + 0.0 + ], + [ + -42212.937312318325, + 0.0 + ] + ], + [ + [ + -70256.07204287549, + 0.0 + ], + [ + 33159.54319941298, + 0.0 + ], + [ + 45325.80145089835, + 0.0 + ], + [ + -42212.937312318325, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -1.6238346331861067, + 5354.776469621679 + ], + [ + 18.06146052408917, + -2531.824290816129 + ], + [ + -9.184144452313149, + -3466.2599389692195 + ], + [ + 1.6238346331861067, + 3201.3980384216675 + ] + ], + [ + [ + 1.6238346331861067, + 5354.776469621679 + ], + [ + -18.06146052408917, + -2531.824290816129 + ], + [ + 9.184144452313149, + -3466.2599389692195 + ], + [ + -1.6238346331861067, + 3201.3980384216675 + ] + ] + ], + "e4": [ + [ + [ + 0.0009887808049986924, + 3.2606153853437103 + ], + [ + -0.010997933602032125, + -1.541671306441153 + ], + [ + 0.005592383337067112, + -2.1106652258450103 + ], + [ + -0.0009887808049986924, + 1.9493862643764768 + ] + ], + [ + [ + -0.0009887808049986924, + 3.2606153853437103 + ], + [ + 0.010997933602032125, + -1.541671306441153 + ], + [ + -0.005592383337067112, + -2.1106652258450103 + ], + [ + 0.0009887808049986924, + 1.9493862643764768 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + -1.2540137325104112e-09, + 0.0 + ], + [ + -1.2540137325104112e-09, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 630.5384958983699, + 171.54003147094602 + ], + [ + -2985.851440205519, + 12872.25357255985 + ], + [ + -59224.16023426427, + -9451.73761000085 + ], + [ + 0.4778042748870366, + 0.07661224130357439 + ], + [ + 142.03141530448173, + -47.80159767595553 + ], + [ + -109.94826530950918, + 6473.526937648077 + ], + [ + -59224.16023426427, + -9451.73761000085 + ], + [ + 0.4778042748870366, + 0.07661224130357443 + ] + ] + } + ] + } + ] + }, + { + "direction": 1, + "loop": 52, + "results": [ + { + "callbacks": [ + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -485.8102229342245, + 0.0 + ], + [ + 1.1046045595645057e-13, + 0.0 + ], + [ + 1.3807556994556321e-14, + -0.0 + ], + [ + -485.8102229342245, + 0.0 + ] + ], + [ + [ + -485.8102229342245, + 0.0 + ], + [ + 1.1046045595645057e-13, + 0.0 + ], + [ + 1.3807556994556321e-14, + -0.0 + ], + [ + -485.8102229342245, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 94.88946695861188, + 0.0 + ], + [ + 92.23191976380615, + -254.44772118376267 + ], + [ + -254.44772118376267, + -92.23191976380615 + ], + [ + 94.88946695861188, + 0.0 + ] + ], + [ + [ + 94.88946695861188, + 0.0 + ], + [ + 92.23191976380615, + 254.44772118376267 + ], + [ + -254.44772118376267, + 92.23191976380615 + ], + [ + 94.88946695861188, + 0.0 + ] + ] + ], + "e4": [ + [ + [ + -0.00032385320090283195, + -0.0 + ], + [ + -0.00031478311975290227, + -0.000868417871961859 + ], + [ + 0.000868417871961859, + -0.00031478311975290227 + ], + [ + -0.00032385320090283195, + -0.0 + ] + ], + [ + [ + -0.00032385320090283195, + -0.0 + ], + [ + -0.00031478311975290227, + 0.000868417871961859 + ], + [ + 0.000868417871961859, + 0.00031478311975290227 + ], + [ + -0.00032385320090283195, + -0.0 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -717299.3838642478, + -2911065.55545177 + ], + [ + 7745164.151745591, + 12725157.51111273 + ], + [ + -43792361.34373234, + 10653286.790615965 + ], + [ + -245.36208639105536, + 16.295380871804625 + ], + [ + -4044761.518874373, + 16415134.604158998 + ], + [ + -1474321.4628490272, + 1368138.8111311332 + ], + [ + -8648844.93113061, + -2874787.3997809156 + ], + [ + -333.13498288047145, + -22.15716703463743 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + 2.2358658269825714e-14, + 0.0 + ], + [ + -5.083770308789489e-30, + 0.0 + ], + [ + -6.354712885986861e-31, + 0.0 + ], + [ + 2.2358658269825714e-14, + 0.0 + ] + ], + [ + [ + 2.2358658269825714e-14, + 0.0 + ], + [ + -5.083770308789489e-30, + 0.0 + ], + [ + -6.354712885986861e-31, + 0.0 + ], + [ + 2.2358658269825714e-14, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 0.0, + 403.9060638193976 + ], + [ + 162.77698326366965, + -119.08472074672603 + ], + [ + -119.08472074672603, + -162.77698326366965 + ], + [ + 0.0, + 403.9060638193976 + ] + ], + [ + [ + 0.0, + 403.9060638193976 + ], + [ + -162.77698326366965, + -119.08472074672603 + ], + [ + 119.08472074672603, + -162.77698326366965 + ], + [ + 0.0, + 403.9060638193976 + ] + ] + ], + "e4": [ + [ + [ + 0.0, + 0.0024823667571795896 + ], + [ + -0.001000411254702996, + -0.0007318829266249073 + ], + [ + 0.0007318829266249073, + -0.001000411254702996 + ], + [ + 0.0, + 0.0024823667571795896 + ] + ], + [ + [ + 0.0, + 0.0024823667571795896 + ], + [ + 0.001000411254702996, + -0.0007318829266249073 + ], + [ + -0.0007318829266249073, + -0.001000411254702996 + ], + [ + 0.0, + 0.0024823667571795896 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 6403859.523616022, + 22448465.02630492 + ], + [ + 53727803.60834205, + -18181157.870893188 + ], + [ + -28846918.608071093, + -104767964.78804712 + ], + [ + 72.36853314705984, + -272.48718980788055 + ], + [ + -36110562.97561416, + 126584086.83838913 + ], + [ + 317832970.69510436, + 112296500.51257817 + ], + [ + 108114989.71131365, + -260042433.14280593 + ], + [ + -144.75917334185192, + 223.22438672083513 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -70663.70729364465, + -0.0 + ], + [ + 33351.93936268317, + 0.0 + ], + [ + 45588.78789325842, + 0.0 + ], + [ + -42457.8624951055, + -0.0 + ] + ], + [ + [ + -70663.70729364465, + -0.0 + ], + [ + 33351.93936268317, + 0.0 + ], + [ + 45588.78789325842, + 0.0 + ], + [ + -42457.8624951055, + -0.0 + ] + ] + ], + "e3": [ + [ + [ + -5354.776469621631, + 1.623834633186334 + ], + [ + 2531.8242908161064, + -18.061460524089853 + ], + [ + 3466.2599389691895, + 9.184144452313603 + ], + [ + -3201.398038421638, + -1.623834633186334 + ] + ], + [ + [ + -5354.776469621631, + -1.623834633186334 + ], + [ + 2531.8242908161064, + 18.061460524089853 + ], + [ + 3466.2599389691895, + -9.184144452313603 + ], + [ + -3201.398038421638, + 1.623834633186334 + ] + ] + ], + "e4": [ + [ + [ + 3.2606153853436233, + 0.0009887808049988134 + ], + [ + -1.541671306441112, + -0.010997933602032347 + ], + [ + -2.1106652258449548, + 0.005592383337067291 + ], + [ + 1.9493862643764244, + -0.0009887808049988134 + ] + ], + [ + [ + 3.2606153853436233, + -0.0009887808049988134 + ], + [ + -1.541671306441112, + 0.010997933602032347 + ], + [ + -2.1106652258449548, + -0.005592383337067291 + ], + [ + 1.9493862643764244, + 0.0009887808049988134 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 1.2612896901245616e-09, + 0.0 + ], + [ + 1.2612896901245616e-09, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -262359833.13130364, + 118079393.39436333 + ], + [ + -16807551782.064245, + 1453371721.5290256 + ], + [ + -302618152871.6837, + -22617282855.520905 + ], + [ + 1033359.8015607675, + 189643.34540202722 + ], + [ + -1148860602.7936502, + -543107152.9629124 + ], + [ + -40015102179.27257, + -15886362296.728045 + ], + [ + -454504255918.4261, + -136300256519.31087 + ], + [ + 1573151.5926152382, + 592245.6570365578 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -632.4219813242424, + -0.0 + ], + [ + 4.023520675606626, + -0.0 + ], + [ + 125.36075724233505, + 0.0 + ], + [ + -361.2892414029083, + 0.0 + ] + ], + [ + [ + -632.4219813242424, + -0.0 + ], + [ + 4.023520675606626, + -0.0 + ], + [ + 125.36075724233505, + 0.0 + ], + [ + -361.2892414029083, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -102.38016501055075, + 24.424154375065008 + ], + [ + -186.02456108421916, + 69.12836899553122 + ], + [ + 0.8346121632132366, + -141.24981102002084 + ], + [ + 102.38016501055075, + 102.33343885457211 + ] + ], + [ + [ + 102.38016501055075, + 24.424154375065008 + ], + [ + 186.02456108421916, + 69.12836899553122 + ], + [ + -0.8346121632132366, + -141.24981102002084 + ], + [ + -102.38016501055075, + 102.33343885457211 + ] + ] + ], + "e4": [ + [ + [ + 0.0007396163699915954, + 0.00017644535342503396 + ], + [ + 0.0013438815085345, + 0.0004993982314313063 + ], + [ + -6.029418085456222e-06, + -0.001020419067285743 + ], + [ + -0.0007396163699915954, + 0.0007392788101735874 + ] + ], + [ + [ + -0.0007396163699915954, + 0.00017644535342503396 + ], + [ + -0.0013438815085345, + 0.0004993982314313063 + ], + [ + 6.029418085456222e-06, + -0.001020419067285743 + ], + [ + 0.0007396163699915954, + 0.0007392788101735874 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 17436.60158774133, + 0.0 + ], + [ + 17436.60158774133, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 12860370.229837265, + -379373.4719734464 + ], + [ + 21883094.5657658, + -35461383.092391245 + ], + [ + -10966826.465376923, + -60661799.80184048 + ], + [ + 15.552847402620179, + -202.20774088637359 + ], + [ + -1822392.0224759784, + 1320751.7588284097 + ], + [ + 5069771.194129076, + 14668202.263705479 + ], + [ + 16677564.572083458, + -61030042.20147915 + ], + [ + -20.994073819148632, + -128.2362938388219 + ] + ] + } + ] + } + ] + }, + { + "direction": 1, + "loop": 71, + "results": [ + { + "callbacks": [ + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -485.8102229342245, + 0.0 + ], + [ + 1.1046045595645057e-13, + 0.0 + ], + [ + 1.3807556994556321e-14, + -0.0 + ], + [ + -485.8102229342245, + 0.0 + ] + ], + [ + [ + -485.8102229342245, + 0.0 + ], + [ + 1.1046045595645057e-13, + 0.0 + ], + [ + 1.3807556994556321e-14, + -0.0 + ], + [ + -485.8102229342245, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 94.88946695861188, + 0.0 + ], + [ + 92.23191976380615, + -254.44772118376267 + ], + [ + -254.44772118376267, + -92.23191976380615 + ], + [ + 94.88946695861188, + 0.0 + ] + ], + [ + [ + 94.88946695861188, + 0.0 + ], + [ + 92.23191976380615, + 254.44772118376267 + ], + [ + -254.44772118376267, + 92.23191976380615 + ], + [ + 94.88946695861188, + 0.0 + ] + ] + ], + "e4": [ + [ + [ + -0.00032385320090283195, + -0.0 + ], + [ + -0.00031478311975290227, + -0.000868417871961859 + ], + [ + 0.000868417871961859, + -0.00031478311975290227 + ], + [ + -0.00032385320090283195, + -0.0 + ] + ], + [ + [ + -0.00032385320090283195, + -0.0 + ], + [ + -0.00031478311975290227, + 0.000868417871961859 + ], + [ + 0.000868417871961859, + 0.00031478311975290227 + ], + [ + -0.00032385320090283195, + -0.0 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -213850700257.94385, + -400853585925.3238 + ], + [ + 2793106249881.745, + -273242759981.9697 + ], + [ + 26403053430459.316, + 12587374688210.213 + ], + [ + 7587728.630033595, + 22990780.145523813 + ], + [ + -1205877354205.7917, + 2260363239570.8247 + ], + [ + -48563567738.36494, + -848466325168.5082 + ], + [ + 6875433890723.121, + -3029439686686.075 + ], + [ + -33489877.38545947, + 24937866.14687216 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -460.3391344474081, + -0.0 + ], + [ + 1.0466900094966335e-13, + 0.0 + ], + [ + 1.3083625118707918e-14, + 0.0 + ], + [ + -460.3391344474081, + 0.0 + ] + ], + [ + [ + -460.3391344474081, + -0.0 + ], + [ + 1.0466900094966335e-13, + 0.0 + ], + [ + 1.3083625118707918e-14, + 0.0 + ], + [ + -460.3391344474081, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 0.0, + 61.086277540202616 + ], + [ + -395.25094021436496, + -143.27011000461098 + ], + [ + -143.27011000461098, + 395.25094021436496 + ], + [ + 0.0, + 61.086277540202616 + ] + ], + [ + [ + 0.0, + 61.086277540202616 + ], + [ + 395.25094021436496, + -143.27011000461098 + ], + [ + 143.27011000461098, + 395.25094021436496 + ], + [ + 0.0, + 61.086277540202616 + ] + ] + ], + "e4": [ + [ + [ + 0.0, + 8.640227066463243e-05 + ], + [ + 0.0005590548334587346, + -0.00020264555840095478 + ], + [ + 0.00020264555840095478, + 0.0005590548334587346 + ], + [ + 0.0, + 8.640227066463243e-05 + ] + ], + [ + [ + 0.0, + 8.640227066463243e-05 + ], + [ + -0.0005590548334587346, + -0.00020264555840095478 + ], + [ + -0.00020264555840095478, + 0.0005590548334587346 + ], + [ + 0.0, + 8.640227066463243e-05 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 2773627450661.994, + -271798975465.70056 + ], + [ + -9691416166574.395, + -12361803954183.814 + ], + [ + -31207433385393.36, + 44734904163300.65 + ], + [ + 4688639.127004724, + 104391841.8726057 + ], + [ + 15640138319503.12, + 1532640430988.0242 + ], + [ + 6530070731760.56, + -14280934240379.22 + ], + [ + -7595710650314.661, + -7559108017865.322 + ], + [ + -22298289.90466622, + -96303823.24870509 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + 2.2358658269825714e-14, + 0.0 + ], + [ + -5.083770308789489e-30, + 0.0 + ], + [ + -6.354712885986861e-31, + 0.0 + ], + [ + 2.2358658269825714e-14, + 0.0 + ] + ], + [ + [ + 2.2358658269825714e-14, + 0.0 + ], + [ + -5.083770308789489e-30, + 0.0 + ], + [ + -6.354712885986861e-31, + 0.0 + ], + [ + 2.2358658269825714e-14, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 0.0, + 403.9060638193976 + ], + [ + 162.77698326366965, + -119.08472074672603 + ], + [ + -119.08472074672603, + -162.77698326366965 + ], + [ + 0.0, + 403.9060638193976 + ] + ], + [ + [ + 0.0, + 403.9060638193976 + ], + [ + -162.77698326366965, + -119.08472074672603 + ], + [ + 119.08472074672603, + -162.77698326366965 + ], + [ + 0.0, + 403.9060638193976 + ] + ] + ], + "e4": [ + [ + [ + 0.0, + 0.0024823667571795896 + ], + [ + -0.001000411254702996, + -0.0007318829266249073 + ], + [ + 0.0007318829266249073, + -0.001000411254702996 + ], + [ + 0.0, + 0.0024823667571795896 + ] + ], + [ + [ + 0.0, + 0.0024823667571795896 + ], + [ + 0.001000411254702996, + -0.0007318829266249073 + ], + [ + -0.0007318829266249073, + -0.001000411254702996 + ], + [ + 0.0, + 0.0024823667571795896 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -8013626440148.551, + 2786660207101.54 + ], + [ + 13638025871073.725, + 41848181020502.13 + ], + [ + 44719041799598.51, + -27004958227611.297 + ], + [ + 92092700.52392672, + 13226113.800874166 + ], + [ + -45187837297628.71, + -15713628403166.045 + ], + [ + -59986613355959.055, + 183466015846815.84 + ], + [ + 279129396672297.72, + 85264834107941.6 + ], + [ + -165528338.856182, + -114719397.47499418 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -473.4417395596135, + -0.0 + ], + [ + 35.007350811828225, + 0.0 + ], + [ + -96.57763452784293, + 0.0 + ], + [ + -462.1626625500776, + 0.0 + ] + ], + [ + [ + -473.4417395596135, + -0.0 + ], + [ + 35.007350811828225, + 0.0 + ], + [ + -96.57763452784293, + 0.0 + ], + [ + -462.1626625500776, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 41.640651004455826, + -15.093855682763026 + ], + [ + 0.0, + 403.39750064235045 + ], + [ + 403.39750064235045, + 0.0 + ], + [ + -41.640651004455826, + 15.093855682763026 + ] + ], + [ + [ + -41.640651004455826, + -15.093855682763026 + ], + [ + 0.0, + 403.39750064235045 + ], + [ + -403.39750064235045, + 0.0 + ], + [ + 41.640651004455826, + 15.093855682763026 + ] + ] + ], + "e4": [ + [ + [ + -6.397217447824372e-05, + -2.3188560841275574e-05 + ], + [ + 0.0, + 0.0006197361153748158 + ], + [ + -0.0006197361153748158, + 0.0 + ], + [ + 6.397217447824372e-05, + 2.3188560841275574e-05 + ] + ], + [ + [ + 6.397217447824372e-05, + -2.3188560841275574e-05 + ], + [ + 0.0, + 0.0006197361153748158 + ], + [ + 0.0006197361153748158, + 0.0 + ], + [ + -6.397217447824372e-05, + 2.3188560841275574e-05 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 724064539250.7698, + -789236835465.0286 + ], + [ + 2130125742568.112, + -6477639402043.985 + ], + [ + -6889369871449.463, + -43190518246255.46 + ], + [ + -6438335.073344027, + -53229677.07077114 + ], + [ + 4082909384036.585, + 4450407811825.551 + ], + [ + 4106631920221.531, + -9251815456954.422 + ], + [ + 440170107678.2675, + 7897668101532.237 + ], + [ + -56035602.30629724, + 89956543.3344401 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -70663.70729364465, + -0.0 + ], + [ + 33351.93936268317, + 0.0 + ], + [ + 45588.78789325842, + 0.0 + ], + [ + -42457.8624951055, + -0.0 + ] + ], + [ + [ + -70663.70729364465, + -0.0 + ], + [ + 33351.93936268317, + 0.0 + ], + [ + 45588.78789325842, + 0.0 + ], + [ + -42457.8624951055, + -0.0 + ] + ] + ], + "e3": [ + [ + [ + -5354.776469621631, + 1.623834633186334 + ], + [ + 2531.8242908161064, + -18.061460524089853 + ], + [ + 3466.2599389691895, + 9.184144452313603 + ], + [ + -3201.398038421638, + -1.623834633186334 + ] + ], + [ + [ + -5354.776469621631, + -1.623834633186334 + ], + [ + 2531.8242908161064, + 18.061460524089853 + ], + [ + 3466.2599389691895, + -9.184144452313603 + ], + [ + -3201.398038421638, + 1.623834633186334 + ] + ] + ], + "e4": [ + [ + [ + 3.2606153853436233, + 0.0009887808049988134 + ], + [ + -1.541671306441112, + -0.010997933602032347 + ], + [ + -2.1106652258449548, + 0.005592383337067291 + ], + [ + 1.9493862643764244, + -0.0009887808049988134 + ] + ], + [ + [ + 3.2606153853436233, + -0.0009887808049988134 + ], + [ + -1.541671306441112, + 0.010997933602032347 + ], + [ + -2.1106652258449548, + -0.005592383337067291 + ], + [ + 1.9493862643764244, + 0.0009887808049988134 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 1.2612896901245616e-09, + 0.0 + ], + [ + 1.2612896901245616e-09, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -269544284043733.78, + 327534778012142.1 + ], + [ + -6152259604904996.0, + 2.0721660403080904e+16 + ], + [ + 4.6112618663587896e+16, + 4.772382890515046e+17 + ], + [ + -55688195577.1292, + -1414971803877.7046 + ], + [ + 854030762808643.8, + 1309991605041875.2 + ], + [ + 3.75873818574861e+16, + 5.9342385061247e+16 + ], + [ + 6.137052351690277e+17, + 9.833522629443133e+17 + ], + [ + -1423800493906.4712, + -2611236365885.3257 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -407.6352507716522, + 0.0 + ], + [ + 192.39616327136915, + 0.0 + ], + [ + 262.9864423616992, + 0.0 + ], + [ + -244.92518278866527, + 0.0 + ] + ], + [ + [ + -407.6352507716522, + 0.0 + ], + [ + 192.39616327136915, + 0.0 + ], + [ + 262.9864423616992, + 0.0 + ], + [ + -244.92518278866527, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -32.3283926411057, + 69.64381523590896 + ], + [ + 359.5797106192315, + 56.13351562509042 + ], + [ + -182.8441282499523, + 186.37889072199437 + ], + [ + 32.3283926411057, + 360.12739696101335 + ] + ], + [ + [ + 32.3283926411057, + 69.64381523590896 + ], + [ + -359.5797106192315, + 56.13351562509042 + ], + [ + 182.8441282499523, + 186.37889072199437 + ], + [ + -32.3283926411057, + 360.12739696101335 + ] + ] + ], + "e4": [ + [ + [ + 4.9665831939483415e-05, + 0.00010699319516223206 + ], + [ + -0.0005524192209220836, + 8.623743791280414e-05 + ], + [ + 0.00028090186374551805, + 0.0002863322889705326 + ], + [ + -4.9665831939483415e-05, + 0.0005532606267447752 + ] + ], + [ + [ + -4.9665831939483415e-05, + 0.00010699319516223206 + ], + [ + 0.0005524192209220836, + 8.623743791280414e-05 + ], + [ + -0.00028090186374551805, + 0.0002863322889705326 + ], + [ + 4.9665831939483415e-05, + 0.0005532606267447752 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 7.275957614183428e-12, + 0.0 + ], + [ + 7.275957614183428e-12, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -59716841366922.68, + 36509399580242.42 + ], + [ + 68825111710038.125, + 136918108919374.23 + ], + [ + 124703742884956.47, + -51164346476204.56 + ], + [ + 53023885.61050813, + -8098671.943285588 + ], + [ + -59716841366922.63, + -36509399580242.4 + ], + [ + -52388756520984.016, + 95157429917963.27 + ], + [ + 93758666622289.02, + 54250214744688.94 + ], + [ + 256832094.7572059, + 75493683.97200027 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -385.8652795293129, + -0.0 + ], + [ + 35.00735081182821, + 0.0 + ], + [ + -96.57763452784289, + 0.0 + ], + [ + -549.7391225803782, + 0.0 + ] + ], + [ + [ + -385.8652795293129, + -0.0 + ], + [ + 35.00735081182821, + 0.0 + ], + [ + -96.57763452784289, + 0.0 + ], + [ + -549.7391225803782, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -64.36924504532887, + -177.58068744580618 + ], + [ + -118.40644676949495, + 0.0 + ], + [ + -0.0, + 118.40644676949495 + ], + [ + 64.36924504532887, + 177.58068744580618 + ] + ], + [ + [ + -64.36924504532887, + 177.58068744580618 + ], + [ + -118.40644676949495, + 0.0 + ], + [ + -0.0, + -118.40644676949495 + ], + [ + 64.36924504532887, + -177.58068744580618 + ] + ] + ], + "e4": [ + [ + [ + 0.001147803981421107, + -0.003166540479545128 + ], + [ + 0.0021113715242775735, + -0.0 + ], + [ + 0.0, + 0.0021113715242775735 + ], + [ + -0.001147803981421107, + 0.003166540479545128 + ] + ], + [ + [ + 0.001147803981421107, + 0.003166540479545128 + ], + [ + 0.0021113715242775735, + -0.0 + ], + [ + 0.0, + -0.0021113715242775735 + ], + [ + -0.001147803981421107, + -0.003166540479545128 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + -2.7110993424472162e-12, + 0.0 + ], + [ + -2.7110993424472162e-12, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -92357345717.40678, + -68866216664.5328 + ], + [ + 966188177809.8527, + 4126334904528.5576 + ], + [ + 4515118079862.109, + 3645748293477.673 + ], + [ + 27304594.273296606, + -12965827.214461932 + ], + [ + -520791522126.6118, + 388327983239.8167 + ], + [ + 1038324058404.8228, + -1766034997159.7712 + ], + [ + 597017579730.8949, + -908402225625.9089 + ], + [ + 11670138.47261888, + 20627582.47378564 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -632.4219813242424, + -0.0 + ], + [ + 4.023520675606626, + -0.0 + ], + [ + 125.36075724233505, + 0.0 + ], + [ + -361.2892414029083, + 0.0 + ] + ], + [ + [ + -632.4219813242424, + -0.0 + ], + [ + 4.023520675606626, + -0.0 + ], + [ + 125.36075724233505, + 0.0 + ], + [ + -361.2892414029083, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -102.38016501055075, + 24.424154375065008 + ], + [ + -186.02456108421916, + 69.12836899553122 + ], + [ + 0.8346121632132366, + -141.24981102002084 + ], + [ + 102.38016501055075, + 102.33343885457211 + ] + ], + [ + [ + 102.38016501055075, + 24.424154375065008 + ], + [ + 186.02456108421916, + 69.12836899553122 + ], + [ + -0.8346121632132366, + -141.24981102002084 + ], + [ + -102.38016501055075, + 102.33343885457211 + ] + ] + ], + "e4": [ + [ + [ + 0.0007396163699915954, + 0.00017644535342503396 + ], + [ + 0.0013438815085345, + 0.0004993982314313063 + ], + [ + -6.029418085456222e-06, + -0.001020419067285743 + ], + [ + -0.0007396163699915954, + 0.0007392788101735874 + ] + ], + [ + [ + -0.0007396163699915954, + 0.00017644535342503396 + ], + [ + -0.0013438815085345, + 0.0004993982314313063 + ], + [ + 6.029418085456222e-06, + -0.001020419067285743 + ], + [ + 0.0007396163699915954, + 0.0007392788101735874 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 17436.60158774133, + 0.0 + ], + [ + 17436.60158774133, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 1592291097558.06, + 1931811450535.7761 + ], + [ + 6721860624528.483, + 1238083652966.497 + ], + [ + 8902085958435.209, + -4478678409931.491 + ], + [ + 28578283.495359752, + -31069504.846254036 + ], + [ + 406443260651.85065, + -506100580881.9079 + ], + [ + -2134749254464.9546, + 890896430246.9655 + ], + [ + -4125146695159.391, + -6775531517428.689 + ], + [ + 6056119.72212597, + 11182609.253855977 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -1038.8631705578791, + 0.0 + ], + [ + -47.76899921816456, + 0.0 + ], + [ + -285.68511568677894, + 0.0 + ], + [ + -45.60407795357918, + -0.0 + ] + ], + [ + [ + -1038.8631705578791, + 0.0 + ], + [ + -47.76899921816456, + 0.0 + ], + [ + -285.68511568677894, + 0.0 + ], + [ + -45.60407795357918, + -0.0 + ] + ] + ], + "e3": [ + [ + [ + 535.8611965348432, + -110.99882545847697 + ], + [ + 107.11334302025128, + -201.68465038759325 + ], + [ + 444.324201160696, + 0.9048722457175771 + ], + [ + -344.85863039430524, + 110.99882545847697 + ] + ], + [ + [ + 535.8611965348432, + 110.99882545847697 + ], + [ + 107.11334302025128, + 201.68465038759325 + ], + [ + 444.324201160696, + -0.9048722457175771 + ], + [ + -344.85863039430524, + -110.99882545847697 + ] + ] + ], + "e4": [ + [ + [ + -0.003293349964003908, + -0.0006821878131725883 + ], + [ + -0.0006583080220423186, + -0.0012395339322744405 + ], + [ + -0.0027307726354533577, + 5.5612554092976685e-06 + ], + [ + 0.0021194670659861322, + 0.0006821878131725883 + ] + ], + [ + [ + -0.003293349964003908, + 0.0006821878131725883 + ], + [ + -0.0006583080220423186, + 0.0012395339322744405 + ], + [ + -0.0027307726354533577, + -5.5612554092976685e-06 + ], + [ + 0.0021194670659861322, + -0.0006821878131725883 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 2.7565178443445723e-11, + 0.0 + ], + [ + 2.7565178443445723e-11, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 6279883521248.18, + -3545146979422.4487 + ], + [ + -18074790728473.746, + -12044462141041.758 + ], + [ + 20227586388587.242, + 39305000441549.64 + ], + [ + -76554467.77575207, + 106771903.38704054 + ], + [ + 1134039265203.1597, + 1604054488084.8923 + ], + [ + -4254239596126.98, + -3384489416823.58 + ], + [ + 26109653751231.438, + 353272198485.9073 + ], + [ + -7805071.676070232, + -27813467.192540005 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -821.3014613769903, + 0.0 + ], + [ + 35.00735081182822, + 0.0 + ], + [ + -96.57763452784292, + 0.0 + ], + [ + -114.30294073270068, + -0.0 + ] + ], + [ + [ + -821.3014613769903, + 0.0 + ], + [ + 35.00735081182822, + 0.0 + ], + [ + -96.57763452784292, + 0.0 + ], + [ + -114.30294073270068, + -0.0 + ] + ] + ], + "e3": [ + [ + [ + 147.91659824021536, + 337.92424170273483 + ], + [ + 266.0093835513015, + 0.0 + ], + [ + -0.0, + 266.0093835513015 + ], + [ + -147.91659824021536, + -337.92424170273483 + ] + ], + [ + [ + 147.91659824021536, + -337.92424170273483 + ], + [ + 266.0093835513015, + 0.0 + ], + [ + -0.0, + -266.0093835513015 + ], + [ + -147.91659824021536, + 337.92424170273483 + ] + ] + ], + "e4": [ + [ + [ + -0.0005225922989926318, + 0.0011938931023142006 + ], + [ + -0.0009398164706162931, + -0.0 + ], + [ + 0.0, + 0.0009398164706162931 + ], + [ + 0.0005225922989926318, + -0.0011938931023142006 + ] + ], + [ + [ + -0.0005225922989926318, + -0.0011938931023142006 + ], + [ + -0.0009398164706162931, + -0.0 + ], + [ + 0.0, + -0.0009398164706162931 + ], + [ + 0.0005225922989926318, + 0.0011938931023142006 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 4615210593755.654, + 10496479612721.59 + ], + [ + -45731329298629.445, + -533627821388.85376 + ], + [ + 24829129183196.246, + -62330560484755.766 + ], + [ + 72212194.28445159, + -34960951.0378117 + ], + [ + 818463016881.6483, + -1861449265627.9456 + ], + [ + -6124623119427.958, + 2247517315624.04 + ], + [ + 812154431612.1111, + 3132059714479.9546 + ], + [ + 36915010.25696966, + 28396951.223088697 + ] + ] + } + ] + } + ] + }, + { + "direction": 2, + "loop": 3, + "results": [ + { + "callbacks": [ + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -70256.07204287549, + 0.0 + ], + [ + 33159.54319941298, + 0.0 + ], + [ + 45325.80145089835, + 0.0 + ], + [ + -42212.937312318325, + 0.0 + ] + ], + [ + [ + -70256.07204287549, + 0.0 + ], + [ + 33159.54319941298, + 0.0 + ], + [ + 45325.80145089835, + 0.0 + ], + [ + -42212.937312318325, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 1.6238346331861067, + 5354.776469621679 + ], + [ + -18.06146052408917, + -2531.824290816129 + ], + [ + 9.184144452313149, + -3466.2599389692195 + ], + [ + -1.6238346331861067, + 3201.3980384216675 + ] + ], + [ + [ + -1.6238346331861067, + 5354.776469621679 + ], + [ + 18.06146052408917, + -2531.824290816129 + ], + [ + -9.184144452313149, + -3466.2599389692195 + ], + [ + 1.6238346331861067, + 3201.3980384216675 + ] + ] + ], + "e4": [ + [ + [ + -0.0009887808049986924, + 3.2606153853437103 + ], + [ + 0.010997933602032125, + -1.541671306441153 + ], + [ + -0.005592383337067112, + -2.1106652258450103 + ], + [ + 0.0009887808049986924, + 1.9493862643764768 + ] + ], + [ + [ + 0.0009887808049986924, + 3.2606153853437103 + ], + [ + -0.010997933602032125, + -1.541671306441153 + ], + [ + 0.005592383337067112, + -2.1106652258450103 + ], + [ + -0.0009887808049986924, + 1.9493862643764768 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + -1.2540137325104112e-09, + 0.0 + ], + [ + -1.2540137325104112e-09, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 142.03141530448173, + -47.80159767595553 + ], + [ + -109.94826530950918, + 6473.526937648077 + ], + [ + -59224.16023426427, + -9451.73761000085 + ], + [ + 0.4778042748870366, + 0.07661224130357443 + ], + [ + 630.5384958983699, + 171.54003147094602 + ], + [ + -2985.851440205519, + 12872.25357255985 + ], + [ + -59224.16023426427, + -9451.73761000085 + ], + [ + 0.4778042748870366, + 0.07661224130357439 + ] + ] + } + ] + } + ] + }, + { + "direction": 2, + "loop": 52, + "results": [ + { + "callbacks": [ + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -70663.70729364465, + 0.0 + ], + [ + 33351.93936268317, + -0.0 + ], + [ + 45588.78789325842, + -0.0 + ], + [ + -42457.8624951055, + 0.0 + ] + ], + [ + [ + -70663.70729364465, + 0.0 + ], + [ + 33351.93936268317, + -0.0 + ], + [ + 45588.78789325842, + -0.0 + ], + [ + -42457.8624951055, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 5354.776469621631, + 1.623834633186334 + ], + [ + -2531.8242908161064, + -18.061460524089853 + ], + [ + -3466.2599389691895, + 9.184144452313603 + ], + [ + 3201.398038421638, + -1.623834633186334 + ] + ], + [ + [ + 5354.776469621631, + -1.623834633186334 + ], + [ + -2531.8242908161064, + 18.061460524089853 + ], + [ + -3466.2599389691895, + -9.184144452313603 + ], + [ + 3201.398038421638, + 1.623834633186334 + ] + ] + ], + "e4": [ + [ + [ + -3.2606153853436233, + 0.0009887808049988134 + ], + [ + 1.541671306441112, + -0.010997933602032347 + ], + [ + 2.1106652258449548, + 0.005592383337067291 + ], + [ + -1.9493862643764244, + -0.0009887808049988134 + ] + ], + [ + [ + -3.2606153853436233, + -0.0009887808049988134 + ], + [ + 1.541671306441112, + 0.010997933602032347 + ], + [ + 2.1106652258449548, + -0.005592383337067291 + ], + [ + -1.9493862643764244, + 0.0009887808049988134 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 1.2612896901245616e-09, + 0.0 + ], + [ + 1.2612896901245616e-09, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 1148860602.7936502, + 543107152.9629124 + ], + [ + -40015102179.27257, + -15886362296.728045 + ], + [ + 454504255918.4261, + 136300256519.31087 + ], + [ + -1573151.5926152382, + -592245.6570365578 + ], + [ + 262359833.13130364, + -118079393.39436333 + ], + [ + -16807551782.064245, + 1453371721.5290256 + ], + [ + 302618152871.6837, + 22617282855.520905 + ], + [ + -1033359.8015607675, + -189643.34540202722 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + 2.2358658269825714e-14, + 0.0 + ], + [ + -5.083770308789489e-30, + 0.0 + ], + [ + -6.354712885986861e-31, + 0.0 + ], + [ + 2.2358658269825714e-14, + 0.0 + ] + ], + [ + [ + 2.2358658269825714e-14, + 0.0 + ], + [ + -5.083770308789489e-30, + 0.0 + ], + [ + -6.354712885986861e-31, + 0.0 + ], + [ + 2.2358658269825714e-14, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 0.0, + 403.9060638193976 + ], + [ + -162.77698326366965, + -119.08472074672603 + ], + [ + 119.08472074672603, + -162.77698326366965 + ], + [ + 0.0, + 403.9060638193976 + ] + ], + [ + [ + 0.0, + 403.9060638193976 + ], + [ + 162.77698326366965, + -119.08472074672603 + ], + [ + -119.08472074672603, + -162.77698326366965 + ], + [ + 0.0, + 403.9060638193976 + ] + ] + ], + "e4": [ + [ + [ + 0.0, + 0.0024823667571795896 + ], + [ + 0.001000411254702996, + -0.0007318829266249073 + ], + [ + -0.0007318829266249073, + -0.001000411254702996 + ], + [ + 0.0, + 0.0024823667571795896 + ] + ], + [ + [ + 0.0, + 0.0024823667571795896 + ], + [ + -0.001000411254702996, + -0.0007318829266249073 + ], + [ + 0.0007318829266249073, + -0.001000411254702996 + ], + [ + 0.0, + 0.0024823667571795896 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -36110562.97561416, + 126584086.83838913 + ], + [ + 317832970.69510436, + 112296500.51257817 + ], + [ + 108114989.71131365, + -260042433.14280593 + ], + [ + -144.75917334185192, + 223.22438672083513 + ], + [ + 6403859.523616022, + 22448465.02630492 + ], + [ + 53727803.60834205, + -18181157.870893188 + ], + [ + -28846918.608071093, + -104767964.78804712 + ], + [ + 72.36853314705984, + -272.48718980788055 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -485.8102229342245, + -0.0 + ], + [ + 1.1046045595645057e-13, + 0.0 + ], + [ + 1.3807556994556321e-14, + 0.0 + ], + [ + -485.8102229342245, + 0.0 + ] + ], + [ + [ + -485.8102229342245, + -0.0 + ], + [ + 1.1046045595645057e-13, + 0.0 + ], + [ + 1.3807556994556321e-14, + 0.0 + ], + [ + -485.8102229342245, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -94.88946695861188, + 0.0 + ], + [ + -92.23191976380615, + -254.44772118376267 + ], + [ + 254.44772118376267, + -92.23191976380615 + ], + [ + -94.88946695861188, + 0.0 + ] + ], + [ + [ + -94.88946695861188, + 0.0 + ], + [ + -92.23191976380615, + 254.44772118376267 + ], + [ + 254.44772118376267, + 92.23191976380615 + ], + [ + -94.88946695861188, + 0.0 + ] + ] + ], + "e4": [ + [ + [ + 0.00032385320090283195, + -0.0 + ], + [ + 0.00031478311975290227, + -0.000868417871961859 + ], + [ + -0.000868417871961859, + -0.00031478311975290227 + ], + [ + 0.00032385320090283195, + -0.0 + ] + ], + [ + [ + 0.00032385320090283195, + -0.0 + ], + [ + 0.00031478311975290227, + 0.000868417871961859 + ], + [ + -0.000868417871961859, + 0.00031478311975290227 + ], + [ + 0.00032385320090283195, + -0.0 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 4044761.518874373, + -16415134.604158998 + ], + [ + -1474321.4628490272, + 1368138.8111311332 + ], + [ + 8648844.93113061, + 2874787.3997809156 + ], + [ + 333.13498288047145, + 22.15716703463743 + ], + [ + 717299.3838642478, + 2911065.55545177 + ], + [ + 7745164.151745591, + 12725157.51111273 + ], + [ + 43792361.34373234, + -10653286.790615965 + ], + [ + 245.36208639105536, + -16.295380871804625 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -632.4219813242423, + -0.0 + ], + [ + 4.0235206756066475, + -0.0 + ], + [ + 125.36075724233504, + 0.0 + ], + [ + -361.2892414029084, + 0.0 + ] + ], + [ + [ + -632.4219813242423, + -0.0 + ], + [ + 4.0235206756066475, + -0.0 + ], + [ + 125.36075724233504, + 0.0 + ], + [ + -361.2892414029084, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -36.024200205068965, + -151.00475966256496 + ], + [ + -101.96030398036127, + -274.37535517706755 + ], + [ + 208.33521574479659, + 1.231004160859456 + ], + [ + -150.93584131346108, + 151.00475966256496 + ] + ], + [ + [ + -36.024200205068965, + 151.00475966256496 + ], + [ + -101.96030398036127, + 274.37535517706755 + ], + [ + 208.33521574479659, + -1.231004160859456 + ], + [ + -150.93584131346108, + -151.00475966256496 + ] + ] + ], + "e4": [ + [ + [ + 0.00011962870865373277, + -0.000501454697013872 + ], + [ + 0.00033858848856265167, + -0.0009111422110524278 + ], + [ + -0.0006918369508489444, + 4.087903056075821e-06 + ], + [ + 0.0005012258338313748, + 0.000501454697013872 + ] + ], + [ + [ + 0.00011962870865373277, + 0.000501454697013872 + ], + [ + 0.00033858848856265167, + 0.0009111422110524278 + ], + [ + -0.0006918369508489444, + -4.087903056075821e-06 + ], + [ + 0.0005012258338313748, + -0.000501454697013872 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 17436.601587741334, + 0.0 + ], + [ + 17436.601587741334, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -1217282.5405222964, + -41264625.2359185 + ], + [ + -47605634.68968885, + 77144557.59508845 + ], + [ + 89472609.25816585, + -16175428.067483937 + ], + [ + 298.24459954045136, + 22.939540914582246 + ], + [ + 4237850.4960369365, + 5847446.262933163 + ], + [ + -11029046.860931035, + -31909978.564587615 + ], + [ + 90015745.27527691, + 24598433.004135516 + ], + [ + 189.141038492698, + -30.965031860145768 + ] + ] + } + ] + } + ] + }, + { + "direction": 2, + "loop": 71, + "results": [ + { + "callbacks": [ + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -407.6352507716522, + -0.0 + ], + [ + 192.39616327136915, + 0.0 + ], + [ + 262.9864423616992, + 0.0 + ], + [ + -244.92518278866527, + 0.0 + ] + ], + [ + [ + -407.6352507716522, + -0.0 + ], + [ + 192.39616327136915, + 0.0 + ], + [ + 262.9864423616992, + 0.0 + ], + [ + -244.92518278866527, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 32.3283926411057, + 69.64381523590896 + ], + [ + -359.5797106192315, + 56.13351562509042 + ], + [ + 182.8441282499523, + 186.37889072199437 + ], + [ + -32.3283926411057, + 360.12739696101335 + ] + ], + [ + [ + -32.3283926411057, + 69.64381523590896 + ], + [ + 359.5797106192315, + 56.13351562509042 + ], + [ + -182.8441282499523, + 186.37889072199437 + ], + [ + 32.3283926411057, + 360.12739696101335 + ] + ] + ], + "e4": [ + [ + [ + -4.9665831939483415e-05, + 0.00010699319516223206 + ], + [ + 0.0005524192209220836, + 8.623743791280414e-05 + ], + [ + -0.00028090186374551805, + 0.0002863322889705326 + ], + [ + 4.9665831939483415e-05, + 0.0005532606267447752 + ] + ], + [ + [ + 4.9665831939483415e-05, + 0.00010699319516223206 + ], + [ + -0.0005524192209220836, + 8.623743791280414e-05 + ], + [ + 0.00028090186374551805, + 0.0002863322889705326 + ], + [ + -4.9665831939483415e-05, + 0.0005532606267447752 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 7.275957614183428e-12, + 0.0 + ], + [ + 7.275957614183428e-12, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -59716841366922.63, + -36509399580242.4 + ], + [ + -52388756520984.016, + 95157429917963.27 + ], + [ + 93758666622289.02, + 54250214744688.94 + ], + [ + 256832094.7572059, + 75493683.97200027 + ], + [ + -59716841366922.68, + 36509399580242.42 + ], + [ + 68825111710038.125, + 136918108919374.23 + ], + [ + 124703742884956.47, + -51164346476204.56 + ], + [ + 53023885.61050813, + -8098671.943285588 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -70663.70729364465, + 0.0 + ], + [ + 33351.93936268317, + -0.0 + ], + [ + 45588.78789325842, + -0.0 + ], + [ + -42457.8624951055, + 0.0 + ] + ], + [ + [ + -70663.70729364465, + 0.0 + ], + [ + 33351.93936268317, + -0.0 + ], + [ + 45588.78789325842, + -0.0 + ], + [ + -42457.8624951055, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 5354.776469621631, + 1.623834633186334 + ], + [ + -2531.8242908161064, + -18.061460524089853 + ], + [ + -3466.2599389691895, + 9.184144452313603 + ], + [ + 3201.398038421638, + -1.623834633186334 + ] + ], + [ + [ + 5354.776469621631, + -1.623834633186334 + ], + [ + -2531.8242908161064, + 18.061460524089853 + ], + [ + -3466.2599389691895, + -9.184144452313603 + ], + [ + 3201.398038421638, + 1.623834633186334 + ] + ] + ], + "e4": [ + [ + [ + -3.2606153853436233, + 0.0009887808049988134 + ], + [ + 1.541671306441112, + -0.010997933602032347 + ], + [ + 2.1106652258449548, + 0.005592383337067291 + ], + [ + -1.9493862643764244, + -0.0009887808049988134 + ] + ], + [ + [ + -3.2606153853436233, + -0.0009887808049988134 + ], + [ + 1.541671306441112, + 0.010997933602032347 + ], + [ + 2.1106652258449548, + -0.005592383337067291 + ], + [ + -1.9493862643764244, + 0.0009887808049988134 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 1.2612896901245616e-09, + 0.0 + ], + [ + 1.2612896901245616e-09, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 854030762808643.8, + 1309991605041875.2 + ], + [ + -3.75873818574861e+16, + -5.9342385061247e+16 + ], + [ + 6.137052351690277e+17, + 9.833522629443133e+17 + ], + [ + -1423800493906.4712, + -2611236365885.3257 + ], + [ + -269544284043733.78, + 327534778012142.1 + ], + [ + 6152259604904996.0, + -2.0721660403080904e+16 + ], + [ + 4.6112618663587896e+16, + 4.772382890515046e+17 + ], + [ + -55688195577.1292, + -1414971803877.7046 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + 2.2358658269825714e-14, + 0.0 + ], + [ + -5.083770308789489e-30, + 0.0 + ], + [ + -6.354712885986861e-31, + 0.0 + ], + [ + 2.2358658269825714e-14, + 0.0 + ] + ], + [ + [ + 2.2358658269825714e-14, + 0.0 + ], + [ + -5.083770308789489e-30, + 0.0 + ], + [ + -6.354712885986861e-31, + 0.0 + ], + [ + 2.2358658269825714e-14, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 0.0, + 403.9060638193976 + ], + [ + -162.77698326366965, + -119.08472074672603 + ], + [ + 119.08472074672603, + -162.77698326366965 + ], + [ + 0.0, + 403.9060638193976 + ] + ], + [ + [ + 0.0, + 403.9060638193976 + ], + [ + 162.77698326366965, + -119.08472074672603 + ], + [ + -119.08472074672603, + -162.77698326366965 + ], + [ + 0.0, + 403.9060638193976 + ] + ] + ], + "e4": [ + [ + [ + 0.0, + 0.0024823667571795896 + ], + [ + 0.001000411254702996, + -0.0007318829266249073 + ], + [ + -0.0007318829266249073, + -0.001000411254702996 + ], + [ + 0.0, + 0.0024823667571795896 + ] + ], + [ + [ + 0.0, + 0.0024823667571795896 + ], + [ + -0.001000411254702996, + -0.0007318829266249073 + ], + [ + 0.0007318829266249073, + -0.001000411254702996 + ], + [ + 0.0, + 0.0024823667571795896 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -45187837297628.71, + -15713628403166.045 + ], + [ + -59986613355959.055, + 183466015846815.84 + ], + [ + 279129396672297.72, + 85264834107941.6 + ], + [ + -165528338.856182, + -114719397.47499418 + ], + [ + -8013626440148.551, + 2786660207101.54 + ], + [ + 13638025871073.725, + 41848181020502.13 + ], + [ + 44719041799598.51, + -27004958227611.297 + ], + [ + 92092700.52392672, + 13226113.800874166 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -473.4417395596135, + 0.0 + ], + [ + 35.007350811828225, + 0.0 + ], + [ + -96.57763452784293, + 0.0 + ], + [ + -462.1626625500776, + 0.0 + ] + ], + [ + [ + -473.4417395596135, + 0.0 + ], + [ + 35.007350811828225, + 0.0 + ], + [ + -96.57763452784293, + 0.0 + ], + [ + -462.1626625500776, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -41.640651004455826, + -15.093855682763026 + ], + [ + 0.0, + 403.39750064235045 + ], + [ + -403.39750064235045, + 0.0 + ], + [ + 41.640651004455826, + 15.093855682763026 + ] + ], + [ + [ + 41.640651004455826, + -15.093855682763026 + ], + [ + 0.0, + 403.39750064235045 + ], + [ + 403.39750064235045, + 0.0 + ], + [ + -41.640651004455826, + 15.093855682763026 + ] + ] + ], + "e4": [ + [ + [ + 6.397217447824372e-05, + -2.3188560841275574e-05 + ], + [ + 0.0, + 0.0006197361153748158 + ], + [ + 0.0006197361153748158, + 0.0 + ], + [ + -6.397217447824372e-05, + 2.3188560841275574e-05 + ] + ], + [ + [ + -6.397217447824372e-05, + -2.3188560841275574e-05 + ], + [ + 0.0, + 0.0006197361153748158 + ], + [ + -0.0006197361153748158, + 0.0 + ], + [ + 6.397217447824372e-05, + 2.3188560841275574e-05 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 4082909384036.585, + 4450407811825.551 + ], + [ + 4106631920221.531, + -9251815456954.422 + ], + [ + 440170107678.2675, + 7897668101532.237 + ], + [ + -56035602.30629724, + 89956543.3344401 + ], + [ + 724064539250.7698, + -789236835465.0286 + ], + [ + 2130125742568.112, + -6477639402043.985 + ], + [ + -6889369871449.463, + -43190518246255.46 + ], + [ + -6438335.073344027, + -53229677.07077114 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -460.3391344474081, + 0.0 + ], + [ + 1.0466900094966335e-13, + -0.0 + ], + [ + 1.3083625118707918e-14, + 0.0 + ], + [ + -460.3391344474081, + 0.0 + ] + ], + [ + [ + -460.3391344474081, + 0.0 + ], + [ + 1.0466900094966335e-13, + -0.0 + ], + [ + 1.3083625118707918e-14, + 0.0 + ], + [ + -460.3391344474081, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + 0.0, + 61.086277540202616 + ], + [ + 395.25094021436496, + -143.27011000461098 + ], + [ + 143.27011000461098, + 395.25094021436496 + ], + [ + 0.0, + 61.086277540202616 + ] + ], + [ + [ + 0.0, + 61.086277540202616 + ], + [ + -395.25094021436496, + -143.27011000461098 + ], + [ + -143.27011000461098, + 395.25094021436496 + ], + [ + 0.0, + 61.086277540202616 + ] + ] + ], + "e4": [ + [ + [ + 0.0, + 8.640227066463243e-05 + ], + [ + -0.0005590548334587346, + -0.00020264555840095478 + ], + [ + -0.00020264555840095478, + 0.0005590548334587346 + ], + [ + 0.0, + 8.640227066463243e-05 + ] + ], + [ + [ + 0.0, + 8.640227066463243e-05 + ], + [ + 0.0005590548334587346, + -0.00020264555840095478 + ], + [ + 0.00020264555840095478, + 0.0005590548334587346 + ], + [ + 0.0, + 8.640227066463243e-05 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 15640138319503.12, + 1532640430988.0242 + ], + [ + 6530070731760.56, + -14280934240379.22 + ], + [ + -7595710650314.661, + -7559108017865.322 + ], + [ + -22298289.90466622, + -96303823.24870509 + ], + [ + 2773627450661.994, + -271798975465.70056 + ], + [ + -9691416166574.395, + -12361803954183.814 + ], + [ + -31207433385393.36, + 44734904163300.65 + ], + [ + 4688639.127004724, + 104391841.8726057 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -485.8102229342245, + -0.0 + ], + [ + 1.1046045595645057e-13, + 0.0 + ], + [ + 1.3807556994556321e-14, + 0.0 + ], + [ + -485.8102229342245, + 0.0 + ] + ], + [ + [ + -485.8102229342245, + -0.0 + ], + [ + 1.1046045595645057e-13, + 0.0 + ], + [ + 1.3807556994556321e-14, + 0.0 + ], + [ + -485.8102229342245, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -94.88946695861188, + 0.0 + ], + [ + -92.23191976380615, + -254.44772118376267 + ], + [ + 254.44772118376267, + -92.23191976380615 + ], + [ + -94.88946695861188, + 0.0 + ] + ], + [ + [ + -94.88946695861188, + 0.0 + ], + [ + -92.23191976380615, + 254.44772118376267 + ], + [ + 254.44772118376267, + 92.23191976380615 + ], + [ + -94.88946695861188, + 0.0 + ] + ] + ], + "e4": [ + [ + [ + 0.00032385320090283195, + -0.0 + ], + [ + 0.00031478311975290227, + -0.000868417871961859 + ], + [ + -0.000868417871961859, + -0.00031478311975290227 + ], + [ + 0.00032385320090283195, + -0.0 + ] + ], + [ + [ + 0.00032385320090283195, + -0.0 + ], + [ + 0.00031478311975290227, + 0.000868417871961859 + ], + [ + -0.000868417871961859, + 0.00031478311975290227 + ], + [ + 0.00032385320090283195, + -0.0 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -1205877354205.7917, + 2260363239570.8247 + ], + [ + 48563567738.36494, + 848466325168.5082 + ], + [ + 6875433890723.121, + -3029439686686.075 + ], + [ + -33489877.38545947, + 24937866.14687216 + ], + [ + -213850700257.94385, + -400853585925.3238 + ], + [ + -2793106249881.745, + 273242759981.9697 + ], + [ + 26403053430459.316, + 12587374688210.213 + ], + [ + 7587728.630033595, + 22990780.145523813 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -821.3014613769902, + 0.0 + ], + [ + 35.00735081182822, + 0.0 + ], + [ + -96.57763452784292, + 0.0 + ], + [ + -114.30294073270076, + -0.0 + ] + ], + [ + [ + -821.3014613769902, + 0.0 + ], + [ + 35.00735081182822, + 0.0 + ], + [ + -96.57763452784292, + 0.0 + ], + [ + -114.30294073270076, + -0.0 + ] + ] + ], + "e3": [ + [ + [ + 147.91659824021536, + -337.92424170273483 + ], + [ + 266.0093835513015, + 0.0 + ], + [ + -0.0, + -266.0093835513015 + ], + [ + -147.91659824021536, + 337.92424170273483 + ] + ], + [ + [ + 147.91659824021536, + 337.92424170273483 + ], + [ + 266.0093835513015, + 0.0 + ], + [ + -0.0, + 266.0093835513015 + ], + [ + -147.91659824021536, + -337.92424170273483 + ] + ] + ], + "e4": [ + [ + [ + -0.0005225922989926317, + -0.0011938931023142004 + ], + [ + -0.0009398164706162929, + -0.0 + ], + [ + 0.0, + -0.0009398164706162929 + ], + [ + 0.0005225922989926317, + 0.0011938931023142004 + ] + ], + [ + [ + -0.0005225922989926317, + 0.0011938931023142004 + ], + [ + -0.0009398164706162929, + -0.0 + ], + [ + 0.0, + 0.0009398164706162929 + ], + [ + 0.0005225922989926317, + -0.0011938931023142004 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + -1.0913936421275139e-11, + 0.0 + ], + [ + -1.0913936421275139e-11, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 818463016881.6483, + -1861449265627.9456 + ], + [ + -6124623119427.956, + 2247517315624.0405 + ], + [ + 812154431612.1083, + 3132059714479.9536 + ], + [ + 36915010.256969646, + 28396951.22308869 + ], + [ + 4615210593755.654, + 10496479612721.59 + ], + [ + -45731329298629.445, + -533627821388.8543 + ], + [ + 24829129183196.234, + -62330560484755.74 + ], + [ + 72212194.28445157, + -34960951.03781168 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -1038.86317055788, + 0.0 + ], + [ + -47.76899921816474, + 0.0 + ], + [ + -285.68511568677945, + 0.0 + ], + [ + -45.60407795357867, + -0.0 + ] + ], + [ + [ + -1038.86317055788, + 0.0 + ], + [ + -47.76899921816474, + 0.0 + ], + [ + -285.68511568677945, + 0.0 + ], + [ + -45.60407795357867, + -0.0 + ] + ] + ], + "e3": [ + [ + [ + 433.79469195489116, + 89.8566673767053 + ], + [ + 86.71126019237191, + 163.2693901940836 + ], + [ + 359.69292275126406, + -0.7325195024902769 + ], + [ + -279.1727490388565, + -89.8566673767053 + ] + ], + [ + [ + 433.79469195489116, + -89.8566673767053 + ], + [ + 86.71126019237191, + -163.2693901940836 + ], + [ + 359.69292275126406, + 0.7325195024902769 + ], + [ + -279.1727490388565, + 89.8566673767053 + ] + ] + ], + "e4": [ + [ + [ + -0.00406823431694418, + 0.0008426981348729001 + ], + [ + -0.0008131997254055051, + 0.001531180875221936 + ], + [ + -0.0033732895285191952, + -6.869749752889342e-06 + ], + [ + 0.0026181513491493414, + -0.0008426981348729001 + ] + ], + [ + [ + -0.00406823431694418, + -0.0008426981348729001 + ], + [ + -0.0008131997254055051, + -0.001531180875221936 + ], + [ + -0.0033732895285191952, + 6.869749752889342e-06 + ], + [ + 0.0026181513491493414, + 0.0008426981348729001 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + -1.6653962076814006e-11, + 0.0 + ], + [ + -1.6653962076814006e-11, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 487030083534.8105, + 688885134137.243 + ], + [ + -2256928067962.152, + -1795514565635.6724 + ], + [ + 17110589042302.086, + 231511894640.79807 + ], + [ + -5114942.35685319, + -18227158.87033372 + ], + [ + 2696989680859.4863, + -1522516267743.1726 + ], + [ + -9588905748226.469, + -6389739941862.259 + ], + [ + 13255860124014.75, + 25757971219022.246 + ], + [ + -50168878.14535881, + 69971443.4180831 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -632.4219813242423, + -0.0 + ], + [ + 4.0235206756066475, + -0.0 + ], + [ + 125.36075724233504, + 0.0 + ], + [ + -361.2892414029084, + 0.0 + ] + ], + [ + [ + -632.4219813242423, + -0.0 + ], + [ + 4.0235206756066475, + -0.0 + ], + [ + 125.36075724233504, + 0.0 + ], + [ + -361.2892414029084, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -36.024200205068965, + -151.00475966256496 + ], + [ + -101.96030398036127, + -274.37535517706755 + ], + [ + 208.33521574479659, + 1.231004160859456 + ], + [ + -150.93584131346108, + 151.00475966256496 + ] + ], + [ + [ + -36.024200205068965, + 151.00475966256496 + ], + [ + -101.96030398036127, + 274.37535517706755 + ], + [ + 208.33521574479659, + -1.231004160859456 + ], + [ + -150.93584131346108, + -151.00475966256496 + ] + ] + ], + "e4": [ + [ + [ + 0.00011962870865373277, + -0.000501454697013872 + ], + [ + 0.00033858848856265167, + -0.0009111422110524278 + ], + [ + -0.0006918369508489444, + 4.087903056075821e-06 + ], + [ + 0.0005012258338313748, + 0.000501454697013872 + ] + ], + [ + [ + 0.00011962870865373277, + 0.000501454697013872 + ], + [ + 0.00033858848856265167, + 0.0009111422110524278 + ], + [ + -0.0006918369508489444, + -4.087903056075821e-06 + ], + [ + 0.0005012258338313748, + -0.000501454697013872 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 17436.601587741334, + 0.0 + ], + [ + 17436.601587741334, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + 7535667229726.062, + 9142479201282.602 + ], + [ + 3972596203478.498, + -21568201739302.094 + ], + [ + -19366065930019.65, + 9743152534255.562 + ], + [ + -62170700.768566094, + 67590234.70173109 + ], + [ + 1923530920152.9204, + -2395168551872.1885 + ], + [ + 2858588567914.334, + 6849696111685.54 + ], + [ + 8974061050686.822, + 14739847569447.076 + ], + [ + -13174801.318072157, + -24327236.233280502 + ] + ] + }, + { + "kind": "t3", + "inputs": { + "a": [ + [ + [ + -385.8652795293128, + -0.0 + ], + [ + 35.00735081182822, + 0.0 + ], + [ + -96.57763452784292, + 0.0 + ], + [ + -549.7391225803783, + 0.0 + ] + ], + [ + [ + -385.8652795293128, + -0.0 + ], + [ + 35.00735081182822, + 0.0 + ], + [ + -96.57763452784292, + 0.0 + ], + [ + -549.7391225803783, + 0.0 + ] + ] + ], + "e3": [ + [ + [ + -68.97650118435871, + 190.29110080907745 + ], + [ + -126.88143864481219, + 0.0 + ], + [ + -0.0, + -126.88143864481219 + ], + [ + 68.97650118435871, + -190.29110080907745 + ] + ], + [ + [ + -68.97650118435871, + -190.29110080907745 + ], + [ + -126.88143864481219, + 0.0 + ], + [ + -0.0, + 126.88143864481219 + ], + [ + 68.97650118435871, + 190.29110080907745 + ] + ] + ], + "e4": [ + [ + [ + 0.0010711369013430522, + 0.0029550327513569808 + ], + [ + 0.0019703433588883082, + -0.0 + ], + [ + 0.0, + -0.0019703433588883082 + ], + [ + -0.0010711369013430522, + -0.0029550327513569808 + ] + ], + [ + [ + 0.0010711369013430522, + -0.0029550327513569808 + ], + [ + 0.0019703433588883082, + -0.0 + ], + [ + 0.0, + 0.0019703433588883082 + ], + [ + -0.0010711369013430522, + 0.0029550327513569808 + ] + ] + ], + "lanes": [ + 0, + 0 + ], + "mindeg": 2, + "param": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ] + }, + "high_rounded": [ + [ + -686680774200.9235, + 512023235489.9441 + ], + [ + 1277618387783.2673, + -2173039108143.6318 + ], + [ + 685539700901.2659, + -1043094560690.0487 + ], + [ + 13400515.34429136, + 23686114.445355747 + ], + [ + -121776202119.03705, + -90802374782.11728 + ], + [ + 1188857921606.011, + 5077298657874.485 + ], + [ + 5184592218201.984, + 4186317588501.426 + ], + [ + 31353152.782843627, + -14888320.900946159 + ] + ] + } + ] + } + ] + } +] diff --git a/vendor/ninjars/tests/data/compensated/inputs.json b/vendor/ninjars/tests/data/compensated/inputs.json new file mode 100644 index 0000000000..852a168506 --- /dev/null +++ b/vendor/ninjars/tests/data/compensated/inputs.json @@ -0,0 +1,1536 @@ +[ + { + "sequence": 2, + "loop": 3, + "split_order": 1, + "direction": 1, + "n": 3, + "rank": 2, + "scale_squared": 1000000.0, + "status_ninjars": 0, + "status_ninja": 0, + "coefficients": [ + [ + 303.4709793441715, + 76.95983865811037 + ], + [ + -2.096910804639461, + -0.7943387014425094 + ], + [ + -1.8801479316162066, + -1.0366143693833578 + ], + [ + -3.7279713133173398, + -0.5160895437521557 + ], + [ + -0.5796750453279773, + 0.17932851424069174 + ], + [ + 0.002983880914251248, + 0.0005145587212392066 + ], + [ + 0.000140074548660056, + 0.0001892974052734359 + ], + [ + -0.006872657439147392, + -0.0005115269455999176 + ], + [ + 0.0004612940322267404, + -0.000500003413389284 + ], + [ + 0.001669419871443478, + 0.0005879275873860635 + ], + [ + -0.0059887675266295, + -0.001769722687753871 + ], + [ + 0.0006053435602825986, + -0.00038817578201484637 + ], + [ + -0.0018033475795622294, + -0.0026741385120379836 + ], + [ + -0.0033577628060212335, + 0.0010402954194233633 + ], + [ + -0.0035499200626049735, + -0.0005488233334618485 + ] + ], + "s_matrix_column_major": [ + 0.0, + 0.0, + -283043.9685493738, + 0.0, + 0.0, + -284686.22801171057, + -283043.9685493738, + -284686.22801171057, + 0.0 + ], + "momenta_column_major": [ + 0.0, + 0.0, + 0.0, + 0.0, + -407.63525077165207, + 192.3961632713691, + 262.9864423616991, + -244.9251827886652, + -86.33378939466184, + 157.38881245954087, + 359.56407688954204, + 369.3777579440356 + ], + "masses_squared": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ], + "ninjars": [ + [ + 0.01666153246769042, + 0.0031188377592510363 + ], + [ + 0.006525657514657723, + 0.0012045613396551857 + ], + [ + 0.0, + 0.0 + ] + ], + "ninja": [ + [ + 0.016661532460467754, + 0.0031188377601623074 + ], + [ + 0.006525657514629302, + 0.0012045613403302013 + ], + [ + 0.0, + 0.0 + ] + ] + }, + { + "sequence": 51, + "loop": 52, + "split_order": 1, + "direction": 1, + "n": 4, + "rank": 3, + "scale_squared": 1000000.0, + "status_ninjars": 0, + "status_ninja": 0, + "coefficients": [ + [ + -78661955.75129849, + -22593760.95623888 + ], + [ + -606572.8034190417, + -79487.02533296082 + ], + [ + -125146.05851715094, + 316063.33456953696 + ], + [ + 403998.5649313835, + -219922.40391271425 + ], + [ + 280886.8914270589, + -14084.303405579767 + ], + [ + -1166.5158858485993, + -130.1252948891908 + ], + [ + 81.64991948802148, + 255.7650684772247 + ], + [ + 2483.0682170485425, + 308.0517707539549 + ], + [ + 620.8252942371038, + -5.38051820172607 + ], + [ + -577.1819564252557, + -195.85583004654265 + ], + [ + 2259.893406861936, + 636.7147494842235 + ], + [ + 17.088335031317595, + -13.00698513204654 + ], + [ + 53.58314490516186, + 1103.3500171620108 + ], + [ + 888.2669322700452, + -567.2213906836693 + ], + [ + 812.7035498385093, + 46.36466636911194 + ], + [ + -0.4257934921136414, + -0.08272193016193805 + ], + [ + 0.0791346977793388, + 0.11701455552722106 + ], + [ + 1.3132223423321923, + 0.08112618906999879 + ], + [ + 0.016027126378201015, + -0.2761914659889988 + ], + [ + 0.2466421735325739, + -0.028531512779057105 + ], + [ + -0.36159273701927735, + -0.15567153843720974 + ], + [ + -0.1821470466017118, + 0.22075769801095824 + ], + [ + 1.1166677963692466, + 0.41091508806678423 + ], + [ + -0.020274659768723446, + -0.2735177826136616 + ], + [ + -0.17832063399312612, + 0.24612335823753345 + ], + [ + -0.4817675180830654, + -0.016263003701832302 + ], + [ + 0.11053726282822163, + 0.3657680621047574 + ], + [ + 1.795673199619422, + 0.1355113984666361 + ], + [ + 0.7681088994559746, + -0.05822067506769852 + ], + [ + -0.6011680992598211, + -0.16902786485297683 + ], + [ + 1.5275377593968282, + 0.478445988988232 + ], + [ + 0.29824346689505604, + 0.06143572077273292 + ], + [ + 0.3787549935257288, + 0.7375535598639311 + ], + [ + 0.7317196495199413, + -0.3104328135693144 + ], + [ + 0.6093175433016508, + 0.037549213091037835 + ] + ], + "s_matrix_column_major": [ + 0.0, + 0.0, + -284686.22801171057, + 0.0, + 0.0, + 0.0, + 8315.251343999998, + -162710.0679829868, + -284686.22801171057, + 8315.251343999998, + 0.0, + -283043.9685493738, + 0.0, + -162710.0679829868, + -283043.9685493738, + 0.0 + ], + "momenta_column_major": [ + 0.0, + 0.0, + 0.0, + 0.0, + 500.0, + -1.1368683772161603e-13, + -1.4210854715202004e-14, + 500.0, + 321.30146137699023, + -35.00735081182822, + 96.57763452784292, + 614.3029407327008, + 407.63525077165207, + -192.3961632713691, + -262.9864423616991, + 244.9251827886652 + ], + "masses_squared": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ], + "ninjars": [ + [ + -0.018133066777508727, + -0.003179419145432155 + ], + [ + -0.009869035565245099, + -0.002135385835806858 + ], + [ + -0.0016981805218419137, + -0.00048776164290072015 + ] + ], + "ninja": [ + [ + -0.018133066770166933, + -0.00317941913903496 + ], + [ + -0.009869035562473982, + -0.0021353858335118048 + ], + [ + -0.0016981805218419144, + -0.00048776164290072123 + ] + ] + }, + { + "sequence": 70, + "loop": 71, + "split_order": 1, + "direction": 1, + "n": 5, + "rank": 4, + "scale_squared": 1000000.0, + "status_ninjars": 0, + "status_ninja": 0, + "coefficients": [ + [ + -82158090522951.36, + -5319453645083.32 + ], + [ + -33306841408.352882, + -7371743805.889658 + ], + [ + -412748007732.93207, + 282499081452.9375 + ], + [ + -264732677923.20346, + -230439900980.0112 + ], + [ + -543227728169.1915, + -35430234350.08104 + ], + [ + 181046967.98464897, + -7872406.469844067 + ], + [ + -572071073.8840569, + 553799651.8083472 + ], + [ + 727434210.409425, + 49979106.40016688 + ], + [ + -550988009.2682989, + -406246711.9944138 + ], + [ + -1008154280.1329933, + -221239296.52847722 + ], + [ + 518077621.5786309, + 247048731.19391817 + ], + [ + -838727595.4622492, + -93842643.58071288 + ], + [ + -730674203.1929473, + 546769481.2537384 + ], + [ + 26714874.9242674, + -310644757.65409106 + ], + [ + -674862949.1506898, + -3572566.835823916 + ], + [ + 282831.5751421074, + -9315.350303072548 + ], + [ + -356857.831458929, + 466900.0935423008 + ], + [ + 414249.1228635613, + -70839.67834677131 + ], + [ + 869916.5059884393, + -845860.0721598738 + ], + [ + -424013.027794063, + -305263.1984610102 + ], + [ + -741723.6179142466, + -196262.6529553883 + ], + [ + 322897.76714327233, + 217672.26702403105 + ], + [ + 143906.90487111305, + 259439.55834465259 + ], + [ + 367353.589740665, + -745438.5954517606 + ], + [ + 522974.9493794709, + 516668.24590309686 + ], + [ + -689825.8076224086, + -110683.96060577735 + ], + [ + -234153.51517277645, + 541484.6502873406 + ], + [ + 2888463.0289384755, + -227568.3996097611 + ], + [ + 290780.43356406025, + -195951.9115486293 + ], + [ + -2275619.957457552, + -642129.7226567364 + ], + [ + 1948183.1086721728, + 883503.368816638 + ], + [ + -623241.5410402217, + -31085.6551170091 + ], + [ + -265549.6649978882, + 348106.7710355472 + ], + [ + 641508.6069605588, + -46160.55458530256 + ], + [ + 14022.174390508128, + 69162.01571631372 + ], + [ + 108.65850858998608, + -4.938864387298442 + ], + [ + -89.03671297922459, + 89.45315135886166 + ], + [ + 30.38637624000935, + -71.31779395747401 + ], + [ + 385.95202228070417, + -427.9640092896254 + ], + [ + -216.90349427545922, + 72.0757868655988 + ], + [ + -36.70401816188669, + -61.23350379048214 + ], + [ + -175.82800883283633, + -97.0902650049351 + ], + [ + -57.43684959525515, + 106.9008829874212 + ], + [ + 523.801542700696, + 85.2753906706884 + ], + [ + -108.56329058020435, + 51.54099630474714 + ], + [ + 163.5494620898317, + -299.9706473666205 + ], + [ + -311.2900686727216, + -53.94273906582397 + ], + [ + 125.73944509810627, + 262.3033679365002 + ], + [ + 386.36790581953665, + 139.9552055601762 + ], + [ + -16.132157640864502, + -29.987577957658868 + ], + [ + -175.9219862577596, + -58.00752414554714 + ], + [ + 58.11473744690427, + 239.6602810840644 + ], + [ + 1327.0905495222066, + -123.26498754924204 + ], + [ + 669.1149038379833, + -770.4237779724845 + ], + [ + 174.52475655221957, + -112.6500231255797 + ], + [ + -925.4619058738881, + -316.4428950852942 + ], + [ + 20.094332042381684, + 66.17197799811728 + ], + [ + 874.2167744069511, + 523.3960930385148 + ], + [ + 27.992496256059635, + -682.3259153735132 + ], + [ + 146.17462088573586, + 514.15250128553 + ], + [ + -373.33235102568415, + -37.507954622255106 + ], + [ + 97.49956055889159, + 215.70751138029132 + ], + [ + 2217.5886772465215, + -313.2414612069803 + ], + [ + 473.43135032114714, + 55.32013866331473 + ], + [ + -1383.6132670452762, + -519.5382970514655 + ], + [ + 1474.0571473658172, + 653.5501967794029 + ], + [ + 175.92198625775967, + 58.007524145547244 + ], + [ + 80.65858394911609, + 96.73847135149772 + ], + [ + 306.908624717066, + 15.682978451856783 + ], + [ + 264.6738424356981, + 42.44681900955364 + ] + ], + "s_matrix_column_major": [ + 0.0, + 0.0, + -284686.22801171057, + 650918.1740979805, + 0.0, + 0.0, + 0.0, + 8315.251343999998, + -56080.34654630897, + -162710.0679829868, + -284686.22801171057, + 8315.251343999998, + 0.0, + 0.0, + -283043.9685493738, + 650918.1740979805, + -56080.34654630897, + 0.0, + 0.0, + 0.0, + 0.0, + -162710.0679829868, + -283043.9685493738, + 0.0, + 0.0 + ], + "momenta_column_major": [ + 0.0, + 0.0, + 0.0, + 0.0, + 500.0, + -1.1368683772161603e-13, + -1.4210854715202004e-14, + 500.0, + 321.30146137699023, + -35.00735081182822, + 96.57763452784292, + 614.3029407327008, + 821.3014613769902, + -35.00735081182822, + 96.57763452784292, + 114.30294073270079, + 407.63525077165207, + -192.3961632713691, + -262.9864423616991, + 244.9251827886652 + ], + "masses_squared": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ], + "ninjars": [ + [ + -0.00854520367337379, + -0.004339845675765987 + ], + [ + -0.010913126877331258, + -0.002124518842364864 + ], + [ + -0.004955766446303191, + 0.00014666433464108748 + ] + ], + "ninja": [ + [ + -0.008545203675205492, + -0.004339845673946449 + ], + [ + -0.010913126877907686, + -0.0021245188416845195 + ], + [ + -0.004955766446303337, + 0.0001466643346409171 + ] + ] + }, + { + "sequence": 118, + "loop": 3, + "split_order": 1, + "direction": 2, + "n": 3, + "rank": 2, + "scale_squared": 1000000.0, + "status_ninjars": 0, + "status_ninja": 0, + "coefficients": [ + [ + 303.4709793441715, + 76.95983865811037 + ], + [ + -2.096910804639461, + -0.7943387014425094 + ], + [ + -1.8801479316162066, + -1.0366143693833578 + ], + [ + -3.7279713133173398, + -0.5160895437521557 + ], + [ + -0.5796750453279773, + 0.17932851424069174 + ], + [ + 0.002983880914251248, + 0.0005145587212392066 + ], + [ + 0.000140074548660056, + 0.0001892974052734359 + ], + [ + -0.006872657439147392, + -0.0005115269455999176 + ], + [ + 0.0004612940322267404, + -0.000500003413389284 + ], + [ + 0.001669419871443478, + 0.0005879275873860635 + ], + [ + -0.0059887675266295, + -0.001769722687753871 + ], + [ + 0.0006053435602825986, + -0.00038817578201484637 + ], + [ + -0.0018033475795622294, + -0.0026741385120379836 + ], + [ + -0.0033577628060212335, + 0.0010402954194233633 + ], + [ + -0.0035499200626049735, + -0.0005488233334618485 + ] + ], + "s_matrix_column_major": [ + 0.0, + -283043.9685493738, + 0.0, + -283043.9685493738, + 0.0, + -284686.22801171057, + 0.0, + -284686.22801171057, + 0.0 + ], + "momenta_column_major": [ + 0.0, + 0.0, + 0.0, + 0.0, + -86.33378939466184, + 157.38881245954087, + 359.56407688954204, + 369.3777579440356, + -407.63525077165207, + 192.3961632713691, + 262.9864423616991, + -244.9251827886652 + ], + "masses_squared": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ], + "ninjars": [ + [ + 0.016661532445862548, + 0.003118837753794068 + ], + [ + 0.006525657509200755, + 0.0012045613378361963 + ], + [ + 0.0, + 0.0 + ] + ], + "ninja": [ + [ + 0.016661532456829775, + 0.00311883775288635 + ], + [ + 0.006525657512810312, + 0.0012045613380564646 + ], + [ + 0.0, + 0.0 + ] + ] + }, + { + "sequence": 167, + "loop": 52, + "split_order": 1, + "direction": 2, + "n": 4, + "rank": 3, + "scale_squared": 1000000.0, + "status_ninjars": 0, + "status_ninja": 0, + "coefficients": [ + [ + -78661955.75129849, + -22593760.95623888 + ], + [ + -606572.8034190417, + -79487.02533296082 + ], + [ + -125146.05851715094, + 316063.33456953696 + ], + [ + 403998.5649313835, + -219922.40391271425 + ], + [ + 280886.8914270589, + -14084.303405579767 + ], + [ + -1166.5158858485993, + -130.1252948891908 + ], + [ + 81.64991948802148, + 255.7650684772247 + ], + [ + 2483.0682170485425, + 308.0517707539549 + ], + [ + 620.8252942371038, + -5.38051820172607 + ], + [ + -577.1819564252557, + -195.85583004654265 + ], + [ + 2259.893406861936, + 636.7147494842235 + ], + [ + 17.088335031317595, + -13.00698513204654 + ], + [ + 53.58314490516186, + 1103.3500171620108 + ], + [ + 888.2669322700452, + -567.2213906836693 + ], + [ + 812.7035498385093, + 46.36466636911194 + ], + [ + -0.4257934921136414, + -0.08272193016193805 + ], + [ + 0.0791346977793388, + 0.11701455552722106 + ], + [ + 1.3132223423321923, + 0.08112618906999879 + ], + [ + 0.016027126378201015, + -0.2761914659889988 + ], + [ + 0.2466421735325739, + -0.028531512779057105 + ], + [ + -0.36159273701927735, + -0.15567153843720974 + ], + [ + -0.1821470466017118, + 0.22075769801095824 + ], + [ + 1.1166677963692466, + 0.41091508806678423 + ], + [ + -0.020274659768723446, + -0.2735177826136616 + ], + [ + -0.17832063399312612, + 0.24612335823753345 + ], + [ + -0.4817675180830654, + -0.016263003701832302 + ], + [ + 0.11053726282822163, + 0.3657680621047574 + ], + [ + 1.795673199619422, + 0.1355113984666361 + ], + [ + 0.7681088994559746, + -0.05822067506769852 + ], + [ + -0.6011680992598211, + -0.16902786485297683 + ], + [ + 1.5275377593968282, + 0.478445988988232 + ], + [ + 0.29824346689505604, + 0.06143572077273292 + ], + [ + 0.3787549935257288, + 0.7375535598639311 + ], + [ + 0.7317196495199413, + -0.3104328135693144 + ], + [ + 0.6093175433016508, + 0.037549213091037835 + ] + ], + "s_matrix_column_major": [ + 0.0, + 0.0, + -284686.22801171057, + 0.0, + 0.0, + 0.0, + -283043.9685493738, + -162710.0679829868, + -284686.22801171057, + -283043.9685493738, + 0.0, + 8315.251343999998, + 0.0, + -162710.0679829868, + 8315.251343999998, + 0.0 + ], + "momenta_column_major": [ + 0.0, + 0.0, + 0.0, + 0.0, + 407.63525077165207, + -192.3961632713691, + -262.9864423616991, + 244.9251827886652, + 321.30146137699023, + -35.00735081182822, + 96.57763452784292, + 614.3029407327008, + 500.0, + -1.1368683772161603e-13, + -1.4210854715202004e-14, + 500.0 + ], + "masses_squared": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ], + "ninjars": [ + [ + -0.018133066792088953, + -0.003179419147241125 + ], + [ + -0.009869035568883435, + -0.002135385836261287 + ], + [ + -0.0016981805218419133, + -0.00048776164290072026 + ] + ], + "ninja": [ + [ + -0.018133066770195244, + -0.003179419137205916 + ], + [ + -0.009869035560655352, + -0.0021353858330567326 + ], + [ + -0.001698180521841916, + -0.00048776164290072205 + ] + ] + }, + { + "sequence": 186, + "loop": 71, + "split_order": 1, + "direction": 2, + "n": 5, + "rank": 4, + "scale_squared": 1000000.0, + "status_ninjars": 0, + "status_ninja": 0, + "coefficients": [ + [ + -82158090522951.36, + -5319453645083.32 + ], + [ + -33306841408.352882, + -7371743805.889658 + ], + [ + -412748007732.93207, + 282499081452.9375 + ], + [ + -264732677923.20346, + -230439900980.0112 + ], + [ + -543227728169.1915, + -35430234350.08104 + ], + [ + 181046967.98464897, + -7872406.469844067 + ], + [ + -572071073.8840569, + 553799651.8083472 + ], + [ + 727434210.409425, + 49979106.40016688 + ], + [ + -550988009.2682989, + -406246711.9944138 + ], + [ + -1008154280.1329933, + -221239296.52847722 + ], + [ + 518077621.5786309, + 247048731.19391817 + ], + [ + -838727595.4622492, + -93842643.58071288 + ], + [ + -730674203.1929473, + 546769481.2537384 + ], + [ + 26714874.9242674, + -310644757.65409106 + ], + [ + -674862949.1506898, + -3572566.835823916 + ], + [ + 282831.5751421074, + -9315.350303072548 + ], + [ + -356857.831458929, + 466900.0935423008 + ], + [ + 414249.1228635613, + -70839.67834677131 + ], + [ + 869916.5059884393, + -845860.0721598738 + ], + [ + -424013.027794063, + -305263.1984610102 + ], + [ + -741723.6179142466, + -196262.6529553883 + ], + [ + 322897.76714327233, + 217672.26702403105 + ], + [ + 143906.90487111305, + 259439.55834465259 + ], + [ + 367353.589740665, + -745438.5954517606 + ], + [ + 522974.9493794709, + 516668.24590309686 + ], + [ + -689825.8076224086, + -110683.96060577735 + ], + [ + -234153.51517277645, + 541484.6502873406 + ], + [ + 2888463.0289384755, + -227568.3996097611 + ], + [ + 290780.43356406025, + -195951.9115486293 + ], + [ + -2275619.957457552, + -642129.7226567364 + ], + [ + 1948183.1086721728, + 883503.368816638 + ], + [ + -623241.5410402217, + -31085.6551170091 + ], + [ + -265549.6649978882, + 348106.7710355472 + ], + [ + 641508.6069605588, + -46160.55458530256 + ], + [ + 14022.174390508128, + 69162.01571631372 + ], + [ + 108.65850858998608, + -4.938864387298442 + ], + [ + -89.03671297922459, + 89.45315135886166 + ], + [ + 30.38637624000935, + -71.31779395747401 + ], + [ + 385.95202228070417, + -427.9640092896254 + ], + [ + -216.90349427545922, + 72.0757868655988 + ], + [ + -36.70401816188669, + -61.23350379048214 + ], + [ + -175.82800883283633, + -97.0902650049351 + ], + [ + -57.43684959525515, + 106.9008829874212 + ], + [ + 523.801542700696, + 85.2753906706884 + ], + [ + -108.56329058020435, + 51.54099630474714 + ], + [ + 163.5494620898317, + -299.9706473666205 + ], + [ + -311.2900686727216, + -53.94273906582397 + ], + [ + 125.73944509810627, + 262.3033679365002 + ], + [ + 386.36790581953665, + 139.9552055601762 + ], + [ + -16.132157640864502, + -29.987577957658868 + ], + [ + -175.9219862577596, + -58.00752414554714 + ], + [ + 58.11473744690427, + 239.6602810840644 + ], + [ + 1327.0905495222066, + -123.26498754924204 + ], + [ + 669.1149038379833, + -770.4237779724845 + ], + [ + 174.52475655221957, + -112.6500231255797 + ], + [ + -925.4619058738881, + -316.4428950852942 + ], + [ + 20.094332042381684, + 66.17197799811728 + ], + [ + 874.2167744069511, + 523.3960930385148 + ], + [ + 27.992496256059635, + -682.3259153735132 + ], + [ + 146.17462088573586, + 514.15250128553 + ], + [ + -373.33235102568415, + -37.507954622255106 + ], + [ + 97.49956055889159, + 215.70751138029132 + ], + [ + 2217.5886772465215, + -313.2414612069803 + ], + [ + 473.43135032114714, + 55.32013866331473 + ], + [ + -1383.6132670452762, + -519.5382970514655 + ], + [ + 1474.0571473658172, + 653.5501967794029 + ], + [ + 175.92198625775967, + 58.007524145547244 + ], + [ + 80.65858394911609, + 96.73847135149772 + ], + [ + 306.908624717066, + 15.682978451856783 + ], + [ + 264.6738424356981, + 42.44681900955364 + ] + ], + "s_matrix_column_major": [ + 0.0, + 0.0, + 650918.1740979805, + -284686.22801171057, + 0.0, + 0.0, + 0.0, + 0.0, + -283043.9685493738, + -162710.0679829868, + 650918.1740979805, + 0.0, + 0.0, + 0.0, + -56080.34654630897, + -284686.22801171057, + -283043.9685493738, + 0.0, + 0.0, + 8315.251343999998, + 0.0, + -162710.0679829868, + -56080.34654630897, + 8315.251343999998, + 0.0 + ], + "momenta_column_major": [ + 0.0, + 0.0, + 0.0, + 0.0, + 407.63525077165207, + -192.3961632713691, + -262.9864423616991, + 244.9251827886652, + 821.3014613769902, + -35.00735081182822, + 96.57763452784292, + 114.30294073270079, + 321.30146137699023, + -35.00735081182822, + 96.57763452784292, + 614.3029407327008, + 500.0, + -1.1368683772161603e-13, + -1.4210854715202004e-14, + 500.0 + ], + "masses_squared": [ + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + 0.0 + ] + ], + "ninjars": [ + [ + -0.00854520367655437, + -0.004339845682590476 + ], + [ + -0.010913126878297933, + -0.0021245188444091595 + ], + [ + -0.004955766446303172, + 0.00014666433464096014 + ] + ], + "ninja": [ + [ + -0.008545203671110162, + -0.004339845678497253 + ], + [ + -0.010913126876715208, + -0.002124518843275857 + ], + [ + -0.004955766446303326, + 0.00014666433464086793 + ] + ] + } +] diff --git a/vendor/ninjars/tests/data/convergence.json b/vendor/ninjars/tests/data/convergence.json new file mode 100644 index 0000000000..9d80346601 --- /dev/null +++ b/vendor/ninjars/tests/data/convergence.json @@ -0,0 +1,362 @@ +{ + "convergence_max_scaled_error": "2.01273995940312641211677207790390315307e-76", + "convergence_tolerance": "1e-31", + "dp_max_scaled_error": 1.945869752726985e-17, + "dp_tolerance": 1e-10, + "finite_split_identity_tolerance": "1e-60 times largest output component", + "fixture": "cases/madloop-gg-hhh-top-pentagon-26.json", + "input": { + "coefficients": [ + "3.30344161693719042968750000000260589686e12", + "-1.12757771960866284179687500000088959635e12", + "7.85814109276715240478515625000619922238e10", + "-4.50817700798420429229736328125355604945e9", + "2.25239349138858642578125000000177678396e10", + "-1.44035519527321338653564453125113633937e9", + "1.45402290470077896118164062500114709271e9", + "1.91739039078555717468261718750151241703e10", + "-7.85207590788601684570312500000619392843e10", + "4.50817700798420429229736328125355604945e9", + "5.15382144481954276561737060547281559271e8", + "-7.51362834664034098386764526367780258919e6", + "1.66712444729793608188629150390756521717e8", + "-3.72529029846191406250000000000293873588e-9", + "2.62913662702519446611404418945519900998e6", + "7.51362834664034191519021987915631821419e6", + "5.77508849052041769027709960937955595572e7", + "6.66849778919174522161483764648963535171e7", + "0", + "0", + "2.62913662702519446611404418945519900998e6", + "7.51362834664034191519021987915631821419e6", + "-2.56275417512778967618942260742389668112e8", + "0", + "-1.00027466837876170873641967773516405276e8", + "0", + "-5.77508849052041769027709960937955595572e7", + "-3.72529029846191406250000000000293873588e-9", + "-2.59106726969175398349761962890829391159e8", + "7.51362834664034098386764526367780258919e6", + "1.28137708756389515474438667297464356420e6", + "0", + "2.50068667094690434169024229049879895523e5", + "4.81257374210034831776283681393049340711e4", + "-4.27125695854631718248128890991547888392e5", + "0", + "8.33562223648968065390363335610093629607e4", + "-4.81257374210034831776283681393049340711e4", + "1.44377212263010442256927490234488898893e5", + "2.77854074549655997543595731258611511098e4", + "0", + "0", + "4.81257374210034831776283681393049340711e4", + "-2.77854074549656070303171873092870544301e4", + "-4.27125695854631718248128890991547888392e5", + "0", + "8.33562223648968065390363335610093629607e4", + "-4.81257374210034831776283681393049340711e4", + "4.81257374210034831776283681393049340711e4", + "-2.77854074549656033923383802175741027700e4", + "-4.27125695854631718248128890991547888392e5", + "0", + "0", + "0", + "4.27125695854631601832807064056733435267e5", + "0", + "0", + "0", + "0", + "0", + "4.27125695854631601832807064056733435267e5", + "0", + "-1.28137708756389468908309936523538575170e6", + "0", + "-2.50068667094690434169024229049879895523e5", + "-4.81257374210034831776283681393049340711e4", + "-1.44377212263010442256927490234488898893e5", + "-2.77854074549655997543595731258611511098e4", + "4.27125695854631601832807064056733435267e5", + "0", + "1.06781423963657903186685871332968065462e3", + "0", + "0", + "0", + "-7.11876159757719278786680661142433976363e2", + "0", + "0", + "0", + "-3.55938079878859696236759191379231857871e2", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "-7.11876159757719278786680661142433976363e2", + "0", + "0", + "0", + "-7.11876159757719392473518382758463715743e2", + "0", + "0", + "0", + "0", + "0", + "-3.55938079878859696236759191379231857871e2", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "-2.13562847927315806373371742665936130924e3", + "0", + "0", + "0", + "7.11876159757719392473518382758463715743e2", + "0", + "0", + "0", + "0", + "0", + "7.11876159757719392473518382758463715743e2", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "1.06781423963657903186685871332968065462e3", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0" + ], + "masses_squared": [ + "2.992900000000000000000000000000000000000e4", + "-2.992900000000000204636307898908853530884e2", + "2.992900000000000000000000000000000000000e4", + "-2.992900000000000204636307898908853530884e2", + "2.992900000000000000000000000000000000000e4", + "-2.992900000000000204636307898908853530884e2", + "2.992900000000000000000000000000000000000e4", + "-2.992900000000000204636307898908853530884e2", + "2.992900000000000000000000000000000000000e4", + "-2.992900000000000204636307898908853530884e2" + ], + "momenta": [ + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "3.000000000000000000000000000000000000000e2", + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "3.000000000000000000000000000000000000000e2", + "6.000000000000000000000000000000000000000e2", + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "4.000000000000000000000000000000000000000e2", + "-1.561249499599599630528246052563190460205e2", + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "2.000000000000000000000000000000000000000e2", + "-7.806247497997998152641230262815952301025e1", + "-1.352081728298996097237250069156289100647e2", + "0.000000000000000000000000000000000000000e0" + ], + "n": 5, + "rank": 5, + "s_matrix": [ + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "3.600000000000000000000000000000000000000e5", + "1.356250000000000000000000000000000000000e5", + "1.562500000000000000000000000000000000000e4", + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "-1.043750000000000000000000000000000000000e5", + "-1.043750000000000000000000000000000000000e5", + "3.600000000000000000000000000000000000000e5", + "0.000000000000000000000000000000000000000e0", + "0.000000000000000000000000000000000000000e0", + "1.562500000000000000000000000000000000000e4", + "1.356250000000000000000000000000000000000e5", + "1.356250000000000000000000000000000000000e5", + "-1.043750000000000000000000000000000000000e5", + "1.562500000000000000000000000000000000000e4", + "0.000000000000000000000000000000000000000e0", + "1.562500000000000000000000000000000000000e4", + "1.562500000000000000000000000000000000000e4", + "-1.043750000000000000000000000000000000000e5", + "1.356250000000000000000000000000000000000e5", + "1.562500000000000000000000000000000000000e4", + "0.000000000000000000000000000000000000000e0" + ], + "scale_squared": [ + "1.000000000000000000000000000000000000000e4" + ] + }, + "lane": "gg-hhh-top-pentagon-26-madloop-sqrt_s_600", + "modification": "Each squared mass gets Im=-299.29 as binary64 promoted to binary128; tensor multiplied by 1+2^-100 in binary128.", + "passed": true, + "production_bits": 256, + "reference_bits": 384, + "result_256": [ + "3.77446489635831593477054206645965810845e-3", + "-9.38863946381058773322685445204837043502e-3", + "4.78615786622665754385425261927658862950e-79", + "-1.88968898132407128796448189869015090713e-78", + "0", + "0", + "2.16758035333863871592114861742045966250e-20", + "1.09638858609597441533225170133208197680e-79" + ], + "result_384": [ + "3.77446489635831593477054206645965810845e-3", + "-9.38863946381058773322685445204837043502e-3", + "3.95314182667818409289264567045870796600e-117", + "1.79688264849008367858756621384486725727e-118", + "0", + "0", + "2.16758035333863871592114861742045966250e-20", + "-4.95691765100712738920707921060653036489e-119" + ], + "upstream": { + "repository": "https://github.com/alphal00p/ninjars", + "revision": "0d0d7e7a8033431b60a8580731084742e0655cda", + "fixture": "validation/benchmark/madloop/cases/madloop-gg-hhh-top-pentagon-26.json" + }, + "reproduce": "CARGO_TARGET_DIR=\"$PWD/.ninjars-build/cargo\" cargo test --manifest-path vendor/ninjars/Cargo.toml --locked complex_mass_pentagon_converges_at_binary128_output_precision -- --test-threads=1 --nocapture", + "abi_version": 2 +} diff --git a/vendor/ninjars/tests/data/ninja/madloop-four-photon-top-box-0.json b/vendor/ninjars/tests/data/ninja/madloop-four-photon-top-box-0.json new file mode 100644 index 0000000000..e73d100bd3 --- /dev/null +++ b/vendor/ninjars/tests/data/ninja/madloop-four-photon-top-box-0.json @@ -0,0 +1,495 @@ +{ + "format": "ninjars-reference-ninja-results-v1", + "case": "madloop-four-photon-top-box-0", + "case_file": "/shared/external/ninja/references/claude_reference/validation/benchmark/madloop/cases/madloop-four-photon-top-box-0.json", + "case_sha256": "9aea91e4e6c70b0f5984b2070e7aef8a77699260dacac1a9b3c9d65f23189796", + "n": 4, + "rank": 4, + "lanes_count": 3, + "amplitude": "ninja::Amplitude(n, rank, V, m2); setRenormalizationScale(mu_squared) (Ninja passes mu_R^2 to IntegralLibrary::init, AvHOneLoop uses mu_R=sqrt); setSMatrix if s_matrix given", + "all_replays_bitwise_identical": true, + "lanes": [ + { + "id": "four-photon-top-box-0-madloop-sqrt_s_200", + "return_status": 0, + "eps0": [ + 0.0002754479878171569, + 2.192084389594703e-17 + ], + "eps_m1": [ + -0.0008553751652717531, + -4.918836857910419e-16 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.0009051510962427033, + 3.0492168319309095e-17 + ], + "rational": [ + 0.0011805990840598603, + -8.571324423362066e-18 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 2, + "muExpansion": 1, + "t3Expansion": 12, + "t2Expansion": 12, + "total": 27, + "output_values": 119 + }, + "master_calls": { + "box_cm": 1, + "rank2_bubble_cm": 6, + "tadpole_cm": 4, + "triangle_cm": 4, + "total": 15, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "four-photon-top-box-0-madloop-sqrt_s_500", + "return_status": 0, + "eps0": [ + 0.0033036499636558874, + -0.0001657964967402878 + ], + "eps_m1": [ + -0.0017040362397646464, + 8.15946310762427e-19 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 0.0039373430227599366, + -0.0001657964967402875 + ], + "rational": [ + -0.0006336930591040492, + -2.981555974335137e-19 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 2, + "muExpansion": 1, + "t3Expansion": 12, + "t2Expansion": 12, + "total": 27, + "output_values": 119 + }, + "master_calls": { + "box_cm": 1, + "rank2_bubble_cm": 6, + "tadpole_cm": 4, + "triangle_cm": 4, + "total": 15, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "four-photon-top-box-0-madloop-sqrt_s_800", + "return_status": 0, + "eps0": [ + 0.004251842260027151, + 0.001576289498000266 + ], + "eps_m1": [ + -0.0013452053881199614, + -9.372539838599777e-18 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 0.005313964938342923, + 0.001576289498000266 + ], + "rational": [ + -0.001062122678315772, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 2, + "muExpansion": 1, + "t3Expansion": 12, + "t2Expansion": 12, + "total": 27, + "output_values": 119 + }, + "master_calls": { + "box_cm": 1, + "rank2_bubble_cm": 6, + "tadpole_cm": 4, + "triangle_cm": 4, + "total": 15, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + } + ], + "timing_unit": "ns per phase-space point (one lane), lanes cycled; median of interleaved blocks", + "timing_cpu": 250, + "timing_modes": { + "full": "TensorNumerator + AvHOneLoop (OneLOop, cache disabled), Amplitude::evaluate", + "pure_reduction": "ReplayNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "reduction_plus_tensor_numerator": "TensorNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "masters_only": "recorded AvHOneLoop interface calls replayed through ninja::avh_olo, no reduction", + "numerator_only": "recorded TensorNumerator calls (inputs) replayed, no reduction", + "full_madloop_entry": "MadLoop's entry point ninja_tensor_evaluate_[smat_]cm_ (new TensorNumerator + Amplitude per call, default AvHOneLoop)", + "masters_boxes": "recorded boxes calls only, replayed through ninja::avh_olo", + "masters_triangles": "recorded triangles calls only, replayed through ninja::avh_olo", + "masters_bubbles": "recorded bubbles calls only, replayed through ninja::avh_olo", + "masters_tadpoles": "recorded tadpoles calls only, replayed through ninja::avh_olo" + }, + "timing": { + "o3-fortranrules": { + "median_ns": { + "full": 41891.291666666664, + "pure_reduction": 9153.216814159292, + "reduction_plus_tensor_numerator": 32115.3141025641, + "masters_only": 9128.694414019716, + "numerator_only": 21326.441326530614, + "full_madloop_entry": 42228.96464646464, + "masters_boxes": 3847.0908532842236, + "masters_triangles": 3656.430377885605, + "masters_bubbles": 1355.9751744280384, + "masters_tadpoles": 169.13658572898058 + }, + "blocks_ns": { + "full": [ + 41848.00833333333, + 41825.44, + 41933.308333333334, + 41866.325, + 41978.291666666664, + 41718.69, + 41891.291666666664, + 41898.875, + 41919.15666666667 + ], + "pure_reduction": [ + 9101.34365781711, + 9176.564896755162, + 9153.216814159292, + 9125.786873156343, + 9113.685103244838, + 9134.654498525073, + 9174.466814159292, + 9179.300884955752, + 9162.512536873157 + ], + "reduction_plus_tensor_numerator": [ + 32051.82564102564, + 32159.248717948718, + 32113.492307692308, + 32096.915384615386, + 31971.646153846155, + 32127.03205128205, + 32558.45641025641, + 32115.3141025641, + 32178.160256410258 + ], + "masters_only": [ + 9146.025921869295, + 9122.92625045637, + 9130.750273822563, + 9122.699890470974, + 9121.22818546915, + 9106.492880613363, + 9128.694414019716, + 9140.326761591821, + 9130.0857977364 + ], + "numerator_only": [ + 21385.174319727892, + 21319.093537414967, + 21345.743197278913, + 21313.880952380954, + 21411.968537414967, + 21297.844387755104, + 21326.441326530614, + 21306.789965986394, + 21382.11224489796 + ], + "full_madloop_entry": [ + 42230.62962962963, + 42256.47306397306, + 42228.96464646464, + 42140.00841750842, + 42154.318181818184, + 42149.87373737374, + 42274.68855218855, + 42174.57070707071, + 42274.402356902356 + ], + "masters_boxes": [ + 3840.2601289134436, + 3874.1843155310007, + 3848.9953959484346, + 3852.9226519337017, + 3842.252148557397, + 3838.125230202578, + 3847.0908532842236, + 3851.386586863106, + 3842.3058624923265 + ], + "masters_triangles": [ + 3644.52492280547, + 3658.300838112042, + 3649.385972651081, + 3659.7991471842374, + 3644.419056021173, + 3656.430377885605, + 3657.986178503161, + 3658.4390530804294, + 3641.2930451404204 + ], + "masters_bubbles": [ + 1358.4922927145872, + 1349.88501271026, + 1356.972470117367, + 1350.391313754124, + 1356.2845475688248, + 1349.1488993455569, + 1363.7289739845314, + 1349.802260803721, + 1355.9751744280384 + ], + "masters_tadpoles": [ + 169.13658572898058, + 167.88678198256727, + 168.81465540577122, + 169.07337177196686, + 169.71052595961237, + 169.89852336094418, + 170.0531576525364, + 169.2242163391262, + 168.77147961669644 + ] + }, + "iterations_per_block": { + "full": 200, + "pure_reduction": 904, + "reduction_plus_tensor_numerator": 260, + "masters_only": 913, + "numerator_only": 392, + "full_madloop_entry": 198, + "masters_boxes": 2172, + "masters_triangles": 2267, + "masters_bubbles": 6163, + "masters_tadpoles": 49256 + }, + "derived": { + "full_ns": 41891.291666666664, + "pure_reduction_ns": 9153.216814159292, + "numerator_part_ns": 22962.09728840481, + "numerator_only_ns": 21326.441326530614, + "masters_ns": 9128.694414019716, + "sum_pure_numerator_masters_ns": 41244.00851658382, + "sum_over_full": 0.9845485034160955 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "98.33", + "98.39", + "94.07" + ], + "libninja_sha256": "858309a8a0759066bcdb6a95d216e84a27470bdab1b005b54caa743d742458cb", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "6e98ba3ff436083861a029695192a16707066542fdf1533450402b7cdc2e52f6" + }, + "o3": { + "median_ns": { + "full": 52252.589098532495, + "pure_reduction": 11101.096514745308, + "reduction_plus_tensor_numerator": 42500.65143824027, + "masters_only": 9120.08160291439, + "numerator_only": 29249.516317016318, + "full_madloop_entry": 52730.30573248408, + "masters_boxes": 3869.3714467206605, + "masters_triangles": 3642.671974052779, + "masters_bubbles": 1336.9588470690028, + "masters_tadpoles": 157.23924700728824 + }, + "blocks_ns": { + "full": [ + 52568.35429769392, + 52303.25786163522, + 52263.86582809225, + 52204.22222222222, + 52314.976939203356, + 52196.297693920336, + 52252.589098532495, + 52233.74004192872, + 52171.95807127882 + ], + "pure_reduction": [ + 11149.831992850759, + 11154.434316353887, + 11107.660411081322, + 11102.544235924934, + 11099.604110813227, + 11086.409294012512, + 11101.096514745308, + 11065.74798927614, + 11093.29490616622 + ], + "reduction_plus_tensor_numerator": [ + 42711.51438240271, + 42555.74450084603, + 42490.83756345178, + 42538.434856175976, + 42601.03891708968, + 42500.65143824027, + 42461.7834179357, + 42460.448392554994, + 42273.88324873096 + ], + "masters_only": [ + 9130.085610200364, + 9123.382513661201, + 9107.225865209472, + 9110.832058287797, + 9121.990892531876, + 9100.923132969034, + 9101.768670309653, + 9132.6029143898, + 9120.08160291439 + ], + "numerator_only": [ + 29308.4324009324, + 29154.573426573428, + 29253.304195804194, + 29170.19230769231, + 29249.516317016318, + 29181.54428904429, + 29251.70745920746, + 29300.110722610723, + 29135.42540792541 + ], + "full_madloop_entry": [ + 53054.46709129512, + 52758.30997876858, + 52702.45010615711, + 52739.81740976645, + 52608.24628450106, + 52696.88747346072, + 52730.30573248408, + 52642.47133757962, + 52774.84713375796 + ], + "masters_boxes": [ + 3871.072415435922, + 3880.562648880419, + 3869.3714467206605, + 3874.732729871367, + 3871.4567254248054, + 3869.3269811021123, + 3863.0034937271716, + 3866.2540892488487, + 3863.773701762744 + ], + "masters_triangles": [ + 3634.075335397317, + 3657.9793601651186, + 3658.7268170426064, + 3652.441987321244, + 3629.3547103051746, + 3642.671974052779, + 3650.4635117204775, + 3637.187675070028, + 3633.3514669025503 + ], + "masters_bubbles": [ + 1334.7633571274064, + 1334.5989076357343, + 1341.5203331170235, + 1339.6979234263465, + 1338.1085874972962, + 1336.9588470690028, + 1330.9043370105992, + 1336.841499026606, + 1338.6893791910015 + ], + "masters_tadpoles": [ + 157.6002605641781, + 157.23924700728824, + 157.21790466120362, + 157.1366514356205, + 157.4782800246718, + 156.6695869994839, + 157.29903201037223, + 156.8270583940687, + 157.38935463162267 + ] + }, + "iterations_per_block": { + "full": 159, + "pure_reduction": 746, + "reduction_plus_tensor_numerator": 197, + "masters_only": 915, + "numerator_only": 286, + "full_madloop_entry": 157, + "masters_boxes": 2099, + "masters_triangles": 2261, + "masters_bubbles": 6164, + "masters_tadpoles": 52962 + }, + "derived": { + "full_ns": 52252.589098532495, + "pure_reduction_ns": 11101.096514745308, + "numerator_part_ns": 31399.554923494958, + "numerator_only_ns": 29249.516317016318, + "masters_ns": 9120.08160291439, + "sum_pure_numerator_masters_ns": 51620.73304115466, + "sum_over_full": 0.987907660303945 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "98.33", + "98.39", + "94.07" + ], + "libninja_sha256": "b6c3a01e70c155211b3abdab557afa99eb60ec9a50e5ab5b49323f22381b1869", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "69fa60af770227ff72f18623be916e625649a2a30fd42b8f05a91aff5572dac3" + } + }, + "date_utc": "2026-10-18T00:59:42+00:00", + "driver_sha256": "fcebb40f7be0c02e8472789e2119df3d9c382c91f756aa3e1ef80ae2b8f03f10" +} diff --git a/vendor/ninjars/tests/data/ninja/madloop-gg-hh-top-box-2.json b/vendor/ninjars/tests/data/ninja/madloop-gg-hh-top-box-2.json new file mode 100644 index 0000000000..24a230f4bc --- /dev/null +++ b/vendor/ninjars/tests/data/ninja/madloop-gg-hh-top-box-2.json @@ -0,0 +1,495 @@ +{ + "format": "ninjars-reference-ninja-results-v1", + "case": "madloop-gg-hh-top-box-2", + "case_file": "/shared/external/ninja/references/claude_reference/validation/benchmark/madloop/cases/madloop-gg-hh-top-box-2.json", + "case_sha256": "c9271b79b2a4df2155ee8855fda3ffc6090f37261711468efd3126cf6665d5a3", + "n": 4, + "rank": 4, + "lanes_count": 3, + "amplitude": "ninja::Amplitude(n, rank, V, m2); setRenormalizationScale(mu_squared) (Ninja passes mu_R^2 to IntegralLibrary::init, AvHOneLoop uses mu_R=sqrt); setSMatrix if s_matrix given", + "all_replays_bitwise_identical": true, + "lanes": [ + { + "id": "gg-hh-top-box-2-madloop-sqrt_s_312.5", + "return_status": 0, + "eps0": [ + 0.8635665696414119, + -3.0290244896020196e-14 + ], + "eps_m1": [ + 1.4641071403572923, + 7.113115411197317e-14 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 0.3755308561890549, + -3.3216035915907285e-14 + ], + "rational": [ + 0.48803571345235697, + 2.925791019887089e-15 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 2, + "muExpansion": 1, + "t3Expansion": 12, + "t2Expansion": 12, + "total": 27, + "output_values": 119 + }, + "master_calls": { + "box_cm": 1, + "rank2_bubble_cm": 6, + "tadpole_cm": 4, + "triangle_cm": 4, + "total": 15, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hh-top-box-2-madloop-sqrt_s_416.7", + "return_status": 0, + "eps0": [ + 2.093867254458311, + 3.176916847652975 + ], + "eps_m1": [ + 1.4641071403570864, + 1.7413116447417696e-14 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 1.605831541005953, + 3.1769168476529748 + ], + "rational": [ + 0.48803571345235786, + 4.440892098500626e-16 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 2, + "muExpansion": 1, + "t3Expansion": 12, + "t2Expansion": 12, + "total": 27, + "output_values": 119 + }, + "master_calls": { + "box_cm": 1, + "rank2_bubble_cm": 6, + "tadpole_cm": 4, + "triangle_cm": 4, + "total": 15, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hh-top-box-2-madloop-sqrt_s_650", + "return_status": 0, + "eps0": [ + -1.2128348286046828, + 4.710982224686321 + ], + "eps_m1": [ + 1.4641071403570907, + -4.235318890509442e-16 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -1.7008705420570422, + 4.710982224686321 + ], + "rational": [ + 0.4880357134523594, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 2, + "muExpansion": 1, + "t3Expansion": 12, + "t2Expansion": 12, + "total": 27, + "output_values": 119 + }, + "master_calls": { + "box_cm": 1, + "rank2_bubble_cm": 6, + "tadpole_cm": 4, + "triangle_cm": 4, + "total": 15, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + } + ], + "timing_unit": "ns per phase-space point (one lane), lanes cycled; median of interleaved blocks", + "timing_cpu": 250, + "timing_modes": { + "full": "TensorNumerator + AvHOneLoop (OneLOop, cache disabled), Amplitude::evaluate", + "pure_reduction": "ReplayNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "reduction_plus_tensor_numerator": "TensorNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "masters_only": "recorded AvHOneLoop interface calls replayed through ninja::avh_olo, no reduction", + "numerator_only": "recorded TensorNumerator calls (inputs) replayed, no reduction", + "full_madloop_entry": "MadLoop's entry point ninja_tensor_evaluate_[smat_]cm_ (new TensorNumerator + Amplitude per call, default AvHOneLoop)", + "masters_boxes": "recorded boxes calls only, replayed through ninja::avh_olo", + "masters_triangles": "recorded triangles calls only, replayed through ninja::avh_olo", + "masters_bubbles": "recorded bubbles calls only, replayed through ninja::avh_olo", + "masters_tadpoles": "recorded tadpoles calls only, replayed through ninja::avh_olo" + }, + "timing": { + "o3-fortranrules": { + "median_ns": { + "full": 66683.0188172043, + "pure_reduction": 9224.313399778515, + "reduction_plus_tensor_numerator": 32072.73717948718, + "masters_only": 33210.020833333336, + "numerator_only": 21400.592497868714, + "full_madloop_entry": 66713.39733333333, + "masters_boxes": 16482.980198019803, + "masters_triangles": 11431.353424657535, + "masters_bubbles": 3941.082275505407, + "masters_tadpoles": 170.5811786154024 + }, + "blocks_ns": { + "full": [ + 66940.06451612903, + 66596.4059139785, + 66962.40322580645, + 66434.33870967742, + 66683.0188172043, + 66610.17204301075, + 66783.93548387097, + 66599.09677419355, + 66819.2311827957 + ], + "pure_reduction": [ + 9260.821336286452, + 9211.810262089331, + 9232.998892580288, + 9207.672203765227, + 9239.399778516057, + 9192.183093392396, + 9240.736434108527, + 9224.313399778515, + 9213.623108157992 + ], + "reduction_plus_tensor_numerator": [ + 32052.3, + 32128.03205128205, + 32048.826923076922, + 32137.134615384617, + 32062.979487179487, + 32099.03205128205, + 32031.646153846155, + 32322.494871794872, + 32072.73717948718 + ], + "masters_only": [ + 33114.251302083336, + 33107.91015625, + 32867.740885416664, + 33210.020833333336, + 33295.85546875, + 33311.361979166664, + 33234.578125, + 33210.970052083336, + 33208.080729166664 + ], + "numerator_only": [ + 21402.894288150044, + 21378.623188405796, + 21400.592497868714, + 21399.313725490196, + 21400.583120204603, + 21405.988917306055, + 21428.452685421995, + 21326.883205456095, + 21412.817561807333 + ], + "full_madloop_entry": [ + 66932.57333333333, + 66777.05333333333, + 66649.95733333334, + 66876.464, + 66679.29333333333, + 66713.39733333333, + 66671.26666666666, + 66653.48, + 66814.78666666667 + ], + "masters_boxes": [ + 16457.019141914192, + 16553.25082508251, + 16472.38613861386, + 16563.904290429044, + 16482.980198019803, + 16516.986798679867, + 16446.24686468647, + 16512.80198019802, + 16472.37887788779 + ], + "masters_triangles": [ + 11452.381278538813, + 11484.194063926941, + 11478.700456621005, + 11417.262557077625, + 11428.887671232877, + 11405.613698630137, + 11436.308219178081, + 11412.581735159818, + 11431.353424657535 + ], + "masters_bubbles": [ + 3952.7385989656796, + 3931.7685315781227, + 3949.5431750509324, + 3936.546622786397, + 3945.101864911456, + 3915.5561824165493, + 3934.431123648331, + 3956.3743927284127, + 3941.082275505407 + ], + "masters_tadpoles": [ + 170.5811786154024, + 170.52213220138364, + 170.5825323292722, + 173.37480187479167, + 175.9084304401951, + 170.65430637469984, + 170.47219444501133, + 169.78629007571274, + 169.33840805969947 + ] + }, + "iterations_per_block": { + "full": 124, + "pure_reduction": 903, + "reduction_plus_tensor_numerator": 260, + "masters_only": 256, + "numerator_only": 391, + "full_madloop_entry": 125, + "masters_boxes": 505, + "masters_triangles": 730, + "masters_bubbles": 2127, + "masters_tadpoles": 49001 + }, + "derived": { + "full_ns": 66683.0188172043, + "pure_reduction_ns": 9224.313399778515, + "numerator_part_ns": 22848.423779708664, + "numerator_only_ns": 21400.592497868714, + "masters_ns": 33210.020833333336, + "sum_pure_numerator_masters_ns": 65282.758012820515, + "sum_over_full": 0.9790012385578664 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "92.44", + "97.21", + "93.78" + ], + "libninja_sha256": "858309a8a0759066bcdb6a95d216e84a27470bdab1b005b54caa743d742458cb", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "6e98ba3ff436083861a029695192a16707066542fdf1533450402b7cdc2e52f6" + }, + "o3": { + "median_ns": { + "full": 77490.84876543209, + "pure_reduction": 11211.697986577181, + "reduction_plus_tensor_numerator": 42674.651360544216, + "masters_only": 33557.841397849465, + "numerator_only": 29216.533101045297, + "full_madloop_entry": 77755, + "masters_boxes": 16960.460606060606, + "masters_triangles": 11584.84401114206, + "masters_bubbles": 4035.4518411320146, + "masters_tadpoles": 157.41166543879203 + }, + "blocks_ns": { + "full": [ + 77490.84876543209, + 77493.22530864198, + 77664.95370370371, + 77342.29938271605, + 77350.54012345678, + 77427.91666666667, + 77581.43518518518, + 77255.91049382716, + 77646.55864197531 + ], + "pure_reduction": [ + 11191.603579418344, + 11253.299776286354, + 11232.946308724831, + 11205.728859060402, + 11183.840715883669, + 11211.697986577181, + 11228.445190156599, + 11212.699776286354, + 11210.181208053691 + ], + "reduction_plus_tensor_numerator": [ + 42553.324829931975, + 42788.29081632653, + 42625.29761904762, + 42748.15476190476, + 42636.62414965987, + 42707.865646258506, + 42634.804421768706, + 42705.04081632653, + 42674.651360544216 + ], + "masters_only": [ + 33495.74462365591, + 33635.48924731183, + 33557.841397849465, + 33745.584677419356, + 33515.717741935485, + 33674.469086021505, + 33456.94220430108, + 33773.904569892475, + 33555.341397849465 + ], + "numerator_only": [ + 29216.533101045297, + 29163.50174216028, + 29230.040650406503, + 29193.55981416957, + 29221.109175377467, + 29150.47038327526, + 29257.88037166086, + 29202.39837398374, + 29263.780487804877 + ], + "full_madloop_entry": [ + 77671.63239875389, + 77709.42367601246, + 77500.01246105919, + 77766.52336448598, + 78041.47663551402, + 77646.6199376947, + 77913.96884735202, + 77827.71028037384, + 77755 + ], + "masters_boxes": [ + 16847.59259259259, + 16960.460606060606, + 16932.91919191919, + 17008.5898989899, + 16947.895622895623, + 16981.76767676768, + 16857.154882154882, + 17019.06734006734, + 16973.444444444445 + ], + "masters_triangles": [ + 11550.33147632312, + 11607.555710306407, + 11564.49164345404, + 11585.489786443826, + 11605.442896935932, + 11606.849582172701, + 11584.84401114206, + 11565.322191272053, + 11584.630454967502 + ], + "masters_bubbles": [ + 4037.436082971539, + 4022.734362437691, + 4040.545907702203, + 4025.3087313072842, + 4051.1633703167713, + 4052.692555073163, + 4035.4518411320146, + 4027.2768933912203, + 4030.7485126226084 + ], + "masters_tadpoles": [ + 157.05898206043662, + 158.1472568021107, + 157.60895026163175, + 157.0762982413057, + 157.43396238295836, + 157.33106648783775, + 157.41166543879203, + 157.29410431267357, + 157.4881085063377 + ] + }, + "iterations_per_block": { + "full": 108, + "pure_reduction": 745, + "reduction_plus_tensor_numerator": 196, + "masters_only": 248, + "numerator_only": 287, + "full_madloop_entry": 107, + "masters_boxes": 495, + "masters_triangles": 718, + "masters_bubbles": 2073, + "masters_tadpoles": 52937 + }, + "derived": { + "full_ns": 77490.84876543209, + "pure_reduction_ns": 11211.697986577181, + "numerator_part_ns": 31462.953373967037, + "numerator_only_ns": 29216.533101045297, + "masters_ns": 33557.841397849465, + "sum_pure_numerator_masters_ns": 76232.49275839368, + "sum_over_full": 0.9837612308151701 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "87.92", + "96.19", + "93.47" + ], + "libninja_sha256": "b6c3a01e70c155211b3abdab557afa99eb60ec9a50e5ab5b49323f22381b1869", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "69fa60af770227ff72f18623be916e625649a2a30fd42b8f05a91aff5572dac3" + } + }, + "date_utc": "2026-10-18T01:00:03+00:00", + "driver_sha256": "fcebb40f7be0c02e8472789e2119df3d9c382c91f756aa3e1ef80ae2b8f03f10" +} diff --git a/vendor/ninjars/tests/data/ninja/madloop-gg-hh-top-triangle-0.json b/vendor/ninjars/tests/data/ninja/madloop-gg-hh-top-triangle-0.json new file mode 100644 index 0000000000..0112d70d1b --- /dev/null +++ b/vendor/ninjars/tests/data/ninja/madloop-gg-hh-top-triangle-0.json @@ -0,0 +1,465 @@ +{ + "format": "ninjars-reference-ninja-results-v1", + "case": "madloop-gg-hh-top-triangle-0", + "case_file": "/shared/external/ninja/references/claude_reference/validation/benchmark/madloop/cases/madloop-gg-hh-top-triangle-0.json", + "case_sha256": "5178de553b5dcfa0fcca616748943a63f2933399203f7d7040ba9c98aa3b4ea2", + "n": 3, + "rank": 3, + "lanes_count": 3, + "amplitude": "ninja::Amplitude(n, rank, V, m2); setRenormalizationScale(mu_squared) (Ninja passes mu_R^2 to IntegralLibrary::init, AvHOneLoop uses mu_R=sqrt); setSMatrix if s_matrix given", + "all_replays_bitwise_identical": true, + "lanes": [ + { + "id": "gg-hh-top-triangle-0-madloop-sqrt_s_312.5", + "return_status": 0, + "eps0": [ + -0.35645182120683677, + -3.4795109649317294e-17 + ], + "eps_m1": [ + 6.106226635438361e-16, + -7.448623145238073e-17 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 0.48018083042577936, + -3.4795109649317294e-17 + ], + "rational": [ + -0.8366326516326161, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 0, + "muExpansion": 0, + "t3Expansion": 5, + "t2Expansion": 6, + "total": 11, + "output_values": 48 + }, + "master_calls": { + "rank2_bubble_cm": 3, + "tadpole_cm": 3, + "triangle_cm": 1, + "total": 7, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hh-top-triangle-0-madloop-sqrt_s_416.7", + "return_status": 0, + "eps0": [ + -0.9932760902057609, + -0.5327233261037041 + ], + "eps_m1": [ + 1.3877787807814457e-17, + 8.045414371751377e-17 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.5588706749349793, + -0.5327233261037041 + ], + "rational": [ + -0.4344054152707816, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 0, + "muExpansion": 0, + "t3Expansion": 5, + "t2Expansion": 6, + "total": 11, + "output_values": 48 + }, + "master_calls": { + "rank2_bubble_cm": 3, + "tadpole_cm": 3, + "triangle_cm": 1, + "total": 7, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hh-top-triangle-0-madloop-sqrt_s_650", + "return_status": 0, + "eps0": [ + -0.39115336167231063, + -0.9447313276249424 + ], + "eps_m1": [ + 1.734723475976807e-17, + -2.152084627299275e-18 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.22247742384315414, + -0.9447313276249424 + ], + "rational": [ + -0.1686759378291565, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 0, + "muExpansion": 0, + "t3Expansion": 5, + "t2Expansion": 6, + "total": 11, + "output_values": 48 + }, + "master_calls": { + "rank2_bubble_cm": 3, + "tadpole_cm": 3, + "triangle_cm": 1, + "total": 7, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + } + ], + "timing_unit": "ns per phase-space point (one lane), lanes cycled; median of interleaved blocks", + "timing_cpu": 250, + "timing_modes": { + "full": "TensorNumerator + AvHOneLoop (OneLOop, cache disabled), Amplitude::evaluate", + "pure_reduction": "ReplayNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "reduction_plus_tensor_numerator": "TensorNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "masters_only": "recorded AvHOneLoop interface calls replayed through ninja::avh_olo, no reduction", + "numerator_only": "recorded TensorNumerator calls (inputs) replayed, no reduction", + "full_madloop_entry": "MadLoop's entry point ninja_tensor_evaluate_[smat_]cm_ (new TensorNumerator + Amplitude per call, default AvHOneLoop)", + "masters_triangles": "recorded triangles calls only, replayed through ninja::avh_olo", + "masters_bubbles": "recorded bubbles calls only, replayed through ninja::avh_olo", + "masters_tadpoles": "recorded tadpoles calls only, replayed through ninja::avh_olo" + }, + "timing": { + "o3-fortranrules": { + "median_ns": { + "full": 9611.617715617716, + "pure_reduction": 2921.895068205666, + "reduction_plus_tensor_numerator": 7598.283059110298, + "masters_only": 1885.3661214599424, + "numerator_only": 4279.690100186789, + "full_madloop_entry": 9776.80857699805, + "masters_triangles": 903.1334626297454, + "masters_bubbles": 860.9981358740679, + "masters_tadpoles": 128.57746523338227 + }, + "blocks_ns": { + "full": [ + 9611.804195804196, + 9623.346542346542, + 9634.885003885003, + 9611.617715617716, + 9604.344988344988, + 9589.78749028749, + 9638.066822066821, + 9592.309246309247, + 9606.18648018648 + ], + "pure_reduction": [ + 2919.7359216509267, + 2929.324355835374, + 2918.103649294625, + 2931.6666666666665, + 2921.895068205666, + 2922.307916520928, + 2916.323189926548, + 2924.6257432668767, + 2918.6363530371923 + ], + "reduction_plus_tensor_numerator": [ + 7598.283059110298, + 7598.151736745886, + 7585.400365630713, + 7613.358927483242, + 7606.756550883608, + 7607.256246191347, + 7581.993906154784, + 7594.885435709933, + 7612.222730042657 + ], + "masters_only": [ + 1880.560654248069, + 1881.8010752688172, + 1874.0454338936847, + 1892.739285173406, + 1893.3661971830986, + 1884.4134484325307, + 1887.6771164622141, + 1885.3661214599424, + 1892.524155686809 + ], + "numerator_only": [ + 4278.272202411275, + 4281.340804890474, + 4280.298013245033, + 4262.381558838512, + 4279.690100186789, + 4254.811512990321, + 4264.261334691798, + 4300.408388520971, + 4283.4107658346065 + ], + "full_madloop_entry": [ + 9763.611695906433, + 9776.80857699805, + 9791.888888888889, + 9741.869005847953, + 9819.28849902534, + 9783.564912280703, + 9748.282261208577, + 9783.428849902533, + 9760.341130604289 + ], + "masters_triangles": [ + 903.5917824947024, + 901.8110476600941, + 903.1334626297454, + 905.3620299536688, + 905.9244693459757, + 900.8617965018137, + 901.3204396078008, + 901.4263908343211, + 903.3428509858851 + ], + "masters_bubbles": [ + 862.1597970173985, + 860.9981358740679, + 855.0985225075946, + 862.8053369235018, + 859.9096934548468, + 866.1024233637116, + 857.4721761944214, + 858.2737503452086, + 862.4038249102458 + ], + "masters_tadpoles": [ + 131.4846069254366, + 128.43845137935207, + 128.57746523338227, + 125.66789790216413, + 129.04849173651562, + 128.8817487753416, + 127.0712485464581, + 127.25156666824518, + 130.8344198723514 + ] + }, + "iterations_per_block": { + "full": 858, + "pure_reduction": 2859, + "reduction_plus_tensor_numerator": 1094, + "masters_only": 4402, + "numerator_only": 1963, + "full_madloop_entry": 855, + "masters_triangles": 9281, + "masters_bubbles": 9656, + "masters_tadpoles": 63351 + }, + "derived": { + "full_ns": 9611.617715617716, + "pure_reduction_ns": 2921.895068205666, + "numerator_part_ns": 4676.387990904632, + "numerator_only_ns": 4279.690100186789, + "masters_ns": 1885.3661214599424, + "sum_pure_numerator_masters_ns": 9483.649180570239, + "sum_over_full": 0.9866860565168396 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "87.92", + "96.19", + "93.47" + ], + "libninja_sha256": "858309a8a0759066bcdb6a95d216e84a27470bdab1b005b54caa743d742458cb", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "6e98ba3ff436083861a029695192a16707066542fdf1533450402b7cdc2e52f6" + }, + "o3": { + "median_ns": { + "full": 11722.023977433004, + "pure_reduction": 3579.1417607877206, + "reduction_plus_tensor_numerator": 9740.273504273504, + "masters_only": 1897.474530224134, + "numerator_only": 5766.577977424557, + "full_madloop_entry": 11902.137422729435, + "masters_triangles": 912.796148955495, + "masters_bubbles": 871.5397768741528, + "masters_tadpoles": 121.3423615543821 + }, + "blocks_ns": { + "full": [ + 11781.746591443347, + 11737.500705218617, + 11752.000470145746, + 11718.831687823225, + 11722.023977433004, + 11677.275035260931, + 11771.962388340386, + 11708.737188528445, + 11712.639398213447 + ], + "pure_reduction": [ + 3581.6831740515495, + 3575.433536055604, + 3583.358384013901, + 3572.8457862728064, + 3579.1417607877206, + 3580.0583550535766, + 3568.603243556328, + 3579.4792933680856, + 3578.4264407761366 + ], + "reduction_plus_tensor_numerator": [ + 9780.759518259518, + 9751.280108780109, + 9737.07264957265, + 9743.39355089355, + 9749.232711732711, + 9714.594017094018, + 9684.648018648018, + 9740.273504273504, + 9737.6554001554 + ], + "masters_only": [ + 1898.0502603577088, + 1891.1980227907327, + 1901.639498905743, + 1893.0597690740321, + 1892.461323673685, + 1897.474530224134, + 1906.4987548109577, + 1898.5672779412876, + 1892.2907705078862 + ], + "numerator_only": [ + 5759.8675420410045, + 5768.625892651463, + 5778.098364432159, + 5758.842202257544, + 5758.73393227367, + 5762.896567611149, + 5774.518544114259, + 5766.577977424557, + 5766.808108730707 + ], + "full_madloop_entry": [ + 11909.16547788873, + 11983.445078459345, + 11902.137422729435, + 11903.901569186875, + 11885.54160722777, + 11913.193057536851, + 11892.256300523062, + 11890.691868758915, + 11866.607227769853 + ], + "masters_triangles": [ + 908.8001453224341, + 917.5409990917348, + 904.2635422343325, + 916.0368755676658, + 909.684795640327, + 915.2935513169846, + 912.796148955495, + 912.6769845594914, + 914.1887375113533 + ], + "masters_bubbles": [ + 874.9690682236819, + 871.5397768741528, + 870.1447190074027, + 869.9251033955444, + 867.5808570534876, + 871.6899523859173, + 868.2158620929343, + 875.1567789246864, + 875.8963264171272 + ], + "masters_tadpoles": [ + 121.45324377647536, + 121.37103715739183, + 121.6840509487611, + 121.29225903789242, + 121.0691454380162, + 121.3423615543821, + 121.24893614963538, + 121.52060484728912, + 121.3367521615505 + ] + }, + "iterations_per_block": { + "full": 709, + "pure_reduction": 2302, + "reduction_plus_tensor_numerator": 858, + "masters_only": 4417, + "numerator_only": 1447, + "full_madloop_entry": 701, + "masters_triangles": 9175, + "masters_bubbles": 9591, + "masters_tadpoles": 68932 + }, + "derived": { + "full_ns": 11722.023977433004, + "pure_reduction_ns": 3579.1417607877206, + "numerator_part_ns": 6161.131743485783, + "numerator_only_ns": 5766.577977424557, + "masters_ns": 1897.474530224134, + "sum_pure_numerator_masters_ns": 11637.748034497637, + "sum_over_full": 0.9928104614785286 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "87.20", + "95.90", + "93.39" + ], + "libninja_sha256": "b6c3a01e70c155211b3abdab557afa99eb60ec9a50e5ab5b49323f22381b1869", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "69fa60af770227ff72f18623be916e625649a2a30fd42b8f05a91aff5572dac3" + } + }, + "date_utc": "2026-10-18T01:00:08+00:00", + "driver_sha256": "fcebb40f7be0c02e8472789e2119df3d9c382c91f756aa3e1ef80ae2b8f03f10" +} diff --git a/vendor/ninjars/tests/data/ninja/madloop-gg-hhh-top-box-8.json b/vendor/ninjars/tests/data/ninja/madloop-gg-hhh-top-box-8.json new file mode 100644 index 0000000000..4e15f6ce87 --- /dev/null +++ b/vendor/ninjars/tests/data/ninja/madloop-gg-hhh-top-box-8.json @@ -0,0 +1,495 @@ +{ + "format": "ninjars-reference-ninja-results-v1", + "case": "madloop-gg-hhh-top-box-8", + "case_file": "/shared/external/ninja/references/claude_reference/validation/benchmark/madloop/cases/madloop-gg-hhh-top-box-8.json", + "case_sha256": "3f14438d72237acbd9c74f8ba813fa6fd04c2aa1af2cdde143134146a650a489", + "n": 4, + "rank": 4, + "lanes_count": 3, + "amplitude": "ninja::Amplitude(n, rank, V, m2); setRenormalizationScale(mu_squared) (Ninja passes mu_R^2 to IntegralLibrary::init, AvHOneLoop uses mu_R=sqrt); setSMatrix if s_matrix given", + "all_replays_bitwise_identical": true, + "lanes": [ + { + "id": "gg-hhh-top-box-8-madloop-sqrt_s_450", + "return_status": 0, + "eps0": [ + 0.004745403814461617, + 0.009526277015327298 + ], + "eps_m1": [ + 0.004129426678774671, + 9.419528422935137e-17 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 0.0033689282548700276, + 0.009526277015327298 + ], + "rational": [ + 0.001376475559591589, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 2, + "muExpansion": 1, + "t3Expansion": 12, + "t2Expansion": 12, + "total": 27, + "output_values": 119 + }, + "master_calls": { + "box_cm": 1, + "rank2_bubble_cm": 6, + "tadpole_cm": 4, + "triangle_cm": 4, + "total": 15, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hhh-top-box-8-madloop-sqrt_s_525", + "return_status": 0, + "eps0": [ + 0.0004576813987146065, + 0.008943515033074419 + ], + "eps_m1": [ + 0.0030338644986916304, + 7.306347810726291e-18 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.0005536067675159388, + 0.008943515033074419 + ], + "rational": [ + 0.0010112881662305453, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 2, + "muExpansion": 1, + "t3Expansion": 12, + "t2Expansion": 12, + "total": 27, + "output_values": 119 + }, + "master_calls": { + "box_cm": 1, + "rank2_bubble_cm": 6, + "tadpole_cm": 4, + "triangle_cm": 4, + "total": 15, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hhh-top-box-8-madloop-sqrt_s_600", + "return_status": 0, + "eps0": [ + -0.0018669687177375535, + 0.007055746793121237 + ], + "eps_m1": [ + 0.0023228025068107697, + -1.2398686281860599e-17 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.002641236220007812, + 0.007055746793121237 + ], + "rational": [ + 0.0007742675022702583, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 2, + "muExpansion": 1, + "t3Expansion": 12, + "t2Expansion": 12, + "total": 27, + "output_values": 119 + }, + "master_calls": { + "box_cm": 1, + "rank2_bubble_cm": 6, + "tadpole_cm": 4, + "triangle_cm": 4, + "total": 15, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + } + ], + "timing_unit": "ns per phase-space point (one lane), lanes cycled; median of interleaved blocks", + "timing_cpu": 250, + "timing_modes": { + "full": "TensorNumerator + AvHOneLoop (OneLOop, cache disabled), Amplitude::evaluate", + "pure_reduction": "ReplayNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "reduction_plus_tensor_numerator": "TensorNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "masters_only": "recorded AvHOneLoop interface calls replayed through ninja::avh_olo, no reduction", + "numerator_only": "recorded TensorNumerator calls (inputs) replayed, no reduction", + "full_madloop_entry": "MadLoop's entry point ninja_tensor_evaluate_[smat_]cm_ (new TensorNumerator + Amplitude per call, default AvHOneLoop)", + "masters_boxes": "recorded boxes calls only, replayed through ninja::avh_olo", + "masters_triangles": "recorded triangles calls only, replayed through ninja::avh_olo", + "masters_bubbles": "recorded bubbles calls only, replayed through ninja::avh_olo", + "masters_tadpoles": "recorded tadpoles calls only, replayed through ninja::avh_olo" + }, + "timing": { + "o3-fortranrules": { + "median_ns": { + "full": 61093.22384428224, + "pure_reduction": 9583.753356348294, + "reduction_plus_tensor_numerator": 32294.689832689834, + "masters_only": 27398.525219298244, + "numerator_only": 21371.007653061224, + "full_madloop_entry": 61703.026960784315, + "masters_boxes": 13258.695238095239, + "masters_triangles": 10375.286724927175, + "masters_bubbles": 3160.2149520927887, + "masters_tadpoles": 155.03945565520678 + }, + "blocks_ns": { + "full": [ + 61112.03163017031, + 60836.846715328466, + 61242.177615571774, + 61008.087591240874, + 61443.90754257907, + 61299.914841849146, + 61042.32116788321, + 60833.10218978102, + 61093.22384428224 + ], + "pure_reduction": [ + 9536.867663981588, + 9583.753356348294, + 9566.595320291523, + 9601.793248945147, + 9522.275795934023, + 9589.63367855773, + 9590.738396624472, + 9582.337552742616, + 9605.01879555044 + ], + "reduction_plus_tensor_numerator": [ + 32198.396396396398, + 32321.525096525096, + 32294.689832689834, + 32350.431145431146, + 32215.577863577862, + 32374.81981981982, + 32229.70913770914, + 32280.263835263835, + 32309.015444015444 + ], + "masters_only": [ + 27297.27412280702, + 27342.143640350878, + 27398.525219298244, + 27384.697368421053, + 27519.490131578947, + 27569.775219298244, + 27476.10197368421, + 27344.269736842107, + 27506.167763157893 + ], + "numerator_only": [ + 21360.76955782313, + 21304.73979591837, + 21393.9574829932, + 21397.988945578232, + 21382.18962585034, + 21306.01530612245, + 21371.007653061224, + 21346.977040816328, + 21401.71343537415 + ], + "full_madloop_entry": [ + 61698.39460784314, + 61670.526960784315, + 61913.69117647059, + 61857.291666666664, + 61703.026960784315, + 61696.23774509804, + 61778.541666666664, + 61588.31862745098, + 62040.23284313725 + ], + "masters_boxes": [ + 13226.256613756614, + 13261.087301587302, + 13246.478306878307, + 13277.357142857143, + 13258.695238095239, + 13261.156084656084, + 13249.742857142857, + 13252.562962962964, + 13306.457671957673 + ], + "masters_triangles": [ + 10347.783187682064, + 10378.986267166043, + 10379.090303786934, + 10375.29546400333, + 10354.183936745734, + 10364.98709945901, + 10376.239700374532, + 10342.31543903454, + 10375.286724927175 + ], + "masters_bubbles": [ + 3173.810514372163, + 3149.3726676752394, + 3176.1516641452345, + 3160.2149520927887, + 3181.4102370146243, + 3153.848209783157, + 3158.966843166919, + 3170.1582198688857, + 3155.3788451840646 + ], + "masters_tadpoles": [ + 155.90206153462879, + 155.03945565520678, + 154.9987730443448, + 155.01976831091181, + 154.7012580966617, + 155.62496263079223, + 155.52020428500248, + 155.01951918286, + 155.36393871449926 + ] + }, + "iterations_per_block": { + "full": 137, + "pure_reduction": 869, + "reduction_plus_tensor_numerator": 259, + "masters_only": 304, + "numerator_only": 392, + "full_madloop_entry": 136, + "masters_boxes": 630, + "masters_triangles": 801, + "masters_bubbles": 2644, + "masters_tadpoles": 53520 + }, + "derived": { + "full_ns": 61093.22384428224, + "pure_reduction_ns": 9583.753356348294, + "numerator_part_ns": 22710.93647634154, + "numerator_only_ns": 21371.007653061224, + "masters_ns": 27398.525219298244, + "sum_pure_numerator_masters_ns": 59693.21505198808, + "sum_over_full": 0.9770840577039677 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "101.59", + "99.07", + "94.31" + ], + "libninja_sha256": "858309a8a0759066bcdb6a95d216e84a27470bdab1b005b54caa743d742458cb", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "6e98ba3ff436083861a029695192a16707066542fdf1533450402b7cdc2e52f6" + }, + "o3": { + "median_ns": { + "full": 71312.43304843304, + "pure_reduction": 11145.13101604278, + "reduction_plus_tensor_numerator": 42490.10998307953, + "masters_only": 27493.17486338798, + "numerator_only": 29195.075757575756, + "full_madloop_entry": 71648.77586206897, + "masters_boxes": 13321.525026624067, + "masters_triangles": 10340.903926482873, + "masters_bubbles": 3188.5310864292096, + "masters_tadpoles": 163.21404867256638 + }, + "blocks_ns": { + "full": [ + 71312.43304843304, + 71345.88319088319, + 71370.09971509971, + 71305.1396011396, + 71487.07977207977, + 71277.93447293447, + 71354.02849002849, + 71179.61253561254, + 71032.8603988604 + ], + "pure_reduction": [ + 11145.13101604278, + 11169.133244206774, + 11165.598930481283, + 11100.648395721924, + 11117.32798573975, + 11145.451871657753, + 11167.087789661318, + 11127.613190730837, + 11139.191176470587 + ], + "reduction_plus_tensor_numerator": [ + 42569.97461928934, + 42555.82910321489, + 42415.62436548223, + 42557.51945854484, + 42454.7461928934, + 42572.39255499154, + 42490.10998307953, + 42402.83417935702, + 42391.191201353635 + ], + "masters_only": [ + 27493.17486338798, + 27399.885245901638, + 27435.535519125682, + 27457.655737704918, + 27556.726775956286, + 27521.087431693988, + 27572.016393442624, + 27545.491803278688, + 27388.67213114754 + ], + "numerator_only": [ + 29259.28205128205, + 29195.075757575756, + 29398.723776223775, + 29167.66317016317, + 29283.747086247087, + 29167.98951048951, + 29302.43006993007, + 29182.918414918415, + 29172.62703962704 + ], + "full_madloop_entry": [ + 71727.08045977012, + 71711.44827586207, + 72068.43390804598, + 71626.10344827586, + 71598, + 71624.32183908045, + 71786.50574712643, + 71604.69540229885, + 71648.77586206897 + ], + "masters_boxes": [ + 13299.746538871139, + 13284.917465388711, + 13332.64856230032, + 13302.456869009584, + 13322.600638977636, + 13321.525026624067, + 13295.390841320554, + 13342.569222577209, + 13326.083067092652 + ], + "masters_triangles": [ + 10411.839598997494, + 10344.420634920634, + 10311.989974937344, + 10332.190476190477, + 10331.547201336674, + 10362.70426065163, + 10366.493316624896, + 10309.358395989975, + 10340.903926482873 + ], + "masters_bubbles": [ + 3202.4018894421038, + 3195.408528022469, + 3188.5310864292096, + 3197.7001148985064, + 3190.526618153964, + 3180.834163155879, + 3178.27945870037, + 3181.212051576663, + 3173.3338439933614 + ], + "masters_tadpoles": [ + 162.9482985672145, + 162.41554071849978, + 163.33553255372945, + 163.3878134218289, + 163.45095211757268, + 162.32276522334598, + 163.36510350821746, + 161.9655565212811, + 163.21404867256638 + ] + }, + "iterations_per_block": { + "full": 117, + "pure_reduction": 748, + "reduction_plus_tensor_numerator": 197, + "masters_only": 305, + "numerator_only": 286, + "full_madloop_entry": 116, + "masters_boxes": 626, + "masters_triangles": 798, + "masters_bubbles": 2611, + "masters_tadpoles": 50624 + }, + "derived": { + "full_ns": 71312.43304843304, + "pure_reduction_ns": 11145.13101604278, + "numerator_part_ns": 31344.978967036746, + "numerator_only_ns": 29195.075757575756, + "masters_ns": 27493.17486338798, + "sum_pure_numerator_masters_ns": 69983.2848464675, + "sum_over_full": 0.9813616203353653 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "99.70", + "98.72", + "94.22" + ], + "libninja_sha256": "b6c3a01e70c155211b3abdab557afa99eb60ec9a50e5ab5b49323f22381b1869", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "69fa60af770227ff72f18623be916e625649a2a30fd42b8f05a91aff5572dac3" + } + }, + "date_utc": "2026-10-18T00:59:48+00:00", + "driver_sha256": "fcebb40f7be0c02e8472789e2119df3d9c382c91f756aa3e1ef80ae2b8f03f10" +} diff --git a/vendor/ninjars/tests/data/ninja/madloop-gg-hhh-top-pentagon-26.json b/vendor/ninjars/tests/data/ninja/madloop-gg-hhh-top-pentagon-26.json new file mode 100644 index 0000000000..f2a5f69d50 --- /dev/null +++ b/vendor/ninjars/tests/data/ninja/madloop-gg-hhh-top-pentagon-26.json @@ -0,0 +1,495 @@ +{ + "format": "ninjars-reference-ninja-results-v1", + "case": "madloop-gg-hhh-top-pentagon-26", + "case_file": "/shared/external/ninja/references/claude_reference/validation/benchmark/madloop/cases/madloop-gg-hhh-top-pentagon-26.json", + "case_sha256": "af571c4df618dafad08dc0acdb345f39d0446a2ec814f03b7cc2ee5a25d727ca", + "n": 5, + "rank": 5, + "lanes_count": 3, + "amplitude": "ninja::Amplitude(n, rank, V, m2); setRenormalizationScale(mu_squared) (Ninja passes mu_R^2 to IntegralLibrary::init, AvHOneLoop uses mu_R=sqrt); setSMatrix if s_matrix given", + "all_replays_bitwise_identical": true, + "lanes": [ + { + "id": "gg-hhh-top-pentagon-26-madloop-sqrt_s_450", + "return_status": 0, + "eps0": [ + -0.007618697799685877, + -0.013582054539239862 + ], + "eps_m1": [ + 3.2474146376196322e-18, + -2.8051605633924675e-17 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.007618697799685868, + -0.013582054539239862 + ], + "rational": [ + -9.540979117872439e-18, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 10, + "muExpansion": 5, + "t3Expansion": 25, + "t2Expansion": 20, + "total": 60, + "output_values": 245 + }, + "master_calls": { + "box_cm": 5, + "rank2_bubble_cm": 10, + "tadpole_cm": 5, + "triangle_cm": 10, + "total": 30, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hhh-top-pentagon-26-madloop-sqrt_s_525", + "return_status": 0, + "eps0": [ + -0.0013990033739306362, + -0.012555457584095679 + ], + "eps_m1": [ + -8.174610690025542e-19, + -1.8470873420227657e-17 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.0013990033739306276, + -0.012555457584095679 + ], + "rational": [ + -8.673617379884035e-18, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 10, + "muExpansion": 5, + "t3Expansion": 25, + "t2Expansion": 20, + "total": 60, + "output_values": 245 + }, + "master_calls": { + "box_cm": 5, + "rank2_bubble_cm": 10, + "tadpole_cm": 5, + "triangle_cm": 10, + "total": 30, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hhh-top-pentagon-26-madloop-sqrt_s_600", + "return_status": 0, + "eps0": [ + 0.0038141150440443917, + -0.00962102782074803 + ], + "eps_m1": [ + 1.596643755179027e-17, + 2.265098815784494e-18 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 0.003814115044044392, + -0.00962102782074803 + ], + "rational": [ + -4.336808689942018e-19, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 10, + "muExpansion": 5, + "t3Expansion": 25, + "t2Expansion": 20, + "total": 60, + "output_values": 245 + }, + "master_calls": { + "box_cm": 5, + "rank2_bubble_cm": 10, + "tadpole_cm": 5, + "triangle_cm": 10, + "total": 30, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + } + ], + "timing_unit": "ns per phase-space point (one lane), lanes cycled; median of interleaved blocks", + "timing_cpu": 250, + "timing_modes": { + "full": "TensorNumerator + AvHOneLoop (OneLOop, cache disabled), Amplitude::evaluate", + "pure_reduction": "ReplayNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "reduction_plus_tensor_numerator": "TensorNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "masters_only": "recorded AvHOneLoop interface calls replayed through ninja::avh_olo, no reduction", + "numerator_only": "recorded TensorNumerator calls (inputs) replayed, no reduction", + "full_madloop_entry": "MadLoop's entry point ninja_tensor_evaluate_[smat_]cm_ (new TensorNumerator + Amplitude per call, default AvHOneLoop)", + "masters_boxes": "recorded boxes calls only, replayed through ninja::avh_olo", + "masters_triangles": "recorded triangles calls only, replayed through ninja::avh_olo", + "masters_bubbles": "recorded bubbles calls only, replayed through ninja::avh_olo", + "masters_tadpoles": "recorded tadpoles calls only, replayed through ninja::avh_olo" + }, + "timing": { + "o3-fortranrules": { + "median_ns": { + "full": 215805.6403508772, + "pure_reduction": 22724.962761126248, + "reduction_plus_tensor_numerator": 103770.02057613169, + "masters_only": 107467.79914529914, + "numerator_only": 78309.08099688473, + "full_madloop_entry": 216368.42735042734, + "masters_boxes": 63624.59287531806, + "masters_triangles": 33441.658602150535, + "masters_bubbles": 7218.662292213473, + "masters_tadpoles": 204.61247068925658 + }, + "blocks_ns": { + "full": [ + 216430.2894736842, + 215805.6403508772, + 215311.51754385966, + 215960.91228070174, + 215578.88596491228, + 215407.21929824562, + 216297.13157894736, + 215667.21929824562, + 216928.79824561405 + ], + "pure_reduction": [ + 22702.16621253406, + 22742.80199818347, + 22621.529518619438, + 22746.743869209808, + 22719.52225249773, + 22716.75204359673, + 22741.276112624888, + 22724.962761126248, + 22730.821980018165 + ], + "reduction_plus_tensor_numerator": [ + 103931.00823045267, + 103853.3950617284, + 103613.47736625515, + 103776.23868312757, + 103709.32098765433, + 103663.39917695473, + 103878.58024691358, + 103770.02057613169, + 103737.55144032922 + ], + "masters_only": [ + 107228.91025641025, + 107514.33760683761, + 107467.79914529914, + 107392.02991452992, + 107839.16666666667, + 107605.23931623931, + 107440.9188034188, + 107818.44017094017, + 107450.02136752137 + ], + "numerator_only": [ + 78328.89408099689, + 78222.72274143303, + 78324.71962616823, + 78309.08099688473, + 78324.31152647975, + 78193.06853582554, + 78432.84735202492, + 78214.19003115266, + 78287.89719626168 + ], + "full_madloop_entry": [ + 216368.42735042734, + 216605.42735042734, + 216225.68376068375, + 217475.00854700856, + 215650.3076923077, + 216588.94017094016, + 216157.73504273503, + 217645.00854700856, + 215677.90598290597 + ], + "masters_boxes": [ + 63392.274809160306, + 63551.6641221374, + 63837.95165394402, + 63624.59287531806, + 63694.76844783715, + 63685.48091603054, + 63670.3155216285, + 63341.104325699744, + 62559.67684478372 + ], + "masters_triangles": [ + 33208.592741935485, + 33654.44220430108, + 33802.39919354839, + 33393.41801075269, + 33568.647849462366, + 33441.658602150535, + 33333.52688172043, + 33349.88440860215, + 33713.51478494624 + ], + "masters_bubbles": [ + 7213.725284339457, + 7218.662292213473, + 7225.28550597842, + 7239.823272090988, + 7211.363079615048, + 7220.899387576553, + 7227.081948089822, + 7216.912802566346, + 7213.211723534559 + ], + "masters_tadpoles": [ + 204.4039103008686, + 204.2992172793025, + 204.57812345189734, + 205.9744790118564, + 205.1577330823343, + 206.29062221341525, + 203.84461177713928, + 205.29892004359456, + 204.61247068925658 + ] + }, + "iterations_per_block": { + "full": 38, + "pure_reduction": 367, + "reduction_plus_tensor_numerator": 81, + "masters_only": 78, + "numerator_only": 107, + "full_madloop_entry": 39, + "masters_boxes": 131, + "masters_triangles": 248, + "masters_bubbles": 1143, + "masters_tadpoles": 40372 + }, + "derived": { + "full_ns": 215805.6403508772, + "pure_reduction_ns": 22724.962761126248, + "numerator_part_ns": 81045.05781500545, + "numerator_only_ns": 78309.08099688473, + "masters_ns": 107467.79914529914, + "sum_pure_numerator_masters_ns": 211237.81972143083, + "sum_over_full": 0.9788336364980101 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "99.70", + "98.72", + "94.22" + ], + "libninja_sha256": "858309a8a0759066bcdb6a95d216e84a27470bdab1b005b54caa743d742458cb", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "6e98ba3ff436083861a029695192a16707066542fdf1533450402b7cdc2e52f6" + }, + "o3": { + "median_ns": { + "full": 252605.6568627451, + "pure_reduction": 27192.479913137893, + "reduction_plus_tensor_numerator": 140151.47222222222, + "masters_only": 108259.23809523809, + "numerator_only": 107751.68803418803, + "full_madloop_entry": 253598.52525252526, + "masters_boxes": 63849.274809160306, + "masters_triangles": 33818.22402159244, + "masters_bubbles": 7335.340076223982, + "masters_tadpoles": 192.33586177833965 + }, + "blocks_ns": { + "full": [ + 251523.30392156861, + 252933.10784313726, + 253665.26470588235, + 251648.88235294117, + 252605.6568627451, + 256639.39215686274, + 255480.17647058822, + 251521.53921568627, + 252136.14705882352 + ], + "pure_reduction": [ + 27192.479913137893, + 27140.42779587405, + 27263.697068403908, + 27283.512486427797, + 27162.44733984799, + 27654.957654723126, + 27292.459283387623, + 27093.00217155266, + 27157.85450597177 + ], + "reduction_plus_tensor_numerator": [ + 139984.36666666667, + 140151.47222222222, + 140130.86111111112, + 140015.13888888888, + 141556.02777777778, + 142636.53333333333, + 140122.02777777778, + 140238.80555555556, + 140580.41666666666 + ], + "masters_only": [ + 107691.96536796537, + 108351.58008658008, + 108259.23809523809, + 108207.46753246753, + 111186.09090909091, + 110197.81818181818, + 108827.12121212122, + 107816.90043290044, + 107971.09956709956 + ], + "numerator_only": [ + 107751.68803418803, + 107675.7905982906, + 107560.23504273505, + 107632.54273504273, + 109518.61538461539, + 109785.92735042734, + 107886.60256410256, + 107517.20085470086, + 107988.26923076923 + ], + "full_madloop_entry": [ + 254272.77777777778, + 253598.52525252526, + 252913.18181818182, + 252440.0404040404, + 259921.88888888888, + 255757.42424242425, + 253615.80808080808, + 252089.44444444444, + 252181.05050505052 + ], + "masters_boxes": [ + 64009.24936386768, + 64001.361323155215, + 63849.274809160306, + 63834.66921119593, + 65880.11959287531, + 64644.798982188295, + 63757.3893129771, + 63113.21628498728, + 63618.45801526718 + ], + "masters_triangles": [ + 33638.12955465587, + 33885.01349527665, + 33362.771929824565, + 34140.49257759784, + 34709.29419703104, + 34048.225371120105, + 33625.4318488529, + 33519.02024291498, + 33818.22402159244 + ], + "masters_bubbles": [ + 7308.441512752858, + 7280.927587217825, + 7276.424508941659, + 7341.971562591615, + 7475.864849017883, + 7417.236880680152, + 7290.982996188801, + 7361.598944591029, + 7335.340076223982 + ], + "masters_tadpoles": [ + 192.33586177833965, + 192.07972263724477, + 192.52066812243802, + 192.14683369727618, + 194.1212580929395, + 193.1597517526721, + 192.0504463088534, + 192.6713787687239, + 192.26054476496955 + ] + }, + "iterations_per_block": { + "full": 34, + "pure_reduction": 307, + "reduction_plus_tensor_numerator": 60, + "masters_only": 77, + "numerator_only": 78, + "full_madloop_entry": 33, + "masters_boxes": 131, + "masters_triangles": 247, + "masters_bubbles": 1137, + "masters_tadpoles": 43505 + }, + "derived": { + "full_ns": 252605.6568627451, + "pure_reduction_ns": 27192.479913137893, + "numerator_part_ns": 112958.99230908432, + "numerator_only_ns": 107751.68803418803, + "masters_ns": 108259.23809523809, + "sum_pure_numerator_masters_ns": 248410.7103174603, + "sum_over_full": 0.9833932992737208 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "97.00", + "98.17", + "94.07" + ], + "libninja_sha256": "b6c3a01e70c155211b3abdab557afa99eb60ec9a50e5ab5b49323f22381b1869", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "69fa60af770227ff72f18623be916e625649a2a30fd42b8f05a91aff5572dac3" + } + }, + "date_utc": "2026-10-18T00:59:53+00:00", + "driver_sha256": "fcebb40f7be0c02e8472789e2119df3d9c382c91f756aa3e1ef80ae2b8f03f10" +} diff --git a/vendor/ninjars/tests/data/ninja/madloop-gg-hhh-top-triangle-0.json b/vendor/ninjars/tests/data/ninja/madloop-gg-hhh-top-triangle-0.json new file mode 100644 index 0000000000..40d738e3b4 --- /dev/null +++ b/vendor/ninjars/tests/data/ninja/madloop-gg-hhh-top-triangle-0.json @@ -0,0 +1,465 @@ +{ + "format": "ninjars-reference-ninja-results-v1", + "case": "madloop-gg-hhh-top-triangle-0", + "case_file": "/shared/external/ninja/references/claude_reference/validation/benchmark/madloop/cases/madloop-gg-hhh-top-triangle-0.json", + "case_sha256": "98483fd5759713618d7dfa784d604b83a7f03b241a5402d9a808af3655920353", + "n": 3, + "rank": 3, + "lanes_count": 3, + "amplitude": "ninja::Amplitude(n, rank, V, m2); setRenormalizationScale(mu_squared) (Ninja passes mu_R^2 to IntegralLibrary::init, AvHOneLoop uses mu_R=sqrt); setSMatrix if s_matrix given", + "all_replays_bitwise_identical": true, + "lanes": [ + { + "id": "gg-hhh-top-triangle-0-madloop-sqrt_s_450", + "return_status": 0, + "eps0": [ + -0.0038015540580315565, + -0.002900768787119988 + ], + "eps_m1": [ + -5.421010862427522e-20, + 4.53843279127176e-19 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.002309988568708247, + -0.002900768787119988 + ], + "rational": [ + -0.0014915654893233096, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 0, + "muExpansion": 0, + "t3Expansion": 5, + "t2Expansion": 6, + "total": 11, + "output_values": 48 + }, + "master_calls": { + "rank2_bubble_cm": 3, + "tadpole_cm": 3, + "triangle_cm": 1, + "total": 7, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hhh-top-triangle-0-madloop-sqrt_s_525", + "return_status": 0, + "eps0": [ + -0.0029050933334423346, + -0.003725560935235813 + ], + "eps_m1": [ + 3.1170812458958252e-19, + -5.154511082958864e-20 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.0018330306379912066, + -0.003725560935235813 + ], + "rational": [ + -0.001072062695451128, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 0, + "muExpansion": 0, + "t3Expansion": 5, + "t2Expansion": 6, + "total": 11, + "output_values": 48 + }, + "master_calls": { + "rank2_bubble_cm": 3, + "tadpole_cm": 3, + "triangle_cm": 1, + "total": 7, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "gg-hhh-top-triangle-0-madloop-sqrt_s_600", + "return_status": 0, + "eps0": [ + -0.0020522266262361, + -0.0038956488706526396 + ], + "eps_m1": [ + 3.9979955110402976e-19, + -1.1875886695185016e-19 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + -0.0012428290195071175, + -0.0038956488706526396 + ], + "rational": [ + -0.0008093976067289827, + 0 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 0, + "muExpansion": 0, + "t3Expansion": 5, + "t2Expansion": 6, + "total": 11, + "output_values": 48 + }, + "master_calls": { + "rank2_bubble_cm": 3, + "tadpole_cm": 3, + "triangle_cm": 1, + "total": 7, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + } + ], + "timing_unit": "ns per phase-space point (one lane), lanes cycled; median of interleaved blocks", + "timing_cpu": 250, + "timing_modes": { + "full": "TensorNumerator + AvHOneLoop (OneLOop, cache disabled), Amplitude::evaluate", + "pure_reduction": "ReplayNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "reduction_plus_tensor_numerator": "TensorNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "masters_only": "recorded AvHOneLoop interface calls replayed through ninja::avh_olo, no reduction", + "numerator_only": "recorded TensorNumerator calls (inputs) replayed, no reduction", + "full_madloop_entry": "MadLoop's entry point ninja_tensor_evaluate_[smat_]cm_ (new TensorNumerator + Amplitude per call, default AvHOneLoop)", + "masters_triangles": "recorded triangles calls only, replayed through ninja::avh_olo", + "masters_bubbles": "recorded bubbles calls only, replayed through ninja::avh_olo", + "masters_tadpoles": "recorded tadpoles calls only, replayed through ninja::avh_olo" + }, + "timing": { + "o3-fortranrules": { + "median_ns": { + "full": 8899.670584045583, + "pure_reduction": 2912.867461430575, + "reduction_plus_tensor_numerator": 7567.667586629868, + "masters_only": 1298.4668130030313, + "numerator_only": 4278.009587399418, + "full_madloop_entry": 9093.50255288111, + "masters_triangles": 682.7984872153252, + "masters_bubbles": 494.9551921766663, + "masters_tadpoles": 129.320133259883 + }, + "blocks_ns": { + "full": [ + 8895.628205128205, + 8900.122507122507, + 8907.334401709402, + 8925.905982905982, + 8884.812678062679, + 8880.849002849003, + 8921.949430199431, + 8899.670584045583, + 8868.733618233618 + ], + "pure_reduction": [ + 2907.17788686302, + 2912.867461430575, + 2904.801776531089, + 2905.9401589527815, + 2910.0729312762974, + 2920.8607994389904, + 2918.135226741468, + 2915.439925198691, + 2920.122019635344 + ], + "reduction_plus_tensor_numerator": [ + 7570.964121435142, + 7580.534498620055, + 7547.949402023919, + 7561.365838699785, + 7579.252989880405, + 7567.667586629868, + 7562.911070223858, + 7565.591536338547, + 7571.227844219565 + ], + "masters_only": [ + 1298.4668130030313, + 1301.0930281174872, + 1299.965715480297, + 1301.7750601024354, + 1297.5333960489181, + 1297.9859935193895, + 1301.7907912616286, + 1296.273805790739, + 1297.8140482910003 + ], + "numerator_only": [ + 4278.009587399418, + 4279.875877418251, + 4285.943331621298, + 4262.6560520458825, + 4279.6788221195, + 4277.102208525937, + 4273.8510529019, + 4286.148604690978, + 4277.340181475774 + ], + "full_madloop_entry": [ + 9088.816192560174, + 9113.203501094093, + 9093.50255288111, + 9081.25601750547, + 9092.24434719183, + 9111.872355944566, + 9103.56455142232, + 9124.403355215172, + 9075.508388037928 + ], + "masters_triangles": [ + 685.567842363452, + 681.0184987256433, + 681.6660911507578, + 682.6740935624434, + 683.491024692373, + 682.7984872153252, + 683.4595083449807, + 686.4672641069911, + 681.1722436898791 + ], + "masters_bubbles": [ + 494.76339625666304, + 494.9551921766663, + 495.3002685263116, + 495.5798164402228, + 496.34609835277143, + 496.12007534768145, + 494.488277022965, + 493.01957837361226, + 494.264638691836 + ], + "masters_tadpoles": [ + 129.320133259883, + 129.92955588783084, + 128.22928569554838, + 129.6822433829123, + 129.106287872826, + 130.36422968967236, + 129.14793945594292, + 130.8502662574434, + 127.9927756354765 + ] + }, + "iterations_per_block": { + "full": 936, + "pure_reduction": 2852, + "reduction_plus_tensor_numerator": 1087, + "masters_only": 6378, + "numerator_only": 1947, + "full_madloop_entry": 914, + "masters_triangles": 12163, + "masters_bubbles": 16634, + "masters_tadpoles": 63535 + }, + "derived": { + "full_ns": 8899.670584045583, + "pure_reduction_ns": 2912.867461430575, + "numerator_part_ns": 4654.800125199294, + "numerator_only_ns": 4278.009587399418, + "masters_ns": 1298.4668130030313, + "sum_pure_numerator_masters_ns": 8866.1343996329, + "sum_over_full": 0.9962317499174853 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "97.00", + "98.17", + "94.07" + ], + "libninja_sha256": "858309a8a0759066bcdb6a95d216e84a27470bdab1b005b54caa743d742458cb", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "6e98ba3ff436083861a029695192a16707066542fdf1533450402b7cdc2e52f6" + }, + "o3": { + "median_ns": { + "full": 11054.175111111112, + "pure_reduction": 3575.0214316330903, + "reduction_plus_tensor_numerator": 9741.4898989899, + "masters_only": 1267.7751016260163, + "numerator_only": 5751.725206611571, + "full_madloop_entry": 11216.633064516129, + "masters_triangles": 666.7684343231136, + "masters_bubbles": 498.3086093775004, + "masters_tadpoles": 120.6951242401929 + }, + "blocks_ns": { + "full": [ + 11033.366222222223, + 11066.539555555555, + 11060.97511111111, + 11042.024, + 11078.784, + 11060.97511111111, + 11054.175111111112, + 11045.384, + 11042.921777777778 + ], + "pure_reduction": [ + 3564.512644663523, + 3581.8308329761394, + 3581.730961565938, + 3557.0815830832976, + 3564.121160165738, + 3584.9784254893557, + 3575.0214316330903, + 3577.7875410772967, + 3574.629947135305 + ], + "reduction_plus_tensor_numerator": [ + 9756.602564102564, + 9786.280497280497, + 9721.765734265735, + 9719.139083139084, + 9752.869075369075, + 9724.858197358197, + 9752.977466977467, + 9741.4898989899, + 9738.84421134421 + ], + "masters_only": [ + 1264.8884146341463, + 1268.2623983739838, + 1267.7751016260163, + 1269.593699186992, + 1267.6983739837399, + 1274.3309959349594, + 1266.8518800813008, + 1273.8579776422764, + 1266.6714939024391 + ], + "numerator_only": [ + 5751.725206611571, + 5749.44536271809, + 5777.333562901745, + 5755.974517906336, + 5754.291781450873, + 5749.732552800735, + 5766.761937557392, + 5749.978191000918, + 5749.144628099173 + ], + "full_madloop_entry": [ + 11217.900537634408, + 11216.633064516129, + 11232.04077060932, + 11232.65905017921, + 11214.733422939069, + 11292.690412186379, + 11214.670250896057, + 11198.957885304659, + 11213.39829749104 + ], + "masters_triangles": [ + 670.9016657278506, + 664.5179582092755, + 663.2137818191572, + 668.5757892760387, + 668.7015906225691, + 664.6802392639682, + 666.8057187307207, + 666.7684343231136, + 666.1751025991792 + ], + "masters_bubbles": [ + 497.54548727796447, + 497.5072811649864, + 496.5407065130421, + 497.4060649703953, + 501.7817850856137, + 499.14054248679787, + 498.7724835973756, + 498.38002080332853, + 498.3086093775004 + ], + "masters_tadpoles": [ + 120.6951242401929, + 120.54251310261186, + 121.02503573439598, + 120.57442139154792, + 120.6537782205474, + 120.7592295808608, + 120.78275893600535, + 120.5843788952898, + 120.73531039594192 + ] + }, + "iterations_per_block": { + "full": 750, + "pure_reduction": 2333, + "reduction_plus_tensor_numerator": 858, + "masters_only": 6560, + "numerator_only": 1452, + "full_madloop_entry": 744, + "masters_triangles": 12427, + "masters_bubbles": 16664, + "masters_tadpoles": 69261 + }, + "derived": { + "full_ns": 11054.175111111112, + "pure_reduction_ns": 3575.0214316330903, + "numerator_part_ns": 6166.468467356809, + "numerator_only_ns": 5751.725206611571, + "masters_ns": 1267.7751016260163, + "sum_pure_numerator_masters_ns": 11009.265000615917, + "sum_over_full": 0.9959372716603654 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "92.44", + "97.21", + "93.78" + ], + "libninja_sha256": "b6c3a01e70c155211b3abdab557afa99eb60ec9a50e5ab5b49323f22381b1869", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "69fa60af770227ff72f18623be916e625649a2a30fd42b8f05a91aff5572dac3" + } + }, + "date_utc": "2026-10-18T00:59:58+00:00", + "driver_sha256": "fcebb40f7be0c02e8472789e2119df3d9c382c91f756aa3e1ef80ae2b8f03f10" +} diff --git a/vendor/ninjars/tests/data/ninja/madloop-hgg-top-triangle-0.json b/vendor/ninjars/tests/data/ninja/madloop-hgg-top-triangle-0.json new file mode 100644 index 0000000000..1c2ab49e45 --- /dev/null +++ b/vendor/ninjars/tests/data/ninja/madloop-hgg-top-triangle-0.json @@ -0,0 +1,465 @@ +{ + "format": "ninjars-reference-ninja-results-v1", + "case": "madloop-hgg-top-triangle-0", + "case_file": "/shared/external/ninja/references/claude_reference/validation/benchmark/madloop/cases/madloop-hgg-top-triangle-0.json", + "case_sha256": "8a70a0fc3569676b2601dbeb36b16cb70817b40df8eb3e762e4ed1899246d590", + "n": 3, + "rank": 3, + "lanes_count": 3, + "amplitude": "ninja::Amplitude(n, rank, V, m2); setRenormalizationScale(mu_squared) (Ninja passes mu_R^2 to IntegralLibrary::init, AvHOneLoop uses mu_R=sqrt); setSMatrix if s_matrix given", + "all_replays_bitwise_identical": true, + "lanes": [ + { + "id": "hgg-top-triangle-0-madloop-rest_frame", + "return_status": 0, + "eps0": [ + 295.7368669924487, + 5.174648683882581e-13 + ], + "eps_m1": [ + -1.3642420526593924e-12, + -1.555128479050653e-12 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 656.2270695870282, + 5.170701224239469e-13 + ], + "rational": [ + -360.49020259457944, + 3.94745964311178e-16 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 0, + "muExpansion": 0, + "t3Expansion": 5, + "t2Expansion": 6, + "total": 11, + "output_values": 48 + }, + "master_calls": { + "rank2_bubble_cm": 3, + "tadpole_cm": 3, + "triangle_cm": 1, + "total": 7, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "hgg-top-triangle-0-madloop-boosted_a", + "return_status": 0, + "eps0": [ + 112.86452619141687, + 169.66402744176276 + ], + "eps_m1": [ + 2.2737367544323206e-13, + -1.1368683772161603e-12 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 363.4632706753274, + 546.3775413839537 + ], + "rational": [ + -250.59874448391054, + -376.71351394219096 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 0, + "muExpansion": 0, + "t3Expansion": 5, + "t2Expansion": 6, + "total": 11, + "output_values": 48 + }, + "master_calls": { + "rank2_bubble_cm": 3, + "tadpole_cm": 3, + "triangle_cm": 1, + "total": 7, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + }, + { + "id": "hgg-top-triangle-0-madloop-boosted_b", + "return_status": 0, + "eps0": [ + 134.13727236888226, + 193.75383786616243 + ], + "eps_m1": [ + -2.2737367544323206e-13, + 1.1368683772161603e-12 + ], + "eps_m2": [ + 0, + 0 + ], + "cut_constructible": [ + 373.53099638750876, + 539.5447725597339 + ], + "rational": [ + -239.3937240186265, + -345.7909346935715 + ], + "checks": { + "recorded_identical": true, + "pure_replay_identical": true, + "tensor_reduction_identical": true, + "replays_fully_consumed": true, + "masters_replay_identical": true, + "madloop_entry_identical": true + }, + "numerator_calls": { + "evaluate": 0, + "muExpansion": 0, + "t3Expansion": 5, + "t2Expansion": 6, + "total": 11, + "output_values": 48 + }, + "master_calls": { + "rank2_bubble_cm": 3, + "tadpole_cm": 3, + "triangle_cm": 1, + "total": 7, + "init_calls": 1 + }, + "max_scaled_difference_between_builds": 0.0, + "checks_all_builds": true + } + ], + "timing_unit": "ns per phase-space point (one lane), lanes cycled; median of interleaved blocks", + "timing_cpu": 250, + "timing_modes": { + "full": "TensorNumerator + AvHOneLoop (OneLOop, cache disabled), Amplitude::evaluate", + "pure_reduction": "ReplayNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "reduction_plus_tensor_numerator": "TensorNumerator + ReplayIntegralLibrary, Amplitude::evaluate", + "masters_only": "recorded AvHOneLoop interface calls replayed through ninja::avh_olo, no reduction", + "numerator_only": "recorded TensorNumerator calls (inputs) replayed, no reduction", + "full_madloop_entry": "MadLoop's entry point ninja_tensor_evaluate_[smat_]cm_ (new TensorNumerator + Amplitude per call, default AvHOneLoop)", + "masters_triangles": "recorded triangles calls only, replayed through ninja::avh_olo", + "masters_bubbles": "recorded bubbles calls only, replayed through ninja::avh_olo", + "masters_tadpoles": "recorded tadpoles calls only, replayed through ninja::avh_olo" + }, + "timing": { + "o3-fortranrules": { + "median_ns": { + "full": 10965.171290180537, + "pure_reduction": 2967.493038200643, + "reduction_plus_tensor_numerator": 7601.381779402803, + "masters_only": 3241.5895541731466, + "numerator_only": 4254.904053360698, + "full_madloop_entry": 11114.464078536368, + "masters_triangles": 1489.4150863885377, + "masters_bubbles": 1627.797310465796, + "masters_tadpoles": 128.53590484775017 + }, + "blocks_ns": { + "full": [ + 10983.048877146632, + 10982.48128577719, + 11005.805812417437, + 10975.598855129898, + 10941.080581241744, + 10960.560986349627, + 10928.482606781154, + 10965.171290180537, + 10947.544693967415 + ], + "pure_reduction": [ + 3002.9364512674047, + 2967.493038200643, + 2978.65452814471, + 2962.67809115792, + 2983.95632512198, + 2963.088658812329, + 2947.948827799595, + 2960.756158514816, + 2971.5214804236584 + ], + "reduction_plus_tensor_numerator": [ + 7594.34338817794, + 7593.560024375381, + 7610.294028031688, + 7607.006093845216, + 7563.599634369287, + 7611.400060938452, + 7601.381779402803, + 7585.403412553321, + 7612.572821450335 + ], + "masters_only": [ + 3243.236651114567, + 3241.5895541731466, + 3240.640746500778, + 3219.6727579056505, + 3257.968506998445, + 3248.436236391913, + 3243.582685329186, + 3237.1468377397614, + 3235.780844997408 + ], + "numerator_only": [ + 4254.685308705319, + 4259.518385496836, + 4271.066358816487, + 4251.066358816487, + 4256.2688558234995, + 4255.721566615358, + 4254.904053360698, + 4250.067384983752, + 4253.176671797503 + ], + "full_madloop_entry": [ + 11181.157518964748, + 11106.695225345828, + 11112.192771084337, + 11141.979027219992, + 11141.073181615351, + 11114.464078536368, + 11102.879964301652, + 11114.29004908523, + 11169.7072735386 + ], + "masters_triangles": [ + 1487.3556077298176, + 1498.6908674974416, + 1489.4150863885377, + 1494.520739269159, + 1487.9515983384504, + 1494.7013424838963, + 1474.8349286617301, + 1497.2400216723859, + 1483.6652820420204 + ], + "masters_bubbles": [ + 1624.3762749301632, + 1638.2638212174365, + 1627.797310465796, + 1621.2469304229196, + 1626.73189111934, + 1620.0717209121028, + 1631.4016111219385, + 1630.3147534593647, + 1632.3358019879165 + ], + "masters_tadpoles": [ + 127.02739357017789, + 129.35475916658896, + 128.53590484775017, + 126.90021135734933, + 128.39230617805822, + 128.46353567691335, + 129.17578404252012, + 128.81414022109635, + 130.39854847232152 + ] + }, + "iterations_per_block": { + "full": 757, + "pure_reduction": 2801, + "reduction_plus_tensor_numerator": 1094, + "masters_only": 2572, + "numerator_only": 1949, + "full_madloop_entry": 747, + "masters_triangles": 5537, + "masters_bubbles": 5131, + "masters_tadpoles": 64346 + }, + "derived": { + "full_ns": 10965.171290180537, + "pure_reduction_ns": 2967.493038200643, + "numerator_part_ns": 4633.8887412021595, + "numerator_only_ns": 4254.904053360698, + "masters_ns": 3241.5895541731466, + "sum_pure_numerator_masters_ns": 10842.971333575948, + "sum_over_full": 0.9888556272062963 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "87.20", + "95.90", + "93.39" + ], + "libninja_sha256": "858309a8a0759066bcdb6a95d216e84a27470bdab1b005b54caa743d742458cb", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "6e98ba3ff436083861a029695192a16707066542fdf1533450402b7cdc2e52f6" + }, + "o3": { + "median_ns": { + "full": 13090.065194532071, + "pure_reduction": 3532.4682843763303, + "reduction_plus_tensor_numerator": 9728.308021806854, + "masters_only": 3267.9886408147277, + "numerator_only": 5758.069511355816, + "full_madloop_entry": 13235.878164556962, + "masters_triangles": 1515.2007874015749, + "masters_bubbles": 1636.944929222416, + "masters_tadpoles": 118.2342776858413 + }, + "blocks_ns": { + "full": [ + 13153.772344900106, + 13076.279179810726, + 13090.065194532071, + 13048.92429022082, + 13118.435331230285, + 13125.933228180862, + 13088.666666666666, + 13101.295478443744, + 13074.718191377497 + ], + "pure_reduction": [ + 3541.579963104867, + 3529.302398183624, + 3528.3021143749115, + 3532.4682843763303, + 3536.7709663686674, + 3526.975166737619, + 3538.4367816091954, + 3534.676316162906, + 3530.434794948205 + ], + "reduction_plus_tensor_numerator": [ + 9727.229361370717, + 9714.869158878504, + 9754.604361370717, + 9728.308021806854, + 9725.204049844237, + 9737.07320872274, + 9745.819314641745, + 9760.321261682244, + 9727.45132398754 + ], + "masters_only": [ + 3292.446141793968, + 3245.0194542368454, + 3284.4385690037866, + 3251.7946207076643, + 3231.866301083692, + 3279.503198851025, + 3241.478652565609, + 3298.0343386865125, + 3267.9886408147277 + ], + "numerator_only": [ + 5755.773113099334, + 5751.0931406285845, + 5751.2720807524665, + 5754.830236292728, + 5771.696490020647, + 5773.747419132828, + 5764.582243633861, + 5758.069511355816, + 5771.912135810966 + ], + "full_madloop_entry": [ + 13202.82911392405, + 13244.570147679326, + 13246.268459915611, + 13235.878164556962, + 13212.618670886075, + 13296.416139240506, + 13227.739978902953, + 13277.449894514768, + 13223.763185654008 + ], + "masters_triangles": [ + 1543.7448103078025, + 1543.6015867334766, + 1511.8894655213553, + 1507.379861608208, + 1526.8662610355523, + 1544.9509067048436, + 1515.2007874015749, + 1478.5071581961345, + 1497.2336554521594 + ], + "masters_bubbles": [ + 1642.8766724840023, + 1636.944929222416, + 1644.227651735505, + 1636.2067739641911, + 1641.2452976536747, + 1638.5388791933294, + 1625.636675069485, + 1626.8783530476376, + 1624.9657423566673 + ], + "masters_tadpoles": [ + 118.45831506390763, + 117.96558275931976, + 118.0206079121936, + 118.2884494797339, + 118.25422082667383, + 118.4255055326893, + 118.2342776858413, + 117.93777080003584, + 118.15963942047024 + ] + }, + "iterations_per_block": { + "full": 634, + "pure_reduction": 2349, + "reduction_plus_tensor_numerator": 856, + "masters_only": 2553, + "numerator_only": 1453, + "full_madloop_entry": 632, + "masters_triangles": 5588, + "masters_bubbles": 5157, + "masters_tadpoles": 70701 + }, + "derived": { + "full_ns": 13090.065194532071, + "pure_reduction_ns": 3532.4682843763303, + "numerator_part_ns": 6195.839737430523, + "numerator_only_ns": 5758.069511355816, + "masters_ns": 3267.9886408147277, + "sum_pure_numerator_masters_ns": 12996.296662621582, + "sum_over_full": 0.9928366642551438 + }, + "protocol": "one calibration and one discarded warm-up block per mode; then 9 interleaved rounds, each running one block (>= 25 ms) of every mode; median over rounds", + "oneloop_warnings": false, + "host_loadavg_before": [ + "85.98", + "95.51", + "93.27" + ], + "libninja_sha256": "b6c3a01e70c155211b3abdab557afa99eb60ec9a50e5ab5b49323f22381b1869", + "libavh_olo_sha256": "502929c43f0dcb301cad8aa37ca4e88e15052a6f7e2042c6d88620d922ca68bb", + "driver_binary_sha256": "69fa60af770227ff72f18623be916e625649a2a30fd42b8f05a91aff5572dac3" + } + }, + "date_utc": "2026-10-18T01:00:13+00:00", + "driver_sha256": "fcebb40f7be0c02e8472789e2119df3d9c382c91f756aa3e1ef80ae2b8f03f10" +} diff --git a/vendor/ninjars/tests/data/provenance.json b/vendor/ninjars/tests/data/provenance.json new file mode 100644 index 0000000000..5c7a461c70 --- /dev/null +++ b/vendor/ninjars/tests/data/provenance.json @@ -0,0 +1,88 @@ +{ + "source": "https://github.com/alphal00p/ninjars", + "revision": "0d0d7e7a8033431b60a8580731084742e0655cda", + "attribution": "NinjaRS contributors; archived MadLoop tensor calls and original Ninja reference outputs. Copied byte for byte from the pinned upstream repository.", + "license": "GPL-3.0-or-later", + "comparison": "Complete finite, single pole, double pole: abs(value-reference)/max(1,abs(reference)) <= 1e-9 for DP and MP. The original Ninja rational split is also asserted for DP; MP records its basis-dependent difference.", + "commands": [ + "CARGO_TARGET_DIR=\"$PWD/.ninjars-build/cargo\" python3 vendor/ninjars/tests/replay.py --precision dp --output docs/benchmarkfolder/data/bridge-dp-replays.json", + "CARGO_TARGET_DIR=\"$PWD/.ninjars-build/cargo\" python3 vendor/ninjars/tests/replay.py --precision mp --output docs/benchmarkfolder/data/bridge-mp-replays.json" + ], + "notes": [ + "MP fixture replay promotes the archived binary64 input numbers; genuine binary128 transport is separately tested using 1+2^-100 in smoke.f90 and the Rust unit suite.", + "MP uses one process-wide Symbolica worker with independent context states. Under a restricted Symbolica license, no other Symbolica process may be active for this user.", + "Generic CC/rational split convention is documented at pinned upstream crates/ninjars-cli/README.md and crates/ninjars-symbolica/tests/fast_parity.rs; MadLoop uses complete Laurent coefficients and discards this diagnostic." + ], + "files": [ + { + "file": "cases/madloop-four-photon-top-box-0.json", + "upstream_path": "validation/benchmark/madloop/cases/madloop-four-photon-top-box-0.json", + "sha256": "9aea91e4e6c70b0f5984b2070e7aef8a77699260dacac1a9b3c9d65f23189796" + }, + { + "file": "cases/madloop-gg-hh-top-box-2.json", + "upstream_path": "validation/benchmark/madloop/cases/madloop-gg-hh-top-box-2.json", + "sha256": "c9271b79b2a4df2155ee8855fda3ffc6090f37261711468efd3126cf6665d5a3" + }, + { + "file": "cases/madloop-gg-hh-top-triangle-0.json", + "upstream_path": "validation/benchmark/madloop/cases/madloop-gg-hh-top-triangle-0.json", + "sha256": "5178de553b5dcfa0fcca616748943a63f2933399203f7d7040ba9c98aa3b4ea2" + }, + { + "file": "cases/madloop-gg-hhh-top-box-8.json", + "upstream_path": "validation/benchmark/madloop/cases/madloop-gg-hhh-top-box-8.json", + "sha256": "3f14438d72237acbd9c74f8ba813fa6fd04c2aa1af2cdde143134146a650a489" + }, + { + "file": "cases/madloop-gg-hhh-top-pentagon-26.json", + "upstream_path": "validation/benchmark/madloop/cases/madloop-gg-hhh-top-pentagon-26.json", + "sha256": "af571c4df618dafad08dc0acdb345f39d0446a2ec814f03b7cc2ee5a25d727ca" + }, + { + "file": "cases/madloop-gg-hhh-top-triangle-0.json", + "upstream_path": "validation/benchmark/madloop/cases/madloop-gg-hhh-top-triangle-0.json", + "sha256": "98483fd5759713618d7dfa784d604b83a7f03b241a5402d9a808af3655920353" + }, + { + "file": "cases/madloop-hgg-top-triangle-0.json", + "upstream_path": "validation/benchmark/madloop/cases/madloop-hgg-top-triangle-0.json", + "sha256": "8a70a0fc3569676b2601dbeb36b16cb70817b40df8eb3e762e4ed1899246d590" + }, + { + "file": "ninja/madloop-four-photon-top-box-0.json", + "upstream_path": "validation/benchmark/ninja/madloop-four-photon-top-box-0.json", + "sha256": "dc34ad2683fbe535140c63bba564b8f6e8e74ce3c64eb17ef3cfa96baa5a6dde" + }, + { + "file": "ninja/madloop-gg-hh-top-box-2.json", + "upstream_path": "validation/benchmark/ninja/madloop-gg-hh-top-box-2.json", + "sha256": "d893de26b4e2e4edbeb4d6ba3122a6cd231bd5842719b3b8b2c4a84ee5e67dcc" + }, + { + "file": "ninja/madloop-gg-hh-top-triangle-0.json", + "upstream_path": "validation/benchmark/ninja/madloop-gg-hh-top-triangle-0.json", + "sha256": "669b92538382201f26487865cd44a1d8eea03b13ed7b99dcdae21bd7662cca95" + }, + { + "file": "ninja/madloop-gg-hhh-top-box-8.json", + "upstream_path": "validation/benchmark/ninja/madloop-gg-hhh-top-box-8.json", + "sha256": "c49f6d9db0c09602c6e663e60499a9b5126b9ca66d1738f6b5bac5846afda572" + }, + { + "file": "ninja/madloop-gg-hhh-top-pentagon-26.json", + "upstream_path": "validation/benchmark/ninja/madloop-gg-hhh-top-pentagon-26.json", + "sha256": "e4b1522302bab1592924b251a7ee153c94623726d68b2d552e6211a4b0b3ded3" + }, + { + "file": "ninja/madloop-gg-hhh-top-triangle-0.json", + "upstream_path": "validation/benchmark/ninja/madloop-gg-hhh-top-triangle-0.json", + "sha256": "7905a646d4bb23daf1b0506b662913f60796c87dfcbbd556c5bd957f7eba3bd2" + }, + { + "file": "ninja/madloop-hgg-top-triangle-0.json", + "upstream_path": "validation/benchmark/ninja/madloop-hgg-top-triangle-0.json", + "sha256": "a50906866f8e8812c02365cff98cb56a20639537f1804d290edbd8020ed9d30b" + } + ] +} diff --git a/vendor/ninjars/tests/fenv_helpers.c b/vendor/ninjars/tests/fenv_helpers.c new file mode 100644 index 0000000000..3942c2bc3d --- /dev/null +++ b/vendor/ninjars/tests/fenv_helpers.c @@ -0,0 +1,10 @@ +#include +/* Test helpers keep platform FE_* constants out of Rust. */ +int ninjars_t3_flags(void) { return fetestexcept(FE_ALL_EXCEPT); } +int ninjars_t3_clear_flags(void) { return feclearexcept(FE_ALL_EXCEPT); } +int ninjars_t3_bad_flags(void) { + return fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW); +} +int ninjars_t3_round_upward(void) { return fesetround(FE_UPWARD); } +int ninjars_t3_round_nearest(void) { return fesetround(FE_TONEAREST); } +int ninjars_t3_raise_inexact(void) { return feraiseexcept(FE_INEXACT); } diff --git a/vendor/ninjars/tests/poles/README.md b/vendor/ninjars/tests/poles/README.md new file mode 100644 index 0000000000..52bb7fccd9 --- /dev/null +++ b/vendor/ninjars/tests/poles/README.md @@ -0,0 +1,175 @@ +# Independent UV/IR pole checks + +These fixtures compare the **bare tensor loop integral** with COLLIER, without +UFO counterterms or R2 vertices. The eight kinematic cases contain 455 individual +tensor components: massive tadpole, scaleless lightlike bubble, massive bubble, +massless off-shell bubble, massive triangle, infrared triangle, massive box and +complex-mass bubble. The largest tested rank is four. The scaleless bubble has +separate nonzero UV and IR residues even though their sum vanishes. Tensor +triangles and boxes also include nonzero UV residues. + +The current qualification uses upstream NinjaRS +[`41a4c00e`](https://github.com/alphal00p/ninjars/commit/41a4c00e7635e3ab188fc26bacf0aae6941e8082) +and oneloopmaster +[`5b710437`](https://github.com/alphal00p/oneloopmaster/commit/5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5). +Pole selection is provided by those upstream libraries. +`upstream-migration-validation.json` binds the installed archive and dependency +pins to the fresh numerical campaign, production installation smoke, 31 passing +bridge Rust tests (7 ignored), and upstream provider/core test commands and counts. + +Run from the MadGraph repository root after `install ninjars --update`: + +```sh +python3 vendor/ninjars/tests/poles/tensor_validation.py \ + --lib HEPTools/ninjars/lib \ + --output .benchmark-work/uv-ir-independent +``` + +The driver uses the installed Fortran module and native linking metadata. The +default runs all 455 components in both double precision and the binary128-input, +256-bit rescue. `--focused` selects 61 representative components. The precision +can also be selected explicitly with `--precision dp` or `--precision mp`. +Every context cycles through `both, UV, IR, none, both, IR, UV, none`; repeated +evaluations of the same mode must agree exactly, including all printed rescue +digits. Binary128 inputs and selected poles traverse the production Fortran ABI. +Run the two precisions serially: the restricted Symbolica license permits one +active numerical worker per user. + +Each output directory records the input stream, raw numerical values, statuses, +comparison results, compiler logs and hashes of the reference and installed +library. No generated binaries belong in this source directory. The default +check requires: + +- All UV-only and IR-only DP evaluations to succeed and agree with COLLIER. +- All four modes in the higher-precision evaluation to succeed and agree. +- Exact agreement of repeated evaluations after changing modes in a reused + context. +- Successful higher-precision evaluation of every ordinary-DP unstable control + when both precisions are run together. + +Ordinary DP uses the unchanged fast engine. The original ABI-3 library already +returns `UNSTABLE` for the wholly spacelike massive-box case. Fourteen rank-four +massive-triangle components also miss the strict COLLIER tolerance in the native +combined result, by at most 4.09 times its bound. The historical ABI-3 to first +ABI-4 comparison found identical combined DP outputs for all 455 components, +including statuses. The current selected DP path passes all components, and the +rescue passes all modes. These +ordinary-DP diagnostics remain visible in the JSON results. To make them fatal +as well, use `--diagnostic-all`; this intentionally fails on the recorded native +DP controls. They are not counted as newly validated native-DP accuracy results. +`tensor-validation.json` records the current eight-mode-cycle qualification. +`native-dp-baseline.json` preserves the historical ABI-3 to first ABI-4 +combined-output comparison. The subsequent migration to upstream pole APIs +reproduces **all 7,280 prior ABI-4 DP/MP output records exactly**, across all four +modes and their repeats, including Laurent coefficients, rational terms and +statuses. This includes 910 combined-mode records in each precision. The +baseline and current library, input and output hashes are bound in +`upstream-migration-validation.json`. + +The numerical comparison uses +`abs(a-b) <= 1e-7*max(abs(a),abs(b)) + 1e-10*S` for each complex coefficient. +Here `S` is the largest COLLIER finite/UV/IR component at the same kinematic point +and homogeneous tensor rank, so all components have the same mass dimension. +If an entire odd tadpole tensor vanishes by symmetry, the nonzero scalar +reference at that point is multiplied by +`max(mu_R^2, abs(m_i^2))^(rank/2)` to provide the corresponding dimension. There +is no arbitrary absolute tolerance floor. The original zero components are +retained and checked. + +## COLLIER reference provenance and reproduction + +The committed reference was generated with **COLLIER 1.2.9**, the COLI branch +(`SetMode_cll(1)`), its default required accuracy, GNU Fortran 15.3.0 on Linux +x86_64, and the installed library used by MadLoop. Every COLLIER error and +accuracy flag was zero. `provenance.json` records the input, driver, library and +reference checksums. +The reference JSON SHA-256 is +`18f6694dd5af873d847e39bd299957454c698aeb31f3bf4b2389593bc44d3970`. + +The COLLIER driver evaluates each tensor four times with independent regulator +settings. It takes differences from the finite result to extract UV, IR single +and IR double poles, matching MadLoop's COLLIER wrapper. The base uses +`DeltaUV=DeltaIR1=0`, `DeltaIR2=pi^2/6`, and equal UV/IR scales; the latter shift +matches the Ninja/OneLOop normalization. Numerators use contravariant components +of `q`, with denominators `(q+p_i)^2-m_i^2`. There are no extra symmetry factors. +Complex squared masses are passed without changing their signs. + +Regenerate the fixture with an independently installed COLLIER: + +```sh +python3 vendor/ninjars/tests/poles/generate_collier_reference.py \ + --collier HEPTools/collier \ + --work-dir .benchmark-work/uv-ir-collier-reference \ + --output .benchmark-work/uv-ir-collier-reference/reference.json +``` + +Then pass `--reference` with the regenerated JSON to `tensor_validation.py`. +The generator checks the COLLIER status flags and tensor component counts. + +`collier_poles.f90` adapts the tensor reference driver from +[NinjaRS at revision aa6a6307](https://github.com/alphal00p/ninjars/blob/aa6a6307dd081dc3714f9accebc0df9e5561ae73/validation/rank-n2/harness/collier_tensor_driver.f90), +separating the UV and IR regulator variations. This directory uses the same +GPL-3.0-or-later license as the bridge and NinjaRS. + +## Generated MadLoop comparisons + +`madloop-validation.json` records a separate, actual CLI-generated campaign: + +| Process | Model | COLLIER CT modes | NinjaRS CT modes | +|---|---|---|---| +| `u u~ > z [virt=QCD]` | `loop_sm` | 1 | −1, 1, 2, 4, 5 | +| `g g > t t~ [virt=QCD]` | `loop_sm` | 1 | −1, 1, 2, 4, 5 | +| `e+ e- > mu+ mu- [virt=QED]` | `loop_qcd_qed_sm_Gmu` | 1 | 1, 4 | +| `g g > h [sqrvirt=QCD]` | `loop_sm` | 1 | 1, 4 | + +Every listed configuration uses all four explicit pole selectors and three +retained phase-space points, with all helicities and color sums. Two additional +legacy-filter controls bring the total to **74 configurations and 444 rows** +(each point has a total and a split-order row). Three runtime mode-switch series +add 144 rows. All 187 numerical, cache, status and completeness comparisons pass; +the largest numerical difference is `8.37505e-5` times the allowed tolerance. +Fixed DP modes return 110, forced QP returns 120, and all automatic stability +checks in this campaign return 218. Fixed-mode return codes do not assert a +separate stability acceptance test. + +The same disposable generated sources are used for both tools. Immediately +after counterterm construction, the harness zeroes `AMPL(:,1:NCTAMPS)` and its +corresponding MP/DP copies, before interference or squaring. The original +generated sources and their hashes are retained in the working output. This +removes UFO UV and R2 terms without modifying the loop numerator, reduction +wrapper or production source. The reported quantities therefore test the bare +loop contribution. For loop-induced output, each selected squared amplitude is +compared directly with COLLIER; UV+IR additivity is **not** asserted for squared +amplitudes. + +Reproduce the full matrix from the repository root: + +```sh +python3 vendor/ninjars/tests/poles/madloop_validation.py --campaign \ + --output .benchmark-work/uv-ir-madloop \ + --ninjars HEPTools/ninjars/lib --collier HEPTools/collier \ + --ew-model /path/to/loop_qcd_qed_sm_Gmu +``` + +The output contains the command cards submitted to `bin/madgraph`, generated +sources, build logs, parameter cards, numerical outputs and the comparison JSON. +`--points` can select another directory with the four point-file names retained +under `points/`; the qualification above uses the committed files and zero-width +cards under `cards/`. The exact model source checksums and the immutable archive +URL for the EW model are recorded in `madloop-validation.json`. The EW source +is the converted UFO used in the existing benchmark, rather than an unverified +new download. COLLIER and NinjaRS must already be installed. + +For individual checks, use `--case qcd-z --prepare` to generate and compile, +then `--case qcd-z --backend 8 --ctmode 4` to evaluate its four pole modes. +The complete campaign and comparator reject missing configurations, missing or +duplicate point/order rows, nonfinite values, unexpected return codes, and +incomplete runtime-switch sequences. + +The current campaign regenerated and compiled **all four processes** through +the portable harness against the upstream installation. Every one of its 74 +configuration result records agrees exactly with the earlier ABI-4 campaign, +including statuses. The earlier 12-configuration `qcd-z` portability smoke is +retained as historical provenance in `madloop-validation.json`; the current +qualification uses the full fresh campaign. No new timing claim is made by +this numerical migration check. diff --git a/vendor/ninjars/tests/poles/bare_driver.f b/vendor/ninjars/tests/poles/bare_driver.f new file mode 100644 index 0000000000..78210c201a --- /dev/null +++ b/vendor/ninjars/tests/poles/bare_driver.f @@ -0,0 +1,122 @@ + PROGRAM BENCHMARK_MADLOOP + IMPLICIT NONE + INTEGER NEXTERNAL + PARAMETER(NEXTERNAL=@NEXTERNAL@) + INCLUDE 'coupl.inc' + INTEGER NSQSO_BORN + PARAMETER(NSQSO_BORN=@NBORN@) + REAL*8 ZERO + PARAMETER(ZERO=0D0) + REAL*8 PMASS(NEXTERNAL) + REAL*8, ALLOCATABLE :: POINTS(:,:,:),ANS(:,:),ACC(:) + REAL*8, ALLOCATABLE :: VALUES(:,:,:),ACCURACIES(:,:) + INTEGER, ALLOCATABLE :: CODES(:) + REAL*8 P(0:3,NEXTERNAL),TOTAL(0:3),COLD,ELAPSED + INTEGER NPOINTS,NDIM,NSO,I,J,K,L,NLOOPS,CODE + INTEGER SWITCH_MODES(8),M,MODE + DATA SWITCH_MODES/0,1,2,3,0,2,1,0/ + INTEGER TENS,WARM_POINTS + INTEGER*8 TIMED_CODES(0:499) + INTEGER*8 T0,T1,RATE + CHARACTER*1024 ARG + + CALL SETPARA('param_card.dat') + INCLUDE 'pmass.inc' + CALL @PREFIX@GET_ANSWER_DIMENSION(NDIM) + CALL @PREFIX@GET_NSQSO_LOOP(NSO) + OPEN(73,FILE='dimensions.dat',STATUS='REPLACE') + WRITE(73,*) NDIM,NSO,NSQSO_BORN + CLOSE(73) + CALL GET_COMMAND_ARGUMENT(1,ARG) + IF(TRIM(ARG).EQ.'--masses') THEN + OPEN(73,FILE='masses.dat',STATUS='REPLACE') + WRITE(73,'(ES26.17E3)') PMASS + CLOSE(73) + STOP + ENDIF + OPEN(73,FILE=TRIM(ARG),STATUS='OLD') + READ(73,*) NPOINTS + IF(NPOINTS.LE.0) STOP 1 + ALLOCATE(POINTS(0:3,NEXTERNAL,NPOINTS)) + DO K=1,NPOINTS + DO I=1,NEXTERNAL + READ(73,*) POINTS(:,I,K) + ENDDO + ENDDO + CLOSE(73) + CALL GET_COMMAND_ARGUMENT(2,ARG) + READ(ARG,*) NLOOPS + IF(NLOOPS.LE.0) STOP 2 + ALLOCATE(ANS(0:3,0:NDIM),ACC(0:NSO)) + ALLOCATE(VALUES(0:3,0:NDIM,NPOINTS)) + ALLOCATE(ACCURACIES(0:NSO,NPOINTS),CODES(NPOINTS)) + ANS=0D0 + VALUES=0D0 + TIMED_CODES=0 +C CTModeRun controls stability; explicit pole modes bypass filters. + P=POINTS(:,:,1) + TOTAL=P(:,1)+P(:,2) + MU_R=SQRT(ABS(TOTAL(0)**2-SUM(TOTAL(1:3)**2))) + CALL UPDATE_AS_PARAM() + CALL SYSTEM_CLOCK(T0,RATE) + CALL @PREFIX@SLOOPMATRIX_THRES(P,ANS,-1D0,ACC,CODE) +C Wait for a full warm pass after helicity initialization finishes. + WARM_POINTS=0 + DO K=1,20+NPOINTS + P=POINTS(:,:,1+MOD(K-1,NPOINTS)) + TOTAL=P(:,1)+P(:,2) + MU_R=SQRT(ABS(TOTAL(0)**2-SUM(TOTAL(1:3)**2))) + CALL UPDATE_AS_PARAM() + CALL @PREFIX@SLOOPMATRIX_THRES(P,ANS,-1D0,ACC,CODE) + TENS=MOD(CODE,100)/10 + IF(TENS.EQ.1.OR.TENS.EQ.2) THEN + WARM_POINTS=WARM_POINTS+1 + ELSE + WARM_POINTS=0 + ENDIF + IF(WARM_POINTS.GE.NPOINTS) EXIT + ENDDO + IF(WARM_POINTS.LT.NPOINTS) STOP 3 + CALL SYSTEM_CLOCK(T1) + COLD=DBLE(T1-T0)/DBLE(RATE) +C Save numerical outputs outside the timing interval. + DO K=1,NPOINTS + P=POINTS(:,:,K) + TOTAL=P(:,1)+P(:,2) + MU_R=SQRT(ABS(TOTAL(0)**2-SUM(TOTAL(1:3)**2))) + CALL UPDATE_AS_PARAM() + CALL @PREFIX@SLOOPMATRIX_THRES(P,ANS,-1D0,ACC,CODE) + VALUES(:,:,K)=ANS + ACCURACIES(:,K)=ACC + CODES(K)=CODE + ENDDO + OPEN(73,FILE='values.dat',STATUS='REPLACE') + DO K=1,NPOINTS + DO J=0,NSO + WRITE(73,'(3I8,5ES26.17E3)') K,J,CODES(K), + $ VALUES(:,J,K),ACCURACIES(J,K) + ENDDO + ENDDO + CLOSE(73) + CALL GET_COMMAND_ARGUMENT(3,ARG) + IF(TRIM(ARG).EQ.'--switch') THEN + OPEN(73,FILE='switch_values.dat',STATUS='REPLACE') + DO M=1,8 + MODE=SWITCH_MODES(M) + CALL @PREFIX@SET_LOOP_POLE_MODE(MODE) + DO K=1,NPOINTS + P=POINTS(:,:,K) + TOTAL=P(:,1)+P(:,2) + MU_R=SQRT(ABS(TOTAL(0)**2-SUM(TOTAL(1:3)**2))) + CALL UPDATE_AS_PARAM() + CALL @PREFIX@SLOOPMATRIX_THRES(P,ANS,-1D0,ACC,CODE) + DO J=0,NSO + WRITE(73,'(5I8,5ES26.17E3)') M,MODE,K,J,CODE, + $ ANS(:,J),ACC(J) + ENDDO + ENDDO + ENDDO + CLOSE(73) + ENDIF + CALL @PREFIX@EXIT_MADLOOP() + END diff --git a/vendor/ninjars/tests/poles/cards/ew-mumu.dat b/vendor/ninjars/tests/poles/cards/ew-mumu.dat new file mode 100644 index 0000000000..d3663a5099 --- /dev/null +++ b/vendor/ninjars/tests/poles/cards/ew-mumu.dat @@ -0,0 +1,127 @@ +###################################################################### +## PARAM_CARD AUTOMATICALLY GENERATED BY MG5 FOLLOWING UFO MODEL #### +###################################################################### +## ## +## Width set on Auto will be computed following the information ## +## present in the decay.py files of the model. ## +## See arXiv:1402.1178 for more details. ## +## ## +###################################################################### + +################################### +## INFORMATION FOR LOOP +################################### +Block loop + 666 1.000000e+03 # MU_R + +################################### +## INFORMATION FOR MASS +################################### +Block mass + 6 1.733000e+02 # MT + 23 9.118800e+01 # MZ + 24 8.041900e+01 # MW + 25 1.250000e+02 # MH +## Dependent parameters, given by model restrictions. +## Those values should be edited following the +## analytical expression. MG5 ignores those values +## but they are important for interfacing the output of MG5 +## to external program such as Pythia. + 1 0.000000e+00 # d : 0.0 + 2 0.000000e+00 # u : 0.0 + 3 0.000000e+00 # s : 0.0 + 4 0.000000e+00 # c : 0.0 + 5 0.000000e+00 # b : 0.0 + 11 0.000000e+00 # e- : 0.0 + 12 0.000000e+00 # ve : 0.0 + 13 0.000000e+00 # mu- : 0.0 + 14 0.000000e+00 # vm : 0.0 + 15 0.000000e+00 # ta- : 0.0 + 16 0.000000e+00 # vt : 0.0 + 21 0.000000e+00 # g : 0.0 + 22 0.000000e+00 # a : 0.0 + 9000002 9.118800e+01 # ghz : MZ + 9000003 8.041900e+01 # ghwp : MW + 9000004 8.041900e+01 # ghwm : MW + 250 9.118800e+01 # g0 : MZ + 251 8.041900e+01 # g+ : MW + +################################### +## INFORMATION FOR SMINPUTS +################################### +Block sminputs + 2 1.166390e-05 # Gf + 3 1.180000e-01 # aS (Note: this Parameter is not used if you use a PDF set) + +################################### +## INFORMATION FOR YUKAWA +################################### +Block yukawa + 6 1.733000e+02 # ymt + +################################### +## INFORMATION FOR DECAY +################################### +DECAY 6 0.000000e+00 # WT +DECAY 23 0.000000e+00 # WZ +DECAY 24 0.000000e+00 # WW +DECAY 25 0.000000e+00 # WH +## Dependent parameters, given by model restrictions. +## Those values should be edited following the +## analytical expression. MG5 ignores those values +## but they are important for interfacing the output of MG5 +## to external program such as Pythia. +DECAY 1 0.000000e+00 # d : 0.0 +DECAY 2 0.000000e+00 # u : 0.0 +DECAY 3 0.000000e+00 # s : 0.0 +DECAY 4 0.000000e+00 # c : 0.0 +DECAY 5 0.000000e+00 # b : 0.0 +DECAY 11 0.000000e+00 # e- : 0.0 +DECAY 12 0.000000e+00 # ve : 0.0 +DECAY 13 0.000000e+00 # mu- : 0.0 +DECAY 14 0.000000e+00 # vm : 0.0 +DECAY 15 0.000000e+00 # ta- : 0.0 +DECAY 16 0.000000e+00 # vt : 0.0 +DECAY 21 0.000000e+00 # g : 0.0 +DECAY 22 0.000000e+00 # a : 0.0 +DECAY 250 0.000000e+00 # g0 : WZ +DECAY 251 0.000000e+00 # g+ : WW +#=========================================================== +# QUANTUM NUMBERS OF NEW STATE(S) (NON SM PDG CODE) +#=========================================================== + +Block QNUMBERS 9000001 # gha + 1 0 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 1 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 1 # Particle/Antiparticle distinction (0=own anti) +Block QNUMBERS 9000002 # ghz + 1 0 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 1 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 1 # Particle/Antiparticle distinction (0=own anti) +Block QNUMBERS 9000003 # ghwp + 1 3 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 1 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 1 # Particle/Antiparticle distinction (0=own anti) +Block QNUMBERS 9000004 # ghwm + 1 -3 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 1 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 1 # Particle/Antiparticle distinction (0=own anti) +Block QNUMBERS 9000005 # ghg + 1 0 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 8 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 1 # Particle/Antiparticle distinction (0=own anti) +Block QNUMBERS 250 # g0 + 1 0 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 1 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 0 # Particle/Antiparticle distinction (0=own anti) +Block QNUMBERS 251 # g+ + 1 3 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 1 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 1 # Particle/Antiparticle distinction (0=own anti) diff --git a/vendor/ninjars/tests/poles/cards/li-h.dat b/vendor/ninjars/tests/poles/cards/li-h.dat new file mode 100644 index 0000000000..f6fdae1e9d --- /dev/null +++ b/vendor/ninjars/tests/poles/cards/li-h.dat @@ -0,0 +1,93 @@ +###################################################################### +## PARAM_CARD AUTOMATICALLY GENERATED BY MG5 FOLLOWING UFO MODEL #### +###################################################################### +## ## +## Width set on Auto will be computed following the information ## +## present in the decay.py files of the model. ## +## See arXiv:1402.1178 for more details. ## +## ## +###################################################################### + +################################### +## INFORMATION FOR LOOP +################################### +Block loop + 1 9.118800e+01 # MU_R + +################################### +## INFORMATION FOR MASS +################################### +Block mass + 5 4.700000e+00 # MB + 6 1.730000e+02 # MT + 15 1.777000e+00 # MTA + 23 9.118800e+01 # MZ + 25 1.250000e+02 # MH +## Dependent parameters, given by model restrictions. +## Those values should be edited following the +## analytical expression. MG5 ignores those values +## but they are important for interfacing the output of MG5 +## to external program such as Pythia. + 1 0.000000e+00 # d : 0.0 + 2 0.000000e+00 # u : 0.0 + 3 0.000000e+00 # s : 0.0 + 4 0.000000e+00 # c : 0.0 + 11 0.000000e+00 # e- : 0.0 + 12 0.000000e+00 # ve : 0.0 + 13 0.000000e+00 # mu- : 0.0 + 14 0.000000e+00 # vm : 0.0 + 16 0.000000e+00 # vt : 0.0 + 21 0.000000e+00 # g : 0.0 + 22 0.000000e+00 # a : 0.0 + 24 8.041900e+01 # w+ : cmath.sqrt(MZ__exp__2/2. + cmath.sqrt(MZ__exp__4/4. - (aEW*cmath.pi*MZ__exp__2)/(Gf*sqrt__2))) + +################################### +## INFORMATION FOR SMINPUTS +################################### +Block sminputs + 1 1.325070e+02 # aEWM1 + 2 1.166390e-05 # Gf + 3 1.180000e-01 # aS (Note: this Parameter is not used if you use a PDF set) + +################################### +## INFORMATION FOR YUKAWA +################################### +Block yukawa + 5 4.700000e+00 # ymb + 6 1.730000e+02 # ymt + 15 1.777000e+00 # ymtau + +################################### +## INFORMATION FOR DECAY +################################### +DECAY 6 0.000000e+00 # WT +DECAY 23 0.000000e+00 # WZ +DECAY 24 0.000000e+00 # WW +DECAY 25 0.000000e+00 # WH +## Dependent parameters, given by model restrictions. +## Those values should be edited following the +## analytical expression. MG5 ignores those values +## but they are important for interfacing the output of MG5 +## to external program such as Pythia. +DECAY 1 0.000000e+00 # d : 0.0 +DECAY 2 0.000000e+00 # u : 0.0 +DECAY 3 0.000000e+00 # s : 0.0 +DECAY 4 0.000000e+00 # c : 0.0 +DECAY 5 0.000000e+00 # b : 0.0 +DECAY 11 0.000000e+00 # e- : 0.0 +DECAY 12 0.000000e+00 # ve : 0.0 +DECAY 13 0.000000e+00 # mu- : 0.0 +DECAY 14 0.000000e+00 # vm : 0.0 +DECAY 15 0.000000e+00 # ta- : 0.0 +DECAY 16 0.000000e+00 # vt : 0.0 +DECAY 21 0.000000e+00 # g : 0.0 +DECAY 22 0.000000e+00 # a : 0.0 +#=========================================================== +# QUANTUM NUMBERS OF NEW STATE(S) (NON SM PDG CODE) +#=========================================================== + +Block QNUMBERS 82 # gh + 1 0 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 8 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 1 # Particle/Antiparticle distinction (0=own anti) diff --git a/vendor/ninjars/tests/poles/cards/qcd-tt.dat b/vendor/ninjars/tests/poles/cards/qcd-tt.dat new file mode 100644 index 0000000000..f6fdae1e9d --- /dev/null +++ b/vendor/ninjars/tests/poles/cards/qcd-tt.dat @@ -0,0 +1,93 @@ +###################################################################### +## PARAM_CARD AUTOMATICALLY GENERATED BY MG5 FOLLOWING UFO MODEL #### +###################################################################### +## ## +## Width set on Auto will be computed following the information ## +## present in the decay.py files of the model. ## +## See arXiv:1402.1178 for more details. ## +## ## +###################################################################### + +################################### +## INFORMATION FOR LOOP +################################### +Block loop + 1 9.118800e+01 # MU_R + +################################### +## INFORMATION FOR MASS +################################### +Block mass + 5 4.700000e+00 # MB + 6 1.730000e+02 # MT + 15 1.777000e+00 # MTA + 23 9.118800e+01 # MZ + 25 1.250000e+02 # MH +## Dependent parameters, given by model restrictions. +## Those values should be edited following the +## analytical expression. MG5 ignores those values +## but they are important for interfacing the output of MG5 +## to external program such as Pythia. + 1 0.000000e+00 # d : 0.0 + 2 0.000000e+00 # u : 0.0 + 3 0.000000e+00 # s : 0.0 + 4 0.000000e+00 # c : 0.0 + 11 0.000000e+00 # e- : 0.0 + 12 0.000000e+00 # ve : 0.0 + 13 0.000000e+00 # mu- : 0.0 + 14 0.000000e+00 # vm : 0.0 + 16 0.000000e+00 # vt : 0.0 + 21 0.000000e+00 # g : 0.0 + 22 0.000000e+00 # a : 0.0 + 24 8.041900e+01 # w+ : cmath.sqrt(MZ__exp__2/2. + cmath.sqrt(MZ__exp__4/4. - (aEW*cmath.pi*MZ__exp__2)/(Gf*sqrt__2))) + +################################### +## INFORMATION FOR SMINPUTS +################################### +Block sminputs + 1 1.325070e+02 # aEWM1 + 2 1.166390e-05 # Gf + 3 1.180000e-01 # aS (Note: this Parameter is not used if you use a PDF set) + +################################### +## INFORMATION FOR YUKAWA +################################### +Block yukawa + 5 4.700000e+00 # ymb + 6 1.730000e+02 # ymt + 15 1.777000e+00 # ymtau + +################################### +## INFORMATION FOR DECAY +################################### +DECAY 6 0.000000e+00 # WT +DECAY 23 0.000000e+00 # WZ +DECAY 24 0.000000e+00 # WW +DECAY 25 0.000000e+00 # WH +## Dependent parameters, given by model restrictions. +## Those values should be edited following the +## analytical expression. MG5 ignores those values +## but they are important for interfacing the output of MG5 +## to external program such as Pythia. +DECAY 1 0.000000e+00 # d : 0.0 +DECAY 2 0.000000e+00 # u : 0.0 +DECAY 3 0.000000e+00 # s : 0.0 +DECAY 4 0.000000e+00 # c : 0.0 +DECAY 5 0.000000e+00 # b : 0.0 +DECAY 11 0.000000e+00 # e- : 0.0 +DECAY 12 0.000000e+00 # ve : 0.0 +DECAY 13 0.000000e+00 # mu- : 0.0 +DECAY 14 0.000000e+00 # vm : 0.0 +DECAY 15 0.000000e+00 # ta- : 0.0 +DECAY 16 0.000000e+00 # vt : 0.0 +DECAY 21 0.000000e+00 # g : 0.0 +DECAY 22 0.000000e+00 # a : 0.0 +#=========================================================== +# QUANTUM NUMBERS OF NEW STATE(S) (NON SM PDG CODE) +#=========================================================== + +Block QNUMBERS 82 # gh + 1 0 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 8 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 1 # Particle/Antiparticle distinction (0=own anti) diff --git a/vendor/ninjars/tests/poles/cards/qcd-z.dat b/vendor/ninjars/tests/poles/cards/qcd-z.dat new file mode 100644 index 0000000000..f6fdae1e9d --- /dev/null +++ b/vendor/ninjars/tests/poles/cards/qcd-z.dat @@ -0,0 +1,93 @@ +###################################################################### +## PARAM_CARD AUTOMATICALLY GENERATED BY MG5 FOLLOWING UFO MODEL #### +###################################################################### +## ## +## Width set on Auto will be computed following the information ## +## present in the decay.py files of the model. ## +## See arXiv:1402.1178 for more details. ## +## ## +###################################################################### + +################################### +## INFORMATION FOR LOOP +################################### +Block loop + 1 9.118800e+01 # MU_R + +################################### +## INFORMATION FOR MASS +################################### +Block mass + 5 4.700000e+00 # MB + 6 1.730000e+02 # MT + 15 1.777000e+00 # MTA + 23 9.118800e+01 # MZ + 25 1.250000e+02 # MH +## Dependent parameters, given by model restrictions. +## Those values should be edited following the +## analytical expression. MG5 ignores those values +## but they are important for interfacing the output of MG5 +## to external program such as Pythia. + 1 0.000000e+00 # d : 0.0 + 2 0.000000e+00 # u : 0.0 + 3 0.000000e+00 # s : 0.0 + 4 0.000000e+00 # c : 0.0 + 11 0.000000e+00 # e- : 0.0 + 12 0.000000e+00 # ve : 0.0 + 13 0.000000e+00 # mu- : 0.0 + 14 0.000000e+00 # vm : 0.0 + 16 0.000000e+00 # vt : 0.0 + 21 0.000000e+00 # g : 0.0 + 22 0.000000e+00 # a : 0.0 + 24 8.041900e+01 # w+ : cmath.sqrt(MZ__exp__2/2. + cmath.sqrt(MZ__exp__4/4. - (aEW*cmath.pi*MZ__exp__2)/(Gf*sqrt__2))) + +################################### +## INFORMATION FOR SMINPUTS +################################### +Block sminputs + 1 1.325070e+02 # aEWM1 + 2 1.166390e-05 # Gf + 3 1.180000e-01 # aS (Note: this Parameter is not used if you use a PDF set) + +################################### +## INFORMATION FOR YUKAWA +################################### +Block yukawa + 5 4.700000e+00 # ymb + 6 1.730000e+02 # ymt + 15 1.777000e+00 # ymtau + +################################### +## INFORMATION FOR DECAY +################################### +DECAY 6 0.000000e+00 # WT +DECAY 23 0.000000e+00 # WZ +DECAY 24 0.000000e+00 # WW +DECAY 25 0.000000e+00 # WH +## Dependent parameters, given by model restrictions. +## Those values should be edited following the +## analytical expression. MG5 ignores those values +## but they are important for interfacing the output of MG5 +## to external program such as Pythia. +DECAY 1 0.000000e+00 # d : 0.0 +DECAY 2 0.000000e+00 # u : 0.0 +DECAY 3 0.000000e+00 # s : 0.0 +DECAY 4 0.000000e+00 # c : 0.0 +DECAY 5 0.000000e+00 # b : 0.0 +DECAY 11 0.000000e+00 # e- : 0.0 +DECAY 12 0.000000e+00 # ve : 0.0 +DECAY 13 0.000000e+00 # mu- : 0.0 +DECAY 14 0.000000e+00 # vm : 0.0 +DECAY 15 0.000000e+00 # ta- : 0.0 +DECAY 16 0.000000e+00 # vt : 0.0 +DECAY 21 0.000000e+00 # g : 0.0 +DECAY 22 0.000000e+00 # a : 0.0 +#=========================================================== +# QUANTUM NUMBERS OF NEW STATE(S) (NON SM PDG CODE) +#=========================================================== + +Block QNUMBERS 82 # gh + 1 0 # 3 times electric charge + 2 1 # number of spin states (2S+1) + 3 8 # colour rep (1: singlet, 3: triplet, 8: octet) + 4 1 # Particle/Antiparticle distinction (0=own anti) diff --git a/vendor/ninjars/tests/poles/collier_jobs.in b/vendor/ninjars/tests/poles/collier_jobs.in new file mode 100644 index 0000000000..d98e876b2b --- /dev/null +++ b/vendor/ninjars/tests/poles/collier_jobs.in @@ -0,0 +1,63 @@ +8 4 4 +1 3 +7 +4 0 +2 4 +7 +0 0 +0 0 +5 3 0 4 +0 +2 4 +7 +9 0 +4 0 +4 1 2 0.5 +10.75 +2 4 +7 +0 0 +0 0 +0 1 2 3 +-14 +3 4 +7 +9 0 +16 0 +25 0 +1 0.2 0.3 0.4 +0.4 -0.5 0.7 -0.2 +0.71 +-0.65 +-0.6199999999999999 +3 3 +7 +0 0 +0 0 +0 0 +5 0 0 5 +10 0 0 0 +0 +0 +100 +4 4 +7 +9 0 +16 0 +25 0 +36 0 +0 1 2 0 +0 0 1 3 +0 2 0 1 +-5 +-11 +-9 +-5 +-10 +-6 +2 3 +7 +9 -0.2 +4 -0.1 +4 1 2 0.5 +10.75 diff --git a/vendor/ninjars/tests/poles/collier_poles.f90 b/vendor/ninjars/tests/poles/collier_poles.f90 new file mode 100644 index 0000000000..1cf6f3ee5b --- /dev/null +++ b/vendor/ninjars/tests/poles/collier_poles.f90 @@ -0,0 +1,120 @@ +! Adapted from NinjaRS validation/rank-n2/harness/collier_tensor_driver.f90. +! Separate poles use independent DeltaUV/DeltaIR shifts, matching MadLoop. +program collier_tensor_driver + use COLLIER + implicit none + integer :: njobs, nmax, rmax, ijob, N, R, k, iset, n0, n1, n2, n3, errflag, accflag + integer :: errmin, accmax, mode, nargs, ios, unit_in, unit_out + double precision :: mu2, re, im, reqacc, p(0:3), pi2o6 + double precision :: d_uv(4), d_ir1(4), d_ir2(4) + character(len=4096) :: path_in, path_out, arg + double complex, allocatable :: mass2(:), MomInv(:), MomVec(:,:) + double complex, allocatable :: TN(:,:,:,:), TNuv(:,:,:,:), TNs(:,:,:,:,:), TNuv1(:,:,:,:) + double precision, allocatable :: TNerr(:), TNerr1(:) + + pi2o6 = 4d0*atan(1d0) + pi2o6 = pi2o6*pi2o6/6d0 + d_uv = (/ 0d0, 1d0, 0d0, 0d0 /) + d_ir1 = (/ 0d0, 0d0, 1d0, 0d0 /) + d_ir2 = (/ pi2o6, pi2o6, pi2o6, 1d0 + pi2o6 /) + + nargs = command_argument_count() + if (nargs < 2) then + write(0,*) 'usage: collier_tensor_driver JOBS.in OUT.txt [MODE] [REQACC]' + stop 2 + end if + call get_command_argument(1, path_in) + call get_command_argument(2, path_out) + mode = 1 + if (nargs >= 3) then + call get_command_argument(3, arg) + read(arg, *) mode + end if + reqacc = -1d0 + if (nargs >= 4) then + call get_command_argument(4, arg) + read(arg, *) reqacc + end if + + open(newunit=unit_in, file=trim(path_in), status='old', action='read', iostat=ios) + if (ios /= 0) then + write(0,*) 'cannot open ', trim(path_in) + stop 2 + end if + read(unit_in, *) njobs, nmax, rmax + + call Init_cll(max(nmax, 2), max(rmax, 1), '') + call SetMode_cll(mode) + if (reqacc > 0d0) call SetReqAcc_cll(reqacc) + + open(newunit=unit_out, file=trim(path_out), status='replace', action='write') + + do ijob = 1, njobs + read(unit_in, *) N, R + read(unit_in, *) mu2 + allocate(mass2(0:max(N-1,1)), MomVec(0:3, max(N-1,1)), MomInv(max(N*(N-1)/2,1))) + mass2 = (0d0, 0d0) + MomVec = (0d0, 0d0) + MomInv = (0d0, 0d0) + do k = 0, N-1 + read(unit_in, *) re, im + mass2(k) = dcmplx(re, im) + end do + do k = 1, N-1 + read(unit_in, *) p + MomVec(:, k) = dcmplx(p, 0d0) + end do + do k = 1, N*(N-1)/2 + read(unit_in, *) re + MomInv(k) = dcmplx(re, 0d0) + end do + + allocate(TN(0:R,0:R,0:R,0:R), TNuv(0:R,0:R,0:R,0:R), TNs(0:R,0:R,0:R,0:R,4), & + TNuv1(0:R,0:R,0:R,0:R), TNerr(0:R), TNerr1(0:R)) + call SetMuUV2_cll(mu2) + call SetMuIR2_cll(mu2) + errmin = 0 + accmax = 0 + do iset = 1, 4 + call SetDeltaUV_cll(d_uv(iset)) + call SetDeltaIR_cll(d_ir1(iset), d_ir2(iset)) + call InitErrFlag_cll() + call InitAccFlag_cll() + TN = (0d0, 0d0) + TNuv = (0d0, 0d0) + if (N == 1) then + call Aten_cll(TN, TNuv, mass2(0:0), R, TNerr) + else + call TNten_cll(TN, TNuv, MomVec(:, 1:N-1), MomInv(1:N*(N-1)/2), mass2(0:N-1), N, R, TNerr) + end if + call GetErrFlag_cll(errflag) + call GetAccFlag_cll(accflag) + errmin = min(errmin, errflag) + accmax = min(accmax, accflag) + TNs(:,:,:,:,iset) = TN + if (iset == 1) then + TNuv1 = TNuv + TNerr1 = TNerr + end if + end do + + write(unit_out, '(A,1X,I0,1X,I0,1X,I0,1X,I0,1X,I0)') 'JOB', ijob, N, R, errmin, accmax + do k = 0, R + write(unit_out, '(A,1X,I0,1X,ES25.16E3)') 'ERR', k, TNerr1(k) + end do + do n0 = 0, R + do n1 = 0, R - n0 + do n2 = 0, R - n0 - n1 + do n3 = 0, R - n0 - n1 - n2 + write(unit_out, '(4(I0,1X),8(ES25.16E3,1X))') n0, n1, n2, n3, & + TNs(n0,n1,n2,n3,1), TNs(n0,n1,n2,n3,2) - TNs(n0,n1,n2,n3,1), & + TNs(n0,n1,n2,n3,3) - TNs(n0,n1,n2,n3,1), TNs(n0,n1,n2,n3,4) - TNs(n0,n1,n2,n3,1) + end do + end do + end do + end do + deallocate(mass2, MomVec, MomInv, TN, TNuv, TNs, TNuv1, TNerr, TNerr1) + end do + close(unit_out) + close(unit_in) +end program collier_tensor_driver diff --git a/vendor/ninjars/tests/poles/collier_reference.json b/vendor/ninjars/tests/poles/collier_reference.json new file mode 100644 index 0000000000..7644c1e14c --- /dev/null +++ b/vendor/ninjars/tests/poles/collier_reference.json @@ -0,0 +1,11240 @@ +[ + { + "name": "massive-tadpole-r3", + "rank": 3, + "mass2": [ + [ + 4, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ] + ], + "mu2": 7, + "n": 1, + "collier_status": { + "error": 0, + "accuracy": 0 + }, + "components": [ + { + "powers": [ + 0, + 0, + 0, + 0 + ], + "finite": [ + 6.2384631517416915, + 0.0 + ], + "uv": [ + 3.999999999999999, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 2 + ], + "finite": [ + -8.23846315174169, + 0.0 + ], + "uv": [ + -4.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 3 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 0 + ], + "finite": [ + -8.23846315174169, + 0.0 + ], + "uv": [ + -4.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 0 + ], + "finite": [ + -8.23846315174169, + 0.0 + ], + "uv": [ + -4.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 0 + ], + "finite": [ + 8.23846315174169, + 0.0 + ], + "uv": [ + 4.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + } + ] + }, + { + "name": "scaleless-lightlike-bubble-r4", + "rank": 4, + "mass2": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 5, + 3, + 0, + 4 + ] + ], + "mu2": 7, + "n": 2, + "collier_status": { + "error": 0, + "accuracy": 0 + }, + "components": [ + { + "powers": [ + 0, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 1.0, + 0.0 + ], + "ir1": [ + -1.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -2.0, + 0.0 + ], + "ir1": [ + 2.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 5.333333333333333, + 0.0 + ], + "ir1": [ + -5.333333333333333, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 3 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -16.0, + 0.0 + ], + "ir1": [ + 16.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 4 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 51.2, + 0.0 + ], + "ir1": [ + -51.2, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 3 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 4, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -1.5, + 0.0 + ], + "ir1": [ + 1.5, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 4.0, + 0.0 + ], + "ir1": [ + -4.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -12.0, + 0.0 + ], + "ir1": [ + 12.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 3 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 38.400000000000006, + 0.0 + ], + "ir1": [ + -38.400000000000006, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 3, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 3.0, + 0.0 + ], + "ir1": [ + -3.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -9.0, + 0.0 + ], + "ir1": [ + 9.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 28.8, + 0.0 + ], + "ir1": [ + -28.8, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -6.75, + 0.0 + ], + "ir1": [ + 6.75, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 21.6, + 0.0 + ], + "ir1": [ + -21.6, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 4, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 16.2, + 0.0 + ], + "ir1": [ + -16.2, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -2.5, + 0.0 + ], + "ir1": [ + 2.5, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 6.666666666666666, + 0.0 + ], + "ir1": [ + -6.666666666666666, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -20.0, + 0.0 + ], + "ir1": [ + 20.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 3 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 64.0, + 0.0 + ], + "ir1": [ + -64.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 3, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 5.0, + 0.0 + ], + "ir1": [ + -5.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -15.0, + 0.0 + ], + "ir1": [ + 15.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 48.0, + 0.0 + ], + "ir1": [ + -48.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -11.25, + 0.0 + ], + "ir1": [ + 11.25, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 36.0, + 0.0 + ], + "ir1": [ + -36.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 3, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 27.0, + 0.0 + ], + "ir1": [ + -27.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 8.333333333333332, + 0.0 + ], + "ir1": [ + -8.333333333333332, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -25.0, + 0.0 + ], + "ir1": [ + 25.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 80.0, + 0.0 + ], + "ir1": [ + -80.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -18.75, + 0.0 + ], + "ir1": [ + 18.75, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 60.0, + 0.0 + ], + "ir1": [ + -60.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 2, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 45.0, + 0.0 + ], + "ir1": [ + -45.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + -31.25, + 0.0 + ], + "ir1": [ + 31.25, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 100.0, + 0.0 + ], + "ir1": [ + -100.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 75.0, + 0.0 + ], + "ir1": [ + -75.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 4, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 125.0, + 0.0 + ], + "ir1": [ + -125.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + } + ] + }, + { + "name": "massive-bubble-r4", + "rank": 4, + "mass2": [ + [ + 9, + 0 + ], + [ + 4, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 4, + 1, + 2, + 0.5 + ] + ], + "mu2": 7, + "n": 2, + "collier_status": { + "error": 0, + "accuracy": 0 + }, + "components": [ + { + "powers": [ + 0, + 0, + 0, + 0 + ], + "finite": [ + 0.45002763743497565, + -0.0 + ], + "uv": [ + 1.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 1 + ], + "finite": [ + -0.153214611531877, + 0.0 + ], + "uv": [ + -0.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 2 + ], + "finite": [ + -3.0996045698848813, + 0.0 + ], + "uv": [ + -2.2708333333333326, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 3 + ], + "finite": [ + 2.2561468481713924, + 0.0 + ], + "uv": [ + 1.421875, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 4 + ], + "finite": [ + 14.581148454865383, + 0.0 + ], + "uv": [ + 8.438281249999994, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 0 + ], + "finite": [ + -0.612858446127508, + 0.0 + ], + "uv": [ + -1.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 1 + ], + "finite": [ + 0.2211597397830022, + 0.0 + ], + "uv": [ + 0.33333333333333337, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 2 + ], + "finite": [ + 2.9516257600320817, + 0.0 + ], + "uv": [ + 1.8125, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 3 + ], + "finite": [ + -2.957368294316261, + 0.0 + ], + "uv": [ + -1.7687499999999998, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 0 + ], + "finite": [ + -2.2702555456986233, + 0.0 + ], + "uv": [ + -1.0208333333333326, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 1 + ], + "finite": [ + 0.4196999789030359, + 0.0 + ], + "uv": [ + -0.015625, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 2 + ], + "finite": [ + 1.2544803545261964, + 0.0 + ], + "uv": [ + 0.7351562499999991, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 0 + ], + "finite": [ + 7.751761548265632, + 0.0 + ], + "uv": [ + 3.8125, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 1 + ], + "finite": [ + -2.446573833567788, + 0.0 + ], + "uv": [ + -1.0187499999999998, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 4, + 0 + ], + "finite": [ + -5.683634524699799, + 0.0 + ], + "uv": [ + -2.014843750000007, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 0 + ], + "finite": [ + -0.306429223063754, + 0.0 + ], + "uv": [ + -0.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 1 + ], + "finite": [ + 0.1105798698915011, + 0.0 + ], + "uv": [ + 0.16666666666666669, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 2 + ], + "finite": [ + 1.4758128800160408, + 0.0 + ], + "uv": [ + 0.90625, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 3 + ], + "finite": [ + -1.4786841471581305, + 0.0 + ], + "uv": [ + -0.8843749999999999, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 0 + ], + "finite": [ + 0.4423194795660044, + 0.0 + ], + "uv": [ + 0.6666666666666667, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 1 + ], + "finite": [ + -0.16971011258932506, + 0.0 + ], + "uv": [ + -0.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 2 + ], + "finite": [ + -1.9261749108109762, + 0.0 + ], + "uv": [ + -1.1125, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 0 + ], + "finite": [ + 0.8393999578060718, + 0.0 + ], + "uv": [ + -0.03125, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 1 + ], + "finite": [ + -0.22614649732850756, + 0.0 + ], + "uv": [ + 0.09687500000000004, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 3, + 0 + ], + "finite": [ + -4.893147667135576, + 0.0 + ], + "uv": [ + -2.0374999999999996, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 0 + ], + "finite": [ + -2.93373476504763, + 0.0 + ], + "uv": [ + -2.020833333333332, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 1 + ], + "finite": [ + 0.6742651477870235, + 0.0 + ], + "uv": [ + 0.3593749999999999, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 2 + ], + "finite": [ + 4.143742720742662, + 0.0 + ], + "uv": [ + 2.4039062499999986, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 0 + ], + "finite": [ + 2.697060591148094, + 0.0 + ], + "uv": [ + 1.4374999999999996, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 1 + ], + "finite": [ + -0.8609285632557935, + 0.0 + ], + "uv": [ + -0.40625, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 2, + 0 + ], + "finite": [ + 0.9152606085334354, + 0.0 + ], + "uv": [ + 0.880468749999999, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 0 + ], + "finite": [ + 4.385011111900791, + 0.0 + ], + "uv": [ + 2.65625, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 1 + ], + "finite": [ + -1.427604701083283, + 0.0 + ], + "uv": [ + -0.8093750000000002, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 1, + 0 + ], + "finite": [ + -5.710418804333132, + 0.0 + ], + "uv": [ + -3.2375000000000007, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 4, + 0, + 0 + ], + "finite": [ + 10.221715182503262, + 0.0 + ], + "uv": [ + 5.897656249999995, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 0 + ], + "finite": [ + -1.225716892255016, + 0.0 + ], + "uv": [ + -2.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 1 + ], + "finite": [ + 0.4423194795660044, + 0.0 + ], + "uv": [ + 0.6666666666666667, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 2 + ], + "finite": [ + 5.903251520064163, + 0.0 + ], + "uv": [ + 3.625, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 3 + ], + "finite": [ + -5.914736588632522, + 0.0 + ], + "uv": [ + -3.5374999999999996, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 0 + ], + "finite": [ + 1.7692779182640177, + 0.0 + ], + "uv": [ + 2.666666666666667, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 1 + ], + "finite": [ + -0.6788404503573002, + 0.0 + ], + "uv": [ + -1.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 2 + ], + "finite": [ + -7.704699643243905, + 0.0 + ], + "uv": [ + -4.45, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 0 + ], + "finite": [ + 3.357599831224287, + 0.0 + ], + "uv": [ + -0.125, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 1 + ], + "finite": [ + -0.9045859893140302, + 0.0 + ], + "uv": [ + 0.3875000000000002, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 3, + 0 + ], + "finite": [ + -19.572590668542304, + 0.0 + ], + "uv": [ + -8.149999999999999, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 0 + ], + "finite": [ + 0.8846389591320089, + 0.0 + ], + "uv": [ + 1.3333333333333335, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 1 + ], + "finite": [ + -0.3394202251786501, + 0.0 + ], + "uv": [ + -0.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 2 + ], + "finite": [ + -3.8523498216219525, + 0.0 + ], + "uv": [ + -2.225, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 0 + ], + "finite": [ + -1.3576809007146005, + 0.0 + ], + "uv": [ + -2.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 1 + ], + "finite": [ + 0.5448474247983712, + 0.0 + ], + "uv": [ + 0.8, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 2, + 0 + ], + "finite": [ + -1.8091719786280605, + 0.0 + ], + "uv": [ + 0.7750000000000004, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 0 + ], + "finite": [ + 5.394121182296188, + 0.0 + ], + "uv": [ + 2.874999999999999, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 1 + ], + "finite": [ + -1.721857126511587, + 0.0 + ], + "uv": [ + -0.8125, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 1, + 0 + ], + "finite": [ + -6.887428506046348, + 0.0 + ], + "uv": [ + -3.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 3, + 0, + 0 + ], + "finite": [ + -11.420837608666265, + 0.0 + ], + "uv": [ + -6.475000000000001, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 0 + ], + "finite": [ + 6.693450341358668, + 0.0 + ], + "uv": [ + 7.687499999999998, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 1 + ], + "finite": [ + -2.1168011047962865, + 0.0 + ], + "uv": [ + -2.4843749999999996, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 2 + ], + "finite": [ + -20.516229462635962, + 0.0 + ], + "uv": [ + -11.860156249999989, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 0 + ], + "finite": [ + -8.467204419185146, + 0.0 + ], + "uv": [ + -9.937499999999998, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 1 + ], + "finite": [ + 3.1765301186488712, + 0.0 + ], + "uv": [ + 3.80625, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 2, + 0 + ], + "finite": [ + -8.604241517702693, + 0.0 + ], + "uv": [ + 2.4132812500000043, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 0 + ], + "finite": [ + -4.233602209592573, + 0.0 + ], + "uv": [ + -4.968749999999999, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 1 + ], + "finite": [ + 1.5882650593244356, + 0.0 + ], + "uv": [ + 1.903125, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 1, + 0 + ], + "finite": [ + 6.3530602372977425, + 0.0 + ], + "uv": [ + 7.6125, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 2, + 0, + 0 + ], + "finite": [ + -18.133831873649306, + 0.0 + ], + "uv": [ + -9.005468749999995, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 0 + ], + "finite": [ + -29.080332103677268, + 0.0 + ], + "uv": [ + -27.624999999999996, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 1 + ], + "finite": [ + 10.341621915119287, + 0.0 + ], + "uv": [ + 10.037500000000001, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 1, + 0 + ], + "finite": [ + 41.36648766047715, + 0.0 + ], + "uv": [ + 40.150000000000006, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 1, + 0, + 0 + ], + "finite": [ + 20.683243830238574, + 0.0 + ], + "uv": [ + 20.075000000000003, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 4, + 0, + 0, + 0 + ], + "finite": [ + 146.66406129784883, + 0.0 + ], + "uv": [ + 118.73515624999999, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + } + ] + }, + { + "name": "massless-offshell-bubble-r4", + "rank": 4, + "mass2": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 0, + 1, + 2, + 3 + ] + ], + "mu2": 7, + "n": 2, + "collier_status": { + "error": 0, + "accuracy": 0 + }, + "components": [ + { + "powers": [ + 0, + 0, + 0, + 0 + ], + "finite": [ + 1.3068528194400548, + 4.440892098500626e-16 + ], + "uv": [ + 0.9999999999999998, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 1 + ], + "finite": [ + -1.960279229160082, + -1.3322676295501878e-15 + ], + "uv": [ + -1.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 2 + ], + "finite": [ + 2.1181190578623226, + 2.960594732333751e-15 + ], + "uv": [ + 1.8333333333333326, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 3 + ], + "finite": [ + -0.710279229160081, + -1.9984014443252818e-15 + ], + "uv": [ + -1.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 4 + ], + "finite": [ + -3.7433798715266846, + 6.8611782921834655e-15 + ], + "uv": [ + -0.2500000000000071, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 0 + ], + "finite": [ + -1.3068528194400546, + -8.881784197001252e-16 + ], + "uv": [ + -1.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 1 + ], + "finite": [ + 2.9470389722134422, + 2.6645352591003757e-15 + ], + "uv": [ + 1.9999999999999991, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 2 + ], + "finite": [ + -5.078398287022404, + -4.440892098500626e-15 + ], + "uv": [ + -3.333333333333334, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 3 + ], + "finite": [ + 6.4808376874802445, + 1.0791367799356522e-14 + ], + "uv": [ + 4.499999999999995, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 0 + ], + "finite": [ + -0.3377467523155464, + 7.401486830834378e-16 + ], + "uv": [ + 0.16666666666666652, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 1 + ], + "finite": [ + -1.4668993576334008, + -1.6653345369377348e-15 + ], + "uv": [ + -1.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 2 + ], + "finite": [ + 5.544867551836632, + 7.815970093361103e-15 + ], + "uv": [ + 3.4666666666666623, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 0 + ], + "finite": [ + 3.626945895826749, + 1.9984014443252818e-15 + ], + "uv": [ + 1.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 1 + ], + "finite": [ + -4.260279229160082, + 1.332267629550191e-16 + ], + "uv": [ + -1.5000000000000036, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 4, + 0 + ], + "finite": [ + -5.593845253460149, + -2.2426505097428165e-15 + ], + "uv": [ + -2.7500000000000036, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 0 + ], + "finite": [ + -0.6534264097200273, + -4.440892098500626e-16 + ], + "uv": [ + -0.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 1 + ], + "finite": [ + 1.4735194861067211, + 1.3322676295501878e-15 + ], + "uv": [ + 0.9999999999999996, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 2 + ], + "finite": [ + -2.539199143511202, + -2.220446049250313e-15 + ], + "uv": [ + -1.666666666666667, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 3 + ], + "finite": [ + 3.2404188437401222, + 5.395683899678261e-15 + ], + "uv": [ + 2.2499999999999973, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 0 + ], + "finite": [ + 0.9823463240711474, + 8.881784197001252e-16 + ], + "uv": [ + 0.6666666666666665, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 1 + ], + "finite": [ + -2.4602792291600815, + -1.9984014443252818e-15 + ], + "uv": [ + -1.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 2 + ], + "finite": [ + 5.016539843042824, + 5.4622972811557705e-15 + ], + "uv": [ + 2.8999999999999986, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 0 + ], + "finite": [ + -0.488966452544467, + -5.551115123125783e-16 + ], + "uv": [ + -0.41666666666666674, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 1 + ], + "finite": [ + 2.154251306244073, + 2.8643754035329043e-15 + ], + "uv": [ + 1.3499999999999992, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 3, + 0 + ], + "finite": [ + -1.420093076386694, + 4.4408920985006104e-17 + ], + "uv": [ + -0.5000000000000009, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 0 + ], + "finite": [ + -1.8112662384222675, + -5.9211894646675e-16 + ], + "uv": [ + -0.833333333333333, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 1 + ], + "finite": [ + 2.2235194861067216, + 1.3322676295501878e-15 + ], + "uv": [ + 1.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 2 + ], + "finite": [ + -1.9799422127276034, + -3.7747582837255346e-16 + ], + "uv": [ + -0.883333333333336, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 0 + ], + "finite": [ + 1.4823463240711474, + 8.881784197001252e-16 + ], + "uv": [ + 0.6666666666666665, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 1 + ], + "finite": [ + -2.136167537496049, + -6.661338147750939e-16 + ], + "uv": [ + -0.9000000000000008, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 2, + 0 + ], + "finite": [ + -0.19980259814756285, + 1.776356839400252e-16 + ], + "uv": [ + -0.13333333333333397, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 0 + ], + "finite": [ + 3.043612562493415, + 1.9984014443252818e-15 + ], + "uv": [ + 1.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 1 + ], + "finite": [ + -5.352474689572139, + -3.1308289294429418e-15 + ], + "uv": [ + -2.5500000000000007, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 1, + 0 + ], + "finite": [ + -3.568316459714759, + -2.0872192862952948e-15 + ], + "uv": [ + -1.7000000000000002, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 4, + 0, + 0 + ], + "finite": [ + 1.8887690506920296, + 8.215650382226158e-16 + ], + "uv": [ + 0.5499999999999994, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 3 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 3, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 3, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 0 + ], + "finite": [ + 2.3024394004578412, + 1.0362081563168126e-15 + ], + "uv": [ + 1.1666666666666665, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 1 + ], + "finite": [ + -3.453659100686762, + -2.3314683517128287e-15 + ], + "uv": [ + -1.75, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 2 + ], + "finite": [ + 4.488212134249015, + 3.1086244689504387e-15 + ], + "uv": [ + 2.333333333333335, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 0 + ], + "finite": [ + -2.3024394004578412, + -1.5543122344752192e-15 + ], + "uv": [ + -1.1666666666666665, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 1 + ], + "finite": [ + 4.284390920824114, + 2.7977620220553948e-15 + ], + "uv": [ + 2.1000000000000005, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 2, + 0 + ], + "finite": [ + 0.9178863668955872, + 7.771561172376096e-16 + ], + "uv": [ + 0.5833333333333337, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 0 + ], + "finite": [ + -1.1512197002289206, + -7.771561172376096e-16 + ], + "uv": [ + -0.5833333333333333, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 1 + ], + "finite": [ + 2.142195460412057, + 1.3988810110276974e-15 + ], + "uv": [ + 1.0500000000000003, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 1, + 0 + ], + "finite": [ + 1.4281303069413713, + 9.325873406851315e-16 + ], + "uv": [ + 0.7000000000000002, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 2, + 0, + 0 + ], + "finite": [ + -1.2243090935164698, + -6.217248937900877e-16 + ], + "uv": [ + -0.46666666666666656, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 4, + 0, + 0, + 0 + ], + "finite": [ + 5.815122740961466, + 3.2640556923979605e-15 + ], + "uv": [ + 2.45, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + } + ] + }, + { + "name": "massive-triangle-r4", + "rank": 4, + "mass2": [ + [ + 9, + 0 + ], + [ + 16, + 0 + ], + [ + 25, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 1, + 0.2, + 0.3, + 0.4 + ], + [ + 0.4, + -0.5, + 0.7, + -0.2 + ] + ], + "mu2": 7, + "n": 3, + "collier_status": { + "error": 0, + "accuracy": 0 + }, + "components": [ + { + "powers": [ + 0, + 0, + 0, + 0 + ], + "finite": [ + -0.031201006055576255, + -4.3843573801953463e-16 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 1 + ], + "finite": [ + 0.0023185154068492662, + -2.2465975982840172e-15 + ], + "uv": [ + -2.862293735361732e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 2 + ], + "finite": [ + 0.2118078798065786, + -3.707561720436572e-16 + ], + "uv": [ + -0.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 3 + ], + "finite": [ + -0.0356821956025256, + 1.1227668469136642e-13 + ], + "uv": [ + 0.050000000000001606, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 4 + ], + "finite": [ + 0.7123837676012449, + 1.0282417442832014e-12 + ], + "uv": [ + 6.237500000000012, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 0 + ], + "finite": [ + 0.009478288242171713, + 1.3736804768046278e-15 + ], + "uv": [ + -6.245004513516506e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 1 + ], + "finite": [ + -0.000539919580761164, + 1.1868535548349603e-14 + ], + "uv": [ + -2.441623292437356e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 2 + ], + "finite": [ + -0.0779156284031839, + 5.06568555371581e-14 + ], + "uv": [ + 0.08333333333333343, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 3 + ], + "finite": [ + 0.007382332043226639, + -1.5543777797221117e-13 + ], + "uv": [ + -0.011249999999992046, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 0 + ], + "finite": [ + 0.2089173098164957, + 4.03058712799291e-15 + ], + "uv": [ + -0.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 1 + ], + "finite": [ + -0.011823827658795293, + -9.61060474639773e-15 + ], + "uv": [ + 0.016666666666667804, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 2 + ], + "finite": [ + 0.26602943076295726, + -2.5404963134195594e-13 + ], + "uv": [ + 2.051250000000008, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 0 + ], + "finite": [ + -0.2328394842480968, + -6.485482732903844e-14 + ], + "uv": [ + 0.2500000000000027, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 1 + ], + "finite": [ + 0.0074081033667599714, + -3.2780735481818326e-13 + ], + "uv": [ + -0.011249999999991087, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 4, + 0 + ], + "finite": [ + 0.8834638167487648, + 2.1099356745365403e-13 + ], + "uv": [ + 6.069999999999993, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 0 + ], + "finite": [ + -0.0024828136787093734, + -2.5626534699738395e-15 + ], + "uv": [ + 5.204170427930421e-18, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 1 + ], + "finite": [ + -0.00027764246605191693, + -1.5216867970897236e-14 + ], + "uv": [ + 9.053088140253962e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 2 + ], + "finite": [ + 0.02659514501925521, + -2.3540004832055286e-14 + ], + "uv": [ + -0.02499999999999943, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 3 + ], + "finite": [ + 0.007242619531956756, + 5.714728297891038e-13 + ], + "uv": [ + -0.007499999999997373, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 0 + ], + "finite": [ + 0.0011931125985653313, + 1.3365969757338385e-14 + ], + "uv": [ + -1.945058697438995e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 1 + ], + "finite": [ + 0.00010856623207226835, + 1.032522309321962e-13 + ], + "uv": [ + -1.1008175707788448e-15, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 2 + ], + "finite": [ + -0.013336226605186617, + 4.58346481275346e-13 + ], + "uv": [ + 0.01229166666666413, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 0 + ], + "finite": [ + 0.025975370306626906, + -9.883244337126032e-15 + ], + "uv": [ + -0.02499999999999938, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 1 + ], + "finite": [ + 0.002368906338968485, + -2.8697307445351573e-13 + ], + "uv": [ + -0.0024999999999935447, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 3, + 0 + ], + "finite": [ + -0.0396971461105544, + -3.7408504390812765e-13 + ], + "uv": [ + 0.036875000000008366, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 0 + ], + "finite": [ + 0.2116330008846781, + -8.347409209441797e-15 + ], + "uv": [ + -0.2499999999999998, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 1 + ], + "finite": [ + -0.01197016242021788, + -6.715285732854068e-14 + ], + "uv": [ + 0.016666666666668196, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 2 + ], + "finite": [ + 0.24159985501370054, + -1.8257478217246666e-13 + ], + "uv": [ + 2.076250000000005, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 0 + ], + "finite": [ + -0.07773141362727015, + 8.854092047866645e-14 + ], + "uv": [ + 0.08333333333333307, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 1 + ], + "finite": [ + 0.0024961049811965375, + 6.83940717399455e-13 + ], + "uv": [ + -0.003750000000004886, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 2, + 0 + ], + "finite": [ + 0.2700434737306911, + -3.161304443601051e-13 + ], + "uv": [ + 2.0483333333333364, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 0 + ], + "finite": [ + 0.07951698572388818, + 2.87290220188235e-14 + ], + "uv": [ + -0.07499999999999875, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 1 + ], + "finite": [ + 0.0072357287010710826, + -1.922312449499483e-14 + ], + "uv": [ + -0.007499999999991788, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 1, + 0 + ], + "finite": [ + -0.0398989419368519, + 3.3589009521188053e-13 + ], + "uv": [ + 0.036875000000000734, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 4, + 0, + 0 + ], + "finite": [ + 0.7371829404913418, + 6.97126971237641e-13 + ], + "uv": [ + 6.219999999999995, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 0 + ], + "finite": [ + 0.013990949126924682, + -2.377945986338424e-15 + ], + "uv": [ + -1.1449174941446927e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 1 + ], + "finite": [ + -0.0016351240936261623, + -6.696664845095264e-15 + ], + "uv": [ + -3.0661237437890065e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 2 + ], + "finite": [ + -0.10264096676785738, + 5.423370141020565e-14 + ], + "uv": [ + 0.11666666666666797, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 3 + ], + "finite": [ + 0.029249903150366793, + 8.320701036337855e-13 + ], + "uv": [ + -0.03749999999997884, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 0 + ], + "finite": [ + -0.004641711827031216, + 1.2950009408755944e-14 + ], + "uv": [ + -4.466912950640278e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 1 + ], + "finite": [ + 0.00044425468713938065, + 7.535655127694265e-14 + ], + "uv": [ + -8.282762496703011e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 2 + ], + "finite": [ + 0.038840135128002135, + 1.125951063279602e-13 + ], + "uv": [ + -0.04124999999999435, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 0 + ], + "finite": [ + -0.1013059584530435, + -1.2601142447158131e-14 + ], + "uv": [ + 0.11666666666666942, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 1 + ], + "finite": [ + 0.009663079609876593, + -2.875820258003614e-13 + ], + "uv": [ + -0.0124999999999852, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 3, + 0 + ], + "finite": [ + 0.1161729534532523, + -3.4661031242262837e-13 + ], + "uv": [ + -0.12374999999998654, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 0 + ], + "finite": [ + 0.0007896703093335513, + -1.180598326611346e-14 + ], + "uv": [ + -5.106592232406726e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 1 + ], + "finite": [ + 0.00015158516429420197, + -3.972795388734317e-14 + ], + "uv": [ + -3.8624702394796095e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 2 + ], + "finite": [ + -0.010019016370511277, + 2.5554480466693836e-13 + ], + "uv": [ + 0.008750000000003814, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 0 + ], + "finite": [ + -0.0004482933016969268, + 9.80800780543032e-14 + ], + "uv": [ + -1.1283292009056645e-15, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 1 + ], + "finite": [ + -5.362539260075265e-05, + 5.587630799357319e-13 + ], + "uv": [ + -3.647018939016006e-15, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 2, + 0 + ], + "finite": [ + -0.00975038498160598, + -3.2132363526612723e-13 + ], + "uv": [ + 0.00875000000001146, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 0 + ], + "finite": [ + -0.10272353855748126, + -2.080566434774608e-14 + ], + "uv": [ + 0.116666666666669, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 1 + ], + "finite": [ + 0.009787311100253944, + -8.288805884640928e-14 + ], + "uv": [ + -0.012499999999990966, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 1, + 0 + ], + "finite": [ + 0.038809274730680285, + 5.243763675995329e-13 + ], + "uv": [ + -0.04125000000000149, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 3, + 0, + 0 + ], + "finite": [ + -0.029902636619545474, + 3.2285594726229464e-13 + ], + "uv": [ + 0.0262500000000148, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 0 + ], + "finite": [ + -0.220135361363972, + -8.633499895668363e-15 + ], + "uv": [ + 0.249999999999999, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 1 + ], + "finite": [ + 0.01312906847315988, + 1.529384423187183e-14 + ], + "uv": [ + -0.016666666666668852, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 2 + ], + "finite": [ + -0.17563089907878782, + 5.882805252203872e-13 + ], + "uv": [ + -2.149166666666649, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 0 + ], + "finite": [ + 0.08072465052717245, + 8.670607297802767e-14 + ], + "uv": [ + -0.08333333333333481, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 1 + ], + "finite": [ + -0.0028211225817049708, + 3.075124045442066e-13 + ], + "uv": [ + 0.003750000000004732, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 2, + 0 + ], + "finite": [ + -0.20492636817611196, + -3.2291122409647137e-13 + ], + "uv": [ + -2.12124999999997, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 0 + ], + "finite": [ + -0.026789747726856557, + -2.7758108380122333e-14 + ], + "uv": [ + 0.024999999999998836, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 1 + ], + "finite": [ + -0.002519013716625508, + 1.2832481910251908e-13 + ], + "uv": [ + 0.0024999999999977735, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 1, + 0 + ], + "finite": [ + 0.013502114008828874, + 5.404452603951447e-13 + ], + "uv": [ + -0.01229166666666812, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 2, + 0, + 0 + ], + "finite": [ + -0.1796235977551692, + 1.2329506182009385e-13 + ], + "uv": [ + -2.1462499999999833, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 0 + ], + "finite": [ + 0.31399739227981094, + -5.746192617445399e-16 + ], + "uv": [ + -0.35000000000000897, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 1 + ], + "finite": [ + -0.03024756866252254, + 4.013300353811573e-13 + ], + "uv": [ + 0.03749999999999143, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 1, + 0 + ], + "finite": [ + -0.11854537945298371, + 4.0691124618366633e-13 + ], + "uv": [ + 0.12375000000000938, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 1, + 0, + 0 + ], + "finite": [ + 0.0299866641186643, + 1.508232672680846e-13 + ], + "uv": [ + -0.02625000000001174, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 4, + 0, + 0, + 0 + ], + "finite": [ + 0.3362458430153924, + 3.109628638829925e-13 + ], + "uv": [ + 6.657499999999946, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + } + ] + }, + { + "name": "infrared-triangle-r3", + "rank": 3, + "mass2": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 5, + 0, + 0, + 5 + ], + [ + 10, + 0, + 0, + 0 + ] + ], + "mu2": 7, + "n": 3, + "collier_status": { + "error": 0, + "accuracy": 0 + }, + "components": [ + { + "powers": [ + 0, + 0, + 0, + 0 + ], + "finite": [ + -0.01398970228530819, + -0.08354311796012936 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + -0.026592600369327788, + 0.031415926535897934 + ], + "ir2": [ + 0.010000000000000002, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 1 + ], + "finite": [ + 0.13587451511981874, + 0.10355632444166754 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.032963001846638945, + -0.1570796326794897 + ], + "ir2": [ + -0.04999999999999999, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 2 + ], + "finite": [ + -0.6793725755990936, + -0.5177816222083377 + ], + "uv": [ + -0.25, + 0.0 + ], + "ir1": [ + 0.08518499076680519, + 0.7853981633974486 + ], + "ir2": [ + 0.24999999999999978, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 3 + ], + "finite": [ + 3.3906906865505606, + -0.02908576694980658 + ], + "uv": [ + 1.2500000000000009, + 0.0 + ], + "ir1": [ + -1.2592582871673592, + -3.926990816987243 + ], + "ir2": [ + -1.2499999999999991, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 0 + ], + "finite": [ + -0.08518499076680552, + -0.7853981633974483 + ], + "uv": [ + -0.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 1 + ], + "finite": [ + 0.4197527623891202, + 1.308996938995747 + ], + "uv": [ + 0.41666666666666674, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 0 + ], + "finite": [ + -0.08518499076680552, + -0.7853981633974483 + ], + "uv": [ + -0.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 1 + ], + "finite": [ + 0.4197527623891202, + 1.308996938995747 + ], + "uv": [ + 0.41666666666666674, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 0 + ], + "finite": [ + 0.06994851142654095, + 0.4177155898006468 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.13296300184663895, + -0.15707963267948966 + ], + "ir2": [ + -0.04999999999999999, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 1 + ], + "finite": [ + -0.6793725755990936, + -0.5177816222083378 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + -0.1648150092331948, + 0.7853981633974486 + ], + "ir2": [ + 0.24999999999999978, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 2 + ], + "finite": [ + 3.396862877995468, + 2.588908111041688 + ], + "uv": [ + 1.2500000000000009, + 0.0 + ], + "ir1": [ + -0.42592495383402573, + -3.9269908169872436 + ], + "ir2": [ + -1.2499999999999991, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 0 + ], + "finite": [ + 0.42592495383402745, + 3.926990816987241 + ], + "uv": [ + 1.2499999999999998, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 0 + ], + "finite": [ + 0.42592495383402745, + 3.926990816987241 + ], + "uv": [ + 1.2499999999999998, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 0 + ], + "finite": [ + -0.3497425571327046, + -2.0885779490032346 + ], + "uv": [ + 0.25, + 0.0 + ], + "ir1": [ + -0.9148150092331948, + 0.7853981633974483 + ], + "ir2": [ + 0.24999999999999978, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 1 + ], + "finite": [ + 3.3968628779954684, + 2.5889081110416887 + ], + "uv": [ + -0.41666666666666474, + 0.0 + ], + "ir1": [ + 1.2407417128326412, + -3.926990816987242 + ], + "ir2": [ + -1.2499999999999982, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 0 + ], + "finite": [ + 1.748712785663524, + 10.442889745016174 + ], + "uv": [ + -3.7499999999999964, + 0.0 + ], + "ir1": [ + 7.074075046165974, + -3.9269908169872423 + ], + "ir2": [ + -1.2499999999999982, + 0.0 + ] + } + ] + }, + { + "name": "massive-box-r4", + "rank": 4, + "mass2": [ + [ + 9, + 0 + ], + [ + 16, + 0 + ], + [ + 25, + 0 + ], + [ + 36, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 0, + 1, + 2, + 0 + ], + [ + 0, + 0, + 1, + 3 + ], + [ + 0, + 2, + 0, + 1 + ] + ], + "mu2": 7, + "n": 4, + "collier_status": { + "error": 0, + "accuracy": 0 + }, + "components": [ + { + "powers": [ + 0, + 0, + 0, + 0 + ], + "finite": [ + 0.0003348639296380139, + -2.717220123559077e-19 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 1 + ], + "finite": [ + -0.0002853430012594223, + 5.381676565543235e-18 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 2 + ], + "finite": [ + 0.003992955695215057, + -2.7570093572806217e-17 + ], + "uv": [ + -8.673617379884035e-19, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 3 + ], + "finite": [ + -0.010699412736280223, + -1.367953034225212e-16 + ], + "uv": [ + 4.85722573273506e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 4 + ], + "finite": [ + -0.12400537764898162, + 2.99266698380569e-15 + ], + "uv": [ + 0.12499999999999936, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 0 + ], + "finite": [ + -0.00025248005985602717, + 5.496086812337727e-17 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 1 + ], + "finite": [ + 0.0002177897078856132, + -1.8002922182581657e-16 + ], + "uv": [ + -7.128629284092192e-18, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 2 + ], + "finite": [ + -0.0030313098099335784, + 4.830181962696253e-16 + ], + "uv": [ + -9.93129189996722e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 3 + ], + "finite": [ + 0.008149191572554794, + -9.53066465419293e-16 + ], + "uv": [ + 1.0633854907737827e-15, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 0 + ], + "finite": [ + 0.003891725028440756, + -8.361476762860644e-17 + ], + "uv": [ + 4.336808689942018e-19, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 1 + ], + "finite": [ + -0.0035954525784596594, + 2.8436766670971673e-16 + ], + "uv": [ + -7.112366251504909e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 2 + ], + "finite": [ + -0.04302970589833246, + -1.1490045939510778e-15 + ], + "uv": [ + 0.04166666666666705, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 0 + ], + "finite": [ + -0.008553960856504365, + 1.206135232082314e-16 + ], + "uv": [ + -6.765421556309548e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 1 + ], + "finite": [ + 0.007941794089718818, + -9.042479657914772e-16 + ], + "uv": [ + 3.3133218391157016e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 4, + 0 + ], + "finite": [ + -0.1344284997747795, + -2.49012444214794e-16 + ], + "uv": [ + 0.1250000000000001, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 0 + ], + "finite": [ + -0.00021866149810563339, + -6.883436195024119e-17 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 1 + ], + "finite": [ + 0.00017849593556950314, + 2.2396027452910954e-16 + ], + "uv": [ + -1.6263032587282567e-18, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 2 + ], + "finite": [ + -0.0027571189812593323, + -6.773505428032884e-16 + ], + "uv": [ + 1.3010426069826053e-18, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 3 + ], + "finite": [ + 0.007008656449953678, + 3.1727390602954313e-15 + ], + "uv": [ + -1.3357370765021415e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 0 + ], + "finite": [ + 0.0001725545488669159, + -7.841382264012533e-17 + ], + "uv": [ + -4.391018798566293e-18, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 1 + ], + "finite": [ + -0.0001337866282651785, + 1.202088054635471e-16 + ], + "uv": [ + -9.75781955236954e-19, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 2 + ], + "finite": [ + 0.002101397110319767, + 4.405987610880659e-16 + ], + "uv": [ + 4.51461784622964e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 0 + ], + "finite": [ + -0.002735301615455826, + 1.3127146950052167e-16 + ], + "uv": [ + 2.5587171270657905e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 1 + ], + "finite": [ + 0.0023739898473921607, + -3.949311942530387e-16 + ], + "uv": [ + 7.45931094670027e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 3, + 0 + ], + "finite": [ + 0.006067767221687813, + -1.5220599617486436e-15 + ], + "uv": [ + 2.0469737016526324e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 0 + ], + "finite": [ + 0.0038323643026074742, + 4.489010693403294e-16 + ], + "uv": [ + -2.168404344971009e-18, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 1 + ], + "finite": [ + -0.0035440039761507366, + -1.5008174012446895e-15 + ], + "uv": [ + 7.24247051220317e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 2 + ], + "finite": [ + -0.043472645845990344, + 3.964191486518483e-15 + ], + "uv": [ + 0.0416666666666662, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 0 + ], + "finite": [ + -0.0029033472341891318, + -3.7406901642392437e-16 + ], + "uv": [ + -7.546047120499111e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 1 + ], + "finite": [ + 0.0026833045719850367, + 1.447544531847486e-15 + ], + "uv": [ + 5.095750210681871e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 2, + 0 + ], + "finite": [ + -0.045129623563868376, + 1.3048532602340378e-15 + ], + "uv": [ + 0.04166666666666661, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 0 + ], + "finite": [ + -0.007865599785905121, + -1.9715119115068293e-15 + ], + "uv": [ + -1.6479873021779667e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 1 + ], + "finite": [ + 0.006895670861356014, + 7.455525798423797e-15 + ], + "uv": [ + 7.806255641895632e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 1, + 0 + ], + "finite": [ + 0.005999043519576852, + 1.4108371509635632e-15 + ], + "uv": [ + 1.012211148232467e-15, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 4, + 0, + 0 + ], + "finite": [ + -0.13667885863954002, + 1.1280537700677592e-14 + ], + "uv": [ + 0.12500000000000236, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 3 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 3, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 2 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 2, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 3, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 0 + ], + "finite": [ + -0.0036494293539193756, + 4.0985010181519313e-16 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 1 + ], + "finite": [ + 0.0033968784047890633, + -1.4942416040078052e-15 + ], + "uv": [ + 4.336808689942018e-18, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 2 + ], + "finite": [ + 0.04589263282587253, + 5.742994431596361e-15 + ], + "uv": [ + -0.041666666666666664, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 0 + ], + "finite": [ + 0.002761706042179406, + 8.94251529439779e-16 + ], + "uv": [ + 1.9081958235744878e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 1 + ], + "finite": [ + -0.002579323682932827, + -2.8591170784186797e-15 + ], + "uv": [ + -1.8257964584655895e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 2, + 0 + ], + "finite": [ + 0.04754089087624674, + -9.875765215257868e-16 + ], + "uv": [ + -0.04166666666666667, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 0 + ], + "finite": [ + 0.0025622590670153194, + -3.3533804785454608e-15 + ], + "uv": [ + 6.938893903907228e-18, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 1 + ], + "finite": [ + -0.0022504481246563793, + 1.230185292400551e-14 + ], + "uv": [ + -7.45931094670027e-17, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 1, + 0 + ], + "finite": [ + -0.001955971864694055, + -1.5314340734626278e-15 + ], + "uv": [ + -1.235990476633475e-16, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 2, + 0, + 0 + ], + "finite": [ + 0.04789365393224785, + 2.0389446404543688e-14 + ], + "uv": [ + -0.04166666666666674, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 1 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 1, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 1, + 0, + 0 + ], + "finite": [ + 0.0, + 0.0 + ], + "uv": [ + 0.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 4, + 0, + 0, + 0 + ], + "finite": [ + -0.15048772168685196, + 3.0488431934715155e-14 + ], + "uv": [ + 0.12499999999999989, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + } + ] + }, + { + "name": "complex-mass-bubble-r3", + "rank": 3, + "mass2": [ + [ + 9, + -0.2 + ], + [ + 4, + -0.1 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 4, + 1, + 2, + 0.5 + ] + ], + "mu2": 7, + "n": 2, + "collier_status": { + "error": 0, + "accuracy": 0 + }, + "components": [ + { + "powers": [ + 0, + 0, + 0, + 0 + ], + "finite": [ + 0.4494503033543715, + 0.033482537342261254 + ], + "uv": [ + 1.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 1 + ], + "finite": [ + -0.15305840391395908, + -0.008748242432611825 + ], + "uv": [ + -0.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 2 + ], + "finite": [ + -3.100892634333094, + 0.032554951224468255 + ], + "uv": [ + -2.2708333333333326, + 0.07500000000000001 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 0, + 3 + ], + "finite": [ + 2.2570444910263427, + -0.03042613082648199 + ], + "uv": [ + 1.4218749999999991, + -0.05000000000000002 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 0 + ], + "finite": [ + -0.6122336156558363, + -0.0349929697304473 + ], + "uv": [ + -1.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 1 + ], + "finite": [ + 0.22095532384890648, + 0.011550758827908921 + ], + "uv": [ + 0.33333333333333337, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 1, + 2 + ], + "finite": [ + 2.952871599149647, + -0.04339281724364331 + ], + "uv": [ + 1.8124999999999996, + -0.06666666666666668 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 0 + ], + "finite": [ + -2.272310169899695, + 0.07587029682912672 + ], + "uv": [ + -1.0208333333333326, + 0.07500000000000001 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 2, + 1 + ], + "finite": [ + 0.42028696230660567, + -0.026736820107789494 + ], + "uv": [ + -0.015625000000000222, + -0.01666666666666667 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 0, + 3, + 0 + ], + "finite": [ + 7.756454214182147, + -0.18525898649344263 + ], + "uv": [ + 3.8124999999999964, + -0.20000000000000007 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 0 + ], + "finite": [ + -0.30611680782791817, + -0.01749648486522365 + ], + "uv": [ + -0.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 1 + ], + "finite": [ + 0.11047766192445324, + 0.005775379413954461 + ], + "uv": [ + 0.16666666666666669, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 0, + 2 + ], + "finite": [ + 1.4764357995748234, + -0.021696408621821654 + ], + "uv": [ + 0.9062499999999998, + -0.03333333333333334 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 0 + ], + "finite": [ + 0.44191064769781296, + 0.023101517655817843 + ], + "uv": [ + 0.6666666666666667, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 1, + 1 + ], + "finite": [ + -0.1695631666564299, + -0.008473928425001956 + ], + "uv": [ + -0.25, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 1, + 2, + 0 + ], + "finite": [ + 0.8405739246132113, + -0.05347364021557899 + ], + "uv": [ + -0.031250000000000444, + -0.03333333333333334 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 0 + ], + "finite": [ + -2.9351761414464144, + 0.041218020345399946 + ], + "uv": [ + -2.0208333333333326, + 0.07500000000000001 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 0, + 1 + ], + "finite": [ + 0.6746317122912505, + -0.01402592747028656 + ], + "uv": [ + 0.35937499999999967, + -0.01666666666666667 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 2, + 1, + 0 + ], + "finite": [ + 2.698526849165002, + -0.05610370988114624 + ], + "uv": [ + 1.4374999999999987, + -0.06666666666666668 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 0, + 3, + 0, + 0 + ], + "finite": [ + 4.386916607060363, + -0.06720770797171545 + ], + "uv": [ + 2.6562499999999982, + -0.10000000000000002 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 0 + ], + "finite": [ + -1.2244672313116727, + -0.0699859394608946 + ], + "uv": [ + -2.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 1 + ], + "finite": [ + 0.44191064769781296, + 0.023101517655817843 + ], + "uv": [ + 0.6666666666666667, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 0, + 2 + ], + "finite": [ + 5.905743198299294, + -0.08678563448728661 + ], + "uv": [ + 3.624999999999999, + -0.13333333333333336 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 0 + ], + "finite": [ + 1.7676425907912519, + 0.09240607062327137 + ], + "uv": [ + 2.666666666666667, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 1, + 1 + ], + "finite": [ + -0.6782526666257196, + -0.03389571370000782 + ], + "uv": [ + -1.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 0, + 2, + 0 + ], + "finite": [ + 3.3622956984528454, + -0.21389456086231595 + ], + "uv": [ + -0.12500000000000178, + -0.13333333333333336 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 0 + ], + "finite": [ + 0.8838212953956259, + 0.046203035311635686 + ], + "uv": [ + 1.3333333333333335, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 0, + 1 + ], + "finite": [ + -0.3391263333128598, + -0.01694785685000391 + ], + "uv": [ + -0.5, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 1, + 1, + 0 + ], + "finite": [ + -1.3565053332514392, + -0.06779142740001565 + ], + "uv": [ + -2.0, + 0.0 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 1, + 2, + 0, + 0 + ], + "finite": [ + 5.397053698330004, + -0.11220741976229248 + ], + "uv": [ + 2.8749999999999973, + -0.13333333333333336 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 0 + ], + "finite": [ + 6.6914166468778244, + 0.15514487972905172 + ], + "uv": [ + 7.6875, + -0.07500000000000001 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 0, + 1 + ], + "finite": [ + -2.1159186288709044, + -0.058002464142230065 + ], + "uv": [ + -2.484375, + 0.01666666666666667 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 0, + 1, + 0 + ], + "finite": [ + -8.463674515483618, + -0.23200985656892026 + ], + "uv": [ + -9.9375, + 0.06666666666666668 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 2, + 1, + 0, + 0 + ], + "finite": [ + -4.231837257741809, + -0.11600492828446013 + ], + "uv": [ + -4.96875, + 0.03333333333333334 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + }, + { + "powers": [ + 3, + 0, + 0, + 0 + ], + "finite": [ + -29.077961760878686, + -0.3073963010132712 + ], + "uv": [ + -27.624999999999993, + 0.40000000000000013 + ], + "ir1": [ + 0.0, + 0.0 + ], + "ir2": [ + 0.0, + 0.0 + ] + } + ] + } +] diff --git a/vendor/ninjars/tests/poles/compare_madloop.py b/vendor/ninjars/tests/poles/compare_madloop.py new file mode 100644 index 0000000000..d769534c69 --- /dev/null +++ b/vendor/ninjars/tests/poles/compare_madloop.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 +"""Compare bare-loop pole selections with a common point-wise scale.""" +import argparse +import json +import math +from pathlib import Path + +HERE = Path(__file__).resolve().parent +KEYS = ('born', 'finite', 'single', 'double') + + +def main(): + global HERE + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--output', type=Path, required=True) + args = parser.parse_args() + HERE = args.output.resolve() + failures, comparisons, counts, worst = [], [], {}, 0.0 + expected_cases = ['qcd-z', 'qcd-tt', 'ew-mumu', 'li-h'] + configurations = switch_rows = 0 + def status_ok(status, backend, ct): + if ct in (1, 2): + return status == 110 + if ct in (4, 5): + return status == 120 + if ct == -1: + h, t, u = status//100, (status//10)%10, status%10 + return t in (1, 2) and ((h == 2 and u == backend) or (backend == 8 and h == 3 and u == 2)) + return False + def validate_rows(data, path): + dimensions = list(map(int, (path.parent / 'dimensions.dat').read_text().split())) + nso = dimensions[1] + expected = {(point, order) for point in range(1, 4) for order in range(nso+1)} + rows = data['records'] + keys = [(r['point'], r['split_order']) for r in rows] + if len(keys) != len(expected) or set(keys) != expected: + failures.append(dict(case=path.parent.parent.name, reason='missing/duplicate/unexpected point/order rows', path=str(path))) + for row in rows: + if not status_ok(row['status'], data['backend'], data['ctmode']): + failures.append(dict(case=path.parent.parent.name, reason='unexpected evaluation status', path=str(path), status=row['status'])) + if not all(math.isfinite(row[key]) for key in KEYS): + failures.append(dict(case=path.parent.parent.name, reason='nonfinite result', path=str(path))) + return expected + for name in expected_cases: + work = HERE / 'processes' / name + required = {(backend, mode, 1) for backend in (7, 8) for mode in range(4)} + required |= {(8, mode, 4) for mode in range(4)} + if name.startswith('qcd-'): + required |= {(8, mode, ct) for mode in range(4) for ct in (-1, 2, 4, 5)} + results = {} + for path in sorted(work.glob('backend-*-mode-*-ct-*/result.json')): + data = json.loads(path.read_text()) + key = data['backend'], data['mode'], data['ctmode'] + validate_rows(data, path) + configurations += 1 + results[key] = {(r['point'], r['split_order']): r for r in data['records']} + counts[work.name + '/' + path.parent.name] = {str(s): sum(r['status'] == s for r in data['records']) + for s in sorted({r['status'] for r in data['records']})} + missing = sorted(required - set(results)) + if missing: + failures.append(dict(case=name, reason='missing required configurations', missing=missing)) + if not results: + continue + def compare(label, a, b, indices=KEYS): + nonlocal worst + assert a.keys() == b.keys(), label + n = 0 + for point in a: + scale = max(abs(r[point][field]) for r in results.values() for field in KEYS) + for field in indices: + x, y = a[point][field], b[point][field] + tolerance = 1e-7 * max(abs(x), abs(y)) + 1e-10 * scale + ratio = abs(x-y) / tolerance if tolerance else (0 if x == y else float('inf')) + worst = max(worst, ratio) + n += 1 + if not math.isfinite(x) or not math.isfinite(y) or ratio > 1: + failures.append(dict(case=work.name, comparison=label, point=point, + field=field, a=x, b=y, tolerance=tolerance, ratio=ratio)) + comparisons.append(dict(case=work.name, comparison=label, values=n)) + for (backend, mode, ct), rows in results.items(): + if backend == 8 and (7, mode, 1) in results: + compare(f'NinjaRS CTMode={ct},mode={mode} vs COLLIER', rows, results[7, mode, 1]) + if mode and (backend, 0, ct) in results: + compare(f'backend={backend},CTMode={ct},mode={mode} finite unchanged', + rows, results[backend, 0, ct], ('born', 'finite')) + for backend, ct in sorted({(b, c) for b, _, c in results}): + if all((backend, mode, ct) in results for mode in range(4)): + total, uv, ir, none = (results[backend, mode, ct] for mode in range(4)) + sum_poles = {point: dict(uv[point], single=uv[point]['single']+ir[point]['single'], + double=uv[point]['double']+ir[point]['double']) for point in total} + # Loop-induced returned quantities are squared amplitudes and + # need not be additive in the selected amplitude-level poles. + if not name.startswith('li-'): + compare(f'backend={backend},CTMode={ct} UV+IR=both', total, sum_poles, ('single', 'double')) + zero = {point: dict(none[point], single=0, double=0) for point in none} + compare(f'backend={backend},CTMode={ct} no-pole selector', none, zero, ('single', 'double')) + compare(f'backend={backend},CTMode={ct} UV has no double pole', uv, zero, ('double',)) + for path in sorted(work.glob('filtered-backend-*-mode-*-ct-*/result.json')): + data = json.loads(path.read_text()) + validate_rows(data, path) + configurations += 1 + key = data['backend'], max(0, data['mode']), data['ctmode'] + rows = {(r['point'], r['split_order']): r for r in data['records']} + if key in results: + compare(f'backend={key[0]},mode={key[1]},CTMode={key[2]} normal filters', rows, results[key]) + for path in sorted(work.glob('*backend-*-mode-*-ct-*/switch_values.dat')): + data = json.loads((path.parent / 'result.json').read_text()) + switched = {} + for line in path.read_text().splitlines(): + fields = line.split() + iteration, mode, point, split_order, status = map(int, fields[:5]) + if not status_ok(status, data['backend'], data['ctmode']): + failures.append(dict(case=name, reason='unexpected runtime-switch status', path=str(path), status=status)) + rows = switched.setdefault((iteration, mode), {}) + if (point, split_order) in rows: + failures.append(dict(case=name, reason='duplicate runtime-switch row', path=str(path))) + rows[point, split_order] = dict(zip(KEYS, map(float, fields[5:9]))) + switch_rows += 1 + expected_modes = list(enumerate([0, 1, 2, 3, 0, 2, 1, 0], 1)) + expected_points = validate_rows(data, path.parent / 'result.json') + if set(switched) != set(expected_modes) or any(set(rows) != expected_points for rows in switched.values()): + failures.append(dict(case=name, reason='incomplete runtime-switch sequence', path=str(path))) + for (iteration, mode), rows in switched.items(): + key = data['backend'], mode, data['ctmode'] + if key in results: + filtered = path.parent.name.startswith('filtered-') + compare(f'backend={key[0]},CTMode={key[2]},filters={filtered} runtime switch {iteration} to mode {mode}', rows, results[key]) + if name == 'qcd-tt': + for relative in ['backend-7-mode-0-ct-1/switch_values.dat', + 'backend-8-mode-0-ct-1/switch_values.dat', + 'filtered-backend-8-mode--1-ct-1/switch_values.dat', + 'filtered-backend-8-mode-1-ct-1/result.json']: + if not (work / relative).is_file(): + failures.append(dict(case=name, reason='missing required cache/filter control', path=relative)) + report = dict(passed=not failures, comparisons=comparisons, failure_count=len(failures), + worst_normalized_error=worst, failures=failures, statuses=counts, + validated_configurations=configurations, runtime_switch_rows=switch_rows, + loop_induced_additivity_checked=False) + (HERE / 'process_comparison.json').write_text(json.dumps(report, indent=2) + '\n') + print(json.dumps(dict(passed=not failures, comparisons=len(comparisons), failures=len(failures), + worst_normalized_error=worst), indent=2)) + if failures: + raise SystemExit(1) + + +if __name__ == '__main__': + main() diff --git a/vendor/ninjars/tests/poles/generate_collier_reference.py b/vendor/ninjars/tests/poles/generate_collier_reference.py new file mode 100644 index 0000000000..39607ff423 --- /dev/null +++ b/vendor/ninjars/tests/poles/generate_collier_reference.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +"""Regenerate separated tensor-pole fixtures using an installed COLLIER.""" +import argparse +import hashlib +import json +import math +import os +from pathlib import Path +import shlex +import subprocess + +HERE = Path(__file__).resolve().parent + + +def sha(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--collier', type=Path, required=True, help='COLLIER installation prefix') + parser.add_argument('--work-dir', type=Path, required=True, help='temporary compilation and raw-output directory') + parser.add_argument('--output', type=Path, required=True, help='regenerated reference JSON') + parser.add_argument('--fc', default=os.environ.get('FC', 'gfortran')) + args = parser.parse_args() + prefix, work, output = args.collier.resolve(), args.work_dir.resolve(), args.output.resolve() + if work == HERE or HERE in work.parents: + parser.error('--work-dir must be outside the retained test-source directory') + work.mkdir(parents=True, exist_ok=True) + output.parent.mkdir(parents=True, exist_ok=True) + libraries = [directory / name for directory in (prefix, prefix / 'lib') + for name in ('libcollier.so', 'libcollier.a')] + library = next((p for p in libraries if p.exists()), None) + if library is None: + parser.error('cannot locate libcollier.so or libcollier.a below --collier') + command = shlex.split(args.fc) + ['-O2', '-I'+str(prefix / 'include'), + str(HERE / 'collier_poles.f90'), '-L'+str(library.parent), '-lcollier', + '-Wl,-rpath,'+str(library.parent), '-o', str(work / 'collier_poles')] + with (work / 'build.log').open('w') as stream: + subprocess.run(command, cwd=work, stdout=stream, stderr=subprocess.STDOUT, check=True) + raw = work / 'collier_poles.txt' + with (work / 'evaluation.log').open('w') as stream: + subprocess.run([str(work / 'collier_poles'), str(HERE / 'collier_jobs.in'), str(raw)], + cwd=work, stdout=stream, stderr=subprocess.STDOUT, check=True) + cases = json.loads((HERE / 'tensor_cases.json').read_text()) + results, current = [], None + for line in raw.read_text().splitlines(): + fields = line.split() + if fields[0] == 'JOB': + current = dict(cases[int(fields[1])-1]) + current['collier_status'] = dict(error=int(fields[4]), accuracy=int(fields[5])) + current['components'] = [] + results.append(current) + elif fields[0] != 'ERR': + values = list(map(float, fields[4:])) + current['components'].append(dict(powers=list(map(int, fields[:4])), + **{name: values[2*i:2*i+2] for i, name in enumerate(('finite', 'uv', 'ir1', 'ir2'))})) + if len(results) != len(cases): + raise RuntimeError('COLLIER output omitted one or more cases') + for case in results: + if case['collier_status'] != dict(error=0, accuracy=0): + raise RuntimeError('COLLIER flagged ' + case['name'] + ': ' + str(case['collier_status'])) + if len(case['components']) != math.comb(case['rank']+4, 4): + raise RuntimeError('incomplete COLLIER tensor for ' + case['name']) + output.write_text(json.dumps(results, indent=2) + '\n') + provenance = dict(library_sha256=sha(library), + compiler=subprocess.check_output(shlex.split(args.fc)+['--version'], text=True).splitlines()[0], + driver_sha256=sha(HERE / 'collier_poles.f90'), + inputs_sha256=sha(HERE / 'collier_jobs.in'), + cases_sha256=sha(HERE / 'tensor_cases.json'), + raw_output_sha256=sha(raw), reference_sha256=sha(output), command=command) + output.with_suffix('.provenance.json').write_text(json.dumps(provenance, indent=2) + '\n') + print(json.dumps(dict(cases=len(results), tensor_components=sum(len(c['components']) for c in results), + reference_sha256=sha(output)), indent=2)) + + +if __name__ == '__main__': + main() diff --git a/vendor/ninjars/tests/poles/madloop-validation.json b/vendor/ninjars/tests/poles/madloop-validation.json new file mode 100644 index 0000000000..2afcf28b84 --- /dev/null +++ b/vendor/ninjars/tests/poles/madloop-validation.json @@ -0,0 +1,304 @@ +{ + "schema": "madloop-bare-uv-ir-validation-v1", + "scope": "Bare loop contribution only; UFO UV and R2 counterterms removed in disposable generated validation copies.", + "source_base_revision": "3ed442f0444b7e3367da123690b00e12c9d068dc", + "passed": true, + "tolerance": "abs(a-b) <= 1e-7*max(abs(a),abs(b)) + 1e-10*S; S is the largest Born/Laurent magnitude for the same process point across compared modes and tools.", + "points_per_process": 3, + "helicity_policy": "Full helicity and color sums", + "core_masses": "Real masses, all widths set to zero in retained parameter cards", + "configuration_count": 74, + "point_evaluations": 222, + "result_rows_including_total_and_split_order": 444, + "comparison_checks": 187, + "worst_normalized_error": 8.375047153834681e-05, + "loop_induced_additivity_checked": false, + "loop_induced_comparison": "Each selected squared loop amplitude is compared directly with COLLIER; no general additivity of squared UV/IR amplitudes is asserted.", + "pole_modes": { + "-1": "legacy (filter seeding only)", + "0": "both", + "1": "UV", + "2": "IR", + "3": "none" + }, + "cases": [ + { + "case": "qcd-z", + "process": "u u~ > z [virt=QCD]", + "model": "loop_sm", + "points": "points/qcd-1.dat", + "points_sha256": "53591173c9e24c846c5594434484f32b1f6fb117dcc4e2f509156b9349275f5c", + "parameter_card": "cards/qcd-z.dat", + "parameter_card_sha256": "49f08ecba557b9ed0e6760813b7eac089319264252f840fdd0a485d685f60a7d", + "collier_CTModeRun": [ + 1 + ], + "ninjars_CTModeRun": [ + -1, + 1, + 2, + 4, + 5 + ], + "pole_modes": [ + 0, + 1, + 2, + 3 + ], + "generated_bare_patch": [ + { + "path": "loop_matrix.f", + "original_sha256": "de647f1de1d5bc407d0ad2617ebb19da47cd24a06944e9c172cac633c163605b", + "bare_sha256": "740454f0f35baf95ce3f63c4aefa2986126af5942efea1ad116074e45265c008" + }, + { + "path": "mp_compute_loop_coefs.f", + "original_sha256": "4892330f3322cde75680e46dc66a97890e5a9cab46c4658bd85f52cf655c63cd", + "bare_sha256": "ee3ebc4634b587ba416d89d658b0904118ade184ae404da94e6763c636bb8afc" + } + ], + "compiled_driver_sha256": "33e07ad3a9bc23ac1f9d8c04f588c398c366af80977f8ba21d274ae2b6a16f6c" + }, + { + "case": "qcd-tt", + "process": "g g > t t~ [virt=QCD]", + "model": "loop_sm", + "points": "points/qcd-2.dat", + "points_sha256": "5622dfd2708e21acf243197ae26156185ee3404f51c2a0e9583f88c0a54de4bf", + "parameter_card": "cards/qcd-tt.dat", + "parameter_card_sha256": "49f08ecba557b9ed0e6760813b7eac089319264252f840fdd0a485d685f60a7d", + "collier_CTModeRun": [ + 1 + ], + "ninjars_CTModeRun": [ + -1, + 1, + 2, + 4, + 5 + ], + "pole_modes": [ + 0, + 1, + 2, + 3 + ], + "generated_bare_patch": [ + { + "path": "loop_matrix.f", + "original_sha256": "4bcb87f4e89e4b0d4188adfbebe91798d4a099f789f2b85d7966d6206645cb5d", + "bare_sha256": "3b416eac3a5296d1c9e200f9d8478f906071a42d23bcd338a6e8d640cf464c92" + }, + { + "path": "mp_compute_loop_coefs.f", + "original_sha256": "b6f3cbcd902b3b5ee167eb01ee95fa6d6fab30ba6ace4dece0d70513be90659b", + "bare_sha256": "528abc3a8a7e13d4a566b91a8bb20ff7fbe5973fa895bb1ee76e021532083f02" + } + ], + "compiled_driver_sha256": "a6cab82adcfab402b522726f7b0298a3944eb914a92f7778a112b0d28ac54378" + }, + { + "case": "ew-mumu", + "process": "e+ e- > mu+ mu- [virt=QED]", + "model": "loop_qcd_qed_sm_Gmu", + "points": "points/ew-2.dat", + "points_sha256": "027faad8e4b32ba0113a1cbb43cbbe3efd1bdc7385bc91b14371e2a48637c44b", + "parameter_card": "cards/ew-mumu.dat", + "parameter_card_sha256": "f1832ee506b45441279a4076cb274ba37899541f8bd7ec0d3494cfb9c24aa9d5", + "collier_CTModeRun": [ + 1 + ], + "ninjars_CTModeRun": [ + 1, + 4 + ], + "pole_modes": [ + 0, + 1, + 2, + 3 + ], + "generated_bare_patch": [ + { + "path": "loop_matrix.f", + "original_sha256": "50ffd7bd313842514eceb33ea3cfa49ec5a70a735edda4bb508380cc95da57b5", + "bare_sha256": "ad04f8d5cff82814fcee3dd05c7a0a864e2fed1b0268a3ea88f8935ce4bc3500" + }, + { + "path": "mp_compute_loop_coefs.f", + "original_sha256": "b86e5f23ade56534c6126394b25916160c5853f37d5913ca8d2eb88e8f19fc4b", + "bare_sha256": "9c6e42dc1f91cfe246a09d3af56b97f24e7839365b4f3b812746f48b8bc21aa0" + } + ], + "compiled_driver_sha256": "9bd58cff0ff7ed7c4f4bdb631fe76717c8e175dbbab43bc0bdb433e1c6345e52" + }, + { + "case": "li-h", + "process": "g g > h [sqrvirt=QCD]", + "model": "loop_sm", + "points": "points/control-gg-h.dat", + "points_sha256": "a15a02856f75e085f051335cd00d35fa8aa69d19c96bf8c8535ebefcf35330c7", + "parameter_card": "cards/li-h.dat", + "parameter_card_sha256": "49f08ecba557b9ed0e6760813b7eac089319264252f840fdd0a485d685f60a7d", + "collier_CTModeRun": [ + 1 + ], + "ninjars_CTModeRun": [ + 1, + 4 + ], + "pole_modes": [ + 0, + 1, + 2, + 3 + ], + "generated_bare_patch": [ + { + "path": "loop_matrix.f", + "original_sha256": "180d611d1c277766ded79121d37cd3e86d4a1de2054874f80d99dc97a56390e8", + "bare_sha256": "c8ed46db87c93964819fc89103f32b70971e795377f764ede19cd128e1db3c92" + }, + { + "path": "mp_compute_loop_coefs.f", + "original_sha256": "fdc2eb1c9590dbb7534cfb1a7b98c1348457889dfb6a95d28db4712af8f071bf", + "bare_sha256": "d2185aedd173867f36978ca0ff3a6bdee15d4a7b8e93dae62fc21f78379c1e6f" + } + ], + "compiled_driver_sha256": "a3837b26811f3169fc37ca24d59f5062557b8036c6ab16334ab09940fe4d1023" + } + ], + "status_rows": { + "110": 252, + "120": 144, + "218": 48 + }, + "status_meanings": { + "110": "Fixed DP mode; no stability acceptance requested", + "120": "Forced higher-precision mode; no stability acceptance requested", + "218": "Stable NinjaRS DP under normal automatic stability checking" + }, + "cache_filter_controls": { + "case": "qcd-tt", + "normal_runtime_backends": [ + 7, + 8 + ], + "mode_sequence": [ + 0, + 1, + 2, + 3, + 0, + 2, + 1, + 0 + ], + "switch_series": 3, + "switch_rows": 144, + "switch_status_rows": { + "110": 144 + }, + "legacy_filter_seed_mode": -1, + "filter_reuse_mode": 1, + "filtered_configurations": 2, + "method": "Seed saved filters in legacy combined mode, cycle the same warm context through all explicit modes, then reuse the saved combined filters in a fresh UV-only run." + }, + "bare_patch_definition": { + "loop_matrix.f": "Immediately after UVCT_REQ_SO_DONE=.TRUE., set AMPL(:,1:NCTAMPS)=0 before interference/squaring.", + "mp_compute_loop_coefs.f": "Immediately after MP_UVCT_REQ_SO_DONE=.TRUE., set AMPL(:,1:NCTAMPS)=0 and DP_AMPL(:,1:NCTAMPS)=0 before interference/squaring.", + "production_source_changed_for_test": false, + "numerator_changed_for_test": false + }, + "models": { + "loop_sm": { + "aggregate_algorithm": "SHA256 over sorted top-level Python filename, NUL byte and exact file bytes", + "top_level_python_sha256": "e2bf6c1b6b678301ff10457f505335f0b13023ddf090e296eb50d105fc30110a", + "files": { + "CT_couplings.py": "ec0ab5fab1d693e246284c1d82d9ef5219b274dedb909bdd3f6187cbc1ed7b02", + "CT_parameters.py": "fe89b26fcc375dbffc40003d7e064b2e66316d8d4daa897cd7a9c0ae386cfb3d", + "CT_vertices.py": "6f125c6cffdd94491fb6167411b23700468663d46c60cee90cdb675ad5659b0f", + "__init__.py": "f313e3030c3b3a5d8da2db3ed1b8ad487ce45dfb21810b15a1f717b9a4147d4b", + "coupling_orders.py": "c75540ae451aaca4c8f497aed727a252a2960c65c9d6174e94039af8a0615ae0", + "couplings.py": "a91df246f6a68325ead56ec30d49c0586fb9b39451ae62a5c527896acb45014f", + "function_library.py": "4f61390f3cd3ba3baa6b37a908f0f3129c457bca2d4e2b2fa8806c3ac31f9ea3", + "lorentz.py": "2552626d868a558a321c84fbafd14b43dafd2f4bbd45cf04a7693cb1caac3dc1", + "object_library.py": "83eadcfc5e57b633e78cfd8023d1b594d383344d0badbc8c2d07d3a05f7e65ee", + "parameters.py": "5de44653a32f4c213b6fc0696f3585f36bc34830e64d713c7e268814c847b58f", + "particles.py": "ce9d3cf9e7bc05dff7d247acc858e6f5eea982c5e8cfb702821b1dab317ed0b0", + "vertices.py": "89a4311b8305295e3019e1570c57519c2614b784b1f9ee9637a54ee9d2f07b82", + "write_param_card.py": "14dc8cc41f72666cfe28e63b9c26292315b2ecae76e4f31652ee665b663469f9" + }, + "source": "models/loop_sm in the recorded MadGraph source base revision" + }, + "loop_qcd_qed_sm_Gmu": { + "aggregate_algorithm": "SHA256 over sorted top-level Python filename, NUL byte and exact file bytes", + "top_level_python_sha256": "5dd9a66ef0b501f643251a65d9fa21a8be744b04959e1fcecd13eea51476a0e1", + "files": { + "._object_library.py": "e372c03cd0386f25cb181b0e08064bfee36b06798c0c4f94158f26929f04531d", + "CT_couplings.py": "652875148e2442c47d65d7b65295463e95f2d809bfbc02f0b4678d1efa96941f", + "CT_parameters.py": "275cd4426af5b7b0fe51b34fece99427d9ad02b9916aa8e7c3e80652b8feb18e", + "CT_vertices.py": "e2db355896f0eb04583664fb1ca3524cfac005e1cf60f2daed656f04ae6de1fc", + "__init__.py": "b525fab28896c3b483d5019ad6ecee22b361c23425e85bb010f0e4186088818e", + "coupling_orders.py": "d691ddb0315c70991cc248c5f6eb32572326f06fd9583556234944acde36c5d1", + "couplings.py": "a650df30e63c2295bd1c50c375b4f3a2c4b6f223662b85307d8cb4760b39d72d", + "function_library.py": "386190df018e0ee351a4a973b7f0bf1b285a63e4bdbac51fa615581e86fc70d1", + "lorentz.py": "128bc035e18636ba7984e3dd2460393f2cf40dc64f252ca496a08a40c679e0cc", + "object_library.py": "af45adfc62c07fc059866598f7b9f0ce840ac4785ce114e5315514ef0b4e9d1b", + "parameters.py": "02e551e6243ceef645178b67582a8799b4de9854abc9feba920528fe581f2cb2", + "particles.py": "1e9377aede7df810eae946c66ea09f131b1d88209393c0b97ab2ed141c99f17f", + "vertices.py": "179bcea617b52ecef42fcb869d305060e34e57c6a965518cbabdcd89988791df", + "write_param_card.py": "38ef99ae7eba1def565daebe0ec601d0f54c26368fced01718d50a83d195b3f2" + }, + "original_source_url": "http://madgraph.phys.ucl.ac.be/Downloads/models/loop_qcd_qed_sm_Gmu.tgz", + "exact_used_source_archive": "https://github.com/MadGraphTeam/MadGraph7/raw/19d67c8605337c176680878a521b3a014176a7fb/docs/benchmarkfolder/policy-v2/ew-model-source-final-v1/loop_qcd_qed_sm_Gmu-actual-source.tar.gz", + "archive_sha256": "495514a1f52f4d3b7445cbaac87dfe87d07d628a01680a3bf0457408b13fb7dc", + "note": "Exact previously retained converted UFO source, not a newly downloaded or unmodified upstream archive." + } + }, + "reference": { + "collier_version": "1.2.9", + "COLLIER_mode": 1, + "library_sha256": "1753ed686ab3021c149d6ecf80fe8c46cd4276bf8b5f891820c535603d39e127" + }, + "ninjars_candidate": { + "abi_version": 4, + "library_sha256": "43ed42c237412a81838a6c4c0b4f89015a0785b4f331bdb2fbf01020124c67c7", + "configuration_sha256": "45b48d5991cef9b669c2942abb9020a864f462103c4943cb7e307235f84ba25c", + "upstream_pins": { + "ninjars": "git+https://github.com/alphal00p/ninjars?rev=41a4c00e7635e3ab188fc26bacf0aae6941e8082#41a4c00e7635e3ab188fc26bacf0aae6941e8082", + "ninjars-symbolica": "git+https://github.com/alphal00p/ninjars?rev=41a4c00e7635e3ab188fc26bacf0aae6941e8082#41a4c00e7635e3ab188fc26bacf0aae6941e8082", + "oneloop": "git+https://github.com/alphal00p/oneloopmaster.git?rev=5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5#5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5" + } + }, + "input_and_harness_sha256": { + "bare_driver.f": "5412bd1e19ae0744e856cd88b39071f2ef0b937f8b4ba4e3d4c426af26b4eb24", + "madloop_validation.py": "a409f9229dc3a739251b9645a6b461157cd896c9a3bfe25a24d90399270ae11d", + "compare_madloop.py": "42a7218d1cf3bdae0f25f8a5f6bbc6371f11579ca7ec93dde77807a5f42eee1b" + }, + "raw_receipt_sha256": { + "process_comparison.json": "f5145c4e4029724fde9bfc936c89654202d95731a0b8872adf2ee8cf0188d116", + "tensor-summary.json": "0c833553435e39c7358e9453636c120aa4a66dc300f2828b69d82c9e953b8472", + "combined-baseline-comparison.json": "ed4dcbc6c214a63ae54a5d2b830f937b6fd8cbda9aae885a73a255d948054ac4" + }, + "portable_path_reproduction": { + "passed": true, + "scope": "Fresh CLI generation and compilation of all four processes through the retained portable campaign after the upstream dependency update.", + "configurations": 74, + "result_rows": 444, + "runtime_switch_rows": 144, + "values_and_statuses_exactly_equal_to_pre_upstream_campaign": true + }, + "validation_revision_note": "Upstream migration applied to this source revision; exact compiled bridge and generation-source hashes are recorded in upstream-migration-validation.json.", + "recorded_evaluation_count_note": "Count refers to unique recorded configurations; warmup and repeat switch calls are additional.", + "historical_portable_path_smoke": { + "source_revision": "3ed442f0444b7e3367da123690b00e12c9d068dc", + "case": "qcd-z", + "configurations": 12, + "rows": 72, + "passed": true, + "scope": "Earlier one-process portability smoke; superseded for current-library qualification by the full fresh campaign." + }, + "migration_receipt": "upstream-migration-validation.json" +} diff --git a/vendor/ninjars/tests/poles/madloop_validation.py b/vendor/ninjars/tests/poles/madloop_validation.py new file mode 100644 index 0000000000..9b4a005ec7 --- /dev/null +++ b/vendor/ninjars/tests/poles/madloop_validation.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +"""Focused real-CLI bare-loop UV/IR checks against MadLoop's COLLIER wrapper.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import re +import shutil +import subprocess +import sys + +ASSETS = Path(__file__).resolve().parent +ROOT = ASSETS.parents[3] +HERE = None +NATIVE_PATHS = [] +sys.path.insert(0, str(ROOT)) +from madgraph.various.banner import MadLoopParam + +POINTS = ASSETS / 'points' +MODEL = ROOT / 'models/loop_qcd_qed_sm_Gmu' +CASES = { + 'qcd-z': ('loop_sm', 'u u~ > z [virt=QCD]', 'qcd-1', 3), + 'qcd-tt': ('loop_sm', 'g g > t t~ [virt=QCD]', 'qcd-2', 4), + 'ew-mumu': (str(MODEL), 'e+ e- > mu+ mu- [virt=QED]', 'ew-2', 4), + 'li-h': ('loop_sm', 'g g > h [sqrvirt=QCD]', 'control-gg-h', 3), +} + + +def run(command, cwd, log): + env = os.environ.copy() + env.update(OMP_NUM_THREADS='1', OPENBLAS_NUM_THREADS='1', MKL_NUM_THREADS='1', RAYON_NUM_THREADS='1') + env['MAKEFLAGS'] = 'SHELL=' + shutil.which('bash') + generated_lib = cwd.parents[1] / 'lib' + linked_dirs = [p.resolve() for p in generated_lib.iterdir() if p.is_dir()] if generated_lib.is_dir() else [] + env['LD_LIBRARY_PATH'] = ':'.join(str(p) for p in NATIVE_PATHS + [generated_lib] + linked_dirs) + ':' + env.get('LD_LIBRARY_PATH', '') + with log.open('w') as stream: + subprocess.run(command, cwd=cwd, env=env, stdout=stream, stderr=subprocess.STDOUT, check=True) + + +def sha(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def prepare(name, ninjars): + model, process, point_name, nexternal = CASES[name] + work = HERE / 'processes' / name + work.mkdir(parents=True, exist_ok=True) + output = work / 'output' + command_card = work / 'generate.mg5' + commands = ['set automatic_html_opening False --no_save', + 'set notification_center False --no_save', + 'set loop_optimized_output True --no_save'] + if ninjars: + commands.append(f'set ninjars {ninjars} --no_save') + if COLLIER is not None: + commands.append(f'set collier {COLLIER} --no_save') + commands += [f'import model {model}', f'generate {process}', f'output standalone {output} -f', 'quit'] + command_card.write_text('\n'.join(commands) + '\n') + if not output.exists(): + run([sys.executable, '-B', 'bin/madgraph', str(command_card)], ROOT, work / 'generation.log') + subs = sorted((output / 'SubProcesses').glob('P*_*')) + assert len(subs) == 1, subs + sub = subs[0] + loop = sub / 'loop_matrix.f' + prefix = re.search(r'SUBROUTINE\s+(\w+)SLOOPMATRIX\(', loop.read_text(), re.I).group(1) + metadata = {'process': process, 'model': model, 'prefix': prefix, 'generated_bare_patch': []} + # Remove all UFO counterterms only in this disposable generated validation copy. + # The loop numerator, reduction wrappers and production source remain intact. + for filename, marker, extra in [ + ('loop_matrix.f', ' UVCT_REQ_SO_DONE=.TRUE.', ''), + ('mp_compute_loop_coefs.f', ' MP_UVCT_REQ_SO_DONE=.TRUE.', + '\n DP_AMPL(:,1:NCTAMPS)=(0.0D0,0.0D0)')]: + path = sub / filename + text = path.read_text() + if 'UVIR_VALIDATION_BARE_LOOP' not in text: + matches = list(re.finditer(r'^[ \t]*' + re.escape(marker.strip()) + r'\s*$', text, re.M)) + assert len(matches) == 1, (path, len(matches)) + match = matches[0] + replacement = match.group(0) + '\nC UVIR_VALIDATION_BARE_LOOP: discard UFO UV/R2 counterterms.\n AMPL(:,1:NCTAMPS)=0' + extra + original = path.with_suffix('.f.original') + original.write_text(text) + text = text[:match.start()] + replacement + text[match.end():] + path.write_text(text) + metadata['generated_bare_patch'].append({'path': filename, 'original_sha256': sha(path.with_suffix('.f.original')), 'bare_sha256': sha(path)}) + # Use the fixed point stream from the previous benchmark and exactly zero widths. + card = output / 'Cards/param_card.dat' + if not (work / 'param_card.original.dat').exists(): + shutil.copy2(card, work / 'param_card.original.dat') + text = (ASSETS / 'cards' / (name + '.dat')).read_text() + card.write_text(text) + shutil.copy2(card, sub / 'param_card.dat') + stream = (POINTS / (point_name + '.dat')).read_text().splitlines() + (work / 'points.dat').write_text('3\n' + '\n'.join(stream[1:1 + 3*nexternal]) + '\n') + driver = (ASSETS / 'bare_driver.f').read_text().replace('@NEXTERNAL@', str(nexternal)).replace('@NBORN@', '0' if name.startswith('li-') else '1').replace('@PREFIX@', prefix) + (sub / 'check_sa.f').write_text(driver) + run(['make', '-j2', 'check'], sub, work / 'build.log') + metadata['point_sha256'] = sha(work / 'points.dat') + metadata['parameter_card_sha256'] = sha(card) + (work / 'preparation.json').write_text(json.dumps(metadata, indent=2) + '\n') + return work, output, sub + + +def evaluate(name, ninjars, backend, mode, ctmode, switch=False, filters=False, reuse_filters=False): + work = HERE / 'processes' / name + output = work / 'output' + sub = sorted((output / 'SubProcesses').glob('P*_*'))[0] + target = work / (('filtered-' if filters else '') + f'backend-{backend}-mode-{mode}-ct-{ctmode}') + target.mkdir(exist_ok=True) + card = MadLoopParam(str(output / 'Cards/MadLoopParams.dat')) + values = dict(MLReductionLib=str(backend), CTModeRun=ctmode, + CTModeInit=1, UseLoopFilter=filters, LoopPoleMode=mode, + COLLIERComputeUVpoles=True, COLLIERComputeIRpoles=True, + UseQPIntegrandForNinjaRS=True) + for key, value in values.items(): + card[key] = value + template = str(ROOT / 'Template/loop_material/StandAlone/Cards/MadLoopParams.dat') + for path in [output / 'Cards/MadLoopParams.dat', *(output / 'SubProcesses').rglob('MadLoopParams.dat')]: + card.write(str(path), template=template) + if not reuse_filters: + for pattern in ['*HelFilter.dat', '*LoopFilter.dat']: + for path in (output / 'SubProcesses').rglob(pattern): + path.unlink() + shutil.copy2(output / 'Cards/MadLoopParams.dat', target / 'MadLoopParams.dat') + command = [str(sub / 'check'), str(work / 'points.dat'), '1'] + if switch: + command.append('--switch') + run(command, sub, target / 'evaluation.log') + for filename in ['values.dat', 'dimensions.dat']: + shutil.copy2(sub / filename, target / filename) + if switch: + shutil.copy2(sub / 'switch_values.dat', target / 'switch_values.dat') + records = [] + for line in (target / 'values.dat').read_text().splitlines(): + fields = line.split() + records.append(dict(point=int(fields[0]), split_order=int(fields[1]), status=int(fields[2]), + born=float(fields[3]), finite=float(fields[4]), single=float(fields[5]), + double=float(fields[6]), accuracy=float(fields[7]))) + (target / 'result.json').write_text(json.dumps(dict(case=name, backend=backend, mode=mode, ctmode=ctmode, + filters=filters, reused_filters=reuse_filters, records=records), indent=2) + '\n') + print(name, backend, mode, ctmode, 'OK', flush=True) + + +def main(): + global HERE, POINTS, COLLIER, NATIVE_PATHS + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--output', type=Path, required=True) + parser.add_argument('--ew-model', type=Path, default=MODEL) + parser.add_argument('--points', type=Path, default=POINTS) + parser.add_argument('--collier', type=Path) + parser.add_argument('--campaign', action='store_true') + parser.add_argument('--case', choices=CASES, action='append') + parser.add_argument('--ninjars') + parser.add_argument('--prepare', action='store_true') + parser.add_argument('--backend', type=int, default=8) + parser.add_argument('--mode', type=int, action='append') + parser.add_argument('--ctmode', type=int, default=1) + parser.add_argument('--switch', action='store_true') + parser.add_argument('--filters', action='store_true') + parser.add_argument('--reuse-filters', action='store_true') + args = parser.parse_args() + HERE, POINTS = args.output.resolve(), args.points.resolve() + if HERE == ASSETS or ASSETS in HERE.parents: + parser.error('--output must be outside the retained source directory') + HERE.mkdir(parents=True, exist_ok=True) + COLLIER = args.collier.resolve() if args.collier else None + NATIVE_PATHS = [COLLIER, COLLIER / 'lib'] if COLLIER else [] + if args.ninjars: + args.ninjars = str(Path(args.ninjars).resolve()) + CASES['ew-mumu'] = (str(args.ew_model.resolve()), *CASES['ew-mumu'][1:]) + if (args.campaign or args.prepare) and ('ew-mumu' in (args.case or CASES)) and not args.ew_model.is_dir(): + parser.error('EW source is absent: supply --ew-model with loop_qcd_qed_sm_Gmu') + if args.campaign: + if args.case: + parser.error('--campaign runs the complete four-process matrix; omit --case') + for name in CASES: + prepare(name, args.ninjars) + for name in CASES: + for backend in (7, 8): + for mode in range(4): + evaluate(name, args.ninjars, backend, mode, 1) + for ctmode in ([-1, 2, 4, 5] if name.startswith('qcd-') else [4]): + for mode in range(4): + evaluate(name, args.ninjars, 8, mode, ctmode) + for backend in (7, 8): + evaluate('qcd-tt', args.ninjars, backend, 0, 1, switch=True) + evaluate('qcd-tt', args.ninjars, 8, -1, 1, switch=True, filters=True) + evaluate('qcd-tt', args.ninjars, 8, 1, 1, filters=True, reuse_filters=True) + subprocess.run([sys.executable, '-B', str(ASSETS / 'compare_madloop.py'), '--output', str(HERE)], check=True) + return + for name in args.case or CASES: + if args.prepare: + prepare(name, args.ninjars) + for mode in args.mode or ([] if args.prepare else range(4)): + evaluate(name, args.ninjars, args.backend, mode, args.ctmode, args.switch, args.filters, args.reuse_filters) + + +if __name__ == '__main__': + main() diff --git a/vendor/ninjars/tests/poles/native-dp-baseline.json b/vendor/ninjars/tests/poles/native-dp-baseline.json new file mode 100644 index 0000000000..e09f6aa919 --- /dev/null +++ b/vendor/ninjars/tests/poles/native-dp-baseline.json @@ -0,0 +1,18 @@ +{ + "compared_mode0_evaluations": 910, + "identical": true, + "baseline_tree_revision": "d816e1b92ead3cde8cf89c3bc3786f08b938e4b2", + "baseline": { + "libninjars.a": "b0d69deb8c16deb13293176296afc5e18dbeeebe778a20fa39b61804fba89d4c", + "ninjars-config.json": "a2b427c4e1c766180cec068ca716e2ff3d035226b06864c50156202bcfa4617f", + "mninjars.mod": "33ac359d582224a06596f9060e1b37ddaf45e9c66085454cf7e0e693b1c02dec" + }, + "candidate": { + "libninjars.a": "51fc066b71fd26132cc3da53b2cfbab4c7f2ec896c22df3fdcb0dfc15f81467f", + "ninjars-config.json": "a924184de8f4ef03ac86c477c0925fa77e8e13711ff615d76a1b2372232831dc", + "mninjars.mod": "bdbdea4365d04be8693de8ff10d9594137cca6ceaaf9ce2de3e6991467a625ec" + }, + "baseline_values_sha256": "3002bd2e9c5cfa34f3fa9be74f35c993fe114f40992aba6e8d3d81b6b0c28519", + "candidate_values_sha256": "b431b23330834bc4be29d4979b6a580936558ab7d855b2a6229714f5011a4e1b", + "jobs_sha256": "4598f2e39ba45e05650161a7686f8a646bdad9920788e6bc4fc6643057809bc1" +} diff --git a/vendor/ninjars/tests/poles/ninjars_poles.f90 b/vendor/ninjars/tests/poles/ninjars_poles.f90 new file mode 100644 index 0000000000..dc9bbd7e36 --- /dev/null +++ b/vendor/ninjars/tests/poles/ninjars_poles.f90 @@ -0,0 +1,64 @@ +! Focused independent comparison against COLLIER tensor components. +program ninjars_poles + use mninjars + implicit none + integer :: jobs, job, n, rank, count, k, mode, status, unit_in, unit_out, argc + integer :: modes(8) = [0, 1, 2, 3, 0, 2, 1, 3] + real(KI_QNRS) :: re, im, scale + complex(KI_QNRS), allocatable :: coeff(:), mass(:) + real(KI_QNRS), allocatable :: momenta(:,:), smatrix(:,:) + complex(KI_QNRS) :: result(0:2), rational + complex(KI_NRS) :: dpresult(0:2), dprational + character(len=4096) :: input_path, output_path, precision + character(len=1024) :: error_message + argc = command_argument_count() + if (argc /= 3) stop 2 + call get_command_argument(1, input_path) + call get_command_argument(2, output_path) + call get_command_argument(3, precision) + open(newunit=unit_in, file=trim(input_path), status='old') + open(newunit=unit_out, file=trim(output_path), status='replace') + read(unit_in, *) jobs + do job=1,jobs + read(unit_in, *) n, rank + count=(rank+1)*(rank+2)*(rank+3)*(rank+4)/24 + allocate(coeff(count),mass(n),momenta(0:3,n),smatrix(n,n)) + do k=1,count + read(unit_in, *) re, im + coeff(k)=cmplx(re,im,kind=KI_QNRS) + end do + do k=1,n + read(unit_in, *) re, im + mass(k)=cmplx(re,im,kind=KI_QNRS) + end do + do k=1,n + read(unit_in, *) momenta(:,k) + end do + do k=1,n + read(unit_in, *) smatrix(:,k) + end do + read(unit_in, *) scale + do k=1,size(modes) + mode=modes(k) + if (trim(precision)=='mp') then + call ninjars_tensor_evaluate(coeff,n,rank,smatrix,momenta,mass,scale,result,rational,status,mode) + else + call ninjars_tensor_evaluate(cmplx(coeff,kind=KI_NRS),n,rank,real(smatrix,kind=KI_NRS), & + real(momenta,kind=KI_NRS),cmplx(mass,kind=KI_NRS),real(scale,kind=KI_NRS),dpresult,dprational,status,mode) + result=cmplx(dpresult,kind=KI_QNRS) + rational=cmplx(dprational,kind=KI_QNRS) + end if + write(unit_out,'(3(I0,1X),8(ES44.35E3,1X))') job,mode,status,result,rational + flush(unit_out) + if(status /= NINJARS_SUCCESS) then + call ninjars_error_message(error_message) + print *, job,mode,status,trim(error_message) + end if + end do + deallocate(coeff,mass,momenta,smatrix) + end do + call ninjars_finalize(status) + if(status /= NINJARS_SUCCESS) stop 3 + close(unit_in) + close(unit_out) +end program diff --git a/vendor/ninjars/tests/poles/points/control-gg-h.dat b/vendor/ninjars/tests/poles/points/control-gg-h.dat new file mode 100644 index 0000000000..f00aaf69ee --- /dev/null +++ b/vendor/ninjars/tests/poles/points/control-gg-h.dat @@ -0,0 +1,10 @@ +3 +6.92129608372827789e+01 -4.07390704741906351e+00 1.46259291060489307e+01 6.75271754704508567e+01 +5.95282525469314052e+01 -3.77435716937021937e+00 1.35505007202089534e+01 -5.78424671800994901e+01 +1.28741213384214177e+02 -7.84826421678928288e+00 2.81764298262578841e+01 9.68470829035136660e+00 +5.19577104483111611e+01 -1.07157938942352384e+01 -5.76036416988788069e+00 5.05133016232069920e+01 +7.87354307871064663e+01 -1.32227856118232392e+01 -7.10801842740103673e+00 -7.72910219620023042e+01 +1.30693141235417642e+02 -2.39385795060584776e+01 -1.28683825972889156e+01 -2.67777203387953122e+01 +6.62176087500079831e+01 -1.37146437910130139e+01 9.26759240698896214e+00 6.41154582392786381e+01 +6.30267389822837814e+01 -1.33746620070688866e+01 9.03785165342598340e+00 -6.09245884715544292e+01 +1.29244347732291772e+02 -2.70893057980819023e+01 1.83054440604149455e+01 3.19086976772420305e+00 diff --git a/vendor/ninjars/tests/poles/points/ew-2.dat b/vendor/ninjars/tests/poles/points/ew-2.dat new file mode 100644 index 0000000000..eb22f9c5be --- /dev/null +++ b/vendor/ninjars/tests/poles/points/ew-2.dat @@ -0,0 +1,13 @@ +3 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 5.00000000000000000e+02 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 -5.00000000000000000e+02 +4.99999999999999716e+02 8.87803422726094311e+01 4.21638416471375379e+01 4.90245103273366283e+02 +5.00000000000000625e+02 -8.87803422726093174e+01 -4.21638416471379927e+01 -4.90245103273366624e+02 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 5.00000000000000000e+02 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 -5.00000000000000000e+02 +5.00000000000000227e+02 -2.28852966126414344e+02 -4.27698830309395532e+02 -1.21243682091555456e+02 +4.99999999999993690e+02 2.28852966126417272e+02 4.27698830309395021e+02 1.21243682091555655e+02 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 5.00000000000000000e+02 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 -5.00000000000000000e+02 +4.99999999999999773e+02 -1.52715097599330846e+02 3.50728746865285814e+02 -3.21974292587984564e+02 +4.99999999999999829e+02 1.52715097599330818e+02 -3.50728746865285814e+02 3.21974292587984621e+02 diff --git a/vendor/ninjars/tests/poles/points/qcd-1.dat b/vendor/ninjars/tests/poles/points/qcd-1.dat new file mode 100644 index 0000000000..b36e80177f --- /dev/null +++ b/vendor/ninjars/tests/poles/points/qcd-1.dat @@ -0,0 +1,10 @@ +3 +5.68867351801912875e+01 8.21314172775640827e+00 1.47310898866769646e+00 5.62714394016050221e+01 +3.75468714228900566e+01 6.66318171083297983e+00 1.19510818109741757e+00 -3.69315756443037913e+01 +9.44336066030813441e+01 1.48763234385893899e+01 2.66821716976511381e+00 1.93398637573012273e+01 +3.62176374652359598e+01 3.68974835283688440e+00 -4.74442373969148701e+00 3.57154513346010063e+01 +5.86879708147513242e+01 4.70317233544939217e+00 -6.04752420663328571e+00 -5.81857846841163706e+01 +9.49056082799872911e+01 8.39292068828627613e+00 -1.07919479463247736e+01 -2.24703333495153643e+01 +4.76703816501936330e+01 -7.19553056126551738e+00 3.80082069357599428e+00 4.69706651929935575e+01 +4.49571016887699813e+01 -6.98619567330239555e+00 3.69024589060862152e+00 -4.42573852315699057e+01 +9.26274833389636143e+01 -1.41817262345679129e+01 7.49106658418461624e+00 2.71327996142365135e+00 diff --git a/vendor/ninjars/tests/poles/points/qcd-2.dat b/vendor/ninjars/tests/poles/points/qcd-2.dat new file mode 100644 index 0000000000..93b40f6dab --- /dev/null +++ b/vendor/ninjars/tests/poles/points/qcd-2.dat @@ -0,0 +1,13 @@ +3 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 5.00000000000000000e+02 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 -5.00000000000000000e+02 +4.99999999999999716e+02 -3.87379348171925926e+02 -2.27797892295956359e+01 2.63608273414452640e+02 +4.99999999999999375e+02 3.87379348171926381e+02 2.27797892295953943e+01 -2.63608273414452924e+02 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 5.00000000000000000e+02 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 -5.00000000000000000e+02 +4.99999999999999773e+02 -4.67009390857915548e+02 9.62070678112469935e+00 -4.33667021059952518e+01 +5.00000000000000171e+02 4.67009390857915548e+02 -9.62070678112467981e+00 4.33667021059952162e+01 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 5.00000000000000000e+02 +5.00000000000000000e+02 0.00000000000000000e+00 0.00000000000000000e+00 -5.00000000000000000e+02 +5.00000000000000227e+02 2.90055690291405142e+02 -9.51304035657506688e+01 -3.56214686456066715e+02 +5.00000000000000000e+02 -2.90055690291405142e+02 9.51304035657506972e+01 3.56214686456066715e+02 diff --git a/vendor/ninjars/tests/poles/provenance.json b/vendor/ninjars/tests/poles/provenance.json new file mode 100644 index 0000000000..f5d177e57e --- /dev/null +++ b/vendor/ninjars/tests/poles/provenance.json @@ -0,0 +1,53 @@ +{ + "library_sha256": "1753ed686ab3021c149d6ecf80fe8c46cd4276bf8b5f891820c535603d39e127", + "compiler": "GNU Fortran (GCC) 15.3.0", + "driver_sha256": "0265012288259ff01f208416ccd72fce9807eb2baefee7571e7bc00b26c1881e", + "inputs_sha256": "60b0f6965326aff14c31c03ad166798d42d1b8e26ffa4d9e710457f01e458488", + "cases_sha256": "16decf75a9ecc460406ddd87b1ee492f4e48bc6d6f73ec8b9afca5fd3b9bae0f", + "raw_output_sha256": "ded7eb478c4852cb99cadc3f5f7f6733668c54784bd921d82eccc676721023fd", + "reference_sha256": "18f6694dd5af873d847e39bd299957454c698aeb31f3bf4b2389593bc44d3970", + "command": [ + "gfortran", + "-O2", + "-I/include", + "collier_poles.f90", + "-L", + "-lcollier", + "-Wl,-rpath,", + "-o", + "/collier_poles" + ], + "collier_version": "1.2.9", + "collier_branch": "COLI", + "generator_source": "NinjaRS aa6a6307dd081dc3714f9accebc0df9e5561ae73 validation/rank-n2/harness/collier_tensor_driver.f90 (adapted)", + "files": { + "collier_reference.json": "18f6694dd5af873d847e39bd299957454c698aeb31f3bf4b2389593bc44d3970", + "collier_poles.f90": "0265012288259ff01f208416ccd72fce9807eb2baefee7571e7bc00b26c1881e", + "collier_jobs.in": "60b0f6965326aff14c31c03ad166798d42d1b8e26ffa4d9e710457f01e458488", + "tensor_cases.json": "16decf75a9ecc460406ddd87b1ee492f4e48bc6d6f73ec8b9afca5fd3b9bae0f" + }, + "reference_status": { + "cases": 8, + "tensor_components": 455, + "error_flags": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "accuracy_flags": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } +} diff --git a/vendor/ninjars/tests/poles/tensor-validation.json b/vendor/ninjars/tests/poles/tensor-validation.json new file mode 100644 index 0000000000..2f6b5b1c9a --- /dev/null +++ b/vendor/ninjars/tests/poles/tensor-validation.json @@ -0,0 +1,35 @@ +{ + "reference_sha256": "18f6694dd5af873d847e39bd299957454c698aeb31f3bf4b2389593bc44d3970", + "driver_sha256": "904ed1844d14edbe98ff00f21c55b0c23299a9d2affe7e721d2a7fc36e8063b8", + "library_sha256": "43ed42c237412a81838a6c4c0b4f89015a0785b4f331bdb2fbf01020124c67c7", + "installation_sha256": "45b48d5991cef9b669c2942abb9020a864f462103c4943cb7e307235f84ba25c", + "ordinary_dp_unstable_controls_pass_mp": true, + "results": [ + { + "passed": true, + "cases": 455, + "evaluations": 3640, + "checked_against_collier": 1820, + "repeated_state_checks": 1820, + "precision": "dp", + "diagnostic_all": false, + "worst_checked_normalized_error": 0.003925235246128018, + "failures": 0, + "ordinary_dp_diagnostics": 56, + "unstable": 280 + }, + { + "passed": true, + "cases": 455, + "evaluations": 3640, + "checked_against_collier": 3640, + "repeated_state_checks": 1820, + "precision": "mp", + "diagnostic_all": false, + "worst_checked_normalized_error": 0.0024993190990038033, + "failures": 0, + "ordinary_dp_diagnostics": 0, + "unstable": 0 + } + ] +} diff --git a/vendor/ninjars/tests/poles/tensor_cases.json b/vendor/ninjars/tests/poles/tensor_cases.json new file mode 100644 index 0000000000..c3dbc33b90 --- /dev/null +++ b/vendor/ninjars/tests/poles/tensor_cases.json @@ -0,0 +1,272 @@ +[ + { + "name": "massive-tadpole-r3", + "rank": 3, + "mass2": [ + [ + 4, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ] + ], + "mu2": 7, + "n": 1 + }, + { + "name": "scaleless-lightlike-bubble-r4", + "rank": 4, + "mass2": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 5, + 3, + 0, + 4 + ] + ], + "mu2": 7, + "n": 2 + }, + { + "name": "massive-bubble-r4", + "rank": 4, + "mass2": [ + [ + 9, + 0 + ], + [ + 4, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 4, + 1, + 2, + 0.5 + ] + ], + "mu2": 7, + "n": 2 + }, + { + "name": "massless-offshell-bubble-r4", + "rank": 4, + "mass2": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 0, + 1, + 2, + 3 + ] + ], + "mu2": 7, + "n": 2 + }, + { + "name": "massive-triangle-r4", + "rank": 4, + "mass2": [ + [ + 9, + 0 + ], + [ + 16, + 0 + ], + [ + 25, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 1, + 0.2, + 0.3, + 0.4 + ], + [ + 0.4, + -0.5, + 0.7, + -0.2 + ] + ], + "mu2": 7, + "n": 3 + }, + { + "name": "infrared-triangle-r3", + "rank": 3, + "mass2": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 5, + 0, + 0, + 5 + ], + [ + 10, + 0, + 0, + 0 + ] + ], + "mu2": 7, + "n": 3 + }, + { + "name": "massive-box-r4", + "rank": 4, + "mass2": [ + [ + 9, + 0 + ], + [ + 16, + 0 + ], + [ + 25, + 0 + ], + [ + 36, + 0 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 0, + 1, + 2, + 0 + ], + [ + 0, + 0, + 1, + 3 + ], + [ + 0, + 2, + 0, + 1 + ] + ], + "mu2": 7, + "n": 4 + }, + { + "name": "complex-mass-bubble-r3", + "rank": 3, + "mass2": [ + [ + 9, + -0.2 + ], + [ + 4, + -0.1 + ] + ], + "shifts": [ + [ + 0, + 0, + 0, + 0 + ], + [ + 4, + 1, + 2, + 0.5 + ] + ], + "mu2": 7, + "n": 2 + } +] diff --git a/vendor/ninjars/tests/poles/tensor_validation.py b/vendor/ninjars/tests/poles/tensor_validation.py new file mode 100644 index 0000000000..a47ee3b8da --- /dev/null +++ b/vendor/ninjars/tests/poles/tensor_validation.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python3 +"""Compare NinjaRS UV/IR tensor poles with independent COLLIER references. + +Both precisions and every tensor component run by default. Native DP combined +and no-pole results are retained as diagnostics, while selected DP and every MP +mode are checked against COLLIER. --diagnostic-all makes ordinary DP numerical +discrepancies fatal too; see README.md for the known pre-existing controls. +""" +import argparse +import hashlib +import json +import math +import os +from pathlib import Path +import shlex +import subprocess + +HERE = Path(__file__).resolve().parent +FIELDS = ('finite', 'uv', 'ir1', 'ir2') +FOCUSED = {(0, 0, 0, 0), (1, 0, 0, 0), (0, 1, 0, 0), (2, 0, 0, 0), + (1, 1, 0, 0), (0, 2, 0, 0), (3, 0, 0, 0), (4, 0, 0, 0)} + + +def sha(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def monomials(rank): + """Ninja/MadLoop tensor order, without multinomial symmetry factors.""" + terms = [(0, 0, 0, 0)] + lower = list(terms) + for r in range(1, rank + 1): + block = [] + for index, length in enumerate([1, r, r*(r+1)//2, r*(r+1)*(r+2)//6]): + for old in lower[:length]: + term = list(old) + term[index] += 1 + block.append(tuple(term)) + terms += block + lower = block + return terms + + +def write_jobs(cases, work, focused): + selected, rows = [], [] + if not cases: + raise ValueError('empty reference case list') + for case in cases: + powers = [tuple(component['powers']) for component in case['components']] + if len(powers) != math.comb(case['rank']+4, 4) or set(powers) != set(monomials(case['rank'])): + raise ValueError('incomplete or duplicate reference tensor: ' + case['name']) + if case['collier_status'] != dict(error=0, accuracy=0): + raise ValueError('COLLIER reference has a nonzero status: ' + case['name']) + for component in case['components']: + powers = tuple(component['powers']) + if focused and powers not in FOCUSED: + continue + rank = sum(powers) + # All components in this norm have the same mass dimension. + scale = max(abs(complex(*other[key])) for other in case['components'] + if sum(other['powers']) == rank for key in FIELDS) + if not scale: + # A complete odd tadpole tensor vanishes by symmetry. The + # nonzero scalar tensor at this same point fixes its scale; + # the characteristic mass restores the correct dimension. + characteristic = max([case['mu2']] + [abs(complex(*m)) for m in case['mass2']]) + scalar = next(c for c in case['components'] if not any(c['powers'])) + scale = max(abs(complex(*scalar[key])) for key in FIELDS) * characteristic**(rank/2) + selected.append(dict(case=case['name'], powers=powers, + reference=component, common_scale=scale)) + n = case['n'] + rows.append(f'{n} {rank}') + rows += ['1 0' if term == powers else '0 0' for term in monomials(rank)] + rows += [' '.join(map(str, mass)) for mass in case['mass2']] + rows += [' '.join(map(str, p)) for p in case['shifts']] + for a in case['shifts']: + invariants = [] + for b in case['shifts']: + d = [x-y for x, y in zip(a, b)] + invariants.append(d[0]**2-sum(x*x for x in d[1:])) + rows.append(' '.join(map(str, invariants))) + rows.append(str(case['mu2'])) + inputs = work / 'jobs.in' + inputs.write_text(str(len(selected)) + '\n' + '\n'.join(rows) + '\n') + (work / 'jobs.json').write_text(json.dumps(selected, indent=2) + '\n') + return inputs, selected + + +def compare(work, selected, precision, diagnostic_all): + failures, diagnostics, unstable, history = [], [], [], {} + worst, count, selected_count, repeat_count = 0., 0, 0, 0 + sequence = [0, 1, 2, 3, 0, 2, 1, 3] + expected_sequence = [(job, mode) for job in range(1, len(selected)+1) for mode in sequence] + actual_sequence = [] + lines = (work / 'values.dat').read_text().splitlines() + if len(lines) != len(expected_sequence): + failures.append(dict(reason='incomplete or excess result rows', expected=len(expected_sequence), actual=len(lines))) + for line in lines: + fields = line.split() + if len(fields) != 11: + failures.append(dict(reason='malformed result row', row=line)) + continue + job, mode, status = map(int, fields[:3]) + actual_sequence.append((job, mode)) + if not 1 <= job <= len(selected) or mode not in (0, 1, 2, 3): + failures.append(dict(reason='unexpected job or mode', job=job, mode=mode)) + continue + nums = list(map(float, fields[3:])) + actual = [complex(*nums[k:k+2]) for k in range(0, 6, 2)] + case = selected[job-1] + ref = case['reference'] + expected = [complex(*ref['finite']), + complex(*ref['uv']) + complex(*ref['ir1']) if mode == 0 else + complex(*ref['uv' if mode == 1 else 'ir1']) if mode in (1, 2) else 0j, + complex(*ref['ir2']) if mode in (0, 2) else 0j] + scale = case['common_scale'] + entry = dict(job=job, case=case['case'], powers=case['powers'], mode=mode, status=status) + checked = precision == 'mp' or mode in (1, 2) or diagnostic_all + count += 1 + selected_count += checked + # Every mode is evaluated twice, with other modes interleaved. Compare + # all printed binary128 digits, including the rational diagnostic. + key = job, mode + state = fields[2:] + if key in history: + repeat_count += 1 + if state != history[key]: + failures.append(dict(entry, reason='reused context differs after mode cycling')) + else: + history[key] = state + if status == 1: + unstable.append(entry) + if checked: + failures.append(dict(entry, reason='reduction reported unstable')) + continue + ratios = [] + for x, y in zip(actual, expected): + tolerance = 1e-7 * max(abs(x), abs(y)) + 1e-10 * scale + ratios.append(abs(x-y)/tolerance if tolerance else (0. if x == y else float('inf'))) + if checked: + worst = max(worst, max(ratios)) + nonfinite = not all(math.isfinite(x.real) and math.isfinite(x.imag) for x in actual) + if status != 0 or max(ratios) > 1 or nonfinite: + error = dict(entry, actual=[[x.real, x.imag] for x in actual], + expected=[[x.real, x.imag] for x in expected], error_ratios=ratios) + (failures if checked or status not in (0, 1) or nonfinite else diagnostics).append(error) + if actual_sequence != expected_sequence: + failures.append(dict(reason='unexpected/missing/duplicated evaluation sequence')) + result = dict(passed=not failures, cases=len(selected), evaluations=count, + checked_against_collier=selected_count, repeated_state_checks=repeat_count, + precision=precision, diagnostic_all=diagnostic_all, + worst_checked_normalized_error=worst, failures=failures, + ordinary_dp_diagnostics=diagnostics, unstable=unstable) + (work / 'comparison.json').write_text(json.dumps(result, indent=2) + '\n') + return result + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--lib', type=Path, required=True, help='installed NinjaRS lib directory') + parser.add_argument('--output', type=Path, required=True, help='build and evidence directory') + parser.add_argument('--reference', type=Path, default=HERE / 'collier_reference.json') + parser.add_argument('--precision', choices=['dp', 'mp', 'both'], default='both') + parser.add_argument('--focused', action='store_true', help='61 representative components instead of all 455') + parser.add_argument('--diagnostic-all', action='store_true') + parser.add_argument('--fc', default=os.environ.get('FC', 'gfortran')) + args = parser.parse_args() + output, lib = args.output.resolve(), args.lib.resolve() + if output == HERE or HERE in output.parents: + parser.error('--output must be outside the retained test-source directory') + output.mkdir(parents=True, exist_ok=True) + cases = json.loads(args.reference.read_text()) + summaries = [] + precisions = ['dp', 'mp'] if args.precision == 'both' else [args.precision] + for precision in precisions: + work = output / precision + work.mkdir(exist_ok=True) + inputs, selected = write_jobs(cases, work, args.focused) + command = shlex.split(args.fc) + ['-O2', str(HERE / 'ninjars_poles.f90'), '-I'+str(lib)] + command += shlex.split((lib / 'ninjars-link-before.txt').read_text()) + command += ['-L'+str(lib), '-lninjars'] + command += shlex.split((lib / 'ninjars-native-libs.txt').read_text()) + command += ['-o', str(work / 'ninjars_poles')] + with (work / 'build.log').open('w') as stream: + subprocess.run(command, cwd=work, stdout=stream, stderr=subprocess.STDOUT, check=True) + with (work / 'evaluation.log').open('w') as stream: + subprocess.run([str(work / 'ninjars_poles'), str(inputs), str(work / 'values.dat'), precision], + cwd=work, stdout=stream, stderr=subprocess.STDOUT, check=True) + result = compare(work, selected, precision, args.diagnostic_all) + summary = {key: value for key, value in result.items() + if key not in ('failures', 'ordinary_dp_diagnostics', 'unstable')} + summary.update(failures=len(result['failures']), + ordinary_dp_diagnostics=len(result['ordinary_dp_diagnostics']), + unstable=len(result['unstable'])) + summaries.append(summary) + print(json.dumps(summary, indent=2), flush=True) + # An ordinary DP unstable control is only qualified by a successful MP + # evaluation of every corresponding mode at the same input in this run. + rescued = None + if args.precision == 'both': + dp = json.loads((output / 'dp/comparison.json').read_text()) + mp = json.loads((output / 'mp/comparison.json').read_text()) + mp_failures = {(e['job'], e['mode']) for e in mp['failures'] if 'job' in e and 'mode' in e} + rescued = all((e['job'], e['mode']) not in mp_failures for e in dp['unstable']) and mp['passed'] + provenance = dict(reference_sha256=sha(args.reference), + driver_sha256=sha(HERE / 'ninjars_poles.f90'), + library_sha256=sha(lib / 'libninjars.a'), + installation_sha256=sha(lib / 'ninjars-config.json'), + ordinary_dp_unstable_controls_pass_mp=rescued, + results=summaries) + (output / 'summary.json').write_text(json.dumps(provenance, indent=2) + '\n') + if not all(s['passed'] for s in summaries) or rescued is False: + raise SystemExit(1) + + +if __name__ == '__main__': + main() diff --git a/vendor/ninjars/tests/poles/upstream-migration-validation.json b/vendor/ninjars/tests/poles/upstream-migration-validation.json new file mode 100644 index 0000000000..e02226d7e3 --- /dev/null +++ b/vendor/ninjars/tests/poles/upstream-migration-validation.json @@ -0,0 +1,314 @@ +{ + "schema": "madloop-upstream-poles-migration-validation-v1", + "passed": true, + "scope": "Fresh CLI-generated strict bare-loop comparison after migrating UV/IR numerical selection into upstream NinjaRS/oneloopmaster; no timing campaign.", + "source_base_revision": "3ed442f0444b7e3367da123690b00e12c9d068dc", + "source_note": "The exact changed source files and lockfile are hashed below; the recorded base revision precedes the migration commit.", + "historical_abi4_baseline": { + "madgraph_revision": "3ed442f0444b7e3367da123690b00e12c9d068dc", + "source": "HEPTools/ninjars/lib", + "files": { + "libninjars.a": { + "sha256": "51fc066b71fd26132cc3da53b2cfbab4c7f2ec896c22df3fdcb0dfc15f81467f", + "bytes": 310886264 + }, + "mninjars.mod": { + "sha256": "bdbdea4365d04be8693de8ff10d9594137cca6ceaaf9ce2de3e6991467a625ec", + "bytes": 2102 + }, + "ninjars-config.json": { + "sha256": "a924184de8f4ef03ac86c477c0925fa77e8e13711ff615d76a1b2372232831dc", + "bytes": 4050 + }, + "ninjars-link-before.txt": { + "sha256": "f8acb08e54969d1b7572e50c8f55ea84e173342042f3f921709723632c46f8ab", + "bytes": 8 + }, + "ninjars-native-libs.txt": { + "sha256": "afa89c3fb66ad9127499e457c45353861e724856fa630955227d659dd241c871", + "bytes": 48 + } + } + }, + "historical_abi3_to_abi4_evidence": { + "receipt": "native-dp-baseline.json", + "sha256": "253412563b6241e5547f438e10c37c7de9d65694cf3ff8faa986e733b51f73c3", + "scope": "Earlier ABI3 to first selected-pole ABI4 combined-DP comparison; retained unchanged as historical evidence." + }, + "production_installation": { + "passed": true, + "abi_version": 4, + "test_only_mutators_absent_from_install": true, + "installed_inputs_match_working_source_inputs": true, + "pins": { + "ninjars": "git+https://github.com/alphal00p/ninjars?rev=41a4c00e7635e3ab188fc26bacf0aae6941e8082#41a4c00e7635e3ab188fc26bacf0aae6941e8082", + "ninjars-symbolica": "git+https://github.com/alphal00p/ninjars?rev=41a4c00e7635e3ab188fc26bacf0aae6941e8082#41a4c00e7635e3ab188fc26bacf0aae6941e8082", + "oneloop": "git+https://github.com/alphal00p/oneloopmaster.git?rev=5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5#5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5" + }, + "files_sha256": { + "lib/libninjars.a": "43ed42c237412a81838a6c4c0b4f89015a0785b4f331bdb2fbf01020124c67c7", + "lib/mninjars.mod": "bdbdea4365d04be8693de8ff10d9594137cca6ceaaf9ce2de3e6991467a625ec", + "lib/ninjars-config.json": "45b48d5991cef9b669c2942abb9020a864f462103c4943cb7e307235f84ba25c", + "Cargo.toml": "168b0a7239e1fffb23594b19dfaa7938410022015aeed49e99ae5e1ae12d8e95", + "Cargo.lock": "a0db06134fe266f080e0ecf0e4590de19932213cec12908c893e5380e40d549b", + "install.log": "40f79ca67266f65e404d2a0d19c6daa53605719472e0fd913857e012c455f385" + }, + "fortran_compiler": "gfortran", + "native_libs": [ + "-ldl", + "-lgcc_s", + "-lutil", + "-lrt", + "-lpthread", + "-lm", + "-ldl", + "-lc" + ], + "link_before": [ + "-lgcc_s" + ] + }, + "production_installation_receipt_sha256": "515edb73994aa623301b2256e7178ff753b5ac7f62b9c3543788b06e63c7eefd", + "bridge_rust_qualification": { + "passed": true, + "command": [ + "cargo", + "test", + "--manifest-path", + "vendor/ninjars/Cargo.toml", + "--release", + "--locked", + "--features", + "fenv-test-support", + "--", + "--test-threads=1" + ], + "counts": [ + { + "passed": 31, + "failed": 0, + "ignored": 7, + "measured": 0, + "filtered": 0 + }, + { + "passed": 0, + "failed": 0, + "ignored": 0, + "measured": 0, + "filtered": 0 + } + ], + "log_sha256": "19e393682254abe0be58504696b61e758fd8f99d7286ea40ea1d3616fbaa7d33", + "installed_candidate_receipt": "installed-candidate.json", + "installed_files_unchanged_after_test_feature_build": true, + "source_inputs_sha256": { + "vendor/ninjars/Cargo.toml": "168b0a7239e1fffb23594b19dfaa7938410022015aeed49e99ae5e1ae12d8e95", + "vendor/ninjars/Cargo.lock": "a0db06134fe266f080e0ecf0e4590de19932213cec12908c893e5380e40d549b", + "vendor/ninjars/src/lib.rs": "567d984aabd8c94492653741fde71ec4f0ada0c7d8bbc6a48a8229b6de292443", + "vendor/ninjars/src/poles.rs": "4384e5898c4580e41677b543857a965548c7c2b4ae1db6e1bcc24922c7dfa278" + } + }, + "bridge_rust_qualification_receipt_sha256": "b2a8ef3a38dc5afa5a5d2665a55d54ae6c7e852081c1c6d0624876a0050f203e", + "upstream_qualification": { + "oneloopmaster": { + "published_commit": "5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5", + "feature_enabled_new_tests": 6, + "default_features_new_tests": 5, + "existing_native_tensor_tests": 9, + "commands": [ + [ + "cargo", + "test", + "--release", + "--locked", + "--offline", + "--manifest-path", + "/Cargo.toml", + "--features", + "generated-evaluators", + "--test", + "pole_selection", + "--", + "--test-threads=1" + ], + [ + "cargo", + "test", + "--release", + "--locked", + "--offline", + "--manifest-path", + "/Cargo.toml", + "--test", + "pole_selection", + "--", + "--test-threads=1" + ], + [ + "cargo", + "test", + "--release", + "--locked", + "--offline", + "--manifest-path", + "/Cargo.toml", + "--features", + "generated-evaluators", + "--test", + "native_tensor", + "--", + "--test-threads=1" + ] + ], + "private_resolved_lock_sha256": "eafa83ca8ef041de01e03741efd25b548b921ad009890d4b2b6a7949999b0306", + "dependency_resolution": "The upstream root Cargo.lock is ignored by convention. It was seeded from MG7 vendor/ninjars/Cargo.lock, then resolved offline by the first feature-enabled test invocation without --locked. The three final passing commands used --locked and the recorded resolved lock hash. No upstream tracked manifest dependency or lockfile was changed.", + "qualification_receipt_sha256": "573bbaf35abf020a2dc750d8a4e3670bad2ad0346144246975e02cca380c0851" + }, + "ninjars": { + "published_commit": "41a4c00e7635e3ab188fc26bacf0aae6941e8082", + "oneloopmaster_commit": "5b710437ada83cbc6e8c6d51e56f7d6ee6a0edb5", + "distinct_tests_passed": 80, + "workspace_check_passed": true, + "results": [ + { + "name": "provider_tests", + "command": "cargo test --release --locked --offline --manifest-path /Cargo.toml -p ninjars-symbolica --features native-masters --test pole_selection --test masters --test master_status --test fast_native_masters -- --test-threads=1", + "exit_code": 0, + "test_summaries": [ + { + "passed": 6, + "failed": 0, + "ignored": 0 + }, + { + "passed": 13, + "failed": 0, + "ignored": 0 + }, + { + "passed": 15, + "failed": 0, + "ignored": 0 + }, + { + "passed": 6, + "failed": 0, + "ignored": 0 + } + ], + "log_sha256": "6728bbd988bd5573a07e2e94267fd015438c246227d1feb2ba53b4254901549c" + }, + { + "name": "core_fast_tests", + "command": "cargo test --release --locked --offline --manifest-path /Cargo.toml -p ninjars --lib fast:: -- --test-threads=1", + "exit_code": 0, + "test_summaries": [ + { + "passed": 40, + "failed": 0, + "ignored": 0 + } + ], + "log_sha256": "16cf2015b444e2ba422041c72bb6dd52013c40d6f1e1ef9a45c2123e5f25d591" + }, + { + "name": "workspace_check", + "command": "cargo check --locked --offline --manifest-path /Cargo.toml --workspace", + "exit_code": 0, + "test_summaries": [], + "log_sha256": "0473df114f14171032c42d5e0afcb4f478ad03b7ba54b31c49ab529c010e283d" + } + ], + "qualification_receipt_sha256": "39ddf1bb8a55bfa70e578ff5c971f50d82d8618b4d08397bb8f320dd07b0096b" + } + }, + "combined_mode_regression": { + "passed": true, + "comparison": "Exact printed binary128 records, including status, Laurent coefficients and rational diagnostic; combined mode0 repeated twice for each of455 tensor inputs.", + "results": [ + { + "precision": "dp", + "mode": 0, + "compared_evaluations": 910, + "identical": true, + "difference_count": 0, + "differences": [], + "baseline_values_sha256": "a5e3ca0829995c2acffdebe169c73fa11a0862683a81fa8973091a29960bdec8", + "candidate_values_sha256": "a5e3ca0829995c2acffdebe169c73fa11a0862683a81fa8973091a29960bdec8", + "jobs_sha256": "4598f2e39ba45e05650161a7686f8a646bdad9920788e6bc4fc6643057809bc1" + }, + { + "precision": "mp", + "mode": 0, + "compared_evaluations": 910, + "identical": true, + "difference_count": 0, + "differences": [], + "baseline_values_sha256": "170b5b9fd9606cd53a20265b72589b0edb87c543a48b6a8dfdb16af6590f9a07", + "candidate_values_sha256": "170b5b9fd9606cd53a20265b72589b0edb87c543a48b6a8dfdb16af6590f9a07", + "jobs_sha256": "4598f2e39ba45e05650161a7686f8a646bdad9920788e6bc4fc6643057809bc1" + } + ] + }, + "all_mode_regression": [ + { + "precision": "dp", + "compared_evaluations": 3640, + "identical": true, + "difference_count": 0, + "differences": [] + }, + { + "precision": "mp", + "compared_evaluations": 3640, + "identical": true, + "difference_count": 0, + "differences": [] + } + ], + "tensor_qualification": { + "receipt": "tensor-validation.json", + "sha256": "0c833553435e39c7358e9453636c120aa4a66dc300f2828b69d82c9e953b8472", + "reference_sha256": "18f6694dd5af873d847e39bd299957454c698aeb31f3bf4b2389593bc44d3970", + "ordinary_dp_unstable_controls_pass_mp": true + }, + "generated_madloop_qualification": { + "receipt": "madloop-validation.json", + "sha256": "8fd1e41c286a54dd841ecb6455b26d1c72c33a1dff953582a0b5e621cc4ae458", + "configurations": 74, + "recorded_point_evaluations": 222, + "result_rows": 444, + "runtime_switch_rows": 144, + "comparison_checks": 187, + "worst_normalized_error": 8.375047153834681e-05, + "all_74_result_records_equal_to_prior_campaign": true, + "status_rows": { + "110": 252, + "120": 144, + "218": 48 + }, + "switch_status_rows": { + "110": 144 + } + }, + "source_and_inputs_sha256": { + "vendor/ninjars/tests/poles/madloop_validation.py": "a409f9229dc3a739251b9645a6b461157cd896c9a3bfe25a24d90399270ae11d", + "vendor/ninjars/tests/poles/compare_madloop.py": "42a7218d1cf3bdae0f25f8a5f6bbc6371f11579ca7ec93dde77807a5f42eee1b", + "vendor/ninjars/tests/poles/bare_driver.f": "5412bd1e19ae0744e856cd88b39071f2ef0b937f8b4ba4e3d4c426af26b4eb24", + "vendor/ninjars/tests/poles/tensor_validation.py": "7cc16a2fc5c6afdc5f98a0c2f497cc2536b06b20b8dadc211a3a15fce587ee1f", + "vendor/ninjars/tests/poles/ninjars_poles.f90": "904ed1844d14edbe98ff00f21c55b0c23299a9d2affe7e721d2a7fc36e8063b8", + "vendor/ninjars/tests/poles/collier_reference.json": "18f6694dd5af873d847e39bd299957454c698aeb31f3bf4b2389593bc44d3970", + "vendor/ninjars/Cargo.toml": "168b0a7239e1fffb23594b19dfaa7938410022015aeed49e99ae5e1ae12d8e95", + "vendor/ninjars/Cargo.lock": "a0db06134fe266f080e0ecf0e4590de19932213cec12908c893e5380e40d549b", + "vendor/ninjars/src/lib.rs": "567d984aabd8c94492653741fde71ec4f0ada0c7d8bbc6a48a8229b6de292443", + "vendor/ninjars/src/poles.rs": "4384e5898c4580e41677b543857a965548c7c2b4ae1db6e1bcc24922c7dfa278", + "Template/loop_material/StandAlone/SubProcesses/MadLoopParamReader.f": "5652a40c2587d62d17116aca60a3024e54ef598917126dedb8c690d85e128682", + "madgraph/iolibs/template_files/loop_optimized/loop_matrix_standalone.inc": "20ef8e81d1709e692668d5092892b80f436d5d10b486a97bc741f02b6263df40" + }, + "raw_receipt_sha256": { + "process_comparison.json": "f5145c4e4029724fde9bfc936c89654202d95731a0b8872adf2ee8cf0188d116", + "tensor-summary.json": "0c833553435e39c7358e9453636c120aa4a66dc300f2828b69d82c9e953b8472", + "combined-baseline-comparison.json": "ed4dcbc6c214a63ae54a5d2b830f937b6fd8cbda9aae885a73a255d948054ac4" + } +} diff --git a/vendor/ninjars/tests/replay.py b/vendor/ninjars/tests/replay.py new file mode 100644 index 0000000000..f9198af866 --- /dev/null +++ b/vendor/ninjars/tests/replay.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""Replay bundled tensor fixtures against pinned original Ninja results.""" +import argparse +import hashlib +import json +import pathlib +import subprocess + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--precision", choices=("dp", "mp"), default="dp") + parser.add_argument("--output", type=pathlib.Path) + parser.add_argument("--executable", type=pathlib.Path) + args = parser.parse_args() + bridge = pathlib.Path(__file__).resolve().parent.parent + data = bridge / "tests" / "data" + provenance = json.loads((data / "provenance.json").read_text()) + for item in provenance["files"]: + digest = hashlib.sha256((data / item["file"]).read_bytes()).hexdigest() + if digest != item["sha256"]: + raise SystemExit(f"Fixture checksum mismatch: {item['file']}") + + executable = args.executable + if executable is None: + command = ["cargo", "--manifest-path", str(bridge / "Cargo.toml")] + subprocess.run( + [command[0], "build", *command[1:], "--locked", "--example", "replay"], + check=True, + ) + metadata = subprocess.run( + [command[0], "metadata", *command[1:], "--locked", + "--no-deps", "--format-version=1"], + check=True, text=True, capture_output=True, + ) + target = pathlib.Path(json.loads(metadata.stdout)["target_directory"]) + executable = target / "debug" / "examples" / "replay" + executable = executable.resolve() + results = [] + for case in sorted((data / "cases").glob("*.json")): + command = [str(executable), str(case), str(data / "ninja" / case.name)] + if args.precision == "mp": + command.append("--mp") + completed = subprocess.run(command, text=True, capture_output=True) + if completed.returncode: + raise SystemExit( + f"Replay failed: {case.name} ({args.precision})\n" + f"{completed.stdout}{completed.stderr}" + ) + # Symbolica may print its licensing banner before the final JSON line. + result = json.loads(completed.stdout.strip().splitlines()[-1]) + results.append(result) + print(json.dumps(result), flush=True) + if args.output: + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(json.dumps(results, indent=2) + "\n") + + +if __name__ == "__main__": + main()