Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Fix 826" (actually: fix iconfig-channel mapping) #852

Merged
merged 8 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading