Skip to content

Commit

Permalink
GH-434: Support of minimum number of agents to spawn.
Browse files Browse the repository at this point in the history
dds-submit: The command learned a new argument --min-instances. It can be used to provide the minimum number of agents to spawn. (GH-434)
dds-slurm-plugin: Added: Support of minimum number of agents to spawn. (GH-434)
  • Loading branch information
AnarManafov committed Apr 28, 2022
1 parent 0a3b1f4 commit e2f8c6f
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 18 deletions.
2 changes: 2 additions & 0 deletions ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Fixed: skip bad or non-session directories/files when performing clean and list
Added: Users can specify a GroupName tag for each submission. This tag will be assigned to agents and can be used as a requirement in topologies. (GH-407)
Added: Users can provide a Submission Tag (--submission-tag). DDS RMS plug-ins will use this tag to name RMS jobs and directories. (GH-426)
Added: The command learned a new argument --env-config/-e. It can be used to define a custom environment script for each agent. (GH-430)
Added: The command learned a new argument --min-instances. It can be used to provide the minimum number of agents to spawn. (GH-434)

### dds-topology
Added: A new groupName requirement. It can be used on task and collection. (GH-407)
Expand All @@ -29,6 +30,7 @@ Added: Support for SessionID (GH-411)

### dds-slurm-plugin
Added: Support for SessionID (GH-411)
Added: Support of minimum number of agents to spawn. (GH-434)
Modified: Replace array job submission with nodes requirement. (GH-430)

