Merge branch release-2018
authorMark Abraham <mark.j.abraham@gmail.com>
Tue, 6 Mar 2018 14:07:45 +0000 (15:07 +0100)
committerMark Abraham <mark.j.abraham@gmail.com>
Tue, 6 Mar 2018 14:14:39 +0000 (15:14 +0100)
Minor conflicts from separation of multisim from commrec,
and code movement in constraints code.

Change-Id: Id1fea8a7de0726e34eb2d43b2420b4753631f303

16 files changed:
docs/release-notes/2018/2018.1.rst
src/gromacs/awh/awh.cpp
src/gromacs/awh/bias.cpp
src/gromacs/awh/bias.h
src/gromacs/awh/biasstate.cpp
src/gromacs/awh/biasstate.h
src/gromacs/awh/histogramsize.cpp
src/gromacs/awh/tests/bias.cpp
src/gromacs/hardware/cpuinfo.cpp
src/gromacs/hardware/cpuinfo.h
src/gromacs/mdlib/forcerec.cpp
src/gromacs/mdlib/shake.cpp
src/gromacs/mdlib/shake.h
src/gromacs/mdlib/tpi.cpp
src/gromacs/utility/binaryinformation.cpp
src/programs/mdrun/runner.cpp

index fc2ba289e02cfee299dabe283d7f2f8834e1607c..13d0c7ed973b1b8c2161c860f2fb26266a68a97b 100644 (file)
@@ -30,6 +30,13 @@ system.
 
 :issue:`2381`
 
+Fixed FEP calculations with SHAKE
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+All SHAKE + FEP calculations accumulated wrong values to dH/dl output,
+but in some cases the result will look the same.
+
+:issue:`2434`
+
 Fixed handling of mdp ``define`` statement assigning preprocessor values
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 Now .mdp files can configure the topology with values, as originally
@@ -121,3 +128,33 @@ Used isfinite unambiguously
 Patch provdied by Veselin Kolev to quiet some compiler warnings.
 
 :issue:`2400`
