// TODO: Move to after all booleans are defined.
if (useGpuForUpdate && !bFirstStep)
{
- stateGpu->copyCoordinatesFromGpu(ArrayRef<RVec>(state->x), AtomLocality::Local);
+ stateGpu->copyCoordinatesFromGpu(state->x, AtomLocality::Local);
stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
}
/* PME grid + cut-off optimization with GPUs or PME nodes */
stateGpu->waitVelocitiesReadyOnHost(AtomLocality::Local);
}
- // Copy coordinate from the GPU when needed:
- // - On search steps to keep copy on host (device buffers are reinitialized).
- // - There are CPU bonded forces that need current coordinates
- // - When needed for the output.
- if (bNS ||
- (runScheduleWork->domainWork.haveCpuBondedWork || runScheduleWork->domainWork.haveFreeEnergyWork) ||
- do_per_step(step, ir->nstxout) || do_per_step(step, ir->nstxout_compressed))
+ // Copy coordinate from the GPU when needed at the search step.
+ // NOTE: The cases when coordinates needed on CPU for force evaluation are handled in sim_utils.
+ // NOTE: If the coordinates are to be written into output file they are also copied separately before the output.
+ if (bNS)
{
- stateGpu->copyCoordinatesFromGpu(ArrayRef<RVec>(state->x), AtomLocality::Local);
+ stateGpu->copyCoordinatesFromGpu(state->x, AtomLocality::Local);
stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
}
}
}
}
+ // Copy coordinate from the GPU for the output if the update is offloaded and
+ // coordinates have not already been copied for i) search or ii) CPU force tasks.
+ if (useGpuForUpdate && !bNS && !runScheduleWork->domainWork.haveCpuLocalForceWork &&
+ (do_per_step(step, ir->nstxout) || do_per_step(step, ir->nstxout_compressed)))
+ {
+ stateGpu->copyCoordinatesFromGpu(state->x, AtomLocality::Local);
+ stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
+ }
/* Now we have the energies and forces corresponding to the
* coordinates at time t. We must output all of this before
* the update.
// Copy data to the GPU after buffers might have being reinitialized
stateGpu->copyVelocitiesToGpu(state->v, AtomLocality::Local);
- stateGpu->copyCoordinatesToGpu(ArrayRef<RVec>(state->x), AtomLocality::Local);
+ stateGpu->copyCoordinatesToGpu(state->x, AtomLocality::Local);
}
stateGpu->copyForcesToGpu(ArrayRef<RVec>(f), AtomLocality::All);
{
stateGpu->copyVelocitiesFromGpu(state->v, AtomLocality::Local);
stateGpu->waitVelocitiesReadyOnHost(AtomLocality::Local);
- stateGpu->copyCoordinatesFromGpu(ArrayRef<RVec>(state->x), AtomLocality::Local);
- stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
}
}
else
if (bGStat || needHalfStepKineticEnergy || doInterSimSignal)
{
+ // Copy coordinates when needed to stop the CM motion.
+ if (useGpuForUpdate && !EI_VV(ir->eI) && bStopCM)
+ {
+ stateGpu->copyCoordinatesFromGpu(state->x, AtomLocality::Local);
+ stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
+ }
// Since we're already communicating at this step, we
// can propagate intra-simulation signals. Note that
// check_nstglobalcomm has the responsibility for
// TODO: The special case of removing CM motion should be dealt more gracefully
if (useGpuForUpdate)
{
- stateGpu->copyCoordinatesToGpu(ArrayRef<RVec>(state->x), AtomLocality::Local);
+ stateGpu->copyCoordinatesToGpu(state->x, AtomLocality::Local);
stateGpu->waitCoordinatesCopiedToDevice(AtomLocality::Local);
}
}