### dds-localhost-plugin
Expand Down
1 change: 1 addition & 0 deletions dds-commander/src/ConnectionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,7 @@ void CConnectionManager::submitAgents(const dds::tools_api::SSubmitRequestData&
submitRequest.m_id = sSubmissionID;
submitRequest.m_cfgFilePath = _submitInfo.m_config;
submitRequest.m_nInstances = _submitInfo.m_instances;
submitRequest.m_nMinInstances = _submitInfo.m_minInstances;
submitRequest.m_slots = _submitInfo.m_slots;
submitRequest.m_wrkPackagePath = CUserDefaults::instance().getWrkScriptPath(sSubmissionID);
submitRequest.m_groupName = _submitInfo.m_groupName;
Expand Down
1 change: 1 addition & 0 deletions dds-intercom-lib/src/Intercom.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ namespace dds
bool operator==(const SSubmit& _val) const;

uint32_t m_nInstances; ///< A number of instances.
uint32_t m_nMinInstances; ///< A minimum number of instances.
uint32_t m_slots; ///< A number of task slots.
std::string m_cfgFilePath; ///< A path to the configuration file.
std::string m_id; ///< ID for communication with DDS commander.
Expand Down
5 changes: 4 additions & 1 deletion dds-intercom-lib/src/dds_rms_plugin_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ std::string SSubmit::toJSON()

pt.put<string>("dds.plug-in.id", m_id);
pt.put<int>("dds.plug-in.submit.nInstances", m_nInstances);
pt.put<int>("dds.plug-in.submit.nMinInstances", m_nMinInstances);
pt.put<int>("dds.plug-in.submit.slots", m_slots);
pt.put<string>("dds.plug-in.submit.cfgFilePath", m_cfgFilePath);
pt.put<string>("dds.plug-in.submit.wrkPackagePath", m_wrkPackagePath);
Expand All @@ -79,6 +80,7 @@ void SSubmit::fromPT(const boost::property_tree::ptree& _pt)
{
const ptree& pt = _pt.get_child("dds.plug-in");
m_nInstances = pt.get<int>("submit.nInstances", 0);
m_nMinInstances = pt.get<int>("submit.nMinInstances", 0);
m_slots = pt.get<int>("submit.slots", 0);
m_cfgFilePath = pt.get<string>("submit.cfgFilePath", "");
m_wrkPackagePath = pt.get<string>("submit.wrkPackagePath", "");
Expand All @@ -91,7 +93,8 @@ bool SSubmit::operator==(const SSubmit& _val) const
{
return (m_id == _val.m_id) && (m_nInstances == _val.m_nInstances) && (m_slots == _val.m_slots) &&
(m_cfgFilePath == _val.m_cfgFilePath) && (m_wrkPackagePath == _val.m_wrkPackagePath) &&
(m_groupName == _val.m_groupName) && (m_submissionTag == _val.m_submissionTag);
(m_groupName == _val.m_groupName) && (m_submissionTag == _val.m_submissionTag) &&
(m_nMinInstances == _val.m_nMinInstances);
}

///////////////////////////////////
Expand Down
2 changes: 2 additions & 0 deletions dds-intercom-lib/tests/Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ BOOST_AUTO_TEST_CASE(test_protocol_parser_1)
<< "\"submit\":"
<< "{"
<< "\"nInstances\": 11,"
<< "\"nMinInstances\": 8,"
<< "\"cfgFilePath\": \"/path/to/cfg/dds_plugin.cfg\","
<< "\"wrkPackagePath\": \"/path/to/cfg/DDSWorker\","
<< "\"groupName\": \"TestGroup\","
Expand All @@ -78,6 +79,7 @@ BOOST_AUTO_TEST_CASE(test_protocol_parser_1)
[](const SSubmit& _submit)
{
BOOST_CHECK(_submit.m_nInstances == 11);
BOOST_CHECK(_submit.m_nMinInstances == 8);
BOOST_CHECK(_submit.m_cfgFilePath == "/path/to/cfg/dds_plugin.cfg");
BOOST_CHECK(_submit.m_wrkPackagePath == "/path/to/cfg/DDSWorker");
BOOST_CHECK(_submit.m_id == "plug-in-id");
Expand Down
34 changes: 22 additions & 12 deletions dds-submit/src/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ namespace dds
std::string m_sCfgFile;
std::string m_sPath;
size_t m_number{ 0 };
size_t m_minInstances{ 0 };
size_t m_slots{ 0 };
bool m_bListPlugins{ false };
boost::uuids::uuid m_sid = boost::uuids::nil_uuid();
Expand All @@ -54,44 +55,47 @@ namespace dds

// Generic options
bpo::options_description options("dds-submit options");
options.add_options()("help,h", "Produce help message.");
options.add_options()("version,v", "Version information.");
options.add_options()("session,s", bpo::value<std::string>(), "DDS Session ID.");
options.add_options()("help,h", "Produce help message.\n");
options.add_options()("version,v", "Version information.\n");
options.add_options()("session,s", bpo::value<std::string>(), "DDS Session ID.\n");
options.add_options()(
"list,l", bpo::bool_switch(&_options->m_bListPlugins), "List all available RMS plug-ins.");
"list,l", bpo::bool_switch(&_options->m_bListPlugins), "List all available RMS plug-ins.\n");
options.add_options()("rms,r",
bpo::value<std::string>(&_options->m_sRMS),
"Defines a destination resource "
"management system plug-in. Use "
"\"--list\" to find out names "
"of available RMS plug-ins.");
"of available RMS plug-ins.\n");
options.add_options()(
"config,c",
bpo::value<std::string>(&_options->m_sCfgFile),
"A plug-in's configuration file. It can be used to provide additional RMS options. It should contain "
"only RMS options. To define custom environment per agent, use --env-config.");
"only RMS options. To define custom environment per agent, use --env-config.\n");
options.add_options()("env-config,e",
bpo::value<std::string>(&_options->m_envCfgFilePath),
"A path to a user enironment script. Will be execeuted once per agent (valid for all "
"task slots of the agent).");
"task slots of the agent).\n");
options.add_options()("path",
bpo::value<std::string>(&_options->m_sPath),
"A plug-in's directory search path. It can be used for external RMS plug-ins.");
options.add_options()("number,n",
bpo::value<size_t>(&_options->m_number)->default_value(1),
"Defines a number of agents to spawn."
"If 0 is provided as an argument, then a number of available logical cores will be "
"used.\n");
"Defines a number of DDS agents to spawn.\n");
options.add_options()("min-instances",
bpo::value<size_t>(&_options->m_minInstances)->default_value(0),
"Request that a minimum of \"--min-instances\" and maximum of \"--number\" agents to "
"spawn. This option is RMS plug-in depended. At the moment only the slurm plug-in "
"supports it. If set to 0, the minimum is ignored.\n");
options.add_options()(
"slots", bpo::value<size_t>(&_options->m_slots), "Defines a number of task slots per agent.");
options.add_options()("group-name,g",
bpo::value<std::string>(&_options->m_groupName)->default_value("common"),
"Defines a group name of agents of this submission. Default: \"common\"");
"Defines a group name of agents of this submission.\n");
options.add_options()(
"submission-tag,t",
bpo::value<std::string>(&_options->m_submissionTag)->default_value("dds_agent_job"),
"It can be used to define a submission tag. DDS RMS plug-ins will use this tag to name DDS RMS jobs "
"and directories they create on the worker nodes. Default: \"dds_agent_job\"");
"and directories they create on the worker nodes.");

// Parsing command-line
bpo::variables_map vm;
Expand Down Expand Up @@ -175,6 +179,12 @@ namespace dds
_options->m_envCfgFilePath = envCfg.native();
}

if (vm.count("number") && vm.count("min-instances") && _options->m_minInstances > _options->m_number)
{
LOG(dds::misc::log_stderr) << "Value of min-instances is bigger than \"--number\"";
return false;
}

// RMS plug-ins are always lower cased
boost::to_lower(_options->m_sRMS);

