Merge branch 'release-2019' into master
[alexxy/gromacs.git] / src / gromacs / mdrun / runner.cpp
index ae158a4984deefd1d61ca9e2a912143db1c75e05..1ae70af026460cad75cb4bb39136d2f23013456b 100644 (file)
 #include <cstring>
 
 #include <algorithm>
+#include <memory>
 
 #include "gromacs/commandline/filenm.h"
-#include "gromacs/compat/make_unique.h"
 #include "gromacs/domdec/domdec.h"
 #include "gromacs/domdec/domdec_struct.h"
 #include "gromacs/domdec/localatomsetmanager.h"
-#include "gromacs/ewald/ewald-utils.h"
+#include "gromacs/ewald/ewald_utils.h"
 #include "gromacs/ewald/pme.h"
-#include "gromacs/ewald/pme-gpu-program.h"
+#include "gromacs/ewald/pme_gpu_program.h"
 #include "gromacs/fileio/checkpoint.h"
 #include "gromacs/fileio/gmxfio.h"
 #include "gromacs/fileio/oenv.h"
@@ -74,9 +74,9 @@
 #include "gromacs/hardware/cpuinfo.h"
 #include "gromacs/hardware/detecthardware.h"
 #include "gromacs/hardware/printhardware.h"
-#include "gromacs/listed-forces/disre.h"
-#include "gromacs/listed-forces/gpubonded.h"
-#include "gromacs/listed-forces/orires.h"
+#include "gromacs/listed_forces/disre.h"
+#include "gromacs/listed_forces/gpubonded.h"
+#include "gromacs/listed_forces/orires.h"
 #include "gromacs/math/functions.h"
 #include "gromacs/math/utilities.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdlib/mdatoms.h"
 #include "gromacs/mdlib/mdrun.h"
 #include "gromacs/mdlib/membed.h"
-#include "gromacs/mdlib/nb_verlet.h"
-#include "gromacs/mdlib/nbnxn_gpu_data_mgmt.h"
-#include "gromacs/mdlib/nbnxn_search.h"
-#include "gromacs/mdlib/nbnxn_tuning.h"
 #include "gromacs/mdlib/ppforceworkload.h"
 #include "gromacs/mdlib/qmmm.h"
 #include "gromacs/mdlib/sighandler.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/mdtypes/observableshistory.h"
 #include "gromacs/mdtypes/state.h"
+#include "gromacs/nbnxm/nbnxm.h"
+#include "gromacs/nbnxm/pairlist_tuning.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pulling/output.h"
 #include "gromacs/pulling/pull.h"
@@ -169,7 +167,7 @@ Mdrunner Mdrunner::cloneOnSpawnedThread() const
     // part of the interface to the client code, which is associated only with the
     // original thread. Handles to the same resources can be obtained by copy.
     {
-        newRunner.restraintManager_ = compat::make_unique<RestraintManager>(*restraintManager_);
+        newRunner.restraintManager_ = std::make_unique<RestraintManager>(*restraintManager_);
     }
 
     // Copy original cr pointer before master thread can pass the thread barrier
@@ -192,7 +190,7 @@ Mdrunner Mdrunner::cloneOnSpawnedThread() const
     newRunner.replExParams        = replExParams;
     newRunner.pforce              = pforce;
     newRunner.ms                  = ms;
-    newRunner.stopHandlerBuilder_ = compat::make_unique<StopHandlerBuilder>(*stopHandlerBuilder_);
+    newRunner.stopHandlerBuilder_ = std::make_unique<StopHandlerBuilder>(*stopHandlerBuilder_);
 
     threadMpiMdrunnerAccessBarrier();
 
@@ -428,11 +426,8 @@ int Mdrunner::mdrunner()
     int                       nChargePerturbed = -1, nTypePerturbed = 0;
     gmx_wallcycle_t           wcycle;
     gmx_walltime_accounting_t walltime_accounting = nullptr;
