/*! \brief Helper function for reporting GPU usage information * in the mdrun log file * * \param[in] gpu_info Pointer to per-node GPU info struct * \param[in] gpu_opt Pointer to per-node GPU options struct * \param[in] numPpRanks Number of PP ranks per node * \return String to write to the log file * \throws std::bad_alloc if out of memory */ static std::string makeGpuUsageReport(const gmx_gpu_info_t *gpu_info, const gmx_gpu_opt_t *gpu_opt, size_t numPpRanks) { int ngpu_use = gpu_opt->ncuda_dev_use; int ngpu_comp = gpu_info->ncuda_dev_compatible; /* Issue a note if GPUs are available but not used */ if (ngpu_comp > 0 && ngpu_use < 1) { return gmx::formatString("%d compatible GPU%s detected in the system, but none will be used.\n" "Consider trying GPU acceleration with the Verlet scheme!\n", ngpu_comp, (ngpu_comp > 1) ? "s" : ""); } std::string output; if (!gpu_opt->bUserSet) { // gpu_opt->cuda_dev_compatible is only populated during auto-selection std::string gpuIdsString = formatAndJoin(gmx::constArrayRefFromArray(gpu_opt->cuda_dev_compatible, gpu_opt->ncuda_dev_compatible), ",", gmx::StringFormatter("%d")); bool bPluralGpus = gpu_opt->ncuda_dev_compatible > 1; output += gmx::formatString("%d compatible GPU%s %s present, with ID%s %s\n", gpu_opt->ncuda_dev_compatible, bPluralGpus ? "s" : "", bPluralGpus ? "are" : "is", bPluralGpus ? "s" : "", gpuIdsString.c_str()); } { std::vector<int> gpuIdsInUse; for (int i = 0; i < ngpu_use; i++) { gpuIdsInUse.push_back(get_gpu_device_id(gpu_info, gpu_opt, i)); } std::string gpuIdsString = formatAndJoin(gpuIdsInUse, ",", gmx::StringFormatter("%d")); int numGpusInUse = gmx_count_gpu_dev_unique(gpu_info, gpu_opt); bool bPluralGpus = numGpusInUse > 1; output += gmx::formatString("%d GPU%s %sselected for this run.\n" "Mapping of GPU ID%s to the %d PP rank%s in this node: %s\n", numGpusInUse, bPluralGpus ? "s" : "", gpu_opt->bUserSet ? "user-" : "auto-", bPluralGpus ? "s" : "", numPpRanks, (numPpRanks > 1) ? "s" : "", gpuIdsString.c_str()); } return output; }
std::string makeGpuIdString(const std::vector<int> &gpuIds, int totalNumberOfTasks) { auto resultGpuIds = makeGpuIds(gpuIds, totalNumberOfTasks); return formatAndJoin(resultGpuIds, ",", StringFormatter("%d")); }