Expand Down
1 change: 1 addition & 0 deletions dds-submit/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ int main(int argc, char* argv[])
requestInfo.m_config = options.m_sCfgFile;
requestInfo.m_rms = options.m_sRMS;
requestInfo.m_instances = options.m_number;
requestInfo.m_minInstances = options.m_minInstances;
requestInfo.m_slots = options.m_slots;
requestInfo.m_pluginPath = options.m_sPath;
requestInfo.m_groupName = options.m_groupName;
Expand Down
7 changes: 5 additions & 2 deletions dds-tools-lib/src/ToolsProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ SSubmitRequestData::SSubmitRequestData(const boost::property_tree::ptree& _pt)
void SSubmitRequestData::_toPT(boost::property_tree::ptree& _pt) const
{
_pt.put<int>("instances", m_instances);
_pt.put<int>("minInstances", m_minInstances);
_pt.put<int>("slots", m_slots);
_pt.put<string>("config", m_config);
_pt.put<string>("rms", m_rms);
Expand All @@ -186,6 +187,7 @@ void SSubmitRequestData::_toPT(boost::property_tree::ptree& _pt) const
void SSubmitRequestData::_fromPT(const boost::property_tree::ptree& _pt)
{
m_instances = _pt.get<int>("instances", 0);
m_minInstances = _pt.get<int>("minInstances", 0);
m_slots = _pt.get<int>("slots", 0);
m_config = _pt.get<string>("config", "");
m_rms = _pt.get<string>("rms", "");
Expand All @@ -200,7 +202,7 @@ bool SSubmitRequestData::operator==(const SSubmitRequestData& _val) const
return (SBaseData::operator==(_val) && m_rms == _val.m_rms && m_instances == _val.m_instances &&
m_slots == _val.m_slots && m_config == _val.m_config && m_pluginPath == _val.m_pluginPath &&
m_groupName == _val.m_groupName && m_submissionTag == _val.m_submissionTag &&
m_envCfgFilePath == _val.m_envCfgFilePath);
m_envCfgFilePath == _val.m_envCfgFilePath && m_minInstances == _val.m_minInstances);
}

// We need to put function implementation in the same "dds::tools_api" namespace as a friend function declaration.
Expand All @@ -213,7 +215,8 @@ namespace dds
std::ostream& operator<<(std::ostream& _os, const SSubmitRequestData& _data)
{
return _os << _data.defaultToString() << "; instances: " << _data.m_instances
<< "; slots: " << _data.m_slots << "; config: " << _data.m_config << "; rms: " << _data.m_rms
<< "; minInstances: " << _data.m_minInstances << "; slots: " << _data.m_slots
<< "; config: " << _data.m_config << "; rms: " << _data.m_rms
<< "; pluginPath: " << _data.m_pluginPath << "; groupName: " << _data.m_groupName
<< "; submissionTag: " << _data.m_submissionTag
<< "; envCfgFilePath: " << _data.m_envCfgFilePath;
Expand Down
5 changes: 3 additions & 2 deletions dds-tools-lib/src/ToolsProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ namespace dds
SSubmitRequestData(const boost::property_tree::ptree& _pt);

std::string m_rms; ///< RMS.
uint32_t m_instances = 0; ///< Number of instances.
uint32_t m_instances = 0; ///< A number of instances.
uint32_t m_minInstances = 0; ///< A minimum number of instances.
uint32_t m_slots = 0; /// < Number of task slots.
std::string m_config; ///< Path to the configuration file.
std::string m_config; ///< A path to the configuration file.
std::string m_pluginPath; ///< Optional. A plug-in's directory search path
std::string m_groupName; ///< A group name of agents.
std::string m_submissionTag; ///< A Submission Tag
Expand Down
2 changes: 1 addition & 1 deletion plugins/dds-submit-slurm/src/job.slurm.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash

#SBATCH --nodes=%DDS_NINSTANCES%
#SBATCH --nodes=%DDS_NMININSTANCES%%DDS_NINSTANCES%
#SBATCH --no-kill
#SBATCH --ntasks-per-node=1

Expand Down
6 changes: 6 additions & 0 deletions plugins/dds-submit-slurm/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ int main(int argc, char* argv[])
// Replace %DDS_NINSTANCES%
boost::replace_all(sSrcScript, "%DDS_NINSTANCES%", to_string(_submit.m_nInstances));

// Replace %DDS_NMININSTANCES%
if (_submit.m_nMinInstances > 0)
boost::replace_all(sSrcScript, "%DDS_NMININSTANCES%", to_string(_submit.m_nMinInstances) + "-");
else
boost::replace_all(sSrcScript, "%DDS_NMININSTANCES%", "");

// Replace %DDS_NSLOTS%
boost::replace_all(sSrcScript, "%DDS_NSLOTS%", to_string(_submit.m_slots));

Expand Down

0 comments on commit e2f8c6f

Please sign in to comment.