-    int                       rc;
-    int64_t                   reset_counters;
-    int                       nthreads_pme = 1;
-    gmx_membed_t *            membed       = nullptr;
-    gmx_hw_info_t            *hwinfo       = nullptr;
+    gmx_membed_t *            membed              = nullptr;
+    gmx_hw_info_t            *hwinfo              = nullptr;
 
     /* CAUTION: threads may be started later on in this function, so
        cr doesn't reflect the final parallel state right now */
@@ -450,27 +445,14 @@ int Mdrunner::mdrunner()
     std::vector<int>    gpuIdsAvailable;
     try
     {
-        gpuIdsAvailable = parseUserGpuIds(hw_opt.gpuIdsAvailable);
-        // TODO We could put the GPU IDs into a std::map to find
-        // duplicates, but for the small numbers of IDs involved, this
-        // code is simple and fast.
-        for (size_t i = 0; i != gpuIdsAvailable.size(); ++i)
-        {
-            for (size_t j = i+1; j != gpuIdsAvailable.size(); ++j)
-            {
-                if (gpuIdsAvailable[i] == gpuIdsAvailable[j])
-                {
-                    GMX_THROW(InvalidInputError(formatString("The string of available GPU device IDs '%s' may not contain duplicate device IDs", hw_opt.gpuIdsAvailable.c_str())));
-                }
-            }
-        }
+        gpuIdsAvailable = parseUserGpuIdString(hw_opt.gpuIdsAvailable);
     }
     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
 
     std::vector<int> userGpuTaskAssignment;
     try
     {
-        userGpuTaskAssignment = parseUserGpuIds(hw_opt.userGpuTaskAssignment);
+        userGpuTaskAssignment = parseUserTaskAssignmentString(hw_opt.userGpuTaskAssignment);
     }
     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
     auto       nonbondedTarget = findTaskTarget(nbpu_opt);
@@ -552,7 +534,7 @@ int Mdrunner::mdrunner()
     if (SIMMASTER(cr))
     {
         /* Only the master rank has the global state */
-        globalState = compat::make_unique<t_state>();
+        globalState = std::make_unique<t_state>();
 
         /* Read (nearly) all data required for the simulation */
         read_tpx_state(ftp2fn(efTPR, filenames.size(), filenames.data()), inputrec, globalState.get(), &mtop);
@@ -753,7 +735,7 @@ int Mdrunner::mdrunner()
     {
         if (!MASTER(cr))
         {
-            globalState = compat::make_unique<t_state>();
+            globalState = std::make_unique<t_state>();
         }
         broadcastStateWithoutDynamics(cr, globalState.get());
     }
@@ -784,11 +766,6 @@ int Mdrunner::mdrunner()
         gmx_fatal(FARGS, "The .mdp file specified an energy mininization or normal mode algorithm, and these are not compatible with mdrun -rerun");
     }
 
-    if (can_use_allvsall(inputrec, TRUE, cr, fplog) && DOMAINDECOMP(cr))
-    {
-        gmx_fatal(FARGS, "All-vs-all loops do not work with domain decomposition, use a single MPI rank");
-    }
-
     if (!(EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype)))
     {
         if (domdecOptions.numPmeRanks > 0)
@@ -1139,23 +1116,12 @@ int Mdrunner::mdrunner()
         }
     }
 
-    /* getting number of PP/PME threads
+    /* getting number of PP/PME threads on this MPI / tMPI rank.
        PME: env variable should be read only on one node to make sure it is
        identical everywhere;
      */
-    nthreads_pme = gmx_omp_nthreads_get(emntPME);
-
-    int numThreadsOnThisRank;
-    /* threads on this MPI process or TMPI thread */
-    if (thisRankHasDuty(cr, DUTY_PP))
-    {
-        numThreadsOnThisRank = gmx_omp_nthreads_get(emntNonbonded);
-    }
-    else
-    {
-        numThreadsOnThisRank = nthreads_pme;
-    }
-
+    const int numThreadsOnThisRank =
+        thisRankHasDuty(cr, DUTY_PP) ? gmx_omp_nthreads_get(emntNonbonded) : gmx_omp_nthreads_get(emntPME);
     checkHardwareOversubscription(numThreadsOnThisRank, cr->nodeid,
                                   *hwinfo->hardwareTopology,
                                   physicalNodeComm, mdlog);
