std::string GenerateAttributesMPIDatatypesFunction(Model &model, clang::ASTContext *context) {
	std::stringstream stream;

	// Add prototype
	stream << "void CreateAttributesMPIDatatypes(AttributesMPITypes &attributes_MPI_types) {\n"
		   << "\tstd::vector<int> lengths; "
		   << "std::vector<MPI_Aint> offsets; "
		   << "std::vector<MPI_Datatype> mpi_types;\n"
		   << "\tMPI_Datatype t;\n";
	// Generates the MPI_Datatype of each attribute and add it in the map
	std::unordered_set<std::string> temp_database;
	temp_database.insert("t");
	for (const auto &agent : model.GetAgents()) {
		for (const auto& field : agent.second.GetFields()) {
			if (!field.second.IsSendable())
				continue; // Ignore not sendable fields
			std::string code = GenerateCodeMPIDatatype(field.second.GetType(), context, "t", temp_database);
			if (code.substr(0,6) == "MPI_Da" || code.substr(0,3) != "MPI") // If it is a structure, add the code
				stream << code
					   << "\tattributes_MPI_types[std::pair<AgentType, Attribute>("
					   << agent.second.GetId() << ", " << field.second.GetId() << ")]"
					   << " = t;\n";
			else // it is just a constant
				stream << "\tattributes_MPI_types[std::pair<AgentType, Attribute>("
					   << agent.second.GetId() << ", " << field.second.GetId() << ")]"
					   << " = " << code << ";\n";
		}
	}
	stream << "}\n";
	return stream.str();
}
std::string GenerateCriticalStructsMPIDatatypesFunction(Model &model) {
	std::stringstream stream;

	// Add prototype
	stream << "void CreateCriticalStructsMPIDatatypes(std::unordered_map<AgentType, MPI_Datatype> &critical_structs_MPI_types, AttributesMPITypes &attributes_MPI_types) {\n"
		   << "\tstd::vector<int> lengths; "
		   << "std::vector<MPI_Aint> offsets; "
		   << "std::vector<MPI_Datatype> mpi_types;\n"
		   << "\tMPI_Datatype t;\n";

	// Generate the MPI_Datatype for the struct containing the data
	for (const auto &agent : model.GetAgents()) {
		if (!agent.second.IsSendable())
			continue;
		// First the lengths (all 1)
		int n_fields = 0;
		for (const auto &field : agent.second.GetFields()) {
			if (field.second.IsCritical()) {
				n_fields++;
			}
		}
		if (n_fields == 0)
			continue;
		stream << "\tlengths = {";
		for (int i = 0; i<n_fields; ++i)
				stream << "1,";
		stream.seekp(-1, std::ios_base::cur);
		stream << "};\n";
		// Then the offsets
		stream << "\toffsets = {";
		for (const auto &field : agent.second.GetFields()) {
			if (field.second.IsCritical())
				stream << "offsetof(" << agent.first << "CriticalAttrs"
					   << "," << field.first
					   << "),";
		}
		stream.seekp(-1, std::ios_base::cur);
		stream << "};\n";
		// The MPI_Datatypes
		stream << "\tmpi_types = {";
		for (const auto &field : agent.second.GetFields()) {
			if (field.second.IsCritical())
				stream << "attributes_MPI_types[std::pair<AgentType, Attribute>("
					   << agent.second.GetId() << "," << field.second.GetId()
					   << ")],";
		}
		stream.seekp(-1, std::ios_base::cur);
		stream << "};\n";
		stream << "\tMPI_Type_create_struct(" << n_fields
			   << ", lengths.data(), offsets.data(), mpi_types.data(), &t);\n"
			   << "\tMPI_Type_commit(&t);\n";
		// Store the MPI_Datatype
		stream << "\tcritical_structs_MPI_types[" << agent.second.GetId()
			   << "] = t;\n";
	}
	stream << "}\n";

	return stream.str();
}
std::string GenerateNbAgentTypesFunction(Model &model) {
	std::stringstream stream;

	stream << "AgentType NbAgentTypes() {\n"
		   << "\treturn " << model.GetAgents().size() << ";\n"
		   << "}\n";

	return stream.str();
}
std::string GenerateNonSendableAgentTypesFunction(Model &model) {
	std::stringstream stream;
	// Add prototype
	stream << "void CreateNonSendableAgentTypes(std::unordered_set<AgentType> &non_sendable_agents) {\n";
	for (const auto &agent : model.GetAgents()) {
		if (!agent.second.IsSendable())
			stream << "\tnon_sendable_agents.insert(" << agent.second.GetId() << ");\n";
	}
	stream << "}\n";
	return stream.str();
}
std::string GenerateCriticalStructSizesFunction(Model &model) {
	std::stringstream stream;
	// Add prototype
	stream << "void CreateCriticalStructSizes(std::unordered_map<AgentType, size_t> &critical_attributes_struct_sizes) {\n";

	for (const auto &agent : model.GetAgents()) {
		stream << "\tcritical_attributes_struct_sizes[" << agent.second.GetId()
			   << "] = sizeof(" << agent.first << "CriticalAttrs);\n";
	}
	stream << "}\n";

	return stream.str();
}
std::string GenerateAgentsNamesRelation(Model &model) {
	std::stringstream stream;
	// Add prototype
	stream << "void CreateAgentsNamesRelation(\n"
		"\tstd::unordered_map<AgentType, std::string> &agent_type_to_string,\n"
		"\tstd::unordered_map<std::string, AgentType> &string_to_agent_type) {\n";

	// Scan all agent types and build the two maps simultaneously
	for (const auto &agent : model.GetAgents()) {
		stream << "\tagent_type_to_string[" << agent.second.GetId() << "] = \"" << agent.first << "\";\n"
			   << "\tstring_to_agent_type[\"" << agent.first << "\"] = " << agent.second.GetId() << ";\n";
	}
	stream << "}\n";

	return stream.str();
}
std::string GenerateAttributesStruct(Model &model) {
	std::stringstream stream;

	for (const auto &agent : model.GetAgents()) {
		stream << agent.second.AttributesStruct(agent.first);
		stream << agent.second.PublicAttributesStruct(agent.first);
		stream << agent.second.CriticalAttributesStruct(agent.first);
		stream << agent.second.MessageStruct(agent.first);
	}

	for (const auto &interaction : model.GetInteractions()) {
		stream << interaction.second.AttributesStruct(interaction.first);
		stream << interaction.second.MessageStruct(interaction.first);
	}

	return stream.str();
}
std::string GenerateCriticalAttributesFunction(Model &model) {
	std::stringstream stream;
	// Add prototype
	stream << "void CreateCriticalAttributes(CriticalAttributes &critical_attributes) {\n";

	for (const auto &agent : model.GetAgents()) {
		for (const auto &field : agent.second.GetFields()) {
			if (field.second.IsCritical())
				stream << "\tcritical_attributes.insert(std::pair<AgentType, Attribute>("
					   << agent.second.GetId() << "," << field.second.GetId()
					   << "));\n";
		}
	}
	stream << "}\n";

	return stream.str();
}
std::string GenerateCriticalAttributesOffsetsFunction(Model &model) {
	std::stringstream stream;
	// Add prototype
	stream << "void CreateCriticalAttributesOffsets(AttributesOffsets &critical_attributes_offsets) {\n";

	for (const auto &agent : model.GetAgents())
		for (const auto &field : agent.second.GetFields()) {
			if (field.second.IsCritical())
				stream << "\tcritical_attributes_offsets[std::pair<AgentType, Attribute>("
					   << agent.second.GetId() << "," << field.second.GetId()
					   << ")] = "
					   << "offsetof(" << agent.first << "CriticalAttrs"
					   << "," << field.first
					   << ");\n";
	}
	stream << "}\n";

	return stream.str();
}
Example #10
0
std::string GenerateAttributesSizeFunction(Model &model) {
	std::stringstream stream;
	// Add prototype
	stream << "void CreateAttributesSizes(AttributesSizes &attributes_sizes) {\n";

	for (const auto &agent : model.GetAgents()) {
		for (const auto &field : agent.second.GetFields()) {
			if (!field.second.IsSendable())
				continue;
			stream << "\tattributes_sizes[std::pair<AgentType, Attribute>("
				   << agent.second.GetId() << "," << field.second.GetId()
				   << ")] = sizeof(" << GetTypeAsString(field.second.GetType())
				   << ");\n";
		}
	}
	stream << "}\n";

	return stream.str();
}
Example #11
0
std::string GenerateAttributesNamesRelation(Model &model) {
	std::stringstream stream;
	// Add prototype
	stream << "void CreateAttributesNamesRelation(\n"
		"\tAttributesNames &attribute_to_string,\n"
		"\tAttributesIds &string_to_attribute) {\n";

	// Scan all attributes and build the two maps simultaneously
	for (const auto &agent : model.GetAgents()) {
		for (const auto &attribute : agent.second.GetFields()) {
			stream << "\tattribute_to_string[std::make_pair("
				   << agent.second.GetId() << ", " << attribute.second.GetId()
				   << ")] = \"" << attribute.first << "\";\n"
				   << "\tstring_to_attribute[std::make_pair(\""
				   << agent.first << "\", \"" << attribute.first << "\")] = std::make_pair("
				   << agent.second.GetId() << ", " << attribute.second.GetId() << ");\n";
		}
	}
	stream << "}\n";

	return stream.str();
}
Example #12
0
std::string GenerateAgentsMPIDatatypesFunction(Model &model) {
	std::stringstream stream;

	// Add prototype
	stream << "size_t CreateAgentsMPIDatatypes(std::unordered_map<AgentType, MPI_Datatype> &agents_MPI_types, AttributesMPITypes &attributes_MPI_types) {\n"
		   << "\tstd::vector<int> lengths; "
		   << "std::vector<MPI_Aint> offsets; "
		   << "std::vector<MPI_Datatype> mpi_types;\n"
		   << "\tMPI_Datatype t;\n"
		   << "\tsize_t max_size = 0;\n";

	// Generate the MPI_Datatype for the struct containing the data
	for (const auto &agent : model.GetAgents()) {
		// First the lengths (all 1)
		stream << "\tlengths = {";
		int n_fields = 0;
		for (const auto &field : agent.second.GetFields()) {
			if (field.second.IsSendable())
				n_fields++;
		}
		for (int i = 0; i < n_fields; i++) {
			stream << "1,";
		}
		stream.seekp(-1, std::ios_base::cur);
		stream << "};\n";
		// Then the offsets
		stream << "\toffsets = {";
		for (const auto &field : agent.second.GetFields()) {
			if (field.second.IsSendable())
				stream << "offsetof(" << agent.first << "Attrs"
					   << "," << field.first
					   << "),";
		}
		if (n_fields > 0)
			stream.seekp(-1, std::ios_base::cur);
		stream << "};\n";
		// The MPI_Datatypes
		stream << "\tmpi_types = {";
		for (const auto &field : agent.second.GetFields()) {
			if (field.second.IsSendable())
				stream << "attributes_MPI_types[std::pair<AgentType, Attribute>("
					   << agent.second.GetId() << "," << field.second.GetId()
					   << ")],";
		}
		if (n_fields > 0)
			stream.seekp(-1, std::ios_base::cur);
		stream << "};\n";
		stream << "\tMPI_Type_create_struct(" << n_fields
			   << ", lengths.data(), offsets.data(), mpi_types.data(), &t);\n"
			   << "\tMPI_Type_commit(&t);\n";
		// Now the MPI_Datatype of the message structure
		// i.e. we add the type and the id and types of the sender and recipient
		stream << "\tlengths = {1,1,1};\n"
			   << "\toffsets = {offsetof(" << agent.first << "MessageStruct,id),"
			   << "offsetof(" << agent.first << "MessageStruct,type),"
			   << "offsetof(" << agent.first << "MessageStruct,data)"
			   << "};\n";
		stream << "\tmpi_types = {MPI_UINT64_T,MPI_UINT64_T,t};\n";
		stream << "\tMPI_Type_create_struct(" << "3"
			   << ", lengths.data(), offsets.data(), mpi_types.data(), &t);\n"
			   << "\tMPI_Type_commit(&t);\n";

		// Store the MPI_Datatype
		stream << "\tagents_MPI_types[" << agent.second.GetId()
			   << "] = t;\n";
		// Update the maximum size
		stream << "\tif (sizeof(" << agent.first << "MessageStruct) > max_size)"
			   << " {max_size = sizeof(" << agent.first << "MessageStruct);}\n";
	}
	stream << "\treturn max_size;\n"
		   << "}\n";

	return stream.str();
}