diff --git a/MG5aMC/mg5amcnlo b/MG5aMC/mg5amcnlo index f274cab55d..74fd166c1e 160000 --- a/MG5aMC/mg5amcnlo +++ b/MG5aMC/mg5amcnlo @@ -1 +1 @@ -Subproject commit f274cab55d5d983c5612ca7ab3417ee796aa1a8c +Subproject commit 74fd166c1e22bde2dfe01b2e001ac3b177628165 diff --git a/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/madgraph/iolibs/template_files/gpu/coloramps.h b/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/madgraph/iolibs/template_files/gpu/coloramps.h index 3972cf8e9a..3d03a60630 100644 --- a/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/madgraph/iolibs/template_files/gpu/coloramps.h +++ b/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/madgraph/iolibs/template_files/gpu/coloramps.h @@ -6,10 +6,34 @@ #ifndef COLORAMPS_H #define COLORAMPS_H 1 +#include + namespace mgOnGpu { + // Summary of numbering and indexing conventions for the relevant concepts (see issue #826 and PR #852) + // - Diagram number (no variable) in [1, N_diagrams]: all values are allowed (N_diagrams distinct values) + // => this number is displayed for information before each block of code in CPPProcess.cc + // - Channel number (CHANNEL_ID) in [0, N_diagrams]: not all values are allowed (N_config <= N_diagrams distinct values) + // => this number (with indexing like ps/pdf output) is passed around as an API argument between cudacpp functions + // 0 is allowed to fallback to no multi-channel mode. + // - Channel number in C indexing: "IconfiC", this is the equivalent of the Fortran iconfig + // iconfigC = iconfig -1 + // provides a continuous index [0, N_config-1] for array + // iconfigC = ChannelId_to_iconfigC[channelId] + //NOTE: All those ordering are event by event specific (with the intent to have those fix within a vector size/wrap + + // Map channelId to iconfigC + // This array has N_diagrams+1 elements, but only N_config <= N_diagrams valid values + // unvalid values are set to -1 + // The 0 entry is a fall back to still write events even if no multi-channel is setup (wrong color selected in that mode) + __device__ constexpr int channelId_to_iconfigC[%(nb_diag_plus_one)i] = { + 0, // channelId=0: This value means not multi-channel, color will be wrong anyway -> pick the first +%(diag_to_channel)s + }; - __device__ constexpr bool icolamp[%(nb_channel)s][%(nb_color)s] = { + // Map iconfigC (in C indexing, i.e. iconfig-1) to the set of allowed colors + // This array has N_config <= N_diagrams elements + __device__ constexpr bool icolamp[%(nb_channel)s][%(nb_color)s] = { %(is_LC)s }; diff --git a/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/madgraph/iolibs/template_files/gpu/process_sigmaKin_function.inc b/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/madgraph/iolibs/template_files/gpu/process_sigmaKin_function.inc index 1ac5ecb303..2ec052e3a1 100644 --- a/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/madgraph/iolibs/template_files/gpu/process_sigmaKin_function.inc +++ b/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/madgraph/iolibs/template_files/gpu/process_sigmaKin_function.inc @@ -72,7 +72,7 @@ // Event-by-event random choice of color #402 if( channelId != 0 ) // no event-by-event choice of color if channelId == 0 (fix FPE #783) { - const unsigned int channelIdC = channelId - 1; // coloramps.h uses the C array indexing starting at 0 + const unsigned int iconfigC = mgOnGpu::channelId_to_iconfigC[channelId]; // coloramps.h uses a channel ordering not the diagram id fptype targetamp[ncolor] = { 0 }; for( int icolC = 0; icolC < ncolor; icolC++ ) { @@ -80,7 +80,7 @@ targetamp[icolC] = 0; else targetamp[icolC] = targetamp[icolC - 1]; - if( mgOnGpu::icolamp[channelIdC][icolC] ) targetamp[icolC] += jamp2_sv[icolC]; + if( mgOnGpu::icolamp[iconfigC][icolC] ) targetamp[icolC] += jamp2_sv[icolC]; } //printf( "sigmaKin: ievt=%%4d rndcol=%%f\n", ievt, allrndcol[ievt] ); for( int icolC = 0; icolC < ncolor; icolC++ ) @@ -115,7 +115,7 @@ // - firstprivate: give each thread its own copy, and initialise with value from outside #define _OMPLIST0 allcouplings, allMEs, allmomenta, allrndcol, allrndhel, allselcol, allselhel, cGoodHel, cNGoodHel, npagV2 #ifdef MGONGPU_SUPPORTS_MULTICHANNEL -#define _OMPLIST1 , allDenominators, allNumerators, channelId, mgOnGpu::icolamp +#define _OMPLIST1 , allDenominators, allNumerators, channelId, mgOnGpu::icolamp, mgOnGpu::channelId_to_iconfigC #else #define _OMPLIST1 #endif @@ -187,7 +187,7 @@ // Event-by-event random choice of color #402 if( channelId != 0 ) // no event-by-event choice of color if channelId == 0 (fix FPE #783) { - const unsigned int channelIdC = channelId - 1; // coloramps.h uses the C array indexing starting at 0 + const unsigned int iconfigC = mgOnGpu::channelId_to_iconfigC[channelId]; // coloramps.h uses a channel ordering not the diagram id fptype_sv targetamp[ncolor] = { 0 }; for( int icolC = 0; icolC < ncolor; icolC++ ) { @@ -195,9 +195,10 @@ targetamp[icolC] = fptype_sv{ 0 }; else targetamp[icolC] = targetamp[icolC - 1]; - if( mgOnGpu::icolamp[channelIdC][icolC] ) targetamp[icolC] += jamp2_sv[icolC]; + if( mgOnGpu::icolamp[iconfigC][icolC] ) targetamp[icolC] += jamp2_sv[icolC]; } #if defined MGONGPU_CPPSIMD and defined MGONGPU_FPTYPE_DOUBLE and defined MGONGPU_FPTYPE2_FLOAT + const unsigned int iconfigC = mgOnGpu::channelId_to_iconfigC[channelId]; // coloramps.h uses a channel ordering not the diagram id fptype_sv targetamp2[ncolor] = { 0 }; for( int icolC = 0; icolC < ncolor; icolC++ ) { @@ -205,7 +206,7 @@ targetamp2[icolC] = fptype_sv{ 0 }; else targetamp2[icolC] = targetamp2[icolC - 1]; - if( mgOnGpu::icolamp[channelIdC][icolC] ) targetamp2[icolC] += jamp2_sv[ncolor + icolC]; + if( mgOnGpu::icolamp[iconfigC][icolC] ) targetamp2[icolC] += jamp2_sv[ncolor + icolC]; } #endif for( int ieppV = 0; ieppV < neppV; ++ieppV ) diff --git a/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/model_handling.py b/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/model_handling.py index 4d917f5637..a735a80dc8 100644 --- a/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/model_handling.py +++ b/epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/model_handling.py @@ -1432,8 +1432,7 @@ def generate_process_files(self): self.edit_check_sa() self.edit_mgonGPU() self.edit_processidfile() # AV new file (NB this is Sigma-specific, should not be a symlink to Subprocesses) - if self.include_multi_channel: - self.edit_coloramps() # AV new file (NB this is Sigma-specific, should not be a symlink to Subprocesses) + self.edit_testxxx() # AV new file (NB this is generic in Subprocesses and then linked in Sigma-specific) self.edit_memorybuffers() # AV new file (NB this is generic in Subprocesses and then linked in Sigma-specific) self.edit_memoryaccesscouplings() # AV new file (NB this is generic in Subprocesses and then linked in Sigma-specific) @@ -1511,22 +1510,85 @@ def edit_processidfile(self): ff.write(template % replace_dict) ff.close() + + def generate_subprocess_directory_end(self, **opt): + """ opt contain all local variable of the fortran original function""" + if self.include_multi_channel: + #self.edit_coloramps() # AV new file (NB this is Sigma-specific, should not be a symlink to Subprocesses) + subproc_diagrams_for_config = opt['subproc_diagrams_for_config'] + misc.sprint(len(subproc_diagrams_for_config)) + self.edit_coloramps( subproc_diagrams_for_config) + # AV - new method - def edit_coloramps(self): + def edit_coloramps(self, config_subproc_map): """Generate coloramps.h""" + + ###misc.sprint('Entering PLUGIN_OneProcessExporter.edit_coloramps') template = open(pjoin(self.template_path,'gpu','coloramps.h'),'r').read() ff = open(pjoin(self.path, 'coloramps.h'),'w') # The following five lines from OneProcessExporterCPP.get_sigmaKin_lines (using OneProcessExporterCPP.get_icolamp_lines) replace_dict={} + + + iconfig_to_diag = {} + diag_to_iconfig = {} + iconfig = 0 + for config in config_subproc_map: + if set(config) == set([0]): + continue + iconfig += 1 + iconfig_to_diag[iconfig] = config[0] + diag_to_iconfig[config[0]] = iconfig + + misc.sprint(iconfig_to_diag) + misc.sprint(diag_to_iconfig) + + # Note that if the last diagram is/are not mapped to a channel nb_diag + # will be smaller than the true number of diagram. This is fine for color + # but maybe not for something else. + nb_diag = max(config[0] for config in config_subproc_map) + # Output which diagrams correspond ot a channel to get information for valid color + lines = [] + # Note: line for index 0 (no multi-channel is hardcoded in the template, so here we fill the array from index 1) + for diag in range(1, nb_diag+1): + if diag in diag_to_iconfig: + iconfigf = diag_to_iconfig[diag] + iconfigc = iconfigf - 1 # C convention + text = " %(iconfigc)i, // channelId=%(diag)i (diagram=%(diag)i) --> iconfig=%(iconfigf)i (f77 conv) and iconfigC=%(iconfigc)i (c conv)" + else: + iconfigc = -1 + iconfigf = -1 + text = " -1, // channelId=%(diag)i (diagram=%(diag)i): Not consider as a channel of integration (presence of 4 point interaction?)" + lines.append(text % {'diag': diag, 'iconfigc': iconfigc, 'iconfigf':iconfigf}) + + replace_dict['diag_to_channel'] = '\n'.join(lines) + if self.include_multi_channel: # NB unnecessary as edit_coloramps is not called otherwise... multi_channel = self.get_multi_channel_dictionary(self.matrix_elements[0].get('diagrams'), self.include_multi_channel) replace_dict['is_LC'] = self.get_icolamp_lines(multi_channel, self.matrix_elements[0], 1) replace_dict['nb_channel'] = len(multi_channel) + replace_dict['nb_diag_plus_one'] = max(config[0] for config in config_subproc_map)+1 replace_dict['nb_color'] = max(1,len(self.matrix_elements[0].get('color_basis'))) + + misc.sprint(multi_channel) + misc.sprint(self.path, os.getcwd()) + #raise Exception + # AV extra formatting (e.g. gg_tt was "{{true,true};,{true,false};,{false,true};};") - replace_dict['is_LC'] = replace_dict['is_LC'].replace(',',', ').replace('{{',' { ').replace('};, {',' },\n { ').replace('};};',' }') - ff.write(template % replace_dict) + split = replace_dict['is_LC'].split(';,') + misc.sprint(replace_dict['is_LC']) + for i in range(len(split)): + misc.sprint(split[i]) + split[i] = ' ' + split[i].replace(',',', ').replace('{{', '{') + misc.sprint(split[i]) + if '};};' in split[i]: + split[i] = split[i][:-4] + '}, // iconfigC=%i, diag=%i' % (i, iconfig_to_diag[i+1]) + elif 'false' in split[i] or 'true' in split[i]: + split[i] += ', // iconfigC=%i, diag=%i' % (i, iconfig_to_diag[i+1]) + misc.sprint(split[i]) + replace_dict['is_LC'] = '\n'.join(split) + ff.write(template % replace_dict) ff.close() # AV - new method @@ -1675,6 +1737,7 @@ def get_reset_jamp_lines(self, color_amplitudes): if ret_lines != '' : ret_lines = ' // Reset jamp (reset color flows)\n' + ret_lines # AV THIS SHOULD NEVER HAPPEN! return ret_lines + #------------------------------------------------------------------------------------ import madgraph.core.helas_objects as helas_objects