Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/align_tiltseries_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,13 +563,11 @@ void AlignTiltseriesRunner::executeAreTomo(long idx_tomo, int rank)

if (gpu_ids.length() > 0)
{
if (rank >= allThreadIDs.size())
REPORT_ERROR("ERROR: not enough MPI nodes specified for the GPU IDs.");

command += " -Gpu " ;
for (int igpu = 0; igpu < allThreadIDs[rank].size(); igpu++)
const std::vector<std::string> &rankThreadIDs = getDeviceIDsForRank(allThreadIDs, rank);
for (int igpu = 0; igpu < rankThreadIDs.size(); igpu++)
{
command += allThreadIDs[rank][igpu] + " ";
command += rankThreadIDs[igpu] + " ";
}
}

Expand Down
1 change: 1 addition & 0 deletions src/align_tiltseries_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include "src/args.h"
#include <src/metadata_table.h>
#include <src/image.h>
#include <src/time.h>
Expand Down
2 changes: 1 addition & 1 deletion src/amyloid_finder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ void AmyloidFinder::deviceInitialise()
untangleDeviceIDs(gpu_ids, allThreadIDs);

// Sequential initialisation of GPUs on all ranks
if (!std::isdigit(*gpu_ids.begin()))
if (!hasExplicitDeviceIDs(gpu_ids))
device_id = 0;
else
device_id = textToInteger((allThreadIDs[0][0]).c_str());
Expand Down
4 changes: 2 additions & 2 deletions src/amyloid_finder_mpi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ void AmyloidFinderMpi::deviceInitialise()
untangleDeviceIDs(gpu_ids, allThreadIDs);

// Sequential initialisation of GPUs on all ranks
if (!std::isdigit(*gpu_ids.begin()))
if (!hasExplicitDeviceIDs(gpu_ids))
device_id = node->rank%devCount;
else
device_id = textToInteger((allThreadIDs[node->rank][0]).c_str());
device_id = textToInteger(getDeviceIDsForRank(allThreadIDs, node->rank)[0].c_str());

