// for the time being, this is ok. When we can, add some logic in the sprintf calls that checks if a longer buffer would be needed, and in case expand it
// in any case, replace all sprintf() with snprintf(), to avoid in any case writing more than the available buffer size
charvirtual_line[256];
// Create and initialise pristine cid for MPI proc 0 and thread 0
// reallocate a new one (even if it would be more efficient to emty the existing one
deletep_output;
p_output=newVirtualAsciiFile();
// now tppoan
vtppoanp->write_to_disk(output_path+"/c_TPPOAN");
deletevtppoanp;
vtppoanp=newVirtualBinaryFile();
// here go the calls that send data to be duplicated on other MPI processes from process 0 to others, using MPI broadcasts, but only if MPI is actually used
// Create this variable and initialise it with a default here, so that it is defined anyway, with or without OpenMP support enabled
intompnumthreads=1;
// this is for MPI process 0 (or even if we are not using MPI at all)
intmyjxi488startoffset=0;
intmyMPIstride=ompnumthreads;
intmyMPIblock=ompnumthreads;
// Define here shared arrays of virtual ascii and binary files, so that thread 0 will be able to access the all later
VirtualAsciiFile**p_outarray=NULL;
VirtualBinaryFile**vtppoanarray=NULL;
#ifdef USE_NVTX
nvtxRangePush("Parallel loop");
#endif
//===========================================
// open the OpenMP parallel context, so each thread can initialise its stuff
//===========================================
#pragma omp parallel
{
// Create and initialise this variable here, so that if OpenMP is enabled it is local to the thread, and if OpenMP is not enabled it has a well-defiled value anyway
intmyompthread=0;
#ifdef _OPENMP
// If OpenMP is enabled, give actual values to myompthread and ompnumthreads, and open thread-local output files
// only go through this if MPI has been actually used
for(intrr=1;rr<mpidata->nprocs;rr++){
// individually send their respective starting points to other MPI processes: they start immediately after the frequencies computed by previous processes so far
// add an omp barrier to make sure that the global variables defined by thread 0 are known to all threads below this
#pragma omp barrier
// To test parallelism, I will now start feeding this function with "clean" copies of the parameters, so that they will not be changed by previous iterations, and each one will behave as the first one. Define all (empty) variables here, so they have the correct scope, then they get different definitions depending on thread number
ClusterIterationData*cid_2=NULL;
//FILE *output_2 = NULL;
VirtualAsciiFile*p_output_2=NULL;
VirtualBinaryFile*vtppoanp_2=NULL;
// fstream *tppoanp_2 = NULL;
// for threads other than the 0, create distinct copies of all relevant data, while for thread 0 just define new references / pointers to the original ones
if(myompthread==0){
cid_2=cid;
//output_2 = output;
p_output_2=p_output;
// tppoanp_2 = tppoanp;
vtppoanp_2=vtppoanp;
}else{
// this is not thread 0, so do create fresh copies of all local variables
// make sure all threads align here: I don't want the following loop to accidentally start for thread 0, possibly modifying some variables before they are copied by all other threads
#pragma omp barrier
if(myompthread==0){
logger->log("Syncing OpenMP threads and starting the loop on wavelengths\n");
}
#pragma omp barrier
// ok, now I can actually start the parallel calculations
// To test parallelism, I will now start feeding this function with "clean" copies of the parameters, so that they will not be changed by previous iterations, and each one will behave as the first one. Define all (empty) variables here, so they have the correct scope, then they get different definitions depending on thread number
ClusterIterationData*cid_2=NULL;
VirtualAsciiFile*p_output_2=NULL;
VirtualBinaryFile*vtppoanp_2=NULL;
// PLACEHOLDER
// for threads other than the 0, create distinct copies of all relevant data, while for thread 0 just define new references / pointers to the original ones
// this is not thread 0, so do create fresh copies of all local variables
cid_2=newClusterIterationData(*cid);
}
// make sure all threads align here: I don't want the following loop to accidentally start for thread 0, possibly modifying some variables before they are copied by all other threads
#pragma omp barrier
// ok, now I can actually start the parallel calculations
// each thread opens new virtual files and stores their pointers in the shared array
p_output_2=newVirtualAsciiFile();
p_outarray[myompthread]=p_output_2;
vtppoanp_2=newVirtualBinaryFile();
// each thread puts a copy of the pointers to its virtual files in the shared arrays
p_outarray[myompthread]=p_output_2;
vtppoanarray[myompthread]=vtppoanp_2;
// make sure all threads align here: I don't want the following loop to accidentally start for thread 0, possibly modifying some variables before they are copied by all other threads
#pragma omp barrier
if(myompthread==0)logger->log("Syncing OpenMP threads and starting the loop on wavelengths\n");
// ok, now I can actually start the parallel calculations