From: Artem Zhmurov Date: Wed, 10 Mar 2021 18:34:49 +0000 (+0000) Subject: Rename some variables in GPU task assignment and fix their usage X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=e2a2fe80bd8e1af8e8d1385017fe4f96d77de2ce;p=alexxy%2Fgromacs.git Rename some variables in GPU task assignment and fix their usage Some variables are oddly named which causes a confusion. This changes the naming so that it reflects the meaning of the variables. Also, fixes a miss0use of one of such variables cause by the bad naming. Fixes #3980 Fixes #3981 --- diff --git a/src/gromacs/hardware/device_management.h b/src/gromacs/hardware/device_management.h index 60cb54aacc..138b6f7485 100644 --- a/src/gromacs/hardware/device_management.h +++ b/src/gromacs/hardware/device_management.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team. - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,6 +56,7 @@ #include #include +#include "gromacs/utility/arrayref.h" #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/iserializer.h" @@ -153,7 +154,7 @@ getCompatibleDevices(const std::vector>& devi * * \return Vector of compatible GPU ids. */ -std::vector getCompatibleDeviceIds(const std::vector>& deviceInfoList); +std::vector getCompatibleDeviceIds(gmx::ArrayRef> deviceInfoList); /*! \brief Return whether \p deviceId is found in \p deviceInfoList and is compatible * @@ -167,8 +168,8 @@ std::vector getCompatibleDeviceIds(const std::vector>& deviceInfoList, - int deviceId); +bool deviceIdIsCompatible(gmx::ArrayRef> deviceInfoList, + int deviceId); /*! \brief Set the active GPU. * @@ -219,7 +220,7 @@ std::string getDeviceInformationString(const DeviceInformation& deviceInfo); * \param[in] deviceId An index of the device to check * \returns A string describing the compatibility status, useful for error messages. */ -std::string getDeviceCompatibilityDescription(const std::vector>& deviceInfoList, +std::string getDeviceCompatibilityDescription(gmx::ArrayRef> deviceInfoList, int deviceId); /*! \brief Serialization of information on devices for MPI broadcasting. diff --git a/src/gromacs/hardware/device_management_common.cpp b/src/gromacs/hardware/device_management_common.cpp index 608d9498b1..ad6cb0026f 100644 --- a/src/gromacs/hardware/device_management_common.cpp +++ b/src/gromacs/hardware/device_management_common.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team. - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -110,7 +110,7 @@ getCompatibleDevices(const std::vector>& devi return compatibleDeviceInfoList; } -std::vector getCompatibleDeviceIds(const std::vector>& deviceInfoList) +std::vector getCompatibleDeviceIds(gmx::ArrayRef> deviceInfoList) { // Possible minor over-allocation here, but not important for anything std::vector compatibleDeviceIds; @@ -125,8 +125,8 @@ std::vector getCompatibleDeviceIds(const std::vector>& deviceInfoList, - const int deviceId) +bool deviceIdIsCompatible(gmx::ArrayRef> deviceInfoList, + const int deviceId) { auto foundIt = std::find_if(deviceInfoList.begin(), deviceInfoList.end(), @@ -141,7 +141,7 @@ bool deviceIdIsCompatible(const std::vector>& return (*foundIt)->status == DeviceStatus::Compatible; } -std::string getDeviceCompatibilityDescription(const std::vector>& deviceInfoList, +std::string getDeviceCompatibilityDescription(const gmx::ArrayRef> deviceInfoList, int deviceId) { return (deviceId >= static_cast(deviceInfoList.size()) diff --git a/src/gromacs/hardware/hw_info.h b/src/gromacs/hardware/hw_info.h index 4d51d955ad..044c8dd86b 100644 --- a/src/gromacs/hardware/hw_info.h +++ b/src/gromacs/hardware/hw_info.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team. - * Copyright (c) 2017,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -134,9 +134,9 @@ struct gmx_hw_opt_t //! Logical core pinning offset. int core_pinning_offset = 0; //! Empty, or a string provided by the user declaring (unique) GPU IDs available for mdrun to use. - std::string gpuIdsAvailable = ""; + std::string devicesSelectedByUser; //! Empty, or a string provided by the user mapping GPU tasks to devices. - std::string userGpuTaskAssignment = ""; + std::string userGpuTaskAssignment; //! Tells whether mdrun is free to choose the total number of threads (by choosing the number of OpenMP and/or thread-MPI threads). bool totNumThreadsIsAuto; }; diff --git a/src/gromacs/mdrun/legacymdrunoptions.cpp b/src/gromacs/mdrun/legacymdrunoptions.cpp index 3ef319dadd..c78f448792 100644 --- a/src/gromacs/mdrun/legacymdrunoptions.cpp +++ b/src/gromacs/mdrun/legacymdrunoptions.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011-2019,2020, by the GROMACS development team, led by + * Copyright (c) 2011-2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -111,17 +111,17 @@ int LegacyMdrunOptions::updateFromCommandLine(int argc, char** argv, ArrayRef gpuIdsToUse = makeGpuIdsToUse(hwinfo_->deviceInfoList, hw_opt.gpuIdsAvailable); - const int numDevicesToUse = gmx::ssize(gpuIdsToUse); + std::vector availableDevices = + makeListOfAvailableDevices(hwinfo_->deviceInfoList, hw_opt.devicesSelectedByUser); + const int numAvailableDevices = gmx::ssize(availableDevices); // Print citation requests after all software/hardware printing pleaseCiteGromacs(fplog); @@ -837,7 +838,7 @@ int Mdrunner::mdrunner() auto canUseGpuForNonbonded = buildSupportsNonbondedOnGpu(nullptr); useGpuForNonbonded = decideWhetherToUseGpusForNonbondedWithThreadMpi( nonbondedTarget, - numDevicesToUse, + numAvailableDevices > 0, userGpuTaskAssignment, emulateGpuNonbonded, canUseGpuForNonbonded, @@ -845,7 +846,7 @@ int Mdrunner::mdrunner() hw_opt.nthreads_tmpi); useGpuForPme = decideWhetherToUseGpusForPmeWithThreadMpi(useGpuForNonbonded, pmeTarget, - numDevicesToUse, + numAvailableDevices, userGpuTaskAssignment, *hwinfo_, *inputrec, @@ -861,7 +862,7 @@ int Mdrunner::mdrunner() * correctly. */ hw_opt.nthreads_tmpi = get_nthreads_mpi(hwinfo_, &hw_opt, - numDevicesToUse, + numAvailableDevices, useGpuForNonbonded, useGpuForPme, inputrec.get(), @@ -1301,7 +1302,7 @@ int Mdrunner::mdrunner() // Produce the task assignment for this rank - done after DD is constructed GpuTaskAssignments gpuTaskAssignments = GpuTaskAssignmentsBuilder::build( - gpuIdsToUse, + availableDevices, userGpuTaskAssignment, *hwinfo_, simulationCommunicator, @@ -1429,7 +1430,7 @@ int Mdrunner::mdrunner() // where appropriate. if (!userGpuTaskAssignment.empty()) { - gpuTaskAssignments.logPerformanceHints(mdlog, numDevicesToUse); + gpuTaskAssignments.logPerformanceHints(mdlog, numAvailableDevices); } if (PAR(cr)) @@ -1508,7 +1509,7 @@ int Mdrunner::mdrunner() && (runScheduleWork.simulationWork.useGpuHaloExchange || runScheduleWork.simulationWork.useGpuPmePpCommunication)) { - setupGpuDevicePeerAccess(gpuIdsToUse, mdlog); + setupGpuDevicePeerAccess(gpuTaskAssignments.deviceIdsAssigned(), mdlog); } if (hw_opt.threadAffinity != ThreadAffinity::Off) diff --git a/src/gromacs/taskassignment/decidegpuusage.cpp b/src/gromacs/taskassignment/decidegpuusage.cpp index ba2e3563c8..b4d02f8213 100644 --- a/src/gromacs/taskassignment/decidegpuusage.cpp +++ b/src/gromacs/taskassignment/decidegpuusage.cpp @@ -112,7 +112,7 @@ const char* g_specifyEverythingFormatString = } // namespace bool decideWhetherToUseGpusForNonbondedWithThreadMpi(const TaskTarget nonbondedTarget, - const int numDevicesToUse, + const bool haveAvailableDevices, const std::vector& userGpuTaskAssignment, const EmulateGpuNonbonded emulateGpuNonbonded, const bool buildSupportsNonbondedOnGpu, @@ -149,7 +149,7 @@ bool decideWhetherToUseGpusForNonbondedWithThreadMpi(const TaskTarget non // all potential ranks can use, and can use that in a global // decision that will later be consistent. // If we get here, then the user permitted or required GPUs. - return (numDevicesToUse > 0); + return haveAvailableDevices; } bool decideWhetherToUseGpusForPmeWithThreadMpi(const bool useGpuForNonbonded, diff --git a/src/gromacs/taskassignment/decidegpuusage.h b/src/gromacs/taskassignment/decidegpuusage.h index 765636c448..d660da7f11 100644 --- a/src/gromacs/taskassignment/decidegpuusage.h +++ b/src/gromacs/taskassignment/decidegpuusage.h @@ -103,8 +103,7 @@ class MDAtoms; * * \param[in] nonbondedTarget The user's choice for mdrun -nb for where to assign * short-ranged nonbonded interaction tasks. - * \param[in] numDevicesToUse Number of compatible GPUs that the user permitted - * us to use. + * \param[in] haveAvailableDevices Whether there are available devices. * \param[in] userGpuTaskAssignment The user-specified assignment of GPU tasks to device IDs. * \param[in] emulateGpuNonbonded Whether we will emulate GPU calculation of nonbonded * interactions. @@ -118,7 +117,7 @@ class MDAtoms; * \throws std::bad_alloc If out of memory * InconsistentInputError If the user requirements are inconsistent. */ bool decideWhetherToUseGpusForNonbondedWithThreadMpi(TaskTarget nonbondedTarget, - int numDevicesToUse, + bool haveAvailableDevices, const std::vector& userGpuTaskAssignment, EmulateGpuNonbonded emulateGpuNonbonded, bool buildSupportsNonbondedOnGpu, diff --git a/src/gromacs/taskassignment/resourcedivision.cpp b/src/gromacs/taskassignment/resourcedivision.cpp index c2a9e61881..03c80d89e6 100644 --- a/src/gromacs/taskassignment/resourcedivision.cpp +++ b/src/gromacs/taskassignment/resourcedivision.cpp @@ -681,7 +681,7 @@ static void print_hw_opt(FILE* fp, const gmx_hw_opt_t* hw_opt) hw_opt->nthreads_tmpi, hw_opt->nthreads_omp, hw_opt->nthreads_omp_pme, - hw_opt->gpuIdsAvailable.c_str(), + hw_opt->devicesSelectedByUser.c_str(), hw_opt->userGpuTaskAssignment.c_str()); } diff --git a/src/gromacs/taskassignment/taskassignment.cpp b/src/gromacs/taskassignment/taskassignment.cpp index bcfce0e0ec..a9256ba27c 100644 --- a/src/gromacs/taskassignment/taskassignment.cpp +++ b/src/gromacs/taskassignment/taskassignment.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -154,9 +154,9 @@ bool isAnyGpuSharedBetweenRanks(ArrayRef gpuTaskAssignm } // namespace -void GpuTaskAssignments::logPerformanceHints(const MDLogger& mdlog, size_t numCompatibleGpusOnThisNode) +void GpuTaskAssignments::logPerformanceHints(const MDLogger& mdlog, size_t numAvailableDevicesOnThisNode) { - if (numCompatibleGpusOnThisNode > numGpuTasksOnThisNode_) + if (numAvailableDevicesOnThisNode > numGpuTasksOnThisNode_) { /* TODO In principle, this warning could be warranted only on * some nodes, but we lack the infrastructure to do a good job @@ -234,10 +234,10 @@ void barrierOverAllRanks(MPI_Comm comm) GpuTaskAssignmentsBuilder::GpuTaskAssignmentsBuilder() = default; -GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const std::vector& gpuIdsToUse, - const std::vector& userGpuTaskAssignment, - const gmx_hw_info_t& hardwareInfo, - MPI_Comm gromacsWorldComm, +GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const gmx::ArrayRef availableDevices, + const gmx::ArrayRef userGpuTaskAssignment, + const gmx_hw_info_t& hardwareInfo, + MPI_Comm gromacsWorldComm, const PhysicalNodeCommunicator& physicalNodeComm, const TaskTarget nonbondedTarget, const TaskTarget pmeTarget, @@ -249,7 +249,7 @@ GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const std::vector& gpuI bool rankHasPmeTask) { size_t numRanksOnThisNode = physicalNodeComm.size_; - std::vector gpuTasksOnThisRank = findGpuTasksOnThisRank(!gpuIdsToUse.empty(), + std::vector gpuTasksOnThisRank = findGpuTasksOnThisRank(!availableDevices.empty(), nonbondedTarget, pmeTarget, bondedTarget, @@ -265,6 +265,7 @@ GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const std::vector& gpuI std::exception_ptr exceptionPtr; std::vector taskAssignmentOnRanksOfThisNode; + std::vector deviceIdsAssigned; try { // Use the GPU IDs from the user if they supplied @@ -283,11 +284,10 @@ GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const std::vector& gpuI // runtime, and subject to environment modification such as // with CUDA_VISIBLE_DEVICES) that will be used for the // GPU-suitable tasks on all of the ranks of that node. - ArrayRef gpuIdsForTaskAssignment; - std::vector generatedGpuIds; + std::vector generatedGpuIds; if (userGpuTaskAssignment.empty()) { - ArrayRef compatibleGpusToUse = gpuIdsToUse; + ArrayRef compatibleGpusToUse = availableDevices; // enforce the single device/rank restriction if (numRanksOnThisNode == 1 && !compatibleGpusToUse.empty()) @@ -301,8 +301,8 @@ GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const std::vector& gpuI // but we don't have any way to do a better job reliably. generatedGpuIds = makeGpuIds(compatibleGpusToUse, numGpuTasksOnThisNode); - if ((numGpuTasksOnThisNode > gpuIdsToUse.size()) - && (numGpuTasksOnThisNode % gpuIdsToUse.size() != 0)) + if ((numGpuTasksOnThisNode > availableDevices.size()) + && (numGpuTasksOnThisNode % availableDevices.size() != 0)) { // TODO Decorating the message with hostname should be // the job of an error-reporting module. @@ -318,9 +318,9 @@ GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const std::vector& gpuI "perhaps after measuring the performance you can get.", numGpuTasksOnThisNode, host, - gpuIdsToUse.size()))); + availableDevices.size()))); } - gpuIdsForTaskAssignment = generatedGpuIds; + deviceIdsAssigned = generatedGpuIds; } else { @@ -340,12 +340,12 @@ GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const std::vector& gpuI numGpuTasksOnThisNode))); } // Did the user choose compatible GPUs? - checkUserGpuIds(hardwareInfo.deviceInfoList, gpuIdsToUse, userGpuTaskAssignment); + checkUserGpuIds(hardwareInfo.deviceInfoList, availableDevices, userGpuTaskAssignment); - gpuIdsForTaskAssignment = userGpuTaskAssignment; + deviceIdsAssigned = gmx::copyOf(userGpuTaskAssignment); } taskAssignmentOnRanksOfThisNode = - buildTaskAssignment(gpuTasksOnRanksOfThisNode, gpuIdsForTaskAssignment); + buildTaskAssignment(gpuTasksOnRanksOfThisNode, deviceIdsAssigned); } catch (...) { @@ -392,6 +392,7 @@ GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const std::vector& gpuI gpuTaskAssignments.indexOfThisRank_ = physicalNodeComm.rank_; gpuTaskAssignments.numGpuTasksOnThisNode_ = numGpuTasksOnThisNode; gpuTaskAssignments.numRanksOnThisNode_ = numRanksOnThisNode; + gpuTaskAssignments.deviceIdsAssigned_ = deviceIdsAssigned; return gpuTaskAssignments; } diff --git a/src/gromacs/taskassignment/taskassignment.h b/src/gromacs/taskassignment/taskassignment.h index f709f24e40..63cf9c54ff 100644 --- a/src/gromacs/taskassignment/taskassignment.h +++ b/src/gromacs/taskassignment/taskassignment.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,6 +52,7 @@ #include +#include "gromacs/utility/arrayref.h" #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/gmxmpi.h" @@ -140,7 +141,7 @@ public: * the ranks of that node. It throws InconsistentInputError * when a/the useful GPU task assignment is not possible. * - * \param[in] gpuIdsToUse The compatible GPUs that the user permitted us to use. + * \param[in] availableDevices The compatible devices that the user permitted us to use. * \param[in] userGpuTaskAssignment The user-specified assignment of GPU tasks to device IDs. * \param[in] hardwareInfo The detected hardware * \param[in] gromacsWorldComm MPI communicator for all ranks in the current GROMACS run @@ -159,8 +160,8 @@ public: * \throws std::bad_alloc If out of memory. * InconsistentInputError If user and/or detected inputs are inconsistent. */ - static GpuTaskAssignments build(const std::vector& gpuIdsToUse, - const std::vector& userGpuTaskAssignment, + static GpuTaskAssignments build(ArrayRef availableDevices, + ArrayRef userGpuTaskAssignment, const gmx_hw_info_t& hardwareInfo, MPI_Comm gromacsWorldComm, const PhysicalNodeCommunicator& physicalNodeComm, @@ -210,6 +211,9 @@ private: //! Number of ranks on this physical node. size_t numRanksOnThisNode_ = 0; + //! Vector of device IDs assigned to this node + std::vector deviceIdsAssigned_; + public: /*! \brief Log a report on how GPUs are being used on * the ranks of the physical node of rank 0 of the simulation. @@ -235,10 +239,11 @@ public: * learn how to let mdrun make a task assignment that runs * faster. * - * \param[in] mdlog Logging object. - * \param[in] numCompatibleGpusOnThisNode The number of compatible GPUs on this node. + * \param[in] mdlog Logging object. + * \param[in] numAvailableDevicesOnThisNode The number of compatible devices on this node + * that the user permitted us to use. * */ - void logPerformanceHints(const MDLogger& mdlog, size_t numCompatibleGpusOnThisNode); + void logPerformanceHints(const MDLogger& mdlog, size_t numAvailableDevicesOnThisNode); /*! \brief Return handle to the initialized GPU to use in the this rank. * * \param[out] deviceId Index of the assigned device. @@ -251,6 +256,8 @@ public: bool thisRankHasPmeGpuTask() const; //! Return whether this rank has any task running on a GPU bool thisRankHasAnyGpuTask() const; + //! Get the list of devices assigned to this node + std::vector deviceIdsAssigned() { return deviceIdsAssigned_; } }; } // namespace gmx diff --git a/src/gromacs/taskassignment/usergpuids.cpp b/src/gromacs/taskassignment/usergpuids.cpp index 881d3eea86..0162f2eb4f 100644 --- a/src/gromacs/taskassignment/usergpuids.cpp +++ b/src/gromacs/taskassignment/usergpuids.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -136,41 +136,41 @@ std::vector parseUserGpuIdString(const std::string& gpuIdString) return digits; } -std::vector makeGpuIdsToUse(const std::vector>& deviceInfoList, - const std::string& gpuIdsAvailableString) +std::vector makeListOfAvailableDevices(gmx::ArrayRef> deviceInfoList, + const std::string& devicesSelectedByUserString) { - std::vector gpuIdsAvailable = parseUserGpuIdString(gpuIdsAvailableString); + std::vector devicesSelectedByUser = parseUserGpuIdString(devicesSelectedByUserString); - if (gpuIdsAvailable.empty()) + if (devicesSelectedByUser.empty()) { - // The user didn't restrict the choice, so we use all compatible GPUs + // The user didn't restrict the choice, so we use all compatible devices. return getCompatibleDeviceIds(deviceInfoList); } - std::vector gpuIdsToUse; - gpuIdsToUse.reserve(gpuIdsAvailable.size()); - std::vector availableGpuIdsThatAreIncompatible; - for (const int& availableGpuId : gpuIdsAvailable) + std::vector availableDevices; + availableDevices.reserve(devicesSelectedByUser.size()); + std::vector incompatibleDevicesSelectedByUser; + for (const int& selectedDeviceId : devicesSelectedByUser) { - if (deviceIdIsCompatible(deviceInfoList, availableGpuId)) + if (deviceIdIsCompatible(deviceInfoList, selectedDeviceId)) { - gpuIdsToUse.push_back(availableGpuId); + availableDevices.push_back(selectedDeviceId); } else { - // Prepare data for an error message about all incompatible available GPU IDs. - availableGpuIdsThatAreIncompatible.push_back(availableGpuId); + // Prepare data for an error message about all incompatible devices that were selected by the user. + incompatibleDevicesSelectedByUser.push_back(selectedDeviceId); } } - if (!availableGpuIdsThatAreIncompatible.empty()) + if (!incompatibleDevicesSelectedByUser.empty()) { - auto message = "You requested mdrun to use GPUs with IDs " + gpuIdsAvailableString - + ", but that includes the following incompatible GPUs: " - + formatAndJoin(availableGpuIdsThatAreIncompatible, ",", StringFormatter("%d")) - + ". Request only compatible GPUs."; + auto message = "You requested mdrun to use GPU devices with IDs " + devicesSelectedByUserString + + ", but that includes the following incompatible devices: " + + formatAndJoin(incompatibleDevicesSelectedByUser, ",", StringFormatter("%d")) + + ". Request only compatible devices."; GMX_THROW(InvalidInputError(message)); } - return gpuIdsToUse; + return availableDevices; } std::vector parseUserTaskAssignmentString(const std::string& gpuIdString) @@ -209,9 +209,9 @@ std::string makeGpuIdString(const std::vector& gpuIds, int totalNumberOfTas return formatAndJoin(resultGpuIds, ",", StringFormatter("%d")); } -void checkUserGpuIds(const std::vector>& deviceInfoList, - const std::vector& compatibleGpus, - const std::vector& gpuIds) +void checkUserGpuIds(const ArrayRef> deviceInfoList, + const ArrayRef compatibleGpus, + const ArrayRef gpuIds) { bool foundIncompatibleGpuIds = false; std::string message = diff --git a/src/gromacs/taskassignment/usergpuids.h b/src/gromacs/taskassignment/usergpuids.h index e85d15bf18..c6c89aa578 100644 --- a/src/gromacs/taskassignment/usergpuids.h +++ b/src/gromacs/taskassignment/usergpuids.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -84,24 +84,24 @@ std::vector parseUserGpuIdString(const std::string& gpuIdString); * all compatible GPUs on this physical node. Otherwise, check the * user specified compatible GPUs and return their IDs. * - * \param[in] deviceInfoList Information on the GPUs on this physical node. - * \param[in] gpuIdsAvailableString String like "013" or "0,1,3" typically - * supplied by the user to mdrun -gpu_id. - * Must contain only unique decimal digits, or only decimal - * digits separated by comma delimiters. A terminal - * comma is accceptable (and required to specify a - * single ID that is larger than 9). + * \param[in] deviceInfoList Information on the GPUs on this physical node. + * \param[in] devicesSelectedByUserString String like "013" or "0,1,3" typically + * supplied by the user to mdrun -gpu_id. + * Must contain only unique decimal digits, or only decimal + * digits separated by comma delimiters. A terminal + * comma is accceptable (and required to specify a + * single ID that is larger than 9). * * \returns A vector of unique compatible GPU IDs on this physical node. * * \throws std::bad_alloc If out of memory. * InvalidInputError If an invalid character is found (ie not a digit or ',') or if * identifiers are duplicated in the specifier list. - * InvalidInputError If gpuIdsAvailableString specifies GPU IDs that are + * InvalidInputError If devicesSelectedByUserString specifies IDs of the devices that are * not compatible. */ -std::vector makeGpuIdsToUse(const std::vector>& deviceInfoList, - const std::string& gpuIdsAvailableString); +std::vector makeListOfAvailableDevices(gmx::ArrayRef> deviceInfoList, + const std::string& devicesSelectedByUserString); /*! \brief Parse a GPU ID specifier string into a container describing device ID to task mapping. * @@ -172,9 +172,9 @@ std::string makeGpuIdString(const std::vector& gpuIds, int totalNumberOfTas * \throws std::bad_alloc If out of memory * InconsistentInputError If the assigned GPUs are not valid */ -void checkUserGpuIds(const std::vector>& deviceInfoList, - const std::vector& compatibleGpus, - const std::vector& gpuIds); +void checkUserGpuIds(ArrayRef> deviceInfoList, + ArrayRef compatibleGpus, + ArrayRef gpuIds); } // namespace gmx