Skip to content

Commit

Permalink
Merge pull request #852 from madgraph5/fix_826
Browse files Browse the repository at this point in the history
"Fix 826" (actually: fix iconfig-channel mapping)
  • Loading branch information
valassi authored Jul 3, 2024
2 parents 0992927 + d23e773 commit 3ffb82a
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 13 deletions.
2 changes: 1 addition & 1 deletion MG5aMC/mg5amcnlo
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,34 @@
#ifndef COLORAMPS_H
#define COLORAMPS_H 1

#include <map>

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
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@
// 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++ )
{
if( icolC == 0 )
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++ )
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -187,25 +187,26 @@
// 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++ )
{
if( icolC == 0 )
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++ )
{
if( icolC == 0 )
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 )
Expand Down
73 changes: 68 additions & 5 deletions epochX/cudacpp/CODEGEN/PLUGIN/CUDACPP_SA_OUTPUT/model_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 3ffb82a

Please sign in to comment.