/* * Copyright(C) 1999-2021, 2023 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * * See packages/seacas/LICENSE for details */ #include "fmt/ostream.h" #include "ps_pario_const.h" // for Parallel_IO, PIO_Info #include "rf_allo.h" // for array_alloc #include "rf_io_const.h" // for Debug_Flag #include #include // for exit #include // for strlen, etc #include #include /*********** R O U T I N E S I N T H I S F I L E *********************** Name_of_Routine type Called by --------------------------------------------------------------------------- pdisk_stage_begin() void load_mesh (pe_exoII_io.c) pdisk_stage_end() void load_mesh (pe_exoII_io.c) gen_par_filename() void load_lb_info (rf_load_lb_info.c) load_mesh (pe_exoII_io.c) ******************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void gen_disk_map(struct Parallel_IO *pio_info, const std::array &proc_info, int /*proc*/, int nproc) /* * This function generates a map of which processor ID writes to which * RAID. Note that this is for each processor in the list, not necessarily * the same as the number of processors being used during the run. Each * processor has an identical list. */ { /* Allocate memory for the list */ pio_info->RDsk_List = reinterpret_cast(array_alloc(__FILE__, __LINE__, 2, proc_info[0], 2, sizeof(int))); if ((pio_info->RDsk_List) == nullptr) { fmt::print(stderr, "{}: ERROR, insufficient memory\n", __func__); exit(1); } /* Generate the list of disks to which data will be written */ if (pio_info->Dsk_List_Cnt <= 0) { for (int iproc = 0; iproc < proc_info[0]; iproc++) { int ctrl_id = (iproc % pio_info->Num_Dsk_Ctrlrs); pio_info->RDsk_List[iproc][0] = ctrl_id + pio_info->PDsk_Add_Fact; } } else { for (int iproc = 0; iproc < proc_info[0]; iproc++) { pio_info->RDsk_List[iproc][0] = pio_info->Dsk_List[iproc % pio_info->Dsk_List_Cnt]; } } /* Generate the list of processors on which info is stored */ for (int iproc = 0; iproc < proc_info[0]; iproc++) { int proc_id = iproc; while (proc_id >= nproc) { proc_id -= nproc; } pio_info->RDsk_List[iproc][1] = proc_id; } } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ std::string gen_par_filename(const std::string &scalar_fname, int proc_for, int nprocs) /*---------------------------------------------------------------------------- * * Author(s): Gary Hennigan (1421) *---------------------------------------------------------------------------- * Function which generates the name of a parallel file for a * particular processor. The function does this by appending * "N.p" to the end of the input parameter "scalar_fname", where: * * N - The number of processors utilized * p - The processor ID. * * In addition, the location of the parallel disk system is prepended * to each file name. *--------------------------------------------------------------------------- * Example: * * scalar_fname = "Parallel-exoII-" (Input) * par_fname = "/raid/io_01/tmp/rf_crew/Parallel-exoII-8.0" (Output) * * where, for this example: * * N = 8 processors * p = 0 particular processor ID *--------------------------------------------------------------------------- * Revision History: * * 05 November 1993: Date of Creation *--------------------------------------------------------------------------- */ { /* * Find out the number of digits needed to specify the processor ID. * This allows numbers like 01-99, i.e., prepending zeros to the * name to preserve proper alphabetic sorting of the files. */ int iMaxDigit = 0; int iMyDigit = 0; int iTemp1 = nprocs; do { iTemp1 /= 10; iMaxDigit++; } while (iTemp1 >= 1); iTemp1 = proc_for; do { iTemp1 /= 10; iMyDigit++; } while (iTemp1 >= 1); /* * Append the number of processors in this run to the scalar file name * along with a '.' (period). */ std::string par_filename = scalar_fname + std::string(".") + std::to_string(nprocs) + std::string("."); /* * Append the proper number of zeros to the filename. */ for (int i1 = 0; i1 < iMaxDigit - iMyDigit; i1++) { par_filename += std::string("0"); } /* * Generate the name of the directory on which the parallel disk * array resides. This also directs which processor writes to what * disk. */ par_filename += std::to_string(proc_for); /* * Finally, generate the complete file specification for the parallel * file used by this processor. */ if (PIO_Info.NoSubdirectory == 1) { par_filename = PIO_Info.Par_Dsk_Root + PIO_Info.Par_Dsk_SubDirec + par_filename; } else { if (PIO_Info.Zeros != 0) { int ctrlID = PIO_Info.RDsk_List[proc_for][0]; if (ctrlID <= 9) { par_filename = PIO_Info.Par_Dsk_Root + "0" + std::to_string(ctrlID) + "/" + PIO_Info.Par_Dsk_SubDirec + par_filename; } else { par_filename = PIO_Info.Par_Dsk_Root + std::to_string(ctrlID) + "/" + PIO_Info.Par_Dsk_SubDirec + par_filename; } } else { int ctrlID = PIO_Info.RDsk_List[proc_for][0]; par_filename = PIO_Info.Par_Dsk_Root + std::to_string(ctrlID) + "/" + PIO_Info.Par_Dsk_SubDirec + par_filename; } } if (Debug_Flag >= 4) { fmt::print("Parallel file name: {}\n", par_filename); } return par_filename; }