for (int follower = 0; follower < node->size; follower++)
{
Expand Down
28 changes: 28 additions & 0 deletions src/args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "src/gcc_version.h"
#include "src/matrix1d.h"
#include <algorithm>
#include <cctype>

// Get parameters from the command line ====================================
std::string getParameter(int argc, char **argv, const std::string param, const std::string option)
Expand Down Expand Up @@ -472,3 +473,30 @@ void untangleDeviceIDs(std::string &tangled, std::vector < std::vector < std::st
#endif
}

bool hasExplicitDeviceIDs(const std::string &gpu_ids)
{
return gpu_ids.size() > 0 && std::isdigit(static_cast<unsigned char>(gpu_ids[0]));
}

const std::vector<std::string>& getDeviceIDsForRank(
const std::vector < std::vector < std::string > > &allThreadIDs,
int rank)
{
if (rank < 0)
REPORT_ERROR("Negative MPI rank requested for GPU ID assignment.");

if (allThreadIDs.size() == 0)
REPORT_ERROR("No GPU IDs parsed from --gpu.");

const std::vector<std::string> &rankThreadIDs = allThreadIDs[rank % allThreadIDs.size()];
if (rankThreadIDs.size() == 0)
REPORT_ERROR("No GPU IDs parsed for MPI rank from --gpu.");

for (int i = 0; i < rankThreadIDs.size(); i++)
{
if (rankThreadIDs[i] == "")
REPORT_ERROR("Empty GPU ID parsed from --gpu.");
}

return rankThreadIDs;
}
10 changes: 10 additions & 0 deletions src/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,14 @@ class IOParser
*/
void untangleDeviceIDs(std::string &tangled, std::vector < std::vector < std::string > > &untangled);

bool hasExplicitDeviceIDs(const std::string &gpu_ids);

/*
* Returns the device IDs for an MPI rank. If fewer rank-specific GPU ID groups
* are provided than MPI ranks, the groups are reused cyclically.
*/
const std::vector<std::string>& getDeviceIDsForRank(
const std::vector < std::vector < std::string > > &allThreadIDs,
int rank);

#endif
2 changes: 1 addition & 1 deletion src/autopicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ void AutoPicker::deviceInitialise()
untangleDeviceIDs(gpu_ids, allThreadIDs);

// Sequential initialisation of GPUs on all ranks
if (!std::isdigit(*gpu_ids.begin()))
if (!hasExplicitDeviceIDs(gpu_ids))
device_id = 0;
else
device_id = textToInteger((allThreadIDs[0][0]).c_str());
Expand Down
4 changes: 2 additions & 2 deletions src/autopicker_mpi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ void AutoPickerMpi::deviceInitialise()
untangleDeviceIDs(gpu_ids, allThreadIDs);

// Sequential initialisation of GPUs on all ranks
if (!std::isdigit(*gpu_ids.begin()))
if (!hasExplicitDeviceIDs(gpu_ids))
device_id = node->rank%devCount;
else
device_id = textToInteger((allThreadIDs[node->rank][0]).c_str());
device_id = textToInteger(getDeviceIDsForRank(allThreadIDs, node->rank)[0].c_str());

for (int follower = 0; follower < node->size; follower++)
{
Expand Down
4 changes: 2 additions & 2 deletions src/ml_optimiser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1608,7 +1608,7 @@ void MlOptimiser::initialise()
// Sequential initialisation of GPUs on all ranks
bool fullAutomaticMapping(true);
bool semiAutomaticMapping(true);
if (allThreadIDs[0].size()==0 || (!std::isdigit(*gpu_ids.begin())) )
if (allThreadIDs[0].size()==0 || (!hasExplicitDeviceIDs(gpu_ids)) )
std::cout << "gpu-ids not specified, threads will automatically be mapped to devices (incrementally)."<< std::endl;
else
{
Expand Down Expand Up @@ -1714,7 +1714,7 @@ void MlOptimiser::initialise()

bool fullAutomaticMapping;
bool semiAutomaticMapping;
if (allThreadIDs[0].size()==0 || ! std::isdigit(*gpu_ids.begin()) )
if (allThreadIDs[0].size()==0 || !hasExplicitDeviceIDs(gpu_ids) )
{
fullAutomaticMapping = true;
semiAutomaticMapping = true;
Expand Down
6 changes: 3 additions & 3 deletions src/ml_optimiser_mpi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ void MlOptimiserMpi::initialise()
fullAutomaticMapping = true;
semiAutomaticMapping = true; // possible to set fully manual for specific ranks

if ((allThreadIDs.size()<rank) || allThreadIDs[0].size()==0 || (!std::isdigit(*gpu_ids.begin())) )
if ((allThreadIDs.size()<rank) || allThreadIDs[0].size()==0 || (!hasExplicitDeviceIDs(gpu_ids)) )
{
std::cout << "GPU-ids not specified for this rank, threads will automatically be mapped to available devices."<< std::endl;
}
Expand Down Expand Up @@ -485,7 +485,7 @@ will still yield good performance and possibly a more stable execution. \n" << s
{
if (node->isLeader())
{
if (! std::isdigit(*gpu_ids.begin()))
if (!hasExplicitDeviceIDs(gpu_ids))
{
std::cout << std::string(80, '*') << std::endl;
std::cout << "GPU-ids not specified and MPI/threads will automatically be mapped to available devices."<< std::endl;
Expand Down Expand Up @@ -626,7 +626,7 @@ will still yield good performance and possibly a more stable execution. \n" << s

bool fullAutomaticMapping;
bool semiAutomaticMapping;
if (allThreadIDs[node->rank-1].size()==0 || ! std::isdigit(*gpu_ids.begin()) )
if (allThreadIDs[node->rank-1].size()==0 || !hasExplicitDeviceIDs(gpu_ids) )
{
fullAutomaticMapping = true;
semiAutomaticMapping = true;
Expand Down
8 changes: 3 additions & 5 deletions src/motioncorr_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,12 +636,10 @@ bool MotioncorrRunner::executeMotioncor2(Micrograph &mic, int rank)
}
else
{
if (rank >= allThreadIDs.size())
REPORT_ERROR("ERROR: not enough MPI nodes specified for the GPU IDs.");

command += " -Gpu ";
for (int igpu = 0; igpu < allThreadIDs[rank].size(); igpu++)
command += allThreadIDs[rank][igpu] + " ";
const std::vector<std::string> &rankThreadIDs = getDeviceIDsForRank(allThreadIDs, rank);
for (int igpu = 0; igpu < rankThreadIDs.size(); igpu++)
command += rankThreadIDs[igpu] + " ";
}

command += " >> " + fn_out + " 2>> " + fn_err;
Expand Down
1 change: 1 addition & 0 deletions src/motioncorr_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include "src/args.h"
#include <src/time.h>
#include "src/metadata_table.h"
#include "src/image.h"
Expand Down