EEL_PME(inputrec->coulombtype) && thisRankHasDuty(cr, DUTY_PME));
// Get the device handles for the modules, nullptr when no task is assigned.
- // TODO: There should be only one DeviceInformation per rank.
- DeviceInformation* nonbondedDeviceInfo = gpuTaskAssignments.initNonbondedDevice(cr);
- DeviceInformation* pmeDeviceInfo = gpuTaskAssignments.initPmeDevice();
-
+ int deviceId = -1;
+ DeviceInformation* deviceInfo = gpuTaskAssignments.initDevice(&deviceId);
std::unique_ptr<DeviceContext> deviceContext = nullptr;
- if (pmeDeviceInfo)
- {
- deviceContext = std::make_unique<DeviceContext>(*pmeDeviceInfo);
- }
- else if (nonbondedDeviceInfo)
+ if (deviceInfo != nullptr)
{
- deviceContext = std::make_unique<DeviceContext>(*nonbondedDeviceInfo);
+ if (DOMAINDECOMP(cr) && thisRankHasDuty(cr, DUTY_PP))
+ {
+ dd_setup_dlb_resource_sharing(cr, deviceId);
+ }
+ deviceContext = std::make_unique<DeviceContext>(*deviceInfo);
}
// TODO Initialize GPU streams here.
cr->mpi_comm_mysim, cr->dd->pme_nodeid, *deviceContext);
}
- fr->nbv = Nbnxm::init_nb_verlet(mdlog, inputrec, fr, cr, *hwinfo, nonbondedDeviceInfo,
+ fr->nbv = Nbnxm::init_nb_verlet(mdlog, inputrec, fr, cr, *hwinfo, deviceInfo,
fr->deviceContext, &mtop, box, wcycle);
if (useGpuForBonded)
{
if (thisRankHasPmeGpuTask)
{
GMX_RELEASE_ASSERT(
- pmeDeviceInfo != nullptr,
+ deviceInfo != nullptr,
"Device information can not be nullptr when building PME GPU program object.");
GMX_RELEASE_ASSERT(
deviceContext != nullptr,
"Device context can not be nullptr when building PME GPU program object.");
- pmeGpuProgram = buildPmeGpuProgram(*pmeDeviceInfo, *deviceContext);
+ pmeGpuProgram = buildPmeGpuProgram(*deviceInfo, *deviceContext);
}
/* Initiate PME if necessary,
pmedata = gmx_pme_init(cr, getNumPmeDomains(cr->dd), inputrec, nChargePerturbed != 0,
nTypePerturbed != 0, mdrunOptions.reproducible, ewaldcoeff_q,
ewaldcoeff_lj, gmx_omp_nthreads_get(emntPME), pmeRunMode,
- nullptr, pmeDeviceInfo, pmeGpuProgram.get(), mdlog);
+ nullptr, deviceInfo, pmeGpuProgram.get(), mdlog);
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
physicalNodeComm.barrier();
}
- free_gpu(nonbondedDeviceInfo);
- free_gpu(pmeDeviceInfo);
+ free_gpu(deviceInfo);
deviceContext.reset(nullptr);
sfree(fcd);
numRanksOnThisNode_, printHostName, useGpuForBonded, pmeRunMode, useGpuForUpdate);
}
-DeviceInformation* GpuTaskAssignments::initNonbondedDevice(const t_commrec* cr) const
+/*! \brief Function for whether the task of \c mapping has value \c TaskType.
+ *
+ * \param[in] mapping Current GPU task mapping.
+ * \returns If \c TaskType task was assigned to the \c mapping.
+ */
+template<GpuTask TaskType>
+static bool hasTaskType(const GpuTaskMapping& mapping)
{
- DeviceInformation* deviceInfo = nullptr;
- const GpuTaskAssignment& gpuTaskAssignment = assignmentForAllRanksOnThisNode_[indexOfThisRank_];
-
- // This works because only one task of each type per rank is currently permitted.
- auto nbGpuTaskMapping = std::find_if(gpuTaskAssignment.begin(), gpuTaskAssignment.end(),
- hasTaskType<GpuTask::Nonbonded>);
- if (nbGpuTaskMapping != gpuTaskAssignment.end())
- {
- int deviceId = nbGpuTaskMapping->deviceId_;
- deviceInfo = getDeviceInfo(hardwareInfo_.gpu_info, deviceId);
- init_gpu(deviceInfo);
+ return mapping.task_ == TaskType;
+}
- // TODO Setting up this sharing should probably part of
- // init_domain_decomposition after further refactoring.
- if (DOMAINDECOMP(cr))
- {
- /* When we share GPUs over ranks, we need to know this for the DLB */
- dd_setup_dlb_resource_sharing(cr, deviceId);
- }
- }
- return deviceInfo;
+/*! \brief Function for whether the \c mapping has the GPU PME or Nonbonded task.
+ *
+ * \param[in] mapping Current GPU task mapping.
+ * \returns If PME on Nonbonded GPU task was assigned to this mapping.
+ */
+static bool hasPmeOrNonbondedTask(const GpuTaskMapping& mapping)
+{
+ return hasTaskType<GpuTask::Pme>(mapping) || hasTaskType<GpuTask::Nonbonded>(mapping);
}
-DeviceInformation* GpuTaskAssignments::initPmeDevice() const
+DeviceInformation* GpuTaskAssignments::initDevice(int* deviceId) const
{
DeviceInformation* deviceInfo = nullptr;
const GpuTaskAssignment& gpuTaskAssignment = assignmentForAllRanksOnThisNode_[indexOfThisRank_];
- // This works because only one task of each type is currently permitted.
- auto pmeGpuTaskMapping = std::find_if(gpuTaskAssignment.begin(), gpuTaskAssignment.end(),
- hasTaskType<GpuTask::Pme>);
- const bool thisRankHasPmeGpuTask = (pmeGpuTaskMapping != gpuTaskAssignment.end());
- if (thisRankHasPmeGpuTask)
+ // This works because only one task of each type per rank is currently permitted.
+ auto gpuTaskMapping =
+ std::find_if(gpuTaskAssignment.begin(), gpuTaskAssignment.end(), hasPmeOrNonbondedTask);
+
+ if (gpuTaskMapping != gpuTaskAssignment.end())
{
- deviceInfo = getDeviceInfo(hardwareInfo_.gpu_info, pmeGpuTaskMapping->deviceId_);
+ *deviceId = gpuTaskMapping->deviceId_;
+ deviceInfo = getDeviceInfo(hardwareInfo_.gpu_info, *deviceId);
init_gpu(deviceInfo);
}
return deviceInfo;
* \param[in] numCompatibleGpusOnThisNode The number of compatible GPUs on this node.
* */
void logPerformanceHints(const MDLogger& mdlog, size_t numCompatibleGpusOnThisNode);
- /*! \brief Return handle to the initialized GPU to use for the
- * nonbonded task on this rank, if any.
+ /*! \brief Return handle to the initialized GPU to use in the this rank.
*
- * Returns nullptr if no such task is assigned to this rank.
+ * \param[out] deviceId Index of the assigned device.
*
- * \todo This also sets up DLB for device sharing, where
- * appropriate, but that responsbility should move
- * elsewhere. */
- DeviceInformation* initNonbondedDevice(const t_commrec* cr) const;
- /*! \brief Return handle to the initialized GPU to use for the
- * PME task on this rank, if any.
- *
- * Returns nullptr if no such task is assigned to this rank. */
- DeviceInformation* initPmeDevice() const;
+ * \returns Device information on the selected devicce. Returns nullptr if no GPU task
+ * is assigned to this rank.
+ */
+ DeviceInformation* initDevice(int* deviceId) const;
//! Return whether this rank has a PME task running on a GPU
bool thisRankHasPmeGpuTask() const;
//! Return whether this rank has any task running on a GPU
bool thisRankHasAnyGpuTask() const;
};
-//! Function for whether the task of \c mapping has value \c TaskType.
-template<GpuTask TaskType>
-bool hasTaskType(const GpuTaskMapping& mapping)
-{
- return mapping.task_ == TaskType;
-}
-
} // namespace gmx
#endif