@@ -1190,7 +1156,7 @@ int Mdrunner::mdrunner()
     {
         /* Master synchronizes its value of reset_counters with all nodes
          * including PME only nodes */
-        reset_counters = wcycle_get_reset_counters(wcycle);
+        int64_t reset_counters = wcycle_get_reset_counters(wcycle);
         gmx_bcast_sim(sizeof(reset_counters), &reset_counters, cr);
         wcycle_set_reset_counters(wcycle, reset_counters);
     }
@@ -1320,7 +1286,7 @@ int Mdrunner::mdrunner()
                                        mtop.natoms, nChargePerturbed != 0, nTypePerturbed != 0,
                                        mdrunOptions.reproducible,
                                        ewaldcoeff_q, ewaldcoeff_lj,
-                                       nthreads_pme,
+                                       gmx_omp_nthreads_get(emntPME),
                                        pmeRunMode, nullptr,
                                        pmeDeviceInfo, pmeGpuProgram.get(), mdlog);
             }
@@ -1461,6 +1427,9 @@ int Mdrunner::mdrunner()
                pmedata,
                EI_DYNAMICS(inputrec->eI) && !isMultiSim(ms));
 
+    // clean up cycle counter
+    wallcycle_destroy(wcycle);
+
     // Free PME data
     if (pmedata)
     {
@@ -1508,7 +1477,7 @@ int Mdrunner::mdrunner()
         gmx_fedisableexcept();
     }
 
-    rc = static_cast<int>(gmx_get_stop_condition());
+    auto rc = static_cast<int>(gmx_get_stop_condition());
 
 #if GMX_THREAD_MPI
     /* we need to join all threads. The sub-threads join when they
@@ -1516,11 +1485,11 @@ int Mdrunner::mdrunner()
        wait for that. */
     if (PAR(cr) && MASTER(cr))
     {
-        done_commrec(cr);
         tMPI_Finalize();
     }
+    //TODO free commrec in MPI simulations
+    done_commrec(cr);
 #endif
-
     return rc;
 }
 
@@ -1690,7 +1659,7 @@ void Mdrunner::BuilderImplementation::addReplicaExchange(const ReplicaExchangePa
 
 void Mdrunner::BuilderImplementation::addMultiSim(gmx_multisim_t* multisim)
 {
-    multisim_ = compat::make_unique<gmx_multisim_t*>(multisim);
+    multisim_ = std::make_unique<gmx_multisim_t*>(multisim);
 }
 
 Mdrunner Mdrunner::BuilderImplementation::build()
@@ -1767,7 +1736,7 @@ Mdrunner Mdrunner::BuilderImplementation::build()
         GMX_THROW(gmx::APIError("MdrunnerBuilder::addBondedTaskAssignment() is required before build()"));
     }
 
-    newRunner.restraintManager_ = compat::make_unique<gmx::RestraintManager>();
+    newRunner.restraintManager_ = std::make_unique<gmx::RestraintManager>();
 
     if (stopHandlerBuilder_)
     {
@@ -1775,7 +1744,7 @@ Mdrunner Mdrunner::BuilderImplementation::build()
     }
     else
     {
-        newRunner.stopHandlerBuilder_ = compat::make_unique<StopHandlerBuilder>();
+        newRunner.stopHandlerBuilder_ = std::make_unique<StopHandlerBuilder>();
     }
 
     return newRunner;
@@ -1824,7 +1793,7 @@ void Mdrunner::BuilderImplementation::addStopHandlerBuilder(std::unique_ptr<Stop
 }
 
 MdrunnerBuilder::MdrunnerBuilder(compat::not_null<SimulationContext*> context) :
-    impl_ {gmx::compat::make_unique<Mdrunner::BuilderImplementation>(context)}
+    impl_ {std::make_unique<Mdrunner::BuilderImplementation>(context)}
 {
 }