+
+Work around gcc-6 bug in tabulated group non-bonded kernels
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+With the gcc-6 compiler, AVX and -O3, which is the default,
+the tabulated non-bonded kernels of the (deprecated) group
+cutoff-scheme produced incorrect energies and forces.
+The errors are so large that they could not have caused latent issues.
+
+:issue:`2424`
+
+Detect correct AMD Zen SMT topology
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+On recent AMD Zen processors, hardware thread detection and pinning
+handling have been fixed, improving performance.
+
+:issue:`2388`
+
+Fix sharing of the AWH bias over multiple simulations
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Sharing the AWH bias over multiple simulations only worked when
+each simulation was running on a single MPI rank. When a simulation
+itself used multiple MPI ranks, the run would stop with an MPI error.
+
+:issue:`2433`
+
+Miscellaneous
+^^^^^^^^^^^^^
+
+Made multi-atom TPI reproducible with different compilers
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
index 6337ab6e71e0e8319a791a49604aae5524577423..8531347a4d95b3a87ecc12f3f642673f40ca129a 100644 (file)
@@ -242,6 +242,7 @@ real Awh::applyBiasForcesAndUpdateBias(int                     ePBC,
         gmx::ArrayRef<const double> biasForce =
             biasCts.bias.calcForceAndUpdateBias(coordValue,
                                                 &biasPotential, &biasPotentialJump,
+                                                commRecord_,
                                                 multiSimRecord_,
                                                 t, step, seed_, fplog);
 
index 1456ca0e26a62b60c056196d98dea24fb7a1b34e..4aeae9c0fa5aaa7b2c9fa234fb03163f1002a6ab 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018, 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.
@@ -105,6 +105,7 @@ gmx::ArrayRef<const double>
 Bias::calcForceAndUpdateBias(const awh_dvec        coordValue,
                              double               *awhPotential,
                              double               *potentialJump,
+                             const t_commrec      *commRecord,
                              const gmx_multisim_t *ms,
                              double                t,
                              gmx_int64_t           step,
@@ -186,7 +187,8 @@ Bias::calcForceAndUpdateBias(const awh_dvec        coordValue,
     {
         state_.updateFreeEnergyAndAddSamplesToHistogram(dimParams_, grid_,
                                                         params_,
-                                                        ms, t, step, fplog,
+                                                        commRecord, ms,
+                                                        t, step, fplog,
                                                         &updateList_);
 
         if (params_.convolveForce)
index 2a9df4afd0c27ae1446b052cb6fc0acdb91f6be4..c81c4e0c4dfc61de21fd048792d5d2b6735ab152 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018, 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.
@@ -195,6 +195,7 @@ class Bias
          * \param[in]     coordValue     The current coordinate value(s).
          * \param[out]    awhPotential   Bias potential.
          * \param[out]    potentialJump  Change in bias potential for this bias.
+         * \param[in]     commRecord     Struct for intra-simulation communication.
          * \param[in]     ms             Struct for multi-simulation communication.
          * \param[in]     t              Time.
          * \param[in]     step           Time step.
@@ -206,6 +207,7 @@ class Bias
         calcForceAndUpdateBias(const awh_dvec        coordValue,
                                double               *awhPotential,
                                double               *potentialJump,
+                               const t_commrec      *commRecord,
                                const gmx_multisim_t *ms,
                                double                t,
                                gmx_int64_t           step,
index 03b8930ea25a0c4b996a9e5d628d6b7a17ea7668..df5e0a3485b8865cd25798061d5e0520f63332cd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018, 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.
@@ -92,15 +92,65 @@ void BiasState::getPmf(gmx::ArrayRef<float> pmf) const
 namespace
 {
 
+/*! \brief
+ * Sum an array over all simulations on the master rank of each simulation.
+ *
+ * \param[in,out] arrayRef      The data to sum.
+ * \param[in]     multiSimComm  Struct for multi-simulation communication.
+ */
+void sumOverSimulations(gmx::ArrayRef<int>    arrayRef,
+                        const gmx_multisim_t *multiSimComm)
+{
+    gmx_sumi_sim(arrayRef.size(), arrayRef.data(), multiSimComm);
+}
+
+/*! \brief
+ * Sum an array over all simulations on the master rank of each simulation.
+ *
+ * \param[in,out] arrayRef      The data to sum.
+ * \param[in]     multiSimComm  Struct for multi-simulation communication.
+ */
+void sumOverSimulations(gmx::ArrayRef<double> arrayRef,
+                        const gmx_multisim_t *multiSimComm)
+{
+    gmx_sumd_sim(arrayRef.size(), arrayRef.data(), multiSimComm);
+}
+
+/*! \brief
+ * Sum an array over all simulations on all ranks of each simulation.
+ *
+ * This assumes the data is identical on all ranks within each simulation.
+ *
+ * \param[in,out] arrayRef      The data to sum.
+ * \param[in]     commRecord    Struct for intra-simulation communication.
+ * \param[in]     multiSimComm  Struct for multi-simulation communication.
+ */
+template<typename T>
+void sumOverSimulations(gmx::ArrayRef<T>      arrayRef,
+                        const t_commrec      *commRecord,
+                        const gmx_multisim_t *multiSimComm)
+{
+    if (MASTER(commRecord))
+    {
+        sumOverSimulations(arrayRef, multiSimComm);
+    }
+    if (commRecord->nnodes > 1)
+    {
+        gmx_bcast(arrayRef.size()*sizeof(T), arrayRef.data(), commRecord);
+    }
+}
+
 /*! \brief
  * Sum PMF over multiple simulations, when requested.
  *
  * \param[in,out] pointState         The state of the points in the bias.
  * \param[in]     numSharedUpdate    The number of biases sharing the histogram.
+ * \param[in]     commRecord         Struct for intra-simulation communication.
  * \param[in]     multiSimComm       Struct for multi-simulation communication.
  */
 void sumPmf(gmx::ArrayRef<PointState>  pointState,
             int                        numSharedUpdate,
+            const t_commrec           *commRecord,
             const gmx_multisim_t      *multiSimComm)
 {
     if (numSharedUpdate == 1)
@@ -118,7 +168,7 @@ void sumPmf(gmx::ArrayRef<PointState>  pointState,
         buffer[i] = pointState[i].inTargetRegion() ? std::exp(static_cast<float>(pointState[i].logPmfSum())) : 0;
     }
 
-    gmx_sumd_sim(buffer.size(), buffer.data(), multiSimComm);
+    sumOverSimulations(gmx::ArrayRef<double>(buffer), commRecord, multiSimComm);
 
     /* Take log again to get (non-normalized) PMF */
     double normFac = 1.0/numSharedUpdate;
@@ -302,6 +352,7 @@ int BiasState::warnForHistogramAnomalies(const Grid  &grid,
                                          FILE        *fplog,
                                          int          maxNumWarnings) const
 {
+    GMX_ASSERT(fplog != nullptr, "Warnings can only be issued if there is log file.");
     const double maxHistogramRatio = 0.5;  /* Tolerance for printing a warning about the histogram ratios */
 
     /* Sum up the histograms and get their normalization */
@@ -567,10 +618,12 @@ namespace
  *
  * \param[in,out] updateList    Update list for this simulation (assumed >= npoints long).
  * \param[in]     numPoints     Total number of points.
+ * \param[in]     commRecord    Struct for intra-simulation communication.
  * \param[in]     multiSimComm  Struct for multi-simulation communication.
  */
 void mergeSharedUpdateLists(std::vector<int>     *updateList,
                             int                   numPoints,
+                            const t_commrec      *commRecord,
                             const gmx_multisim_t *multiSimComm)
 {
     std::vector<int> numUpdatesOfPoint;
@@ -584,7 +637,7 @@ void mergeSharedUpdateLists(std::vector<int>     *updateList,
     }
 
     /* Sum over the sims to get all the flagged points */
-    gmx_sumi_sim(numPoints, numUpdatesOfPoint.data(), multiSimComm);
+    sumOverSimulations(arrayRefFromArray(numUpdatesOfPoint.data(), numPoints), commRecord, multiSimComm);
 
     /* Collect the indices of the flagged points in place. The resulting array will be the merged update list.*/
     updateList->clear();
@@ -664,12 +717,14 @@ namespace
  * \param[in,out] pointState         The state of the points in the bias.
  * \param[in,out] weightSumCovering  The weights for checking covering.
  * \param[in]     numSharedUpdate    The number of biases sharing the histrogram.
+ * \param[in]     commRecord         Struct for intra-simulation communication.
  * \param[in]     multiSimComm       Struct for multi-simulation communication.
  * \param[in]     localUpdateList    List of points with data.
  */
 void sumHistograms(gmx::ArrayRef<PointState>  pointState,
                    gmx::ArrayRef<double>      weightSumCovering,
                    int                        numSharedUpdate,
+                   const t_commrec           *commRecord,
                    const gmx_multisim_t      *multiSimComm,
                    const std::vector<int>    &localUpdateList)
 {
@@ -701,8 +756,8 @@ void sumHistograms(gmx::ArrayRef<PointState>  pointState,
             coordVisits[localIndex] = ps.numVisitsIteration();
         }
 
-        gmx_sumd_sim(weightSum.size(), weightSum.data(), multiSimComm);
-        gmx_sumd_sim(coordVisits.size(), coordVisits.data(), multiSimComm);
+        sumOverSimulations(gmx::ArrayRef<double>(weightSum), commRecord, multiSimComm);
+        sumOverSimulations(gmx::ArrayRef<double>(coordVisits), commRecord, multiSimComm);
 
         /* Transfer back the result */
         for (size_t localIndex = 0; localIndex < localUpdateList.size(); localIndex++)
@@ -831,6 +886,7 @@ void labelCoveredPoints(const std::vector<bool> &visited,
 bool BiasState::isSamplingRegionCovered(const BiasParams             &params,
                                         const std::vector<DimParams> &dimParams,
                                         const Grid                   &grid,
+                                        const t_commrec              *commRecord,
                                         const gmx_multisim_t         *multiSimComm) const
 {
     /* Allocate and initialize arrays: one for checking visits along each dimension,
@@ -917,7 +973,7 @@ bool BiasState::isSamplingRegionCovered(const BiasParams             &params,
         /* For multiple dimensions this may not be the best way to do it. */
         for (int d = 0; d < grid.numDimensions(); d++)
         {
-            gmx_sumi_sim(grid.axis(d).numPoints(), checkDim[d].covered.data(), multiSimComm);
+            sumOverSimulations(gmx::arrayRefFromArray(checkDim[d].covered.data(), grid.axis(d).numPoints()), commRecord, multiSimComm);
         }
     }
 
@@ -952,6 +1008,7 @@ static void normalizeFreeEnergyAndPmfSum(std::vector<PointState> *pointState)
 void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vector<DimParams> &dimParams,
                                                          const Grid                   &grid,
                                                          const BiasParams             &params,
+                                                         const t_commrec              *commRecord,
                                                          const gmx_multisim_t         *multiSimComm,
                                                          double                        t,
                                                          gmx_int64_t                   step,
@@ -972,7 +1029,7 @@ void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vector<DimPa
                         updateList);
     if (params.numSharedUpdate > 1)
     {
-        mergeSharedUpdateLists(updateList, points_.size(), multiSimComm);
+        mergeSharedUpdateLists(updateList, points_.size(), commRecord, multiSimComm);
     }
 
     /* Reset the range for the next update */
@@ -980,9 +1037,9 @@ void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vector<DimPa
 
     /* Add samples to histograms for all local points and sync simulations if needed */
     sumHistograms(points_, weightSumCovering_,
-                  params.numSharedUpdate, multiSimComm, *updateList);
+                  params.numSharedUpdate, commRecord, multiSimComm, *updateList);
 
-    sumPmf(points_, params.numSharedUpdate, multiSimComm);
+    sumPmf(points_, params.numSharedUpdate, commRecord, multiSimComm);
 
     /* Renormalize the free energy if values are too large. */
     bool needToNormalizeFreeEnergy = false;
@@ -1010,7 +1067,8 @@ void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vector<DimPa
     if (inInitialStage())
     {
         detectedCovering = (params.isCheckStep(points_.size(), step) &&
-                            isSamplingRegionCovered(params, dimParams, grid, multiSimComm));
+                            isSamplingRegionCovered(params, dimParams, grid,
+                                                    commRecord, multiSimComm));
     }
 
     /* The weighthistogram size after this update. */
index 7c197ac02da03dc7130eb18ab378dd521cb2e2ea..b4750e4708243a25362269d4d8aaa023b04f69e9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018, 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.
@@ -342,12 +342,14 @@ class BiasState
          * \param[in] params        The bias parameters.
          * \param[in] dimParams     Bias dimension parameters.
          * \param[in] grid          The grid.
+         * \param[in] commRecord    Struct for intra-simulation communication.
          * \param[in] multiSimComm  Struct for multi-simulation communication.
          * \returns true if covered.
          */
         bool isSamplingRegionCovered(const BiasParams             &params,
                                      const std::vector<DimParams> &dimParams,
                                      const Grid                   &grid,
+                                     const t_commrec              *commRecord,
                                      const gmx_multisim_t         *multiSimComm) const;
 
         /*! \brief
@@ -396,6 +398,7 @@ class BiasState
          * \param[in]     dimParams   The dimension parameters.
          * \param[in]     grid        The grid.
          * \param[in]     params      The bias parameters.
+         * \param[in]     commRecord  Struct for intra-simulation communication.
          * \param[in]     ms          Struct for multi-simulation communication.
          * \param[in]     t           Time.
          * \param[in]     step        Time step.
@@ -405,6 +408,7 @@ class BiasState
         void updateFreeEnergyAndAddSamplesToHistogram(const std::vector<DimParams> &dimParams,
                                                       const Grid                   &grid,
                                                       const BiasParams             &params,
+                                                      const t_commrec              *commRecord,
                                                       const gmx_multisim_t         *ms,
                                                       double                        t,
                                                       gmx_int64_t                   step,
index 886e8b5d37dc505a02501ff23c52b1fe685d1217..ffcae4e4813114b0fd26be470e51f8b466962448 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018, 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.
@@ -223,15 +223,18 @@ double HistogramSize::newHistogramSize(const BiasParams              &params,
             /* The histogram is equilibrated at most once. */
             equilibrateHistogram_ = !histogramIsEquilibrated(pointStates);
 
-            std::string prefix = gmx::formatString("\nawh%d:", params.biasIndex + 1);
-            if (!equilibrateHistogram_)
+            if (fplog != nullptr)
             {
-                fprintf(fplog, "%s equilibrated histogram at t = %g ps.\n", prefix.c_str(), t);
-            }
-            else if (!havePrintedAboutCovering_)
-            {
-                fprintf(fplog, "%s covered but histogram not equilibrated at t = %g ps.\n", prefix.c_str(), t);
-                havePrintedAboutCovering_ = true; /* Just print once. */
+                std::string prefix = gmx::formatString("\nawh%d:", params.biasIndex + 1);
+                if (!equilibrateHistogram_)
+                {
+                    fprintf(fplog, "%s equilibrated histogram at t = %g ps.\n", prefix.c_str(), t);
+                }
+                else if (!havePrintedAboutCovering_)
+                {
+                    fprintf(fplog, "%s covered but histogram not equilibrated at t = %g ps.\n", prefix.c_str(), t);
+                    havePrintedAboutCovering_ = true; /* Just print once. */
+                }
             }
         }
 
index d3f05ca4edcc40bc3d5df27534e4a6f8f1d5648a..663a6b3dd8e625119260a97c05b5fe1b623fd128 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2017, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018, 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.
@@ -237,7 +237,8 @@ TEST_P(BiasTest, ForcesBiasPmf)
         gmx::ArrayRef<const double> biasForce  =
             bias.calcForceAndUpdateBias(coordValue,
                                         &potential, &potentialJump,
-                                        nullptr, step, step, seed_, nullptr);
+                                        nullptr, nullptr, step, step, seed_,
+                                        nullptr);
 
         force.push_back(biasForce[0]);
         pot.push_back(potential);
@@ -321,7 +322,8 @@ TEST(BiasTest, DetectsCovering)
         double   potentialJump = 0;
         bias.calcForceAndUpdateBias(coordValue,
                                     &potential, &potentialJump,
-                                    nullptr, step, step, params.awhParams.seed, nullptr);
+                                    nullptr, nullptr,
+                                    step, step, params.awhParams.seed, nullptr);
 
         inInitialStage = bias.state().inInitialStage();
         if (!inInitialStage)
index d5123641aef6366572d81cd9fd7968ab75ae3ef0..09aca854a88f137011cb642e9e41990dba92992e 100644 (file)
@@ -492,6 +492,81 @@ renumberIndex(std::vector<unsigned int> * v)
     }
 }
 
+/*! \brief The layout of the bits in the APIC ID */
+struct ApicIdLayout
+{
+    unsigned int hwThreadBits; //!< The number of least significant bits for hw-threads
+    unsigned int coreBits;     //!< The number of core bits following the  hw-thread bits
+};
+
+/*! \brief Detect the APIC ID layout for x2APIC
+ */
+ApicIdLayout
+detectX2ApicIdLayout()
+{
+    ApicIdLayout    layout;
+
+    unsigned int    eax;
+    unsigned int    ebx;
+    unsigned int    ecx;
+    unsigned int    edx;
+    executeX86CpuID(0xb, 0, &eax, &ebx, &ecx, &edx);
+    layout.hwThreadBits = eax & 0x1f;
+    executeX86CpuID(0xb, 1, &eax, &ebx, &ecx, &edx);
+    layout.coreBits     = (eax & 0x1f) - layout.hwThreadBits;
+
+    return layout;
+}
+
+/*! \brief Detect the APIC ID layout for standard APIC or xAPIC on AMD
+ *
+ * \param[in] maxExtLevel  The largest CPUID extended function input value supported by the processor implementation
+ */
+ApicIdLayout
+detectAmdApicIdLayout(unsigned int maxExtLevel)
+{
+    ApicIdLayout layout;
+
+    unsigned int eax;
+    unsigned int ebx;
+    unsigned int ecx;
+    unsigned int edx;
+    executeX86CpuID(0x1, 0, &eax, &ebx, &ecx, &edx);
+    int          family = ((eax & 0x0ff00000) >> 20) + ((eax & 0x00000f00) >> 8);
+    executeX86CpuID(0x80000001, 0, &eax, &ebx, &ecx, &edx);
+    bool         haveExtendedTopology = (ecx & (1 << 22));
+
+    // NOTE: Here we assume 1 thread per core, unless we have family >= 17h
+    layout.hwThreadBits = 0;
+    if (family >= 0x17 &&
+        haveExtendedTopology &&
+        maxExtLevel >= 0x8000001e)
+    {
+        executeX86CpuID(0x8000001e, 1, &eax, &ebx, &ecx, &edx);
+        int numThreadsPerCore = ((ebx >> 8) & 0xff) + 1;
+        // NOTE: The AMD documentation only specifies the layout of apicid
+        //       when we have 1 or 2 threads per core.
+        while (numThreadsPerCore > (1 << layout.hwThreadBits))
+        {
+            layout.hwThreadBits++;
+        }
+    }
+
+    // Get number of core bits in apic ID - try modern extended method first
+    executeX86CpuID(0x80000008, 0, &eax, &ebx, &ecx, &edx);
+    layout.coreBits = (ecx >> 12) & 0xf;
+    if (layout.coreBits == 0)
+    {
+        // Legacy method for old single/dual core AMD CPUs
+        int i = ecx & 0xf;
+        while (i >> layout.coreBits)
+        {
+            layout.coreBits++;
+        }
+    }
+
+    return layout;
+}
 
 /*! \brief Try to detect basic CPU topology information using x86 cpuid
  *
@@ -535,32 +610,30 @@ detectX86LogicalProcessors()
 
     if (haveX2Apic || haveApic)
     {
-        unsigned int   hwThreadBits;
-        unsigned int   coreBits;
+        ApicIdLayout layout;
         // Get bits for cores and hardware threads
         if (haveX2Apic)
         {
-            executeX86CpuID(0xb, 0, &eax, &ebx, &ecx, &edx);
-            hwThreadBits    = eax & 0x1f;
-            executeX86CpuID(0xb, 1, &eax, &ebx, &ecx, &edx);
-            coreBits        = (eax & 0x1f) - hwThreadBits;
+            layout = detectX2ApicIdLayout();
         }
         else    // haveApic
         {
-            // AMD without x2APIC does not support SMT - there are no hwthread bits in apic ID
-            hwThreadBits = 0;
-            // Get number of core bits in apic ID - try modern extended method first
-            executeX86CpuID(0x80000008, 0, &eax, &ebx, &ecx, &edx);
-            coreBits = (ecx >> 12) & 0xf;
-            if (coreBits == 0)
+            if (detectX86Vendor() == CpuInfo::Vendor::Amd)
             {
-                // Legacy method for old single/dual core AMD CPUs
-                int i = ecx & 0xf;
-                while (i >> coreBits)
+                layout = detectAmdApicIdLayout(maxExtLevel);
+
+                if (layout.hwThreadBits > 1)
                 {
-                    coreBits++;
+                    // At the time of writing this code we do not know what
+                    // to do with more than 2 threads, so return empty.
+                    return logicalProcessors;
                 }
             }
+            else
+            {
+                // We do not know the APIC ID layout, return empty.
+                return logicalProcessors;
+            }
         }
 
         std::vector<unsigned int>  apicID = detectX86ApicIDs(haveX2Apic);
@@ -570,8 +643,8 @@ detectX86LogicalProcessors()
             // APIC IDs can be buggy, and it is always a mess. Typically more bits are
             // reserved than needed, and the numbers might not increment by 1 even in
             // a single socket or core. Extract, renumber, and check that things make sense.
-            unsigned int               hwThreadMask  = (1 << hwThreadBits) - 1;
-            unsigned int               coreMask      = (1 << coreBits) - 1;
+            unsigned int               hwThreadMask  = (1 << layout.hwThreadBits) - 1;
+            unsigned int               coreMask      = (1 << layout.coreBits) - 1;
             std::vector<unsigned int>  hwThreadRanks;
             std::vector<unsigned int>  coreRanks;
             std::vector<unsigned int>  socketRanks;
@@ -579,8 +652,8 @@ detectX86LogicalProcessors()
             for (auto a : apicID)
             {
                 hwThreadRanks.push_back( static_cast<int>( a & hwThreadMask ) );
-                coreRanks.push_back( static_cast<int>( ( a >> hwThreadBits ) & coreMask ) );
-                socketRanks.push_back( static_cast<int>( a >> ( coreBits + hwThreadBits ) ) );
+                coreRanks.push_back( static_cast<int>( ( a >> layout.hwThreadBits ) & coreMask ) );
+                socketRanks.push_back( static_cast<int>( a >> ( layout.coreBits + layout.hwThreadBits ) ) );
             }
 
             renumberIndex(&hwThreadRanks);
index 021686e85590a74f97574fa810942ecb6b80fffe..15c709b61691e03afe7b5990724532e66abe9a38 100644 (file)
@@ -116,7 +116,7 @@ class CpuInfo
             X86_Fma,         //!< Fused-multiply add support (mainly for AVX)
             X86_Fma4,        //!< 4-operand FMA, only on AMD for now
             X86_Hle,         //!< Hardware lock elision
-            X86_Htt,         //!< Hyper-Threading supported (but maybe not enabled)
+            X86_Htt,         //!< Hyper-Threading enabled (NOTE: might not match the CPUID HTT support flag)
             X86_Intel,       //!< This is an Intel x86 processor
             X86_Lahf,        //!< LAHF/SAHF support in 64 bits
             X86_MisalignSse, //!< Support for misaligned SSE data instructions
index d96b3c24be2119b5c91f358373aa1dc45612fdd1..27e83e82c05553c0339be13b7081045d3bc7224e 100644 (file)
@@ -1350,12 +1350,18 @@ static void make_nbf_tables(FILE *fp,
     nbl->table_vdw->stride        = nbl->table_vdw->formatsize * nbl->table_vdw->ninteractions;
     snew_aligned(nbl->table_vdw->data, nbl->table_vdw->stride*(nbl->table_vdw->n+1), 32);
 
+    /* NOTE: Using a single i-loop here leads to mix-up of data in table_vdw
+     *       with (at least) gcc 6.2, 6.3 and 6.4 when compiled with -O3 and AVX
+     */
     for (i = 0; i <= nbl->table_elec_vdw->n; i++)
     {
         for (j = 0; j < 4; j++)
         {
             nbl->table_elec->data[4*i+j] = nbl->table_elec_vdw->data[12*i+j];
         }
+    }
+    for (i = 0; i <= nbl->table_elec_vdw->n; i++)
+    {
         for (j = 0; j < 8; j++)
         {
             nbl->table_vdw->data[8*i+j] = nbl->table_elec_vdw->data[12*i+4+j];
index 0df8294298a79e36611ad502bc622a169299b484..a7f67fd549f6af435c2775bb6389c44015d95071 100644 (file)
@@ -476,12 +476,12 @@ static void check_cons(FILE *log, int nc, rvec x[], rvec prime[], rvec v[],
 gmx_bool bshakef(FILE *log, gmx_shakedata_t shaked,
                  real invmass[], int nblocks, int sblock[],
                  t_idef *idef, t_inputrec *ir, rvec x_s[], rvec prime[],
-                 t_nrnb *nrnb, real *scaled_lagrange_multiplier, real lambda, real *dvdlambda,
+                 t_nrnb *nrnb, real * const scaled_lagrange_multiplier, real lambda, real *dvdlambda,
                  real invdt, rvec *v, gmx_bool bCalcVir, tensor vir_r_m_dr,
                  gmx_bool bDumpOnError, int econq)
 {
     t_iatom *iatoms;
-    real     dt_2, dvdl;
+    real    *lam, dt_2, dvdl;
     int      i, n0, ncon, blen, type, ll;
     int      tnit = 0, trij = 0;
 
@@ -496,7 +496,11 @@ gmx_bool bshakef(FILE *log, gmx_shakedata_t shaked,
         scaled_lagrange_multiplier[ll] = 0;
     }
 
+    // TODO Rewrite this block so that it is obvious that i, iatoms
+    // and lam are all iteration variables. Is this easier if the
+    // sblock data structure is organized differently?
     iatoms = &(idef->il[F_CONSTR].iatoms[sblock[0]]);
+    lam    = scaled_lagrange_multiplier;
     for (i = 0; (i < nblocks); )
     {
         blen  = (sblock[i+1]-sblock[i]);
@@ -523,7 +527,7 @@ gmx_bool bshakef(FILE *log, gmx_shakedata_t shaked,
         tnit                       += n0*blen;
         trij                       += blen;
         iatoms                     += 3*blen; /* Increment pointer! */
-        scaled_lagrange_multiplier += blen;
+        lam                        += blen;
         i++;
     }
     /* only for position part? */
index 74bfca0c8650166f4444f26faad1b15ff826532b..8d18905310964a51ead0d45aa8b8c66d35e2413d 100644 (file)
@@ -57,7 +57,7 @@ gmx_bool bshakef(FILE           *log,          /* Log file                    */
                  rvec            x_s[],        /* Coords before update         */
                  rvec            prime[],      /* Output coords                */
                  t_nrnb         *nrnb,         /* Performance measure          */
-                 real           *lagr,         /* The Lagrange multipliers     */
+                 real * const    lagr,         /* The Lagrange multipliers     */
                  real            lambda,       /* FEP lambda                   */
                  real           *dvdlambda,    /* FEP force                    */
                  real            invdt,        /* 1/delta_t                    */
index d02b4989b11e411958a4b4a37a0de011598f7775..bf25ece3882365159419203bef1c6697d0f74c5f 100644 (file)
@@ -635,10 +635,11 @@ double do_tpi(FILE *fplog, t_commrec *cr,
                     copy_rvec(x_mol[i-a_tp0], state_global->x[i]);
                 }
                 /* Rotate the molecule randomly */
+                real angleX = 2*M_PI*dist(rng);
+                real angleY = 2*M_PI*dist(rng);
+                real angleZ = 2*M_PI*dist(rng);
                 rotate_conf(a_tp1-a_tp0, as_rvec_array(state_global->x.data())+a_tp0, nullptr,
-                            2*M_PI*dist(rng),
-                            2*M_PI*dist(rng),
-                            2*M_PI*dist(rng));
+                            angleX, angleY, angleZ);
                 /* Shift to the insertion location */
                 for (i = a_tp0; i < a_tp1; i++)
                 {
index f258f225040248486ca4c0b347ec5649ec4e13a8..b106b884d89b3d65aec6ef834dc00381cddb3d6d 100644 (file)
@@ -107,12 +107,14 @@ void printCopyright(gmx::TextWriter *writer)
     static const char * const Contributors[] = {
         "Emile Apol",
         "Rossen Apostolov",
+        "Paul Bauer",
         "Herman J.C. Berendsen",
         "Par Bjelkmar",
         "Aldert van Buuren",
         "Rudi van Drunen",
         "Anton Feenstra",
         "Gerrit Groenhof",
+        "Aleksei Iupinov",
         "Christoph Junghans",
         "Anca Hamuraru",
         "Vincent Hindriksen",
index 67824e3258e4705a9d4c2312dab72175a0124469..25dbfc2188a39385037b7b6593ba3c15018b2f7d 100644 (file)
@@ -1041,7 +1041,7 @@ int Mdrunner::mdrunner()
     }
     if (isMultiSim(ms))
     {
-        if (MASTER(cr))
+        if (SIMMASTER(cr))
         {
             MPI_Barrier(ms->mpi_comm_masters);
         }