Loading src/cluster/cluster.cpp +12 −28 Original line number Diff line number Diff line Loading @@ -440,8 +440,8 @@ void cluster(const string& config_file, const string& data_file, const string& o int jer = cluster_jxi488_cycle(myjxi488, sconf, gconf, p_scattering_angles, cid_2, p_output_2, output_path, vtppoanp_2); } else { if (myompthread > 0) { // If there is no input for this thread, set output pointer to NULL. p_outarray[myompthread] = NULL; // If there is no input for this thread, mark to skip. p_outarray[myompthread] = new ClusterOutputInfo(1); } } #pragma omp barrier Loading @@ -453,11 +453,9 @@ void cluster(const string& config_file, const string& data_file, const string& o // threads different from 0 append their virtual files to the one of thread 0, and delete them if (myompthread == 0) { for (int ti=1; ti<ompnumthreads; ti++) { if (p_outarray[ti] != NULL) { p_outarray[0]->insert(*(p_outarray[ti])); delete p_outarray[ti]; p_outarray[ti] = NULL; } vtppoanarray[0]->append(*(vtppoanarray[ti])); delete vtppoanarray[ti]; } Loading Loading @@ -628,39 +626,25 @@ void cluster(const string& config_file, const string& data_file, const string& o } int jer = cluster_jxi488_cycle(myjxi488, sconf, gconf, p_scattering_angles, cid_2, p_output_2, output_path, vtppoanp_2); } else { // if (myompthread > 0) { // If there is no input for this thread, set the output pointer to NULL. p_outarray[myompthread] = NULL; //} p_outarray[myompthread] = new ClusterOutputInfo(1); } #pragma omp barrier // threads different from 0 append their virtual files to the one of thread 0, and delete them if (myompthread == 0) { for (int ti=1; ti<ompnumthreads; ti++) { if (p_outarray[ti] != NULL) { p_outarray[0]->insert(*(p_outarray[ti])); delete p_outarray[ti]; p_outarray[ti] = NULL; } vtppoanarray[0]->append(*(vtppoanarray[ti])); delete vtppoanarray[ti]; } // thread 0 sends the collected virtualfiles to thread 0 of MPI process 0, then deletes them for (int rr=1; rr<mpidata->nprocs; rr++) { if (rr == mpidata->rank) { if (p_outarray[0] == NULL) { // signal that we are not sending anything int skip_flag = 1; MPI_Send(&skip_flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // signal that we are sending something int skip_flag = 0; MPI_Send(&skip_flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); p_outarray[0]->mpisend(mpidata); delete p_outarray[0]; } p_outarray[0] = NULL; vtppoanarray[0]->mpisend(mpidata); delete vtppoanarray[0]; } Loading src/include/errors.h +26 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,32 @@ #ifndef INCLUDE_ERRORS_H_ #define INCLUDE_ERRORS_H_ /*! \brief Exception for wrong OutputInfo NULL calls. */ class UnrecognizedOutputInfo: public std::exception { protected: //! Description of the problem. std::string message; public: /** * \brief Exception instance constructor. * * \param requested: `int` The index that was requested. */ UnrecognizedOutputInfo(int requested) { message = "Error: passed parameter " + std::to_string(requested) + ", but only 1 is allowed"; } /** * \brief Exception message. */ virtual const char* what() const throw() { return message.c_str(); } }; /*! \brief Exception for out of bounds List requests. */ class ListOutOfBoundsException: public std::exception { Loading src/include/outputs.h +30 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ */ class ClusterOutputInfo { protected: //! \brief Flag for skipping mpisend() and mpireceive() int _skip_flag; //! \brief Number of incident azimuth calculations. int _num_theta; //! \brief Number of scattered azimuth calculations. Loading Loading @@ -63,6 +65,8 @@ protected: int write_legacy(const std::string &output); public: //! \brief Read-only view on skip_flag const int &skip_flag = _skip_flag; //! \brief Read-only view on the ID of the first scale const int &first_xi = _first_xi; //! \brief Number of spheres in the aggregate. Loading Loading @@ -471,6 +475,12 @@ public: */ ClusterOutputInfo(const std::string &hdf5_name); /*! \brief `ClusterOutputInfo` constructor for the dummy NULL case * * \param skip_flag: `const int` must be passed as the `1` constant. */ ClusterOutputInfo(const int skip_flag); /*! \brief `ClusterOutputInfo` instance destroyer. */ ~ClusterOutputInfo(); Loading Loading @@ -551,6 +561,8 @@ public: */ class InclusionOutputInfo { protected: //! \brief Flag for skipping mpisend() and mpireceive() int _skip_flag; //! \brief Number of incident azimuth calculations. int _num_theta; //! \brief Number of scattered azimuth calculations. Loading Loading @@ -581,6 +593,8 @@ protected: int write_legacy(const std::string &output); public: //! \brief Read-only view on skip_flag const int &skip_flag = _skip_flag; //! \brief Read-only view on the ID of the first scale const int &first_xi = _first_xi; //! \brief Number of spheres in the aggregate. Loading Loading @@ -901,6 +915,12 @@ public: */ InclusionOutputInfo(const std::string &hdf5_name); /*! \brief `InclusionOutputInfo` constructor for the dummy NULL case * * \param skip_flag: `const int` must be passed as the `1` constant. */ InclusionOutputInfo(const int skip_flag); /*! \brief `InclusionOutputInfo` instance destroyer. */ ~InclusionOutputInfo(); Loading Loading @@ -981,6 +1001,8 @@ public: */ class SphereOutputInfo { protected: //! \brief Flag for skipping mpisend() and mpireceive() int _skip_flag; //! \brief Number of incident azimuth calculations. int _num_theta; //! \brief Number of scattered azimuth calculations. Loading Loading @@ -1011,6 +1033,8 @@ protected: int write_legacy(const std::string &output); public: //! \brief Read-only view on skip_flag const int &skip_flag = _skip_flag; //! \brief Read-only view on the ID of the first scale const int &first_xi = _first_xi; //! \brief Number of spheres. Loading Loading @@ -1181,6 +1205,12 @@ public: */ SphereOutputInfo(const std::string &hdf5_name); /*! \brief `SphereOutputInfo` constructor for the dummy NULL case * * \param skip_flag: `const int` must be passed as the `1` constant. */ SphereOutputInfo(const int skip_flag); /*! \brief `InclusionOutputInfo` instance destroyer. */ ~SphereOutputInfo(); Loading src/inclusion/inclusion.cpp +11 −27 Original line number Diff line number Diff line Loading @@ -437,7 +437,7 @@ void inclusion(const string& config_file, const string& data_file, const string& } else { if (myompthread > 0) { // If there is no input for this thread, set output pointer to NULL. p_outarray[myompthread] = NULL; p_outarray[myompthread] = new InclusionOutputInfo(1); } } #pragma omp barrier Loading @@ -449,11 +449,9 @@ void inclusion(const string& config_file, const string& data_file, const string& // threads different from 0 append their virtual files to the one of thread 0, and delete them if (myompthread == 0) { for (int ti=1; ti<ompnumthreads; ti++) { if (p_outarray[ti] != NULL) { p_outarray[0]->insert(*(p_outarray[ti])); delete p_outarray[ti]; p_outarray[ti] = NULL; } vtppoanarray[0]->append(*(vtppoanarray[ti])); delete vtppoanarray[ti]; } Loading Loading @@ -624,39 +622,25 @@ void inclusion(const string& config_file, const string& data_file, const string& } int jer = inclusion_jxi488_cycle(myjxi488, sconf, gconf, p_scattering_angles, cid_2, p_output_2, output_path, vtppoanp_2); } else { //if (myompthread > 0) { // If there is no input for this thread, set the output pointer to NULL. p_outarray[myompthread] = NULL; //} p_outarray[myompthread] = new InclusionOutputInfo(1); } #pragma omp barrier // threads different from 0 append their virtual files to the one of thread 0, and delete them if (myompthread == 0) { for (int ti=1; ti<ompnumthreads; ti++) { if (p_outarray[ti] != NULL) { p_outarray[0]->insert(*(p_outarray[ti])); delete p_outarray[ti]; p_outarray[ti] = NULL; } vtppoanarray[0]->append(*(vtppoanarray[ti])); delete vtppoanarray[ti]; } // thread 0 sends the collected virtualfiles to thread 0 of MPI process 0, then deletes them for (int rr=1; rr<mpidata->nprocs; rr++) { if (rr == mpidata->rank) { if (p_outarray[0] == NULL) { // signal that we are not sending anything int skip_flag = 1; MPI_Send(&skip_flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // signal that we are sending something int skip_flag = 0; MPI_Send(&skip_flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); p_outarray[0]->mpisend(mpidata); delete p_outarray[0]; } p_outarray[0] = NULL; vtppoanarray[0]->mpisend(mpidata); delete vtppoanarray[0]; } Loading src/libnptm/outputs.cpp +1173 −1090 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ ClusterOutputInfo::ClusterOutputInfo( ScattererConfiguration *sc, GeometryConfiguration *gc, const mixMPI *mpidata, int first_xi, int xi_length ) { _skip_flag = 0; nsph = gc->number_of_spheres; li = gc->li; le = gc->le; Loading Loading @@ -293,6 +294,7 @@ ClusterOutputInfo::ClusterOutputInfo(const std::string &hdf5_name) { HDFFile *hdf_file = new HDFFile(hdf5_name, flags); herr_t status = hdf_file->get_status(); string str_name, str_type; _skip_flag = 0; if (status == 0) { status = hdf_file->read("NSPH", "INT32_(1)", &nsph); status = hdf_file->read("LI", "INT32_(1)", &li); Loading Loading @@ -701,7 +703,20 @@ ClusterOutputInfo::ClusterOutputInfo(const std::string &hdf5_name) { } } ClusterOutputInfo::ClusterOutputInfo(const int flag) { /* create a dummy placeholder just to know I should skip MPI_Send and MPI_Recv */ if (flag == 1) { _skip_flag = 1; } else { UnrecognizedOutputInfo ex(flag); throw ex; } } ClusterOutputInfo::~ClusterOutputInfo() { if (_skip_flag != 1) { delete[] vec_x_coords; delete[] vec_y_coords; delete[] vec_z_coords; Loading Loading @@ -866,6 +881,7 @@ ClusterOutputInfo::~ClusterOutputInfo() { delete[] vec_dir_mulc; delete[] vec_dir_mulclr; } } long ClusterOutputInfo::compute_size( ScattererConfiguration *sc, GeometryConfiguration *gc, Loading Loading @@ -961,6 +977,7 @@ long ClusterOutputInfo::compute_size() { int ClusterOutputInfo::insert(const ClusterOutputInfo &rhs) { int result = 0; if (rhs.skip_flag != 1) { result += (rhs.nsph == nsph) ? 0 : 1; result += (rhs.inpol == inpol) ? 0 : 1; result += (rhs.iavm == iavm) ? 0 : 1; Loading Loading @@ -1138,6 +1155,7 @@ int ClusterOutputInfo::insert(const ClusterOutputInfo &rhs) { memcpy(vec_dir_mulc + 16 * offset, rhs.vec_dir_mulc, 16 * chunk_size * sizeof(double)); memcpy(vec_dir_mulclr + 16 * offset, rhs.vec_dir_mulclr, 16 * chunk_size * sizeof(double)); } } return result; } Loading Loading @@ -2356,13 +2374,13 @@ int ClusterOutputInfo::write_legacy(const std::string &output) { #ifdef MPI_VERSION int ClusterOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { int result = 0; int skip_flag; int flag; int chk_nsph, chk_inpol, chk_iavm, chk_isam, chk_num_theta, chk_num_thetas; int chk_num_phi, chk_num_phis, chk_ndirs, chk_idfc, chk_configs; double chk_exri; MPI_Recv(&skip_flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if__ skip_flag==0, else nothing is to be received if (skip_flag == 0) { MPI_Recv(&flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if_ skip_flag==0, else nothing is to be received if (flag == 0) { MPI_Recv(&chk_nsph, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_inpol, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_iavm, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); Loading Loading @@ -2562,10 +2580,18 @@ int ClusterOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { return result; } int ClusterOutputInfo::mpisend(const mixMPI *mpidata) { int result = 0; int chunk_size; if (_skip_flag == 1) { // tell the receiver we are not sending anything int flag = 1; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // tell the receiver we are sending actual stuff int flag = 0; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); // Send output metadata for configuration cross-check MPI_Send(&nsph, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&inpol, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); Loading Loading @@ -2748,6 +2774,7 @@ int ClusterOutputInfo::mpisend(const mixMPI *mpidata) { MPI_Send(vec_dir_mulc, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); MPI_Send(vec_dir_mulclr, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); } } return result; } #endif //MPI_VERSION Loading @@ -2758,6 +2785,7 @@ InclusionOutputInfo::InclusionOutputInfo( ScattererConfiguration *sc, GeometryConfiguration *gc, const mixMPI *mpidata, int first_xi, int xi_length ) { _skip_flag = 0; nsph = gc->number_of_spheres; li = gc->li; le = gc->le; Loading Loading @@ -2946,6 +2974,7 @@ InclusionOutputInfo::InclusionOutputInfo(const std::string &hdf5_name) { HDFFile *hdf_file = new HDFFile(hdf5_name, flags); herr_t status = hdf_file->get_status(); string str_name, str_type; _skip_flag = 0; if (status == 0) { status = hdf_file->read("NSPH", "INT32_(1)", &nsph); status = hdf_file->read("LI", "INT32_(1)", &li); Loading Loading @@ -3260,7 +3289,20 @@ InclusionOutputInfo::InclusionOutputInfo(const std::string &hdf5_name) { } } InclusionOutputInfo::InclusionOutputInfo(const int flag) { /* create a dummy placeholder just to know I should skip MPI_Send and MPI_Recv */ if (flag == 1) { _skip_flag = 1; } else { UnrecognizedOutputInfo ex(flag); throw ex; } } InclusionOutputInfo::~InclusionOutputInfo() { if (_skip_flag != 1) { delete[] vec_x_coords; delete[] vec_y_coords; delete[] vec_z_coords; Loading Loading @@ -3382,6 +3424,7 @@ InclusionOutputInfo::~InclusionOutputInfo() { delete[] vec_dir_mull; delete[] vec_dir_mulllr; } } long InclusionOutputInfo::compute_size() { long result = sizeof(np_int); Loading Loading @@ -3439,6 +3482,7 @@ long InclusionOutputInfo::compute_size( int InclusionOutputInfo::insert(const InclusionOutputInfo &rhs) { int result = 0; if (rhs.skip_flag != 1) { result += (rhs.nsph == nsph) ? 0 : 1; result += (rhs.inpol == inpol) ? 0 : 1; result += (rhs.iavm == iavm) ? 0 : 1; Loading Loading @@ -3572,6 +3616,7 @@ int InclusionOutputInfo::insert(const InclusionOutputInfo &rhs) { memcpy(vec_dir_mull + 16 * offset, rhs.vec_dir_mull, 16 * chunk_size * sizeof(double)); memcpy(vec_dir_mulllr + 16 * offset, rhs.vec_dir_mulllr, 16 * chunk_size * sizeof(double)); } } return result; } Loading Loading @@ -4485,13 +4530,13 @@ int InclusionOutputInfo::write_legacy(const std::string &output) { #ifdef MPI_VERSION int InclusionOutputInfo::mpireceive(const mixMPI* mpidata, int pid) { int result = 0; int skip_flag; int flag; int chk_nsph, chk_inpol, chk_iavm, chk_isam, chk_num_theta, chk_num_thetas; int chk_num_phi, chk_num_phis, chk_ndirs, chk_idfc, chk_configs; double chk_exri; MPI_Recv(&skip_flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if__ skip_flag==0, else nothing is to be received if (skip_flag == 0) { MPI_Recv(&flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if_ flag==0, else nothing is to be received if (flag == 0) { MPI_Recv(&chk_nsph, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_inpol, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_iavm, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); Loading Loading @@ -4648,6 +4693,15 @@ int InclusionOutputInfo::mpireceive(const mixMPI* mpidata, int pid) { int InclusionOutputInfo::mpisend(const mixMPI *mpidata) { int result = 0; int chunk_size; if (_skip_flag == 1) { // tell the receiver we are not sending anything int flag = 1; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // tell the receiver we are sending actual stuff int flag = 0; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); // Send output metadata for configuration cross-check MPI_Send(&nsph, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&inpol, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); Loading Loading @@ -4783,6 +4837,7 @@ int InclusionOutputInfo::mpisend(const mixMPI *mpidata) { MPI_Send(vec_dir_mull, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); MPI_Send(vec_dir_mulllr, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); } } return result; } #endif // MPI_VERSION Loading @@ -4793,6 +4848,7 @@ SphereOutputInfo::SphereOutputInfo( ScattererConfiguration *sc, GeometryConfiguration *gc, const mixMPI *mpidata, int first_xi, int xi_length ) { _skip_flag = 0; _first_xi = first_xi; nsph = gc->number_of_spheres; lm = gc->l_max; Loading Loading @@ -4905,6 +4961,7 @@ SphereOutputInfo::SphereOutputInfo(const std::string &hdf5_name) { HDFFile *hdf_file = new HDFFile(hdf5_name, flags); herr_t status = hdf_file->get_status(); string str_name, str_type; _skip_flag = 0; if (status == 0) { status = hdf_file->read("NSPH", "INT32_(1)", &nsph); status = hdf_file->read("LM", "INT32_(1)", &lm); Loading Loading @@ -5077,7 +5134,20 @@ SphereOutputInfo::SphereOutputInfo(const std::string &hdf5_name) { } } SphereOutputInfo::SphereOutputInfo(const int flag) { /* create a dummy placeholder just to know I should skip MPI_Send and MPI_Recv */ if (flag == 1) { _skip_flag = 1; } else { UnrecognizedOutputInfo ex(flag); throw ex; } } SphereOutputInfo::~SphereOutputInfo() { if (_skip_flag != 1) { delete[] vec_jxi; delete[] vec_ier; delete[] vec_vk; Loading Loading @@ -5128,6 +5198,7 @@ SphereOutputInfo::~SphereOutputInfo() { delete[] vec_dir_muls; delete[] vec_dir_mulslr; } } long SphereOutputInfo::compute_size( ScattererConfiguration *sc, GeometryConfiguration *gc, Loading Loading @@ -5202,6 +5273,7 @@ long SphereOutputInfo::compute_size() { int SphereOutputInfo::insert(const SphereOutputInfo &rhs) { int result = 0; if (rhs.skip_flag != 1) { result += (rhs.nsph == nsph) ? 0 : 1; result += (rhs.inpol == inpol) ? 0 : 1; result += (rhs.isam == isam) ? 0 : 1; Loading Loading @@ -5271,6 +5343,7 @@ int SphereOutputInfo::insert(const SphereOutputInfo &rhs) { memcpy(vec_dir_fz + offset, rhs.vec_dir_fz, chunk_size * sizeof(double)); // TODO: fix the vector sizes in HDF5 writer and MPI communicators } } return result; } Loading Loading @@ -5746,13 +5819,13 @@ int SphereOutputInfo::write_legacy(const std::string &file_name) { #ifdef MPI_VERSION int SphereOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { int result = 0; int skip_flag; int flag; int chk_nsph, chk_inpol, chk_isam, chk_num_theta, chk_num_thetas; int chk_num_phi, chk_num_phis, chk_ndirs, chk_idfc, chk_configs; double chk_exri; MPI_Recv(&skip_flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if__ skip_flag==0, else nothing is to be received if (skip_flag == 0) { MPI_Recv(&flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if_ flag==0, else nothing is to be received if (flag == 0) { MPI_Recv(&chk_nsph, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_inpol, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_isam, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); Loading Loading @@ -5842,6 +5915,15 @@ int SphereOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { int SphereOutputInfo::mpisend(const mixMPI *mpidata) { int result = 0; int chunk_size; if (_skip_flag == 1) { // tell the receiver we are not sending anything int flag = 1; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // tell the receiver we are sending actual stuff int flag = 0; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); // Send output metadata for configuration cross-check MPI_Send(&nsph, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&inpol, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); Loading Loading @@ -5911,6 +5993,7 @@ int SphereOutputInfo::mpisend(const mixMPI *mpidata) { MPI_Send(vec_dir_fy, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); MPI_Send(vec_dir_fz, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); } } return result; } #endif // MPI_VERSION Loading Loading
src/cluster/cluster.cpp +12 −28 Original line number Diff line number Diff line Loading @@ -440,8 +440,8 @@ void cluster(const string& config_file, const string& data_file, const string& o int jer = cluster_jxi488_cycle(myjxi488, sconf, gconf, p_scattering_angles, cid_2, p_output_2, output_path, vtppoanp_2); } else { if (myompthread > 0) { // If there is no input for this thread, set output pointer to NULL. p_outarray[myompthread] = NULL; // If there is no input for this thread, mark to skip. p_outarray[myompthread] = new ClusterOutputInfo(1); } } #pragma omp barrier Loading @@ -453,11 +453,9 @@ void cluster(const string& config_file, const string& data_file, const string& o // threads different from 0 append their virtual files to the one of thread 0, and delete them if (myompthread == 0) { for (int ti=1; ti<ompnumthreads; ti++) { if (p_outarray[ti] != NULL) { p_outarray[0]->insert(*(p_outarray[ti])); delete p_outarray[ti]; p_outarray[ti] = NULL; } vtppoanarray[0]->append(*(vtppoanarray[ti])); delete vtppoanarray[ti]; } Loading Loading @@ -628,39 +626,25 @@ void cluster(const string& config_file, const string& data_file, const string& o } int jer = cluster_jxi488_cycle(myjxi488, sconf, gconf, p_scattering_angles, cid_2, p_output_2, output_path, vtppoanp_2); } else { // if (myompthread > 0) { // If there is no input for this thread, set the output pointer to NULL. p_outarray[myompthread] = NULL; //} p_outarray[myompthread] = new ClusterOutputInfo(1); } #pragma omp barrier // threads different from 0 append their virtual files to the one of thread 0, and delete them if (myompthread == 0) { for (int ti=1; ti<ompnumthreads; ti++) { if (p_outarray[ti] != NULL) { p_outarray[0]->insert(*(p_outarray[ti])); delete p_outarray[ti]; p_outarray[ti] = NULL; } vtppoanarray[0]->append(*(vtppoanarray[ti])); delete vtppoanarray[ti]; } // thread 0 sends the collected virtualfiles to thread 0 of MPI process 0, then deletes them for (int rr=1; rr<mpidata->nprocs; rr++) { if (rr == mpidata->rank) { if (p_outarray[0] == NULL) { // signal that we are not sending anything int skip_flag = 1; MPI_Send(&skip_flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // signal that we are sending something int skip_flag = 0; MPI_Send(&skip_flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); p_outarray[0]->mpisend(mpidata); delete p_outarray[0]; } p_outarray[0] = NULL; vtppoanarray[0]->mpisend(mpidata); delete vtppoanarray[0]; } Loading
src/include/errors.h +26 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,32 @@ #ifndef INCLUDE_ERRORS_H_ #define INCLUDE_ERRORS_H_ /*! \brief Exception for wrong OutputInfo NULL calls. */ class UnrecognizedOutputInfo: public std::exception { protected: //! Description of the problem. std::string message; public: /** * \brief Exception instance constructor. * * \param requested: `int` The index that was requested. */ UnrecognizedOutputInfo(int requested) { message = "Error: passed parameter " + std::to_string(requested) + ", but only 1 is allowed"; } /** * \brief Exception message. */ virtual const char* what() const throw() { return message.c_str(); } }; /*! \brief Exception for out of bounds List requests. */ class ListOutOfBoundsException: public std::exception { Loading
src/include/outputs.h +30 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ */ class ClusterOutputInfo { protected: //! \brief Flag for skipping mpisend() and mpireceive() int _skip_flag; //! \brief Number of incident azimuth calculations. int _num_theta; //! \brief Number of scattered azimuth calculations. Loading Loading @@ -63,6 +65,8 @@ protected: int write_legacy(const std::string &output); public: //! \brief Read-only view on skip_flag const int &skip_flag = _skip_flag; //! \brief Read-only view on the ID of the first scale const int &first_xi = _first_xi; //! \brief Number of spheres in the aggregate. Loading Loading @@ -471,6 +475,12 @@ public: */ ClusterOutputInfo(const std::string &hdf5_name); /*! \brief `ClusterOutputInfo` constructor for the dummy NULL case * * \param skip_flag: `const int` must be passed as the `1` constant. */ ClusterOutputInfo(const int skip_flag); /*! \brief `ClusterOutputInfo` instance destroyer. */ ~ClusterOutputInfo(); Loading Loading @@ -551,6 +561,8 @@ public: */ class InclusionOutputInfo { protected: //! \brief Flag for skipping mpisend() and mpireceive() int _skip_flag; //! \brief Number of incident azimuth calculations. int _num_theta; //! \brief Number of scattered azimuth calculations. Loading Loading @@ -581,6 +593,8 @@ protected: int write_legacy(const std::string &output); public: //! \brief Read-only view on skip_flag const int &skip_flag = _skip_flag; //! \brief Read-only view on the ID of the first scale const int &first_xi = _first_xi; //! \brief Number of spheres in the aggregate. Loading Loading @@ -901,6 +915,12 @@ public: */ InclusionOutputInfo(const std::string &hdf5_name); /*! \brief `InclusionOutputInfo` constructor for the dummy NULL case * * \param skip_flag: `const int` must be passed as the `1` constant. */ InclusionOutputInfo(const int skip_flag); /*! \brief `InclusionOutputInfo` instance destroyer. */ ~InclusionOutputInfo(); Loading Loading @@ -981,6 +1001,8 @@ public: */ class SphereOutputInfo { protected: //! \brief Flag for skipping mpisend() and mpireceive() int _skip_flag; //! \brief Number of incident azimuth calculations. int _num_theta; //! \brief Number of scattered azimuth calculations. Loading Loading @@ -1011,6 +1033,8 @@ protected: int write_legacy(const std::string &output); public: //! \brief Read-only view on skip_flag const int &skip_flag = _skip_flag; //! \brief Read-only view on the ID of the first scale const int &first_xi = _first_xi; //! \brief Number of spheres. Loading Loading @@ -1181,6 +1205,12 @@ public: */ SphereOutputInfo(const std::string &hdf5_name); /*! \brief `SphereOutputInfo` constructor for the dummy NULL case * * \param skip_flag: `const int` must be passed as the `1` constant. */ SphereOutputInfo(const int skip_flag); /*! \brief `InclusionOutputInfo` instance destroyer. */ ~SphereOutputInfo(); Loading
src/inclusion/inclusion.cpp +11 −27 Original line number Diff line number Diff line Loading @@ -437,7 +437,7 @@ void inclusion(const string& config_file, const string& data_file, const string& } else { if (myompthread > 0) { // If there is no input for this thread, set output pointer to NULL. p_outarray[myompthread] = NULL; p_outarray[myompthread] = new InclusionOutputInfo(1); } } #pragma omp barrier Loading @@ -449,11 +449,9 @@ void inclusion(const string& config_file, const string& data_file, const string& // threads different from 0 append their virtual files to the one of thread 0, and delete them if (myompthread == 0) { for (int ti=1; ti<ompnumthreads; ti++) { if (p_outarray[ti] != NULL) { p_outarray[0]->insert(*(p_outarray[ti])); delete p_outarray[ti]; p_outarray[ti] = NULL; } vtppoanarray[0]->append(*(vtppoanarray[ti])); delete vtppoanarray[ti]; } Loading Loading @@ -624,39 +622,25 @@ void inclusion(const string& config_file, const string& data_file, const string& } int jer = inclusion_jxi488_cycle(myjxi488, sconf, gconf, p_scattering_angles, cid_2, p_output_2, output_path, vtppoanp_2); } else { //if (myompthread > 0) { // If there is no input for this thread, set the output pointer to NULL. p_outarray[myompthread] = NULL; //} p_outarray[myompthread] = new InclusionOutputInfo(1); } #pragma omp barrier // threads different from 0 append their virtual files to the one of thread 0, and delete them if (myompthread == 0) { for (int ti=1; ti<ompnumthreads; ti++) { if (p_outarray[ti] != NULL) { p_outarray[0]->insert(*(p_outarray[ti])); delete p_outarray[ti]; p_outarray[ti] = NULL; } vtppoanarray[0]->append(*(vtppoanarray[ti])); delete vtppoanarray[ti]; } // thread 0 sends the collected virtualfiles to thread 0 of MPI process 0, then deletes them for (int rr=1; rr<mpidata->nprocs; rr++) { if (rr == mpidata->rank) { if (p_outarray[0] == NULL) { // signal that we are not sending anything int skip_flag = 1; MPI_Send(&skip_flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // signal that we are sending something int skip_flag = 0; MPI_Send(&skip_flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); p_outarray[0]->mpisend(mpidata); delete p_outarray[0]; } p_outarray[0] = NULL; vtppoanarray[0]->mpisend(mpidata); delete vtppoanarray[0]; } Loading
src/libnptm/outputs.cpp +1173 −1090 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ ClusterOutputInfo::ClusterOutputInfo( ScattererConfiguration *sc, GeometryConfiguration *gc, const mixMPI *mpidata, int first_xi, int xi_length ) { _skip_flag = 0; nsph = gc->number_of_spheres; li = gc->li; le = gc->le; Loading Loading @@ -293,6 +294,7 @@ ClusterOutputInfo::ClusterOutputInfo(const std::string &hdf5_name) { HDFFile *hdf_file = new HDFFile(hdf5_name, flags); herr_t status = hdf_file->get_status(); string str_name, str_type; _skip_flag = 0; if (status == 0) { status = hdf_file->read("NSPH", "INT32_(1)", &nsph); status = hdf_file->read("LI", "INT32_(1)", &li); Loading Loading @@ -701,7 +703,20 @@ ClusterOutputInfo::ClusterOutputInfo(const std::string &hdf5_name) { } } ClusterOutputInfo::ClusterOutputInfo(const int flag) { /* create a dummy placeholder just to know I should skip MPI_Send and MPI_Recv */ if (flag == 1) { _skip_flag = 1; } else { UnrecognizedOutputInfo ex(flag); throw ex; } } ClusterOutputInfo::~ClusterOutputInfo() { if (_skip_flag != 1) { delete[] vec_x_coords; delete[] vec_y_coords; delete[] vec_z_coords; Loading Loading @@ -866,6 +881,7 @@ ClusterOutputInfo::~ClusterOutputInfo() { delete[] vec_dir_mulc; delete[] vec_dir_mulclr; } } long ClusterOutputInfo::compute_size( ScattererConfiguration *sc, GeometryConfiguration *gc, Loading Loading @@ -961,6 +977,7 @@ long ClusterOutputInfo::compute_size() { int ClusterOutputInfo::insert(const ClusterOutputInfo &rhs) { int result = 0; if (rhs.skip_flag != 1) { result += (rhs.nsph == nsph) ? 0 : 1; result += (rhs.inpol == inpol) ? 0 : 1; result += (rhs.iavm == iavm) ? 0 : 1; Loading Loading @@ -1138,6 +1155,7 @@ int ClusterOutputInfo::insert(const ClusterOutputInfo &rhs) { memcpy(vec_dir_mulc + 16 * offset, rhs.vec_dir_mulc, 16 * chunk_size * sizeof(double)); memcpy(vec_dir_mulclr + 16 * offset, rhs.vec_dir_mulclr, 16 * chunk_size * sizeof(double)); } } return result; } Loading Loading @@ -2356,13 +2374,13 @@ int ClusterOutputInfo::write_legacy(const std::string &output) { #ifdef MPI_VERSION int ClusterOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { int result = 0; int skip_flag; int flag; int chk_nsph, chk_inpol, chk_iavm, chk_isam, chk_num_theta, chk_num_thetas; int chk_num_phi, chk_num_phis, chk_ndirs, chk_idfc, chk_configs; double chk_exri; MPI_Recv(&skip_flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if__ skip_flag==0, else nothing is to be received if (skip_flag == 0) { MPI_Recv(&flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if_ skip_flag==0, else nothing is to be received if (flag == 0) { MPI_Recv(&chk_nsph, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_inpol, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_iavm, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); Loading Loading @@ -2562,10 +2580,18 @@ int ClusterOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { return result; } int ClusterOutputInfo::mpisend(const mixMPI *mpidata) { int result = 0; int chunk_size; if (_skip_flag == 1) { // tell the receiver we are not sending anything int flag = 1; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // tell the receiver we are sending actual stuff int flag = 0; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); // Send output metadata for configuration cross-check MPI_Send(&nsph, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&inpol, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); Loading Loading @@ -2748,6 +2774,7 @@ int ClusterOutputInfo::mpisend(const mixMPI *mpidata) { MPI_Send(vec_dir_mulc, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); MPI_Send(vec_dir_mulclr, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); } } return result; } #endif //MPI_VERSION Loading @@ -2758,6 +2785,7 @@ InclusionOutputInfo::InclusionOutputInfo( ScattererConfiguration *sc, GeometryConfiguration *gc, const mixMPI *mpidata, int first_xi, int xi_length ) { _skip_flag = 0; nsph = gc->number_of_spheres; li = gc->li; le = gc->le; Loading Loading @@ -2946,6 +2974,7 @@ InclusionOutputInfo::InclusionOutputInfo(const std::string &hdf5_name) { HDFFile *hdf_file = new HDFFile(hdf5_name, flags); herr_t status = hdf_file->get_status(); string str_name, str_type; _skip_flag = 0; if (status == 0) { status = hdf_file->read("NSPH", "INT32_(1)", &nsph); status = hdf_file->read("LI", "INT32_(1)", &li); Loading Loading @@ -3260,7 +3289,20 @@ InclusionOutputInfo::InclusionOutputInfo(const std::string &hdf5_name) { } } InclusionOutputInfo::InclusionOutputInfo(const int flag) { /* create a dummy placeholder just to know I should skip MPI_Send and MPI_Recv */ if (flag == 1) { _skip_flag = 1; } else { UnrecognizedOutputInfo ex(flag); throw ex; } } InclusionOutputInfo::~InclusionOutputInfo() { if (_skip_flag != 1) { delete[] vec_x_coords; delete[] vec_y_coords; delete[] vec_z_coords; Loading Loading @@ -3382,6 +3424,7 @@ InclusionOutputInfo::~InclusionOutputInfo() { delete[] vec_dir_mull; delete[] vec_dir_mulllr; } } long InclusionOutputInfo::compute_size() { long result = sizeof(np_int); Loading Loading @@ -3439,6 +3482,7 @@ long InclusionOutputInfo::compute_size( int InclusionOutputInfo::insert(const InclusionOutputInfo &rhs) { int result = 0; if (rhs.skip_flag != 1) { result += (rhs.nsph == nsph) ? 0 : 1; result += (rhs.inpol == inpol) ? 0 : 1; result += (rhs.iavm == iavm) ? 0 : 1; Loading Loading @@ -3572,6 +3616,7 @@ int InclusionOutputInfo::insert(const InclusionOutputInfo &rhs) { memcpy(vec_dir_mull + 16 * offset, rhs.vec_dir_mull, 16 * chunk_size * sizeof(double)); memcpy(vec_dir_mulllr + 16 * offset, rhs.vec_dir_mulllr, 16 * chunk_size * sizeof(double)); } } return result; } Loading Loading @@ -4485,13 +4530,13 @@ int InclusionOutputInfo::write_legacy(const std::string &output) { #ifdef MPI_VERSION int InclusionOutputInfo::mpireceive(const mixMPI* mpidata, int pid) { int result = 0; int skip_flag; int flag; int chk_nsph, chk_inpol, chk_iavm, chk_isam, chk_num_theta, chk_num_thetas; int chk_num_phi, chk_num_phis, chk_ndirs, chk_idfc, chk_configs; double chk_exri; MPI_Recv(&skip_flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if__ skip_flag==0, else nothing is to be received if (skip_flag == 0) { MPI_Recv(&flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if_ flag==0, else nothing is to be received if (flag == 0) { MPI_Recv(&chk_nsph, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_inpol, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_iavm, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); Loading Loading @@ -4648,6 +4693,15 @@ int InclusionOutputInfo::mpireceive(const mixMPI* mpidata, int pid) { int InclusionOutputInfo::mpisend(const mixMPI *mpidata) { int result = 0; int chunk_size; if (_skip_flag == 1) { // tell the receiver we are not sending anything int flag = 1; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // tell the receiver we are sending actual stuff int flag = 0; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); // Send output metadata for configuration cross-check MPI_Send(&nsph, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&inpol, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); Loading Loading @@ -4783,6 +4837,7 @@ int InclusionOutputInfo::mpisend(const mixMPI *mpidata) { MPI_Send(vec_dir_mull, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); MPI_Send(vec_dir_mulllr, 16 * chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); } } return result; } #endif // MPI_VERSION Loading @@ -4793,6 +4848,7 @@ SphereOutputInfo::SphereOutputInfo( ScattererConfiguration *sc, GeometryConfiguration *gc, const mixMPI *mpidata, int first_xi, int xi_length ) { _skip_flag = 0; _first_xi = first_xi; nsph = gc->number_of_spheres; lm = gc->l_max; Loading Loading @@ -4905,6 +4961,7 @@ SphereOutputInfo::SphereOutputInfo(const std::string &hdf5_name) { HDFFile *hdf_file = new HDFFile(hdf5_name, flags); herr_t status = hdf_file->get_status(); string str_name, str_type; _skip_flag = 0; if (status == 0) { status = hdf_file->read("NSPH", "INT32_(1)", &nsph); status = hdf_file->read("LM", "INT32_(1)", &lm); Loading Loading @@ -5077,7 +5134,20 @@ SphereOutputInfo::SphereOutputInfo(const std::string &hdf5_name) { } } SphereOutputInfo::SphereOutputInfo(const int flag) { /* create a dummy placeholder just to know I should skip MPI_Send and MPI_Recv */ if (flag == 1) { _skip_flag = 1; } else { UnrecognizedOutputInfo ex(flag); throw ex; } } SphereOutputInfo::~SphereOutputInfo() { if (_skip_flag != 1) { delete[] vec_jxi; delete[] vec_ier; delete[] vec_vk; Loading Loading @@ -5128,6 +5198,7 @@ SphereOutputInfo::~SphereOutputInfo() { delete[] vec_dir_muls; delete[] vec_dir_mulslr; } } long SphereOutputInfo::compute_size( ScattererConfiguration *sc, GeometryConfiguration *gc, Loading Loading @@ -5202,6 +5273,7 @@ long SphereOutputInfo::compute_size() { int SphereOutputInfo::insert(const SphereOutputInfo &rhs) { int result = 0; if (rhs.skip_flag != 1) { result += (rhs.nsph == nsph) ? 0 : 1; result += (rhs.inpol == inpol) ? 0 : 1; result += (rhs.isam == isam) ? 0 : 1; Loading Loading @@ -5271,6 +5343,7 @@ int SphereOutputInfo::insert(const SphereOutputInfo &rhs) { memcpy(vec_dir_fz + offset, rhs.vec_dir_fz, chunk_size * sizeof(double)); // TODO: fix the vector sizes in HDF5 writer and MPI communicators } } return result; } Loading Loading @@ -5746,13 +5819,13 @@ int SphereOutputInfo::write_legacy(const std::string &file_name) { #ifdef MPI_VERSION int SphereOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { int result = 0; int skip_flag; int flag; int chk_nsph, chk_inpol, chk_isam, chk_num_theta, chk_num_thetas; int chk_num_phi, chk_num_phis, chk_ndirs, chk_idfc, chk_configs; double chk_exri; MPI_Recv(&skip_flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if__ skip_flag==0, else nothing is to be received if (skip_flag == 0) { MPI_Recv(&flag, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Proceed with the rest _only if_ flag==0, else nothing is to be received if (flag == 0) { MPI_Recv(&chk_nsph, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_inpol, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&chk_isam, 1, MPI_INT32_T, pid, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE); Loading Loading @@ -5842,6 +5915,15 @@ int SphereOutputInfo::mpireceive(const mixMPI *mpidata, int pid) { int SphereOutputInfo::mpisend(const mixMPI *mpidata) { int result = 0; int chunk_size; if (_skip_flag == 1) { // tell the receiver we are not sending anything int flag = 1; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); } else { // tell the receiver we are sending actual stuff int flag = 0; MPI_Send(&flag, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); // Send output metadata for configuration cross-check MPI_Send(&nsph, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); MPI_Send(&inpol, 1, MPI_INT32_T, 0, 10, MPI_COMM_WORLD); Loading Loading @@ -5911,6 +5993,7 @@ int SphereOutputInfo::mpisend(const mixMPI *mpidata) { MPI_Send(vec_dir_fy, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); MPI_Send(vec_dir_fz, chunk_size, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD); } } return result; } #endif // MPI_VERSION Loading