diff --git a/include/model/model_creator.h b/include/model/model_creator.h index b2d22edf89b8597571fb4bbebf26ce83288f3cd8..e93fd0150b36a13cf6427b5ab389a44db29f7ce4 100644 --- a/include/model/model_creator.h +++ b/include/model/model_creator.h @@ -155,6 +155,7 @@ private: void determine_fork_nodes(); void determine_adjacent_nodes(); void determine_number_of_adjacent_nodes(); + int topology_plausibility_check(); // Methods used in agent distribution bool all_nodes_scheduled(); diff --git a/src/model/model_creator.cpp b/src/model/model_creator.cpp index 5b10dc9dc0b51ab1a6d1ea5740ef68732cc432db..4d7eb221c872b8bcd6c387601988a1f251fdf334 100644 --- a/src/model/model_creator.cpp +++ b/src/model/model_creator.cpp @@ -1031,6 +1031,49 @@ unsigned int Model_creator::number_of_nodes_scheduled() { return sum; } +/*! \brief Check if parsed topology is plausible + * \return 1 = topology plausible, 0 = warnings for topology, -1 = error (simulation should exit) + * */ +int Model_creator::topology_plausibility_check(){ + int plausibility = 1; // 1 = plausible, 0 = warning, -1 = error + + // Check if node ids along the branches of the topology tree + // are in increasing order + int node_id = 1; + for(auto& node : adjacent_nodes){ + // Count number of adjacent nodes with smaller ids + unsigned int nodes_with_smaller_id = 0; + for(auto& adjacent_node : node){ + if (adjacent_node < node_id){ + ++nodes_with_smaller_id; + } + } + // Warn user if for a certain node, more than one node with smaller ids was found + if (nodes_with_smaller_id > 1){ + if (world_size > 1){ + plausibility = -1; // This topology cannot be simulated with more than one process + } + else { + if (plausibility != -1) { + plausibility = 0; // Do not overwrite critical plausibility violation + } + } + + if (rank == 0){ + std::cout << "############################### WARNING ###############################" << std::endl + << "## Node " << std::to_string(node_id) + << " has more than one adjacent node with a smaller id!" << std::endl + << "## This topology cannot be simulated with number of processes n>1" << std::endl + << "## Please check the scenario files!" << std::endl + << "#######################################################################" << std::endl; + } + } + ++node_id; + } + return plausibility; +} + + /*! \brief This method distributed agents to processes and creates the agents that belong to a process * \param _agent_rank_relation [out] array that saves for each agent in which rank it is created * \param components_at_nodes [out] vector that saves for each node which components are connected to it @@ -1089,6 +1132,21 @@ void Model_creator::create_model(int *_agent_rank_relation, } }*/ + // Check plausibility of parsed topology before distribution agents among ranks + if(rank==0){ + std::cout << "---> Check plausibility of topology" << std::endl;; + } + // 1 = plausible, 0 = warning, -1 = error + int plausibility = topology_plausibility_check(); + if(rank==0){ + if(plausibility == -1){ + std::cout << " !!! ERROR in plausibility check !!!" << std::endl; + do_exit(-1); + } else if (plausibility == 0){ + std::cout << " Warnings occurred in plausibility check!" << std::endl; + } + } + if(distribution_method == "workitem") { if(rank==0){ std::cout << "---> Start workitem distribution"<< std::endl;;