Use C++ replacement for md_logging.*
authorTeemu Murtola <teemu.murtola@gmail.com>
Wed, 1 Jun 2016 18:20:01 +0000 (21:20 +0300)
committerTeemu Murtola <teemu.murtola@gmail.com>
Wed, 1 Jun 2016 19:17:28 +0000 (22:17 +0300)
Replace md_logging.h with the new C++ implementation.  This removes the
need to pass around a (FILE *, t_commrec *) tuple for just calling
md_logging.h routines.  Initialize the logger in runner.cpp to get the
same output as earlier.  For now, output is the same as earlier, but the
new interface could also relatively easily support, e.g., automatic line
wrapping.

Further changes should see all of fplog access go through the same
object (possibly after finetuning the interface), but that would be too
large of a change to do in one go.

Thread affinity tests for now just discard the log output, making them
more silent.  Future changes should see the log output verified, to
check that the correct messages are produced.

Related to #1505, closes #1644.

Change-Id: I0895b752b040d231cacb49a3a7a48d26c6096944

31 files changed:
src/gromacs/ewald/pme-load-balancing.cpp
src/gromacs/ewald/pme-load-balancing.h
src/gromacs/gmxlib/md_logging.cpp [deleted file]
src/gromacs/gmxlib/md_logging.h [deleted file]
src/gromacs/gpu_utils/gpu_utils.cu
src/gromacs/gpu_utils/gpu_utils.h
src/gromacs/gpu_utils/gpu_utils_ocl.cpp
src/gromacs/hardware/detecthardware.cpp
src/gromacs/hardware/detecthardware.h
src/gromacs/mdlib/force.h
src/gromacs/mdlib/forcerec.cpp
src/gromacs/mdlib/forcerec.h
src/gromacs/mdlib/gmx_omp_nthreads.cpp
src/gromacs/mdlib/gmx_omp_nthreads.h
src/gromacs/mdlib/integrator.h
src/gromacs/mdlib/md_support.cpp
src/gromacs/mdlib/md_support.h
src/gromacs/mdlib/minimize.cpp
src/gromacs/mdlib/sim_util.cpp
src/gromacs/mdlib/sim_util.h
src/gromacs/mdlib/tpi.cpp
src/gromacs/mdrunutility/tests/threadaffinitytest.h
src/gromacs/mdrunutility/threadaffinity.cpp
src/gromacs/mdrunutility/threadaffinity.h
src/gromacs/timing/wallcycle.cpp
src/gromacs/timing/wallcyclereporting.h
src/gromacs/utility/logger.h
src/programs/mdrun/md.cpp
src/programs/mdrun/resource-division.cpp
src/programs/mdrun/resource-division.h
src/programs/mdrun/runner.cpp

index a028c1cb987b011236930bf7075969c2d9996284..c7f284e5ac05a2e1f02b404e2fe6e227712dce23 100644 (file)
@@ -57,7 +57,6 @@
 #include "gromacs/domdec/domdec_network.h"
 #include "gromacs/domdec/domdec_struct.h"
 #include "gromacs/fft/calcgrid.h"
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/gmxlib/network.h"
 #include "gromacs/math/functions.h"
 #include "gromacs/math/vec.h"
@@ -72,6 +71,7 @@
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/smalloc.h"
 
 #include "pme-internal.h"
@@ -155,11 +155,11 @@ bool pme_loadbal_is_active(const pme_load_balancing_t *pme_lb)
 
 void pme_loadbal_init(pme_load_balancing_t     **pme_lb_p,
                       t_commrec                 *cr,
-                      FILE                      *fp_log,
+                      const gmx::MDLogger       &mdlog,
                       const t_inputrec          *ir,
                       matrix                     box,
                       const interaction_const_t *ic,
-                      struct gmx_pme_t          *pmedata,
+                      gmx_pme_t                 *pmedata,
                       gmx_bool                   bUseGPU,
                       gmx_bool                  *bPrinting)
 {
@@ -244,7 +244,7 @@ void pme_loadbal_init(pme_load_balancing_t     **pme_lb_p,
 
     if (!wallcycle_have_counter())
     {
-        md_print_warn(cr, fp_log, "NOTE: Cycle counters unsupported or not enabled in kernel. Cannot use PME-PP balancing.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: Cycle counters unsupported or not enabled in kernel. Cannot use PME-PP balancing.");
     }
 
     /* Tune with GPUs and/or separate PME ranks.
@@ -274,7 +274,7 @@ void pme_loadbal_init(pme_load_balancing_t     **pme_lb_p,
         dd_dlb_lock(cr->dd);
         if (dd_dlb_is_locked(cr->dd))
         {
-            md_print_warn(cr, fp_log, "NOTE: DLB will not turn on during the first phase of PME tuning\n");
+            GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: DLB will not turn on during the first phase of PME tuning");
         }
     }
 
@@ -518,6 +518,7 @@ pme_load_balance(pme_load_balancing_t      *pme_lb,
                  t_commrec                 *cr,
                  FILE                      *fp_err,
                  FILE                      *fp_log,
+                 const gmx::MDLogger       &mdlog,
                  const t_inputrec          *ir,
                  t_state                   *state,
                  double                     cycles,
@@ -746,7 +747,8 @@ pme_load_balance(pme_load_balancing_t      *pme_lb,
                 /* This should not happen, as we set limits on the DLB bounds.
                  * But we implement a complete failsafe solution anyhow.
                  */
-                md_print_warn(cr, fp_log, "The fastest PP/PME load balancing setting (cutoff %.3f nm) is no longer available due to DD DLB or box size limitations\n");
+                GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                        "The fastest PP/PME load balancing setting (cutoff %.3f nm) is no longer available due to DD DLB or box size limitations", pme_lb->fastest);
                 pme_lb->fastest = pme_lb->lower_limit;
                 pme_lb->start   = pme_lb->lower_limit;
             }
@@ -870,6 +872,7 @@ void pme_loadbal_do(pme_load_balancing_t *pme_lb,
                     t_commrec            *cr,
                     FILE                 *fp_err,
                     FILE                 *fp_log,
+                    const gmx::MDLogger  &mdlog,
                     const t_inputrec     *ir,
                     t_forcerec           *fr,
                     t_state              *state,
@@ -951,7 +954,7 @@ void pme_loadbal_do(pme_load_balancing_t *pme_lb,
         {
             /* Unlock the DLB=auto, DLB is allowed to activate */
             dd_dlb_unlock(cr->dd);
-            md_print_warn(cr, fp_log, "NOTE: DLB can now turn on, when beneficial\n");
+            GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: DLB can now turn on, when beneficial");
 
             /* We don't deactivate the tuning yet, since we will balance again
              * after DLB gets turned on, if it does within PMETune_period.
@@ -984,7 +987,7 @@ void pme_loadbal_do(pme_load_balancing_t *pme_lb,
          * but the first data collected is skipped anyhow.
          */
         pme_load_balance(pme_lb, cr,
-                         fp_err, fp_log,
+                         fp_err, fp_log, mdlog,
                          ir, state, pme_lb->cycles_c - cycles_prev,
                          fr->ic, fr->nbv, &fr->pmedata,
                          step);
@@ -1015,7 +1018,7 @@ void pme_loadbal_do(pme_load_balancing_t *pme_lb,
     {
         /* Make sure DLB is allowed when we deactivate PME tuning */
         dd_dlb_unlock(cr->dd);
-        md_print_warn(cr, fp_log, "NOTE: DLB can now turn on, when beneficial\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: DLB can now turn on, when beneficial");
     }
 
     *bPrinting = pme_lb->bBalance;
@@ -1042,8 +1045,8 @@ static void print_pme_loadbal_setting(FILE              *fplog,
 
 /*! \brief Print all load-balancing settings */
 static void print_pme_loadbal_settings(pme_load_balancing_t *pme_lb,
-                                       t_commrec            *cr,
                                        FILE                 *fplog,
+                                       const gmx::MDLogger  &mdlog,
                                        gmx_bool              bNonBondedOnGPU)
 {
     double     pp_ratio, grid_ratio;
@@ -1081,10 +1084,10 @@ static void print_pme_loadbal_settings(pme_load_balancing_t *pme_lb,
 
     if (pp_ratio > 1.5 && !bNonBondedOnGPU)
     {
-        md_print_warn(cr, fplog,
-                      "NOTE: PME load balancing increased the non-bonded workload by more than 50%%.\n"
-                      "      For better performance, use (more) PME ranks (mdrun -npme),\n"
-                      "      or if you are beyond the scaling limit, use fewer total ranks (or nodes).\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                "NOTE: PME load balancing increased the non-bonded workload by more than 50%.\n"
+                "      For better performance, use (more) PME ranks (mdrun -npme),\n"
+                "      or if you are beyond the scaling limit, use fewer total ranks (or nodes).");
     }
     else
     {
@@ -1093,13 +1096,13 @@ static void print_pme_loadbal_settings(pme_load_balancing_t *pme_lb,
 }
 
 void pme_loadbal_done(pme_load_balancing_t *pme_lb,
-                      t_commrec            *cr,
                       FILE                 *fplog,
+                      const gmx::MDLogger  &mdlog,
                       gmx_bool              bNonBondedOnGPU)
 {
     if (fplog != NULL && (pme_lb->cur > 0 || pme_lb->elimited != epmelblimNO))
     {
-        print_pme_loadbal_settings(pme_lb, cr, fplog, bNonBondedOnGPU);
+        print_pme_loadbal_settings(pme_lb, fplog, mdlog, bNonBondedOnGPU);
     }
 
     /* TODO: Here we should free all pointers in pme_lb,
index d0e305a8eb91f248dbe2f40942a8340927b1fbb0..80ddbbebb3b6c2ac2c2b468b6efa44bb8b067a29 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016, 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.
 struct t_commrec;
 struct t_inputrec;
 
+namespace gmx
+{
+class MDLogger;
+}
+
 /*! \brief Object to manage PME load balancing */
 struct pme_load_balancing_t;
 
@@ -69,12 +74,12 @@ bool pme_loadbal_is_active(const pme_load_balancing_t *pme_lb);
  * usage.
  */
 void pme_loadbal_init(pme_load_balancing_t     **pme_lb_p,
-                      struct t_commrec          *cr,
-                      FILE                      *fp_log,
+                      t_commrec                 *cr,
+                      const gmx::MDLogger       &mdlog,
                       const t_inputrec          *ir,
                       matrix                     box,
                       const interaction_const_t *ic,
-                      struct gmx_pme_t          *pmedata,
+                      gmx_pme_t                 *pmedata,
                       gmx_bool                   bUseGPU,
                       gmx_bool                  *bPrinting);
 
@@ -89,6 +94,7 @@ void pme_loadbal_do(pme_load_balancing_t  *pme_lb,
                     struct t_commrec      *cr,
                     FILE                  *fp_err,
                     FILE                  *fp_log,
+                    const gmx::MDLogger   &mdlog,
                     const t_inputrec      *ir,
                     t_forcerec            *fr,
                     t_state               *state,
@@ -99,8 +105,8 @@ void pme_loadbal_do(pme_load_balancing_t  *pme_lb,
 
 /*! \brief Finish the PME load balancing and print the settings when fplog!=NULL */
 void pme_loadbal_done(pme_load_balancing_t *pme_lb,
-                      struct t_commrec     *cr,
                       FILE                 *fplog,
+                      const gmx::MDLogger  &mdlog,
                       gmx_bool              bNonBondedOnGPU);
 
 #endif
diff --git a/src/gromacs/gmxlib/md_logging.cpp b/src/gromacs/gmxlib/md_logging.cpp
deleted file mode 100644 (file)
index a114643..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014,2015, 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.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include "md_logging.h"
-
-#include <cstdarg>
-#include <cstdio>
-
-#include "gromacs/mdtypes/commrec.h"
-
-
-void md_print_info(const t_commrec *cr, FILE *fplog,
-                   const char *fmt, ...)
-{
-    va_list ap;
-
-    if (cr == NULL || SIMMASTER(cr))
-    {
-        va_start(ap, fmt);
-
-        vfprintf(stderr, fmt, ap);
-
-        va_end(ap);
-    }
-    if (fplog != NULL)
-    {
-        va_start(ap, fmt);
-
-        vfprintf(fplog, fmt, ap);
-
-        va_end(ap);
-    }
-}
-
-void md_print_warn(const t_commrec *cr, FILE *fplog,
-                   const char *fmt, ...)
-{
-    va_list ap;
-
-    if (cr == NULL || SIMMASTER(cr))
-    {
-        va_start(ap, fmt);
-
-        fprintf(stderr, "\n");
-        vfprintf(stderr, fmt, ap);
-        fprintf(stderr, "\n");
-
-        va_end(ap);
-    }
-    if (fplog != NULL)
-    {
-        va_start(ap, fmt);
-
-        fprintf(fplog, "\n");
-        vfprintf(fplog, fmt, ap);
-        fprintf(fplog, "\n");
-
-        va_end(ap);
-    }
-}
diff --git a/src/gromacs/gmxlib/md_logging.h b/src/gromacs/gmxlib/md_logging.h
deleted file mode 100644 (file)
index 8da0973..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2014,2015, 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.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#ifndef GMX_GMXLIB_MD_LOGGING_H
-#define GMX_GMXLIB_MD_LOGGING_H
-
-#include <cstdio>
-
-struct t_commrec;
-
-void md_print_info(const t_commrec *cr, FILE *fplog,
-                   const char *fmt, ...);
-/* Print an general information message to stderr on the master node
- * and to fplog if fplog!=NULL.
- * fmt is a standard printf formatting string which should end in \n,
- * the arguments after that contain the values to be printed, as in printf.
- */
-
-void md_print_warn(const t_commrec *cr, FILE *fplog,
-                   const char *fmt, ...);
-/* As md_print_info above, but for important notices or warnings.
- * The only difference with md_print_info is that a newline is printed
- * before and after the message such that it stands out.
- */
-
-#endif
index f08d55443e6d234175d1a822db25ebd03ea39a93..9a3ff29070c1548620ff756de8d52946352bf31c 100644 (file)
@@ -55,6 +55,7 @@
 #include "gromacs/hardware/gpu_hw_info.h"
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/smalloc.h"
 
 #if HAVE_NVML
@@ -206,59 +207,6 @@ static int do_sanity_checks(int dev_id, cudaDeviceProp *dev_prop)
     return 0;
 }
 
-#if HAVE_NVML
-/* TODO: We should actually be using md_print_warn in md_logging.c,
- * but we can't include mpi.h in CUDA code.
- */
-static void md_print_info(FILE       *fplog,
-                          const char *fmt, ...)
-{
-    va_list ap;
-
-    if (fplog != NULL)
-    {
-        /* We should only print to stderr on the master node,
-         * in most cases fplog is only set on the master node, so this works.
-         */
-        va_start(ap, fmt);
-        vfprintf(stderr, fmt, ap);
-        va_end(ap);
-
-        va_start(ap, fmt);
-        vfprintf(fplog, fmt, ap);
-        va_end(ap);
-    }
-}
-#endif /*HAVE_NVML*/
-
-/* TODO: We should actually be using md_print_warn in md_logging.c,
- * but we can't include mpi.h in CUDA code.
- * This is replicated from nbnxn_cuda_data_mgmt.cu.
- */
-static void md_print_warn(FILE       *fplog,
-                          const char *fmt, ...)
-{
-    va_list ap;
-
-    if (fplog != NULL)
-    {
-        /* We should only print to stderr on the master node,
-         * in most cases fplog is only set on the master node, so this works.
-         */
-        va_start(ap, fmt);
-        fprintf(stderr, "\n");
-        vfprintf(stderr, fmt, ap);
-        fprintf(stderr, "\n");
-        va_end(ap);
-
-        va_start(ap, fmt);
-        fprintf(fplog, "\n");
-        vfprintf(fplog, fmt, ap);
-        fprintf(fplog, "\n");
-        va_end(ap);
-    }
-}
-
 #if HAVE_NVML_APPLICATION_CLOCKS
 /*! \brief Determines and adds the NVML device ID to the passed \cuda_dev.
  *
@@ -312,12 +260,14 @@ static bool addNVMLDeviceId(gmx_device_info_t* cuda_dev)
  * allow this. For future GPU architectures a more sophisticated scheme might be
  * required.
  *
- * \param[out] fplog        log file to write to
+ * \param     mdlog         log file to write to
  * \param[in] gpuid         index of the GPU to set application clocks for
  * \param[in] gpu_info      GPU info of all detected devices in the system.
  * \returns                 true if no error occurs during application clocks handling.
  */
-static gmx_bool init_gpu_application_clocks(FILE gmx_unused *fplog, int gmx_unused gpuid, const gmx_gpu_info_t gmx_unused *gpu_info)
+static gmx_bool init_gpu_application_clocks(
+        const gmx::MDLogger &mdlog, int gmx_unused gpuid,
+        const gmx_gpu_info_t gmx_unused *gpu_info)
 {
     const cudaDeviceProp *prop                        = &gpu_info->gpu_dev[gpuid].prop;
     int                   cuda_version_number         = prop->major * 10 + prop->minor;
@@ -333,10 +283,11 @@ static gmx_bool init_gpu_application_clocks(FILE gmx_unused *fplog, int gmx_unus
     int cuda_runtime = 0;
     cudaDriverGetVersion(&cuda_driver);
     cudaRuntimeGetVersion(&cuda_runtime);
-    md_print_warn( fplog, "NOTE: GROMACS was configured without NVML support hence it can not exploit\n"
-                   "      application clocks of the detected %s GPU to improve performance.\n"
-                   "      Recompile with the NVML library (compatible with the driver used) or set application clocks manually.\n",
-                   prop->name);
+    GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+            "NOTE: GROMACS was configured without NVML support hence it can not exploit\n"
+            "      application clocks of the detected %s GPU to improve performance.\n"
+            "      Recompile with the NVML library (compatible with the driver used) or set application clocks manually.",
+            prop->name);
     return true;
 #else
     if (!bCompiledWithApplicationClockSupport)
@@ -345,10 +296,11 @@ static gmx_bool init_gpu_application_clocks(FILE gmx_unused *fplog, int gmx_unus
         int cuda_runtime = 0;
         cudaDriverGetVersion(&cuda_driver);
         cudaRuntimeGetVersion(&cuda_runtime);
-        md_print_warn( fplog, "NOTE: GROMACS was compiled with an old NVML library which does not support\n"
-                       "      managing application clocks of the detected %s GPU to improve performance.\n"
-                       "      If your GPU supports application clocks, upgrade NVML (and driver) and recompile or set the clocks manually.\n",
-                       prop->name );
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "NOTE: GROMACS was compiled with an old NVML library which does not support\n"
+                "      managing application clocks of the detected %s GPU to improve performance.\n"
+                "      If your GPU supports application clocks, upgrade NVML (and driver) and recompile or set the clocks manually.",
+                prop->name );
         return true;
     }
 
@@ -403,23 +355,31 @@ static gmx_bool init_gpu_application_clocks(FILE gmx_unused *fplog, int gmx_unus
        e.g. if max application clocks should not be used for certain GPUs. */
     if (nvml_stat == NVML_SUCCESS && app_sm_clock < max_sm_clock && gpu_info->gpu_dev[gpuid].nvml_is_restricted == NVML_FEATURE_DISABLED)
     {
-        md_print_info( fplog, "Changing GPU application clocks for %s to (%d,%d)\n", gpu_info->gpu_dev[gpuid].prop.name, max_mem_clock, max_sm_clock);
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "Changing GPU application clocks for %s to (%d,%d)",
+                gpu_info->gpu_dev[gpuid].prop.name, max_mem_clock, max_sm_clock);
         nvml_stat = nvmlDeviceSetApplicationsClocks ( gpu_info->gpu_dev[gpuid].nvml_device_id, max_mem_clock, max_sm_clock );
         HANDLE_NVML_RET_ERR( nvml_stat, "nvmlDeviceGetApplicationsClock failed" );
         gpu_info->gpu_dev[gpuid].nvml_ap_clocks_changed = true;
     }
     else if (nvml_stat == NVML_SUCCESS && app_sm_clock < max_sm_clock)
     {
-        md_print_warn( fplog, "Can not change application clocks for %s to optimal values due to insufficient permissions. Current values are (%d,%d), max values are (%d,%d).\nUse sudo nvidia-smi -acp UNRESTRICTED or contact your admin to change application clocks.\n", gpu_info->gpu_dev[gpuid].prop.name, app_mem_clock, app_sm_clock, max_mem_clock, max_sm_clock);
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "Can not change application clocks for %s to optimal values due to insufficient permissions. Current values are (%d,%d), max values are (%d,%d).\nUse sudo nvidia-smi -acp UNRESTRICTED or contact your admin to change application clocks.",
+                gpu_info->gpu_dev[gpuid].prop.name, app_mem_clock, app_sm_clock, max_mem_clock, max_sm_clock);
     }
     else if (nvml_stat == NVML_SUCCESS && app_sm_clock == max_sm_clock)
     {
         //TODO: This should probably be integrated into the GPU Properties table.
-        md_print_info( fplog, "Application clocks (GPU clocks) for %s are (%d,%d)\n", gpu_info->gpu_dev[gpuid].prop.name, app_mem_clock, app_sm_clock);
+        GMX_LOG(mdlog.warning).appendTextFormatted(
+                "Application clocks (GPU clocks) for %s are (%d,%d)",
+                gpu_info->gpu_dev[gpuid].prop.name, app_mem_clock, app_sm_clock);
     }
     else
     {
-        md_print_warn( fplog,  "Can not change GPU application clocks to optimal values due to NVML error (%d): %s.\n", nvml_stat, nvmlErrorString(nvml_stat));
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "Can not change GPU application clocks to optimal values due to NVML error (%d): %s.",
+                nvml_stat, nvmlErrorString(nvml_stat));
     }
     return (nvml_stat == NVML_SUCCESS);
 #endif /* HAVE_NVML */
@@ -449,7 +409,7 @@ static gmx_bool reset_gpu_application_clocks(const gmx_device_info_t gmx_unused
 #endif /* HAVE_NVML_APPLICATION_CLOCKS */
 }
 
-gmx_bool init_gpu(FILE gmx_unused *fplog, int mygpu, char *result_str,
+gmx_bool init_gpu(const gmx::MDLogger &mdlog, int mygpu, char *result_str,
                   const struct gmx_gpu_info_t *gpu_info,
                   const struct gmx_gpu_opt_t *gpu_opt)
 {
@@ -481,7 +441,7 @@ gmx_bool init_gpu(FILE gmx_unused *fplog, int mygpu, char *result_str,
     //Ignoring return value as NVML errors should be treated not critical.
     if (stat == cudaSuccess)
     {
-        init_gpu_application_clocks(fplog, gpuid, gpu_info);
+        init_gpu_application_clocks(mdlog, gpuid, gpu_info);
     }
     return (stat == cudaSuccess);
 }
index f485abb0fb4f1ff8b7b7661ff8c713180ab3919f..b99c57159730e13e293e89e00659cc0d232aabb1 100644 (file)
 struct gmx_gpu_info_t;
 struct gmx_gpu_opt_t;
 
+namespace gmx
+{
+class MDLogger;
+}
+
 /*! \brief Detect all GPUs in the system.
  *
  *  Will detect every GPU supported by the device driver in use. Also
@@ -115,7 +120,7 @@ void free_gpu_info(const struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info)) GPU
  * The varible \p mygpu is the index of the GPU to initialize in the
  * gpu_info.gpu_dev array.
  *
- * \param[out] fplog        log file to write to
+ * \param      mdlog        log file to write to
  * \param[in]  mygpu        index of the GPU to initialize
  * \param[out] result_str   the message related to the error that occurred
  *                          during the initialization (if there was any).
@@ -124,7 +129,7 @@ void free_gpu_info(const struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info)) GPU
  * \returns                 true if no error occurs during initialization.
  */
 GPU_FUNC_QUALIFIER
-gmx_bool init_gpu(FILE *GPU_FUNC_ARGUMENT(fplog),
+gmx_bool init_gpu(const gmx::MDLogger &GPU_FUNC_ARGUMENT(mdlog),
                   int GPU_FUNC_ARGUMENT(mygpu),
                   char *GPU_FUNC_ARGUMENT(result_str),
                   const struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info),
index 3cd6cf0941e7a50819b59cb1dcddc66bc59622d9..1df49450f8bc62bfe603b8f9e189807712293902 100644 (file)
@@ -447,7 +447,7 @@ void get_gpu_device_info_string(char gmx_unused *s, const gmx_gpu_info_t gmx_unu
 }
 
 //! This function is documented in the header file
-gmx_bool init_gpu(FILE gmx_unused                 *fplog,
+gmx_bool init_gpu(const gmx::MDLogger              & /*mdlog*/,
                   int                              mygpu,
                   char                            *result_str,
                   const gmx_gpu_info_t gmx_unused *gpu_info,
index 30537e8765c66aea4d2555b4351a7e1ad055ef5a..cb218b9670e7942bb1669b228efe7c187e88dbb4 100644 (file)
@@ -56,7 +56,6 @@
 
 #include "thread_mpi/threads.h"
 
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/gmxlib/network.h"
 #include "gromacs/gpu_utils/gpu_utils.h"
 #include "gromacs/hardware/cpuinfo.h"
@@ -75,6 +74,7 @@
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/gmxomp.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/programcontext.h"
 #include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/stringutil.h"
@@ -152,9 +152,8 @@ static void sprint_gpus(char *sbuf, const gmx_gpu_info_t *gpu_info)
     }
 }
 
-static void print_gpu_detection_stats(FILE                 *fplog,
-                                      const gmx_gpu_info_t *gpu_info,
-                                      const t_commrec      *cr)
+static void print_gpu_detection_stats(const gmx::MDLogger  &mdlog,
+                                      const gmx_gpu_info_t *gpu_info)
 {
     char onhost[HOSTNAMELEN+10], stmp[STRLEN];
     int  ngpu;
@@ -179,12 +178,13 @@ static void print_gpu_detection_stats(FILE                 *fplog,
     if (ngpu > 0)
     {
         sprint_gpus(stmp, gpu_info);
-        md_print_warn(cr, fplog, "%d GPU%s detected%s:\n%s\n",
-                      ngpu, (ngpu > 1) ? "s" : "", onhost, stmp);
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "%d GPU%s detected%s:\n%s",
+                ngpu, (ngpu > 1) ? "s" : "", onhost, stmp);
     }
     else
     {
-        md_print_warn(cr, fplog, "No GPUs detected%s\n", onhost);
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted("No GPUs detected%s", onhost);
     }
 }
 
@@ -273,8 +273,7 @@ makeGpuUsageReport(const gmx_gpu_info_t *gpu_info,
 /* Give a suitable fatal error or warning if the build configuration
    and runtime CPU do not match. */
 static void
-check_use_of_rdtscp_on_this_cpu(FILE                  *fplog,
-                                const t_commrec       *cr,
+check_use_of_rdtscp_on_this_cpu(const gmx::MDLogger   &mdlog,
                                 const gmx::CpuInfo    &cpuInfo)
 {
 #ifdef HAVE_RDTSCP
@@ -289,10 +288,11 @@ check_use_of_rdtscp_on_this_cpu(FILE                  *fplog,
     {
         if (binaryUsesRdtscp)
         {
-            md_print_warn(cr, fplog, "The %s executable was compiled to use the rdtscp CPU instruction. "
-                          "We cannot detect the features of your current CPU, but will proceed anyway. "
-                          "If you get a crash, rebuild GROMACS with the GMX_USE_RDTSCP=OFF CMake option.",
-                          programName);
+            GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                    "The %s executable was compiled to use the rdtscp CPU instruction. "
+                    "We cannot detect the features of your current CPU, but will proceed anyway. "
+                    "If you get a crash, rebuild GROMACS with the GMX_USE_RDTSCP=OFF CMake option.",
+                    programName);
         }
     }
     else
@@ -309,16 +309,17 @@ check_use_of_rdtscp_on_this_cpu(FILE                  *fplog,
 
         if (cpuHasRdtscp && !binaryUsesRdtscp)
         {
-            md_print_warn(cr, fplog, "The current CPU can measure timings more accurately than the code in\n"
-                          "%s was configured to use. This might affect your simulation\n"
-                          "speed as accurate timings are needed for load-balancing.\n"
-                          "Please consider rebuilding %s with the GMX_USE_RDTSCP=ON CMake option.\n",
-                          programName, programName);
+            GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                    "The current CPU can measure timings more accurately than the code in\n"
+                    "%s was configured to use. This might affect your simulation\n"
+                    "speed as accurate timings are needed for load-balancing.\n"
+                    "Please consider rebuilding %s with the GMX_USE_RDTSCP=ON CMake option.",
+                    programName, programName);
         }
     }
 }
 
-void gmx_check_hw_runconf_consistency(FILE                *fplog,
+void gmx_check_hw_runconf_consistency(const gmx::MDLogger &mdlog,
                                       const gmx_hw_info_t *hwinfo,
                                       const t_commrec     *cr,
                                       const gmx_hw_opt_t  *hw_opt,
@@ -360,18 +361,18 @@ void gmx_check_hw_runconf_consistency(FILE                *fplog,
 
     if (hwinfo->gpu_info.n_dev_compatible > 0)
     {
-        std::string gpuUseageReport;
+        std::string gpuUsageReport;
         try
         {
-            gpuUseageReport = makeGpuUsageReport(&hwinfo->gpu_info,
-                                                 &hw_opt->gpu_opt,
-                                                 cr->nrank_pp_intranode,
-                                                 bMPI && cr->nnodes > 1);
+            gpuUsageReport = makeGpuUsageReport(&hwinfo->gpu_info,
+                                                &hw_opt->gpu_opt,
+                                                cr->nrank_pp_intranode,
+                                                bMPI && cr->nnodes > 1);
         }
         GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
 
         /* NOTE: this print is only for and on one physical node */
-        md_print_info(cr, fplog, "%s\n", gpuUseageReport.c_str());
+        GMX_LOG(mdlog.warning).appendText(gpuUsageReport);
     }
 
     /* Need to ensure that we have enough GPUs:
@@ -439,13 +440,13 @@ void gmx_check_hw_runconf_consistency(FILE                *fplog,
             {
                 /* There are more GPUs than tMPI threads; we have
                    limited the number GPUs used. */
-                md_print_warn(cr, fplog,
-                              "NOTE: %d GPU%s were detected, but only %d PP thread-MPI thread%s can be started.\n"
-                              "      %s can use one GPU per PP tread-MPI thread, so only %d GPU%s will be used.\n",
-                              ngpu_comp, gpu_comp_plural,
-                              npppn, th_or_proc_plural,
-                              programName, npppn,
-                              npppn > 1 ? "s" : "");
+                GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                        "NOTE: %d GPU%s were detected, but only %d PP thread-MPI thread%s can be started.\n"
+                        "      %s can use one GPU per PP tread-MPI thread, so only %d GPU%s will be used.",
+                        ngpu_comp, gpu_comp_plural,
+                        npppn, th_or_proc_plural,
+                        programName, npppn,
+                        npppn > 1 ? "s" : "");
             }
         }
 
@@ -467,13 +468,13 @@ void gmx_check_hw_runconf_consistency(FILE                *fplog,
             /* TODO Should we have a gpu_opt->n_dev_supported field? */
             if (ngpu_comp > npppn && gmx_multiple_gpu_per_node_supported())
             {
-                md_print_warn(cr, fplog,
-                              "NOTE: potentially sub-optimal launch configuration, %s started with less\n"
-                              "      PP %s%s%s than GPU%s available.\n"
-                              "      Each PP %s can use only one GPU, %d GPU%s%s will be used.\n",
-                              programName, th_or_proc,
-                              th_or_proc_plural, pernode, gpu_comp_plural,
-                              th_or_proc, npppn, gpu_use_plural, pernode);
+                GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                        "NOTE: potentially sub-optimal launch configuration, %s started with less\n"
+                        "      PP %s%s%s than GPU%s available.\n"
+                        "      Each PP %s can use only one GPU, %d GPU%s%s will be used.",
+                        programName, th_or_proc,
+                        th_or_proc_plural, pernode, gpu_comp_plural,
+                        th_or_proc, npppn, gpu_use_plural, pernode);
             }
 
             if (ngpu_use != npppn)
@@ -516,9 +517,9 @@ void gmx_check_hw_runconf_consistency(FILE                *fplog,
 
             if (same_count > 0)
             {
-                md_print_info(cr, fplog,
-                              "NOTE: You assigned %s to multiple %s%s.\n",
-                              same_count > 1 ? "GPUs" : "a GPU", th_or_proc, btMPI ? "s" : "es");
+                GMX_LOG(mdlog.warning).appendTextFormatted(
+                        "NOTE: You assigned %s to multiple %s%s.",
+                        same_count > 1 ? "GPUs" : "a GPU", th_or_proc, btMPI ? "s" : "es");
             }
         }
     }
@@ -609,20 +610,20 @@ static int gmx_count_gpu_dev_unique(const gmx_gpu_info_t *gpu_info,
  * _SC_NPROCESSORS_ONLN to report 1 at the beginning of the run. For this
  * reason we now warn if this mismatches with the detected core count.
  */
-static void check_nthreads_hw_avail(const t_commrec gmx_unused *cr,
-                                    FILE gmx_unused *fplog, int nthreads)
+static void check_nthreads_hw_avail(const gmx::MDLogger gmx_unused &mdlog, int nthreads)
 {
 // Now check if we have the argument to use before executing the call
 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
     if (nthreads != sysconf(_SC_NPROCESSORS_ONLN))
     {
-        md_print_warn(cr, fplog,
-                      "%d CPUs configured, but only %d of them are online.\n"
-                      "This can happen on embedded platforms (e.g. ARM) where the OS shuts some cores\n"
-                      "off to save power, and will turn them back on later when the load increases.\n"
-                      "However, this will likely mean GROMACS cannot pin threads to those cores. You\n"
-                      "will likely see much better performance by forcing all cores to be online, and\n"
-                      "making sure they run at their full clock frequency.", nthreads, sysconf(_SC_NPROCESSORS_ONLN));
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "%d CPUs configured, but only %d of them are online.\n"
+                "This can happen on embedded platforms (e.g. ARM) where the OS shuts some cores\n"
+                "off to save power, and will turn them back on later when the load increases.\n"
+                "However, this will likely mean GROMACS cannot pin threads to those cores. You\n"
+                "will likely see much better performance by forcing all cores to be online, and\n"
+                "making sure they run at their full clock frequency.",
+                nthreads, sysconf(_SC_NPROCESSORS_ONLN));
     }
 #endif
 
@@ -634,15 +635,15 @@ static void check_nthreads_hw_avail(const t_commrec gmx_unused *cr,
 #if GMX_OPENMP
     if (nthreads != gmx_omp_get_num_procs())
     {
-        md_print_warn(cr, fplog,
-                      "Number of logical cores detected (%d) does not match the number reported by OpenMP (%d).\n"
-                      "Consider setting the launch configuration manually!",
-                      nthreads, gmx_omp_get_num_procs());
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "Number of logical cores detected (%d) does not match the number reported by OpenMP (%d).\n"
+                "Consider setting the launch configuration manually!",
+                nthreads, gmx_omp_get_num_procs());
     }
 #endif
 }
 
-static void gmx_detect_gpus(FILE *fplog, const t_commrec *cr)
+static void gmx_detect_gpus(const gmx::MDLogger &mdlog, const t_commrec *cr)
 {
 #if GMX_LIB_MPI
     int              rank_world;
@@ -670,6 +671,7 @@ static void gmx_detect_gpus(FILE *fplog, const t_commrec *cr)
     MPI_Comm_split(MPI_COMM_WORLD, gmx_physicalnode_id_hash(),
                    rank_world, &physicalnode_comm);
     MPI_Comm_rank(physicalnode_comm, &rank_local);
+    GMX_UNUSED_VALUE(cr);
 #else
     /* Here there should be only one process, check this */
     GMX_RELEASE_ASSERT(cr->nnodes == 1 && cr->sim_nodeid == 0, "Only a single (master) process should execute here");
@@ -695,10 +697,10 @@ static void gmx_detect_gpus(FILE *fplog, const t_commrec *cr)
             {
                 sprintf(sbuf, ".");
             }
-            md_print_warn(cr, fplog,
-                          "NOTE: Error occurred during GPU detection%s"
-                          "      Can not use GPU acceleration, will fall back to CPU kernels.\n",
-                          sbuf);
+            GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                    "NOTE: Error occurred during GPU detection%s"
+                    "      Can not use GPU acceleration, will fall back to CPU kernels.",
+                    sbuf);
         }
     }
 
@@ -862,7 +864,7 @@ static void gmx_collect_hardware_mpi(const gmx::CpuInfo &cpuInfo)
 #endif
 }
 
-gmx_hw_info_t *gmx_detect_hardware(FILE *fplog, const t_commrec *cr,
+gmx_hw_info_t *gmx_detect_hardware(const gmx::MDLogger &mdlog, const t_commrec *cr,
                                    gmx_bool bDetectGPUs)
 {
     int ret;
@@ -884,7 +886,7 @@ gmx_hw_info_t *gmx_detect_hardware(FILE *fplog, const t_commrec *cr,
 
         // TODO: Get rid of this altogether.
         hwinfo_g->nthreads_hw_avail = hwinfo_g->hardwareTopology->machine().logicalProcessorCount;
-        check_nthreads_hw_avail(cr, fplog, hwinfo_g->nthreads_hw_avail);
+        check_nthreads_hw_avail(mdlog, hwinfo_g->nthreads_hw_avail);
 
         /* detect GPUs */
         hwinfo_g->gpu_info.n_dev            = 0;
@@ -899,7 +901,7 @@ gmx_hw_info_t *gmx_detect_hardware(FILE *fplog, const t_commrec *cr,
              getenv("GMX_DISABLE_GPU_DETECTION") == NULL);
         if (hwinfo_g->gpu_info.bDetectGPUs)
         {
-            gmx_detect_gpus(fplog, cr);
+            gmx_detect_gpus(mdlog, cr);
         }
     }
     /* increase the reference counter */
@@ -1140,6 +1142,7 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo,
 }
 
 void gmx_print_detected_hardware(FILE *fplog, const t_commrec *cr,
+                                 const gmx::MDLogger &mdlog,
                                  const gmx_hw_info_t *hwinfo)
 {
     const gmx::CpuInfo &cpuInfo = *hwinfo_g->cpuInfo;
@@ -1171,7 +1174,7 @@ void gmx_print_detected_hardware(FILE *fplog, const t_commrec *cr,
     }
 
     /* For RDTSCP we only check on our local node and skip the MPI reduction */
-    check_use_of_rdtscp_on_this_cpu(fplog, cr, cpuInfo);
+    check_use_of_rdtscp_on_this_cpu(mdlog, cpuInfo);
 }
 
 //! \brief Return if any GPU ID (e.g in a user-supplied string) is repeated
@@ -1241,7 +1244,7 @@ void gmx_parse_gpu_ids(gmx_gpu_opt_t *gpu_opt)
     }
 }
 
-void gmx_select_gpu_ids(FILE *fplog, const t_commrec *cr,
+void gmx_select_gpu_ids(const gmx::MDLogger &mdlog, const t_commrec *cr,
                         const gmx_gpu_info_t *gpu_info,
                         gmx_bool bForceUseGPU,
                         gmx_gpu_opt_t *gpu_opt)
@@ -1277,7 +1280,7 @@ void gmx_select_gpu_ids(FILE *fplog, const t_commrec *cr,
 
         if (!res)
         {
-            print_gpu_detection_stats(fplog, gpu_info, cr);
+            print_gpu_detection_stats(mdlog, gpu_info);
 
             sprintf(sbuf, "Some of the requested GPUs do not exist, behave strangely, or are not compatible:\n");
             for (i = 0; i < gpu_opt->n_dev_use; i++)
index d60cb0b47cbb831fed3f2c0a48b27ce294870213..2a5ef20f559ea953fb856487dcb7910c8d5ea8b0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016, 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.
@@ -45,6 +45,11 @@ struct gmx_hw_info_t;
 struct gmx_hw_opt_t;
 struct t_commrec;
 
+namespace gmx
+{
+class MDLogger;
+}
+
 /*! \brief Return whether mdrun can use more than one GPU per node
  *
  * The OpenCL implementation cannot use more than one GPU per node,
@@ -59,27 +64,28 @@ gmx_bool gmx_gpu_sharing_supported();
 
 /* Construct the global hwinfo structure and return a pointer to
    it. Caller is responsible for freeing this pointer. */
-gmx_hw_info_t *gmx_detect_hardware(FILE *fplog, const t_commrec *cr,
-                                   gmx_bool bDetectGPUs);
+gmx_hw_info_t *gmx_detect_hardware(const gmx::MDLogger &mdlog,
+                                   const t_commrec *cr, gmx_bool bDetectGPUs);
 
 /* Print information about the detected hardware to fplog (if != NULL)
  * and to stderr the master rank.
  */
 void gmx_print_detected_hardware(FILE *fplog, const t_commrec *cr,
+                                 const gmx::MDLogger &mdlog,
                                  const gmx_hw_info_t *hwinfo);
 
 void gmx_hardware_info_free(gmx_hw_info_t *hwinfo);
 
 void gmx_parse_gpu_ids(gmx_gpu_opt_t *gpu_opt);
 
-void gmx_select_gpu_ids(FILE *fplog, const t_commrec *cr,
+void gmx_select_gpu_ids(const gmx::MDLogger &mdlog, const t_commrec *cr,
                         const gmx_gpu_info_t *gpu_info,
                         gmx_bool bForceUseGPU,
                         gmx_gpu_opt_t *gpu_opt);
 
 /* Check the consistency of hw_opt with hwinfo.
    This function should be called once on each MPI rank. */
-void gmx_check_hw_runconf_consistency(FILE                *fplog,
+void gmx_check_hw_runconf_consistency(const gmx::MDLogger &mdlog,
                                       const gmx_hw_info_t *hwinfo,
                                       const t_commrec     *cr,
                                       const gmx_hw_opt_t  *hw_opt,
index 3fe505cf0b4f3397ac061371fdc115d1a1b5d8fb..4d145f582b5988b90f0bda062d66316fed598c0f 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016, 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.
@@ -60,6 +60,11 @@ struct t_mdatoms;
 struct t_nrnb;
 struct t_pbc;
 
+namespace gmx
+{
+class MDLogger;
+}
+
 void calc_vir(int nxf, rvec x[], rvec f[], tensor vir,
               gmx_bool bScrewPBC, matrix box);
 /* Calculate virial for nxf atoms, and add it to vir */
@@ -106,19 +111,17 @@ gmx_bool can_use_allvsall(const t_inputrec *ir,
  */
 
 
-gmx_bool nbnxn_gpu_acceleration_supported(FILE             *fplog,
-                                          const t_commrec  *cr,
-                                          const t_inputrec *ir,
-                                          gmx_bool          bRerunMD);
+gmx_bool nbnxn_gpu_acceleration_supported(const gmx::MDLogger &mdlog,
+                                          const t_inputrec    *ir,
+                                          gmx_bool             bRerunMD);
 /* Return if GPU acceleration is supported with the given settings.
  *
  * If the return value is FALSE and fplog/cr != NULL, prints a fallback
  * message to fplog/stderr.
  */
 
-gmx_bool nbnxn_simd_supported(FILE             *fplog,
-                              const t_commrec  *cr,
-                              const t_inputrec *ir);
+gmx_bool nbnxn_simd_supported(const gmx::MDLogger &mdlog,
+                              const t_inputrec    *ir);
 /* Return if CPU SIMD support exists for the given inputrec
  * If the return value is FALSE and fplog/cr != NULL, prints a fallback
  * message to fplog/stderr.
index 6ed1608b207b1b98ee179d2b9574a017387924c0..c7030b235ca1d6f8b55d4f9b412247405836f0f2 100644 (file)
@@ -52,7 +52,6 @@
 #include "gromacs/domdec/domdec_struct.h"
 #include "gromacs/ewald/ewald.h"
 #include "gromacs/fileio/filetypes.h"
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/gmxlib/network.h"
 #include "gromacs/gmxlib/nonbonded/nonbonded.h"
 #include "gromacs/gpu_utils/gpu_utils.h"
@@ -91,6 +90,7 @@
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/pleasecite.h"
 #include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/stringutil.h"
@@ -1518,10 +1518,9 @@ gmx_bool can_use_allvsall(const t_inputrec *ir, gmx_bool bPrintNote, t_commrec *
 }
 
 
-gmx_bool nbnxn_gpu_acceleration_supported(FILE             *fplog,
-                                          const t_commrec  *cr,
-                                          const t_inputrec *ir,
-                                          gmx_bool          bRerunMD)
+gmx_bool nbnxn_gpu_acceleration_supported(const gmx::MDLogger &mdlog,
+                                          const t_inputrec    *ir,
+                                          gmx_bool             bRerunMD)
 {
     if (bRerunMD && ir->opts.ngener > 1)
     {
@@ -1533,23 +1532,22 @@ gmx_bool nbnxn_gpu_acceleration_supported(FILE             *fplog,
          * (which runs much faster than a multiple-energy-groups
          * implementation would), and issue a note in the .log
          * file. Users can re-run if they want the information. */
-        md_print_warn(cr, fplog, "Rerun with energy groups is not implemented for GPUs, falling back to the CPU\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText("Rerun with energy groups is not implemented for GPUs, falling back to the CPU");
         return FALSE;
     }
 
     return TRUE;
 }
 
-gmx_bool nbnxn_simd_supported(FILE             *fplog,
-                              const t_commrec  *cr,
-                              const t_inputrec *ir)
+gmx_bool nbnxn_simd_supported(const gmx::MDLogger &mdlog,
+                              const t_inputrec    *ir)
 {
     if (ir->vdwtype == evdwPME && ir->ljpme_combination_rule == eljpmeLB)
     {
         /* LJ PME with LB combination rule does 7 mesh operations.
          * This so slow that we don't compile SIMD non-bonded kernels
          * for that. */
-        md_print_warn(cr, fplog, "LJ-PME with Lorentz-Berthelot is not supported with SIMD kernels, falling back to plain C kernels\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText("LJ-PME with Lorentz-Berthelot is not supported with SIMD kernels, falling back to plain C kernels");
         return FALSE;
     }
 
@@ -1680,7 +1678,7 @@ const char *lookup_nbnxn_kernel_name(int kernel_type)
 };
 
 static void pick_nbnxn_kernel(FILE                *fp,
-                              const t_commrec     *cr,
+                              const gmx::MDLogger &mdlog,
                               gmx_bool             use_simd_kernels,
                               gmx_bool             bUseGPU,
                               gmx_bool             bEmulateGPU,
@@ -1700,7 +1698,7 @@ static void pick_nbnxn_kernel(FILE                *fp,
 
         if (bDoNonbonded)
         {
-            md_print_warn(cr, fp, "Emulating a GPU run on the CPU (slow)");
+            GMX_LOG(mdlog.warning).asParagraph().appendText("Emulating a GPU run on the CPU (slow)");
         }
     }
     else if (bUseGPU)
@@ -1711,7 +1709,7 @@ static void pick_nbnxn_kernel(FILE                *fp,
     if (*kernel_type == nbnxnkNotSet)
     {
         if (use_simd_kernels &&
-            nbnxn_simd_supported(fp, cr, ir))
+            nbnxn_simd_supported(mdlog, ir))
         {
             pick_nbnxn_kernel_cpu(ir, kernel_type, ewald_excl);
         }
@@ -1731,15 +1729,15 @@ static void pick_nbnxn_kernel(FILE                *fp,
         if (nbnxnk4x4_PlainC == *kernel_type ||
             nbnxnk8x8x8_PlainC == *kernel_type)
         {
-            md_print_warn(cr, fp,
-                          "WARNING: Using the slow %s kernels. This should\n"
-                          "not happen during routine usage on supported platforms.\n\n",
-                          lookup_nbnxn_kernel_name(*kernel_type));
+            GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                    "WARNING: Using the slow %s kernels. This should\n"
+                    "not happen during routine usage on supported platforms.",
+                    lookup_nbnxn_kernel_name(*kernel_type));
         }
     }
 }
 
-static void pick_nbnxn_resources(FILE                *fp,
+static void pick_nbnxn_resources(const gmx::MDLogger &mdlog,
                                  const t_commrec     *cr,
                                  const gmx_hw_info_t *hwinfo,
                                  gmx_bool             bDoNonbonded,
@@ -1774,7 +1772,7 @@ static void pick_nbnxn_resources(FILE                *fp,
     {
         /* Each PP node will use the intra-node id-th device from the
          * list of detected/selected GPUs. */
-        if (!init_gpu(fp, cr->rank_pp_intranode, gpu_err_str,
+        if (!init_gpu(mdlog, cr->rank_pp_intranode, gpu_err_str,
                       &hwinfo->gpu_info, gpu_opt))
         {
             /* At this point the init should never fail as we made sure that
@@ -2058,6 +2056,7 @@ init_interaction_const(FILE                       *fp,
 }
 
 static void init_nb_verlet(FILE                *fp,
+                           const gmx::MDLogger &mdlog,
                            nonbonded_verlet_t **nb_verlet,
                            gmx_bool             bFEP_NonBonded,
                            const t_inputrec    *ir,
@@ -2075,7 +2074,7 @@ static void init_nb_verlet(FILE                *fp,
 
     snew(nbv, 1);
 
-    pick_nbnxn_resources(fp, cr, fr->hwinfo,
+    pick_nbnxn_resources(mdlog, cr, fr->hwinfo,
                          fr->bNonbonded,
                          &nbv->bUseGPU,
                          &bEmulateGPU,
@@ -2093,7 +2092,7 @@ static void init_nb_verlet(FILE                *fp,
 
         if (i == 0) /* local */
         {
-            pick_nbnxn_kernel(fp, cr, fr->use_simd_kernels,
+            pick_nbnxn_kernel(fp, mdlog, fr->use_simd_kernels,
                               nbv->bUseGPU, bEmulateGPU, ir,
                               &nbv->grp[i].kernel_type,
                               &nbv->grp[i].ewald_excl,
@@ -2104,7 +2103,7 @@ static void init_nb_verlet(FILE                *fp,
             if (nbpu_opt != NULL && strcmp(nbpu_opt, "gpu_cpu") == 0)
             {
                 /* Use GPU for local, select a CPU kernel for non-local */
-                pick_nbnxn_kernel(fp, cr, fr->use_simd_kernels,
+                pick_nbnxn_kernel(fp, mdlog, fr->use_simd_kernels,
                                   FALSE, FALSE, ir,
                                   &nbv->grp[i].kernel_type,
                                   &nbv->grp[i].ewald_excl,
@@ -2257,19 +2256,20 @@ gmx_bool usingGpu(nonbonded_verlet_t *nbv)
     return nbv != NULL && nbv->bUseGPU;
 }
 
-void init_forcerec(FILE              *fp,
-                   t_forcerec        *fr,
-                   t_fcdata          *fcd,
-                   const t_inputrec  *ir,
-                   const gmx_mtop_t  *mtop,
-                   const t_commrec   *cr,
-                   matrix             box,
-                   const char        *tabfn,
-                   const char        *tabpfn,
-                   const char        *tabbfn,
-                   const char        *nbpu_opt,
-                   gmx_bool           bNoSolvOpt,
-                   real               print_force)
+void init_forcerec(FILE                *fp,
+                   const gmx::MDLogger &mdlog,
+                   t_forcerec          *fr,
+                   t_fcdata            *fcd,
+                   const t_inputrec    *ir,
+                   const gmx_mtop_t    *mtop,
+                   const t_commrec     *cr,
+                   matrix               box,
+                   const char          *tabfn,
+                   const char          *tabpfn,
+                   const char          *tabbfn,
+                   const char          *nbpu_opt,
+                   gmx_bool             bNoSolvOpt,
+                   real                 print_force)
 {
     int            i, m, negp_pp, negptable, egi, egj;
     real           rtab;
@@ -2287,7 +2287,7 @@ void init_forcerec(FILE              *fp,
          * In mdrun, hwinfo has already been set before calling init_forcerec.
          * Here we ignore GPUs, as tools will not use them anyhow.
          */
-        fr->hwinfo = gmx_detect_hardware(fp, cr, FALSE);
+        fr->hwinfo = gmx_detect_hardware(mdlog, cr, FALSE);
     }
 
     /* By default we turn SIMD kernels on, but it might be turned off further down... */
@@ -2380,9 +2380,9 @@ void init_forcerec(FILE              *fp,
     {
         /* turn off non-bonded calculations */
         fr->bNonbonded = FALSE;
-        md_print_warn(cr, fp,
-                      "Found environment variable GMX_NO_NONBONDED.\n"
-                      "Disabling nonbonded calculations.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                "Found environment variable GMX_NO_NONBONDED.\n"
+                "Disabling nonbonded calculations.");
     }
 
     bGenericKernelOnly = FALSE;
@@ -2501,12 +2501,12 @@ void init_forcerec(FILE              *fp,
                     fr->bMolPBC = FALSE;
                     if (fp)
                     {
-                        md_print_warn(cr, fp, "GMX_USE_GRAPH is set, using the graph for bonded interactions\n");
+                        GMX_LOG(mdlog.warning).asParagraph().appendText("GMX_USE_GRAPH is set, using the graph for bonded interactions");
                     }
 
                     if (mtop->bIntermolecularInteractions)
                     {
-                        md_print_warn(cr, fp, "WARNING: Molecules linked by intermolecular interactions have to reside in the same periodic image, otherwise artifacts will occur!\n");
+                        GMX_LOG(mdlog.warning).asParagraph().appendText("WARNING: Molecules linked by intermolecular interactions have to reside in the same periodic image, otherwise artifacts will occur!");
                     }
                 }
 
@@ -3143,7 +3143,7 @@ void init_forcerec(FILE              *fp,
             GMX_RELEASE_ASSERT(ir->rcoulomb == ir->rvdw, "With Verlet lists and no PME rcoulomb and rvdw should be identical");
         }
 
-        init_nb_verlet(fp, &fr->nbv, bFEP_NonBonded, ir, fr, cr, nbpu_opt);
+        init_nb_verlet(fp, mdlog, &fr->nbv, bFEP_NonBonded, ir, fr, cr, nbpu_opt);
     }
 
     if (ir->eDispCorr != edispcNO)
index 9ff5b250c1418a086645fce6960ed04a6fde779a..95d9fc212d8a3d163e91323d059d3307e41b0730 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016, 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.
 struct t_commrec;
 struct t_fcdata;
 
+namespace gmx
+{
+class MDLogger;
+}
+
 /*! \brief Create a new forcerec structure */
 t_forcerec *mk_forcerec(void);
 
@@ -90,6 +95,7 @@ void init_interaction_const_tables(FILE                   *fp,
  *
  * The Force rec struct must be created with mk_forcerec.
  * \param[in]  fplog       File for printing
+ * \param[in]  mdlog       File for printing
  * \param[out] fr          The forcerec
  * \param[in]  fcd         Force constant data
  * \param[in]  ir          Inputrec structure
@@ -104,6 +110,7 @@ void init_interaction_const_tables(FILE                   *fp,
  * \param[in]  print_force Print forces for atoms with force >= print_force
  */
 void init_forcerec(FILE                   *fplog,
+                   const gmx::MDLogger    &mdlog,
                    t_forcerec             *fr,
                    t_fcdata               *fcd,
                    const t_inputrec       *ir,
index 479ca6592817f2fd06b65680c8148f141563adbd..644bb05a8b0e1deab070cc41afc4917a02b1dc0f 100644 (file)
 #include <cstdlib>
 #include <cstring>
 
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/gmxlib/network.h"
 #include "gromacs/mdtypes/commrec.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/gmxomp.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/programcontext.h"
 
 /** Structure with the number of threads for each OpenMP multi-threaded
@@ -107,14 +107,12 @@ static omp_module_nthreads_t modth = { 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}, FALSE}
  *  The "group" scheme supports OpenMP only in PME and in thise case all but
  *  the PME nthread values default to 1.
  */
-static void pick_module_nthreads(FILE *fplog, int m,
-                                 gmx_bool bSimMaster,
+static void pick_module_nthreads(const gmx::MDLogger &mdlog, int m,
                                  gmx_bool bFullOmpSupport,
                                  gmx_bool bSepPME)
 {
     char      *env;
     int        nth;
-    char       sbuf[STRLEN];
 
     const bool bOMP = GMX_OPENMP;
 
@@ -161,16 +159,9 @@ static void pick_module_nthreads(FILE *fplog, int m,
         /* only babble if we are really overriding with a different value */
         if ((bSepPME && m == emntPME && nth != modth.gnth_pme) || (nth != modth.gnth))
         {
-            sprintf(sbuf, "%s=%d set, overriding the default number of %s threads",
+            GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                    "%s=%d set, overriding the default number of %s threads",
                     modth_env_var[m], nth, mod_name[m]);
-            if (bSimMaster)
-            {
-                fprintf(stderr, "\n%s\n", sbuf);
-            }
-            if (fplog)
-            {
-                fprintf(fplog, "%s\n", sbuf);
-            }
         }
     }
     else
@@ -235,16 +226,16 @@ void gmx_omp_nthreads_read_env(int     *nthreads_omp,
 /*! \brief Helper function for parsing various input about the number
     of OpenMP threads to use in various modules and deciding what to
     do about it. */
-static void manage_number_of_openmp_threads(FILE               *fplog,
-                                            const t_commrec    *cr,
-                                            bool                bOMP,
-                                            int                 nthreads_hw_avail,
-                                            int                 omp_nthreads_req,
-                                            int                 omp_nthreads_pme_req,
-                                            gmx_bool gmx_unused bThisNodePMEOnly,
-                                            gmx_bool            bFullOmpSupport,
-                                            int                 nppn,
-                                            gmx_bool            bSepPME)
+static void manage_number_of_openmp_threads(const gmx::MDLogger &mdlog,
+                                            const t_commrec     *cr,
+                                            bool                 bOMP,
+                                            int                  nthreads_hw_avail,
+                                            int                  omp_nthreads_req,
+                                            int                  omp_nthreads_pme_req,
+                                            gmx_bool gmx_unused  bThisNodePMEOnly,
+                                            gmx_bool             bFullOmpSupport,
+                                            int                  nppn,
+                                            gmx_bool             bSepPME)
 {
     int      nth;
     char    *env;
@@ -258,6 +249,8 @@ static void manage_number_of_openmp_threads(FILE               *fplog,
     {
         return;
     }
+#else
+    GMX_UNUSED_VALUE(cr);
 #endif
 
     if (modth.initialized)
@@ -352,15 +345,15 @@ static void manage_number_of_openmp_threads(FILE               *fplog,
 
     /* now set the per-module values */
     modth.nth[emntDefault] = modth.gnth;
-    pick_module_nthreads(fplog, emntDomdec, SIMMASTER(cr), bFullOmpSupport, bSepPME);
-    pick_module_nthreads(fplog, emntPairsearch, SIMMASTER(cr), bFullOmpSupport, bSepPME);
-    pick_module_nthreads(fplog, emntNonbonded, SIMMASTER(cr), bFullOmpSupport, bSepPME);
-    pick_module_nthreads(fplog, emntBonded, SIMMASTER(cr), bFullOmpSupport, bSepPME);
-    pick_module_nthreads(fplog, emntPME, SIMMASTER(cr), bFullOmpSupport, bSepPME);
-    pick_module_nthreads(fplog, emntUpdate, SIMMASTER(cr), bFullOmpSupport, bSepPME);
-    pick_module_nthreads(fplog, emntVSITE, SIMMASTER(cr), bFullOmpSupport, bSepPME);
-    pick_module_nthreads(fplog, emntLINCS, SIMMASTER(cr), bFullOmpSupport, bSepPME);
-    pick_module_nthreads(fplog, emntSETTLE, SIMMASTER(cr), bFullOmpSupport, bSepPME);
+    pick_module_nthreads(mdlog, emntDomdec, bFullOmpSupport, bSepPME);
+    pick_module_nthreads(mdlog, emntPairsearch, bFullOmpSupport, bSepPME);
+    pick_module_nthreads(mdlog, emntNonbonded, bFullOmpSupport, bSepPME);
+    pick_module_nthreads(mdlog, emntBonded, bFullOmpSupport, bSepPME);
+    pick_module_nthreads(mdlog, emntPME, bFullOmpSupport, bSepPME);
+    pick_module_nthreads(mdlog, emntUpdate, bFullOmpSupport, bSepPME);
+    pick_module_nthreads(mdlog, emntVSITE, bFullOmpSupport, bSepPME);
+    pick_module_nthreads(mdlog, emntLINCS, bFullOmpSupport, bSepPME);
+    pick_module_nthreads(mdlog, emntSETTLE, bFullOmpSupport, bSepPME);
 
     /* set the number of threads globally */
     if (bOMP)
@@ -389,11 +382,11 @@ static void manage_number_of_openmp_threads(FILE               *fplog,
 
 /*! \brief Report on the OpenMP settings that will be used */
 static void
-reportOpenmpSettings(FILE            *fplog,
-                     const t_commrec *cr,
-                     gmx_bool         bOMP,
-                     gmx_bool         bFullOmpSupport,
-                     gmx_bool         bSepPME)
+reportOpenmpSettings(const gmx::MDLogger &mdlog,
+                     const t_commrec     *cr,
+                     gmx_bool             bOMP,
+                     gmx_bool             bFullOmpSupport,
+                     gmx_bool             bSepPME)
 {
 #if GMX_THREAD_MPI
     const char *mpi_str = "per tMPI thread";
@@ -440,31 +433,35 @@ reportOpenmpSettings(FILE            *fplog,
     {
         if (nth_max == nth_min)
         {
-            md_print_info(cr, fplog, "Using %d OpenMP thread%s %s\n",
-                          nth_min, nth_min > 1 ? "s" : "",
-                          cr->nnodes > 1 ? mpi_str : "");
+            GMX_LOG(mdlog.warning).appendTextFormatted(
+                    "Using %d OpenMP thread%s %s",
+                    nth_min, nth_min > 1 ? "s" : "",
+                    cr->nnodes > 1 ? mpi_str : "");
         }
         else
         {
-            md_print_info(cr, fplog, "Using %d - %d OpenMP threads %s\n",
-                          nth_min, nth_max, mpi_str);
+            GMX_LOG(mdlog.warning).appendTextFormatted(
+                    "Using %d - %d OpenMP threads %s",
+                    nth_min, nth_max, mpi_str);
         }
     }
     if (bSepPME && (nth_pme_min != nth_min || nth_pme_max != nth_max))
     {
         if (nth_pme_max == nth_pme_min)
         {
-            md_print_info(cr, fplog, "Using %d OpenMP thread%s %s for PME\n",
-                          nth_pme_min, nth_pme_min > 1 ? "s" : "",
-                          cr->nnodes > 1 ? mpi_str : "");
+            GMX_LOG(mdlog.warning).appendTextFormatted(
+                    "Using %d OpenMP thread%s %s for PME",
+                    nth_pme_min, nth_pme_min > 1 ? "s" : "",
+                    cr->nnodes > 1 ? mpi_str : "");
         }
         else
         {
-            md_print_info(cr, fplog, "Using %d - %d OpenMP threads %s for PME\n",
-                          nth_pme_min, nth_pme_max, mpi_str);
+            GMX_LOG(mdlog.warning).appendTextFormatted(
+                    "Using %d - %d OpenMP threads %s for PME",
+                    nth_pme_min, nth_pme_max, mpi_str);
         }
     }
-    md_print_info(cr, fplog, "\n");
+    GMX_LOG(mdlog.warning);
 }
 
 /*! \brief Detect and warn about oversubscription of cores.
@@ -474,11 +471,11 @@ reportOpenmpSettings(FILE            *fplog,
  *
  * \todo Enable this for separate PME nodes as well! */
 static void
-issueOversubscriptionWarning(FILE            *fplog,
-                             const t_commrec *cr,
-                             int              nthreads_hw_avail,
-                             int              nppn,
-                             gmx_bool         bSepPME)
+issueOversubscriptionWarning(const gmx::MDLogger &mdlog,
+                             const t_commrec     *cr,
+                             int                  nthreads_hw_avail,
+                             int                  nppn,
+                             gmx_bool             bSepPME)
 {
     char sbuf[STRLEN], sbuf1[STRLEN], sbuf2[STRLEN];
 
@@ -504,14 +501,14 @@ issueOversubscriptionWarning(FILE            *fplog,
 #endif
         }
 #endif
-        md_print_warn(cr, fplog,
-                      "WARNING: %sversubscribing the available %d logical CPU cores%s with %d %s.\n"
-                      "         This will cause considerable performance loss!",
-                      sbuf2, nthreads_hw_avail, sbuf1, nppn*modth.gnth, sbuf);
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "WARNING: %sversubscribing the available %d logical CPU cores%s with %d %s.\n"
+                "         This will cause considerable performance loss!",
+                sbuf2, nthreads_hw_avail, sbuf1, nppn*modth.gnth, sbuf);
     }
 }
 
-void gmx_omp_nthreads_init(FILE *fplog, t_commrec *cr,
+void gmx_omp_nthreads_init(const gmx::MDLogger &mdlog, t_commrec *cr,
                            int nthreads_hw_avail,
                            int omp_nthreads_req,
                            int omp_nthreads_pme_req,
@@ -529,7 +526,7 @@ void gmx_omp_nthreads_init(FILE *fplog, t_commrec *cr,
     bSepPME = ( (cr->duty & DUTY_PP) && !(cr->duty & DUTY_PME)) ||
         (!(cr->duty & DUTY_PP) &&  (cr->duty & DUTY_PME));
 
-    manage_number_of_openmp_threads(fplog, cr, bOMP,
+    manage_number_of_openmp_threads(mdlog, cr, bOMP,
                                     nthreads_hw_avail,
                                     omp_nthreads_req, omp_nthreads_pme_req,
                                     bThisNodePMEOnly, bFullOmpSupport,
@@ -544,8 +541,8 @@ void gmx_omp_nthreads_init(FILE *fplog, t_commrec *cr,
     }
 #endif
 
-    reportOpenmpSettings(fplog, cr, bOMP, bFullOmpSupport, bSepPME);
-    issueOversubscriptionWarning(fplog, cr, nthreads_hw_avail, nppn, bSepPME);
+    reportOpenmpSettings(mdlog, cr, bOMP, bFullOmpSupport, bSepPME);
+    issueOversubscriptionWarning(mdlog, cr, nthreads_hw_avail, nppn, bSepPME);
 }
 
 int gmx_omp_nthreads_get(int mod)
index 5f769da89161bb01f7d3b82297f33116bfadeab0..35f844db10d7fb17bfb5d816c87a3d5268739620 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016, 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.
 
 struct t_commrec;
 
+namespace gmx
+{
+class MDLogger;
+}
+
 /** Enum values corresponding to multithreaded algorithmic modules. */
 typedef enum module_nth
 {
@@ -58,7 +63,7 @@ typedef enum module_nth
  * It is compatible with tMPI, thread-safety is ensured (for the features
  * available with tMPI).
  * This function should caled only once during the initialization of mdrun. */
-void gmx_omp_nthreads_init(FILE *fplog, t_commrec *cr,
+void gmx_omp_nthreads_init(const gmx::MDLogger &fplog, t_commrec *cr,
                            int nthreads_hw_avail,
                            int omp_nthreads_req,
                            int omp_nthreads_pme_req,
index d19a861b3a8656d2c611d957253096bbc128d449..88684f83cc3c968db47f4ce0eb927c15bbd38743 100644 (file)
@@ -63,10 +63,14 @@ struct t_inputrec;
 
 namespace gmx
 {
+
+class MDLogger;
+
 /*! \brief Integrator algorithm implementation.
  *
  * \param[in] fplog               Log file for output
  * \param[in] cr                  Communication record
+ * \param[in] mdlog               Log writer for important output
  * \param[in] nfile               Number of files
  * \param[in] fnm                 Filename structure array
  * \param[in] oenv                Output information
@@ -93,7 +97,7 @@ namespace gmx
  * \param[in] Flags               Flags to control mdrun
  * \param[in] walltime_accounting More timing information
  */
-typedef double integrator_t (FILE *fplog, t_commrec *cr,
+typedef double integrator_t (FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
                              int nfile, const t_filenm fnm[],
                              const gmx_output_env_t *oenv, gmx_bool bVerbose,
                              int nstglobalcomm,
index 4d6e3217acc96d88262b2f3397d4cf2c264ad954..392d3c889a7de4ed40ab2bc37b9ec290a644c5c1 100644 (file)
@@ -44,7 +44,6 @@
 #include <algorithm>
 
 #include "gromacs/domdec/domdec.h"
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/gmxlib/network.h"
 #include "gromacs/gmxlib/nrnb.h"
 #include "gromacs/math/vec.h"
@@ -68,6 +67,7 @@
 #include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/snprintf.h"
 
@@ -439,16 +439,18 @@ void compute_globals(FILE *fplog, gmx_global_stat *gstat, t_commrec *cr, t_input
     }
 }
 
-void check_nst_param(FILE *fplog, t_commrec *cr,
-                     const char *desc_nst, int nst,
-                     const char *desc_p, int *p)
+/* check whether an 'nst'-style parameter p is a multiple of nst, and
+   set it to be one if not, with a warning. */
+static void check_nst_param(const gmx::MDLogger &mdlog,
+                            const char *desc_nst, int nst,
+                            const char *desc_p, int *p)
 {
     if (*p > 0 && *p % nst != 0)
     {
         /* Round up to the next multiple of nst */
         *p = ((*p)/nst + 1)*nst;
-        md_print_warn(cr, fplog,
-                      "NOTE: %s changes %s to %d\n", desc_nst, desc_p, *p);
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "NOTE: %s changes %s to %d", desc_nst, desc_p, *p);
     }
 }
 
@@ -575,8 +577,7 @@ static int lcd4(int i1, int i2, int i3, int i4)
     return nst;
 }
 
-int check_nstglobalcomm(FILE *fplog, t_commrec *cr,
-                        int nstglobalcomm, t_inputrec *ir)
+int check_nstglobalcomm(const gmx::MDLogger &mdlog, int nstglobalcomm, t_inputrec *ir)
 {
     if (!EI_DYNAMICS(ir->eI))
     {
@@ -613,35 +614,38 @@ int check_nstglobalcomm(FILE *fplog, t_commrec *cr,
             nstglobalcomm > ir->nstlist && nstglobalcomm % ir->nstlist != 0)
         {
             nstglobalcomm = (nstglobalcomm / ir->nstlist)*ir->nstlist;
-            md_print_warn(cr, fplog, "WARNING: nstglobalcomm is larger than nstlist, but not a multiple, setting it to %d\n", nstglobalcomm);
+            GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                    "WARNING: nstglobalcomm is larger than nstlist, but not a multiple, setting it to %d",
+                    nstglobalcomm);
         }
         if (ir->nstcalcenergy > 0)
         {
-            check_nst_param(fplog, cr, "-gcom", nstglobalcomm,
+            check_nst_param(mdlog, "-gcom", nstglobalcomm,
                             "nstcalcenergy", &ir->nstcalcenergy);
         }
         if (ir->etc != etcNO && ir->nsttcouple > 0)
         {
-            check_nst_param(fplog, cr, "-gcom", nstglobalcomm,
+            check_nst_param(mdlog, "-gcom", nstglobalcomm,
                             "nsttcouple", &ir->nsttcouple);
         }
         if (ir->epc != epcNO && ir->nstpcouple > 0)
         {
-            check_nst_param(fplog, cr, "-gcom", nstglobalcomm,
+            check_nst_param(mdlog, "-gcom", nstglobalcomm,
                             "nstpcouple", &ir->nstpcouple);
         }
 
-        check_nst_param(fplog, cr, "-gcom", nstglobalcomm,
+        check_nst_param(mdlog, "-gcom", nstglobalcomm,
                         "nstenergy", &ir->nstenergy);
 
-        check_nst_param(fplog, cr, "-gcom", nstglobalcomm,
+        check_nst_param(mdlog, "-gcom", nstglobalcomm,
                         "nstlog", &ir->nstlog);
     }
 
     if (ir->comm_mode != ecmNO && ir->nstcomm < nstglobalcomm)
     {
-        md_print_warn(cr, fplog, "WARNING: Changing nstcomm from %d to %d\n",
-                      ir->nstcomm, nstglobalcomm);
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "WARNING: Changing nstcomm from %d to %d",
+                ir->nstcomm, nstglobalcomm);
         ir->nstcomm = nstglobalcomm;
     }
 
index 752a25a4d1e68cce71ee89947c17dd5e7dc85628..67c875bee17f8daa552d895b829392529a45f4c1 100644 (file)
@@ -54,6 +54,11 @@ struct t_nrnb;
 struct t_state;
 struct t_trxframe;
 
+namespace gmx
+{
+class MDLogger;
+}
+
 /* Define a number of flags to better control the information
  * passed to compute_globals in md.c and global_stat.
  */
@@ -83,14 +88,7 @@ struct t_trxframe;
 
 
 /* return the number of steps between global communcations */
-int check_nstglobalcomm(FILE *fplog, t_commrec *cr,
-                        int nstglobalcomm, t_inputrec *ir);
-
-/* check whether an 'nst'-style parameter p is a multiple of nst, and
-   set it to be one if not, with a warning. */
-void check_nst_param(FILE *fplog, t_commrec *cr,
-                     const char *desc_nst, int nst,
-                     const char *desc_p, int *p);
+int check_nstglobalcomm(const gmx::MDLogger &mdlog, int nstglobalcomm, t_inputrec *ir);
 
 /* check which of the multisim simulations has the shortest number of
    steps and return that number of nsteps */
index 5a205694090705e66fb3b3a07da9748f185c8bd7..e8b9b83c7323a0406309f85459918871377823df 100644 (file)
@@ -61,7 +61,6 @@
 #include "gromacs/ewald/pme.h"
 #include "gromacs/fileio/confio.h"
 #include "gromacs/fileio/mtxio.h"
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/gmxlib/network.h"
 #include "gromacs/gmxlib/nrnb.h"
 #include "gromacs/imd/imd.h"
@@ -95,6 +94,7 @@
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/smalloc.h"
 
 //! Utility structure for manipulating states during EM
@@ -987,26 +987,26 @@ namespace gmx
 {
 
 /*! \brief Do conjugate gradients minimization
-    \copydoc integrator_t (FILE *fplog, t_commrec *cr,
-                           int nfile, const t_filenm fnm[],
-                           const gmx_output_env_t *oenv, gmx_bool bVerbose,
-                           int nstglobalcomm,
-                           gmx_vsite_t *vsite, gmx_constr_t constr,
-                           int stepout,
-                           t_inputrec *inputrec,
-                           gmx_mtop_t *top_global, t_fcdata *fcd,
-                           t_state *state_global,
-                           t_mdatoms *mdatoms,
-                           t_nrnb *nrnb, gmx_wallcycle_t wcycle,
-                           gmx_edsam_t ed,
-                           t_forcerec *fr,
-                           int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
-                           real cpt_period, real max_hours,
-                           int imdport,
-                           unsigned long Flags,
-                           gmx_walltime_accounting_t walltime_accounting)
+    \copydoc integrator_t(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+                          int nfile, const t_filenm fnm[],
+                          const gmx_output_env_t *oenv, gmx_bool bVerbose,
+                          int nstglobalcomm,
+                          gmx_vsite_t *vsite, gmx_constr_t constr,
+                          int stepout,
+                          t_inputrec *inputrec,
+                          gmx_mtop_t *top_global, t_fcdata *fcd,
+                          t_state *state_global,
+                          t_mdatoms *mdatoms,
+                          t_nrnb *nrnb, gmx_wallcycle_t wcycle,
+                          gmx_edsam_t ed,
+                          t_forcerec *fr,
+                          int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
+                          real cpt_period, real max_hours,
+                          int imdport,
+                          unsigned long Flags,
+                          gmx_walltime_accounting_t walltime_accounting)
  */
-double do_cg(FILE *fplog, t_commrec *cr,
+double do_cg(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
              int nfile, const t_filenm fnm[],
              const gmx_output_env_t gmx_unused *oenv, gmx_bool bVerbose,
              int gmx_unused nstglobalcomm,
@@ -1633,26 +1633,26 @@ double do_cg(FILE *fplog, t_commrec *cr,
 
 
 /*! \brief Do L-BFGS conjugate gradients minimization
-    \copydoc integrator_t (FILE *fplog, t_commrec *cr,
-                           int nfile, const t_filenm fnm[],
-                           const gmx_output_env_t *oenv, gmx_bool bVerbose,
-                           int nstglobalcomm,
-                           gmx_vsite_t *vsite, gmx_constr_t constr,
-                           int stepout,
-                           t_inputrec *inputrec,
-                           gmx_mtop_t *top_global, t_fcdata *fcd,
-                           t_state *state_global,
-                           t_mdatoms *mdatoms,
-                           t_nrnb *nrnb, gmx_wallcycle_t wcycle,
-                           gmx_edsam_t ed,
-                           t_forcerec *fr,
-                           int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
-                           real cpt_period, real max_hours,
-                           int imdport,
-                           unsigned long Flags,
-                           gmx_walltime_accounting_t walltime_accounting)
+    \copydoc integrator_t(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+                          int nfile, const t_filenm fnm[],
+                          const gmx_output_env_t *oenv, gmx_bool bVerbose,
+                          int nstglobalcomm,
+                          gmx_vsite_t *vsite, gmx_constr_t constr,
+                          int stepout,
+                          t_inputrec *inputrec,
+                          gmx_mtop_t *top_global, t_fcdata *fcd,
+                          t_state *state_global,
+                          t_mdatoms *mdatoms,
+                          t_nrnb *nrnb, gmx_wallcycle_t wcycle,
+                          gmx_edsam_t ed,
+                          t_forcerec *fr,
+                          int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
+                          real cpt_period, real max_hours,
+                          int imdport,
+                          unsigned long Flags,
+                          gmx_walltime_accounting_t walltime_accounting)
  */
-double do_lbfgs(FILE *fplog, t_commrec *cr,
+double do_lbfgs(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
                 int nfile, const t_filenm fnm[],
                 const gmx_output_env_t gmx_unused *oenv, gmx_bool bVerbose,
                 int gmx_unused nstglobalcomm,
@@ -2460,26 +2460,26 @@ double do_lbfgs(FILE *fplog, t_commrec *cr,
 }   /* That's all folks */
 
 /*! \brief Do steepest descents minimization
-    \copydoc integrator_t (FILE *fplog, t_commrec *cr,
-                           int nfile, const t_filenm fnm[],
-                           const gmx_output_env_t *oenv, gmx_bool bVerbose,
-                           int nstglobalcomm,
-                           gmx_vsite_t *vsite, gmx_constr_t constr,
-                           int stepout,
-                           t_inputrec *inputrec,
-                           gmx_mtop_t *top_global, t_fcdata *fcd,
-                           t_state *state_global,
-                           t_mdatoms *mdatoms,
-                           t_nrnb *nrnb, gmx_wallcycle_t wcycle,
-                           gmx_edsam_t ed,
-                           t_forcerec *fr,
-                           int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
-                           real cpt_period, real max_hours,
-                           int imdport,
-                           unsigned long Flags,
-                           gmx_walltime_accounting_t walltime_accounting)
+    \copydoc integrator_t(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+                          int nfile, const t_filenm fnm[],
+                          const gmx_output_env_t *oenv, gmx_bool bVerbose,
+                          int nstglobalcomm,
+                          gmx_vsite_t *vsite, gmx_constr_t constr,
+                          int stepout,
+                          t_inputrec *inputrec,
+                          gmx_mtop_t *top_global, t_fcdata *fcd,
+                          t_state *state_global,
+                          t_mdatoms *mdatoms,
+                          t_nrnb *nrnb, gmx_wallcycle_t wcycle,
+                          gmx_edsam_t ed,
+                          t_forcerec *fr,
+                          int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
+                          real cpt_period, real max_hours,
+                          int imdport,
+                          unsigned long Flags,
+                          gmx_walltime_accounting_t walltime_accounting)
  */
-double do_steep(FILE *fplog, t_commrec *cr,
+double do_steep(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
                 int nfile, const t_filenm fnm[],
                 const gmx_output_env_t gmx_unused *oenv, gmx_bool bVerbose,
                 int gmx_unused nstglobalcomm,
@@ -2717,26 +2717,26 @@ double do_steep(FILE *fplog, t_commrec *cr,
 }   /* That's all folks */
 
 /*! \brief Do normal modes analysis
-    \copydoc integrator_t (FILE *fplog, t_commrec *cr,
-                           int nfile, const t_filenm fnm[],
-                           const gmx_output_env_t *oenv, gmx_bool bVerbose,
-                           int nstglobalcomm,
-                           gmx_vsite_t *vsite, gmx_constr_t constr,
-                           int stepout,
-                           t_inputrec *inputrec,
-                           gmx_mtop_t *top_global, t_fcdata *fcd,
-                           t_state *state_global,
-                           t_mdatoms *mdatoms,
-                           t_nrnb *nrnb, gmx_wallcycle_t wcycle,
-                           gmx_edsam_t ed,
-                           t_forcerec *fr,
-                           int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
-                           real cpt_period, real max_hours,
-                           int imdport,
-                           unsigned long Flags,
-                           gmx_walltime_accounting_t walltime_accounting)
+    \copydoc integrator_t(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+                          int nfile, const t_filenm fnm[],
+                          const gmx_output_env_t *oenv, gmx_bool bVerbose,
+                          int nstglobalcomm,
+                          gmx_vsite_t *vsite, gmx_constr_t constr,
+                          int stepout,
+                          t_inputrec *inputrec,
+                          gmx_mtop_t *top_global, t_fcdata *fcd,
+                          t_state *state_global,
+                          t_mdatoms *mdatoms,
+                          t_nrnb *nrnb, gmx_wallcycle_t wcycle,
+                          gmx_edsam_t ed,
+                          t_forcerec *fr,
+                          int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
+                          real cpt_period, real max_hours,
+                          int imdport,
+                          unsigned long Flags,
+                          gmx_walltime_accounting_t walltime_accounting)
  */
-double do_nm(FILE *fplog, t_commrec *cr,
+double do_nm(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
              int nfile, const t_filenm fnm[],
              const gmx_output_env_t gmx_unused *oenv, gmx_bool bVerbose,
              int gmx_unused nstglobalcomm,
@@ -2825,17 +2825,18 @@ double do_nm(FILE *fplog, t_commrec *cr,
      */
     if (EEL_FULL(fr->eeltype) || fr->rlist == 0.0)
     {
-        md_print_info(cr, fplog, "Non-cutoff electrostatics used, forcing full Hessian format.\n");
+        GMX_LOG(mdlog.warning).appendText("Non-cutoff electrostatics used, forcing full Hessian format.");
         bSparse = FALSE;
     }
     else if (atom_index.size() < 1000)
     {
-        md_print_info(cr, fplog, "Small system size (N=%d), using full Hessian format.\n", atom_index.size());
+        GMX_LOG(mdlog.warning).appendTextFormatted("Small system size (N=%d), using full Hessian format.",
+                                                   atom_index.size());
         bSparse = FALSE;
     }
     else
     {
-        md_print_info(cr, fplog, "Using compressed symmetric sparse Hessian format.\n");
+        GMX_LOG(mdlog.warning).appendText("Using compressed symmetric sparse Hessian format.");
         bSparse = TRUE;
     }
 
@@ -2884,14 +2885,14 @@ double do_nm(FILE *fplog, t_commrec *cr,
     /* if forces are not small, warn user */
     get_state_f_norm_max(cr, &(inputrec->opts), mdatoms, state_work);
 
-    md_print_info(cr, fplog, "Maximum force:%12.5e\n", state_work->fmax);
+    GMX_LOG(mdlog.warning).appendTextFormatted("Maximum force:%12.5e", state_work->fmax);
     if (state_work->fmax > 1.0e-3)
     {
-        md_print_info(cr, fplog,
-                      "The force is probably not small enough to "
-                      "ensure that you are at a minimum.\n"
-                      "Be aware that negative eigenvalues may occur\n"
-                      "when the resulting matrix is diagonalized.\n\n");
+        GMX_LOG(mdlog.warning).appendText(
+                "The force is probably not small enough to "
+                "ensure that you are at a minimum.\n"
+                "Be aware that negative eigenvalues may occur\n"
+                "when the resulting matrix is diagonalized.");
     }
 
     /***********************************************************
index 59049eefdd02221dda5b646c49c0a29abc816011..ecdb144fc89ec04807575415e7e60478859e83da 100644 (file)
@@ -2523,7 +2523,7 @@ void put_atoms_in_box_omp(int ePBC, const matrix box, int natoms, rvec x[])
 }
 
 // TODO This can be cleaned up a lot, and move back to runner.cpp
-void finish_run(FILE *fplog, t_commrec *cr,
+void finish_run(FILE *fplog, const gmx::MDLogger &mdlog, t_commrec *cr,
                 t_inputrec *inputrec,
                 t_nrnb nrnb[], gmx_wallcycle_t wcycle,
                 gmx_walltime_accounting_t walltime_accounting,
@@ -2600,7 +2600,7 @@ void finish_run(FILE *fplog, t_commrec *cr,
     {
         struct gmx_wallclock_gpu_t* gputimes = use_GPU(nbv) ? nbnxn_gpu_get_timings(nbv->gpu_nbv) : NULL;
 
-        wallcycle_print(fplog, cr->nnodes, cr->npmenodes, nthreads_pp, nthreads_pme,
+        wallcycle_print(fplog, mdlog, cr->nnodes, cr->npmenodes, nthreads_pp, nthreads_pme,
                         elapsed_time_over_all_ranks,
                         wcycle, cycle_sum, gputimes);
 
index 930bf2c692f16935a3266c472d8c4171d67283c2..dc91aaa27211e667ad4656acf9d73284084d3c74 100644 (file)
@@ -53,6 +53,11 @@ struct t_graph;
 struct t_mdatoms;
 struct t_nrnb;
 
+namespace gmx
+{
+class MDLogger;
+}
+
 typedef struct gmx_global_stat *gmx_global_stat_t;
 
 void do_pbc_first(FILE *log, matrix box, t_forcerec *fr,
@@ -117,7 +122,7 @@ void print_start(FILE *fplog, t_commrec *cr,
                  gmx_walltime_accounting_t walltime_accounting,
                  const char *name);
 
-void finish_run(FILE *log, t_commrec *cr,
+void finish_run(FILE *log, const gmx::MDLogger &mdlog, t_commrec *cr,
                 t_inputrec *inputrec,
                 t_nrnb nrnb[], gmx_wallcycle_t wcycle,
                 gmx_walltime_accounting_t walltime_accounting,
index 23bda0206af1351cbf6ac3946ea80c32e7e61cb4..b1d53972a494e8cc159f718eed94c71c953a1c77 100644 (file)
@@ -126,7 +126,7 @@ namespace gmx
 {
 
 /*! \brief Do test particle insertion.
-    \copydoc integrator_t (FILE *fplog, t_commrec *cr,
+    \copydoc integrator_t (FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
                            int nfile, const t_filenm fnm[],
                            const gmx_output_env_t *oenv, gmx_bool bVerbose,
                            int nstglobalcomm,
@@ -145,7 +145,7 @@ namespace gmx
                            unsigned long Flags,
                            gmx_walltime_accounting_t walltime_accounting)
  */
-double do_tpi(FILE *fplog, t_commrec *cr,
+double do_tpi(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog,
               int nfile, const t_filenm fnm[],
               const gmx_output_env_t *oenv, gmx_bool bVerbose,
               int gmx_unused nstglobalcomm,
index ce5032f440929f6ccbd7fff8977a12851de93865..027e6cf13b2264e61fc9bce9b3cf25e4c10f9f2c 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "gromacs/hardware/hw_info.h"
 #include "gromacs/mdrunutility/threadaffinity.h"
+#include "gromacs/utility/logger.h"
 
 struct t_commrec;
 
@@ -114,7 +115,8 @@ class ThreadAffinityTestHelper
             {
                 setLogicalProcessorCount(1);
             }
-            gmx_set_thread_affinity(nullptr, cr_, hwOpt_, *hwTop_,
+            MDLogger mdlog;
+            gmx_set_thread_affinity(nullptr, mdlog, cr_, hwOpt_, *hwTop_,
                                     nthread_local, &affinityAccess_);
         }
 
index f7a21eedc8dfa133e8e0a2a652f6e4c030186678..ef02695ca3fb228a3d928ff2f75881b7d721a7c9 100644 (file)
@@ -49,7 +49,6 @@
 
 #include "thread_mpi/threads.h"
 
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/hardware/hardwaretopology.h"
 #include "gromacs/hardware/hw_info.h"
 #include "gromacs/mdtypes/commrec.h"
@@ -59,6 +58,7 @@
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/gmxomp.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/programcontext.h"
 #include "gromacs/utility/scoped_cptr.h"
 #include "gromacs/utility/smalloc.h"
@@ -107,7 +107,7 @@ static bool invalidWithinSimulation(const t_commrec *cr, bool invalidLocally)
 }
 
 static bool
-get_thread_affinity_layout(FILE *fplog,
+get_thread_affinity_layout(FILE *fplog, const gmx::MDLogger &mdlog,
                            const t_commrec *cr,
                            const gmx::HardwareTopology &hwTop,
                            int   threads,
@@ -166,8 +166,8 @@ get_thread_affinity_layout(FILE *fplog,
     if (invalidWithinSimulation(cr, invalidValue))
     {
         /* We don't know anything about the hardware, don't pin */
-        md_print_warn(cr, fplog,
-                      "NOTE: No information on available cores, thread pinning disabled.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                "NOTE: No information on available cores, thread pinning disabled.");
         alreadyWarned = true;
     }
     bool validLayout = !invalidValue;
@@ -178,11 +178,11 @@ get_thread_affinity_layout(FILE *fplog,
         bool warn = (invalidValue && threads > 1 && threads < hwThreads);
         if (invalidWithinSimulation(cr, warn) && !alreadyWarned)
         {
-            md_print_warn(cr, fplog,
-                          "NOTE: The number of threads is not equal to the number of (logical) cores\n"
-                          "      and the -pin option is set to auto: will not pin thread to cores.\n"
-                          "      This can lead to significant performance degradation.\n"
-                          "      Consider using -pin on (and -pinoffset in case you run multiple jobs).\n");
+            GMX_LOG(mdlog.warning).asParagraph().appendText(
+                    "NOTE: The number of threads is not equal to the number of (logical) cores\n"
+                    "      and the -pin option is set to auto: will not pin thread to cores.\n"
+                    "      This can lead to significant performance degradation.\n"
+                    "      Consider using -pin on (and -pinoffset in case you run multiple jobs).");
             alreadyWarned = true;
         }
         validLayout = validLayout && !invalidValue;
@@ -191,8 +191,8 @@ get_thread_affinity_layout(FILE *fplog,
     invalidValue = (threads > hwThreads);
     if (invalidWithinSimulation(cr, invalidValue) && !alreadyWarned)
     {
-        md_print_warn(cr, fplog,
-                      "NOTE: Oversubscribing a CPU, will not pin threads.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                "NOTE: Oversubscribing the CPU, will not pin threads");
         alreadyWarned = true;
     }
     validLayout = validLayout && !invalidValue;
@@ -200,8 +200,8 @@ get_thread_affinity_layout(FILE *fplog,
     invalidValue = (pin_offset + threads > hwThreads);
     if (invalidWithinSimulation(cr, invalidValue) && !alreadyWarned)
     {
-        md_print_warn(cr, fplog,
-                      "WARNING: Requested offset too large for available cores, thread pinning disabled.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                "WARNING: Requested offset too large for available cores, thread pinning disabled.");
         alreadyWarned = true;
 
     }
@@ -241,8 +241,8 @@ get_thread_affinity_layout(FILE *fplog,
     if (invalidWithinSimulation(cr, invalidValue) && !alreadyWarned)
     {
         /* We are oversubscribing, don't pin */
-        md_print_warn(cr, fplog,
-                      "WARNING: Requested stride too large for available cores, thread pinning disabled.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                "WARNING: Requested stride too large for available cores, thread pinning disabled.");
     }
     validLayout = validLayout && !invalidValue;
 
@@ -355,6 +355,7 @@ static bool set_affinity(const t_commrec *cr, int nthread_local, int thread0_id_
  */
 void
 gmx_set_thread_affinity(FILE                        *fplog,
+                        const gmx::MDLogger         &mdlog,
                         const t_commrec             *cr,
                         const gmx_hw_opt_t          *hw_opt,
                         const gmx::HardwareTopology &hwTop,
@@ -384,8 +385,8 @@ gmx_set_thread_affinity(FILE                        *fplog,
            no point in warning the user in that case. In any other case
            the user might be able to do something about it. */
 #if !defined(__APPLE__) && !defined(__bg__)
-        md_print_warn(cr, fplog,
-                      "NOTE: Cannot set thread affinities on the current platform.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                "NOTE: Cannot set thread affinities on the current platform.");
 #endif  /* __APPLE__ */
         return;
     }
@@ -417,12 +418,12 @@ gmx_set_thread_affinity(FILE                        *fplog,
     int  core_pinning_stride = hw_opt->core_pinning_stride;
     if (offset != 0)
     {
-        md_print_info(cr, fplog, "Applying core pinning offset %d\n", offset);
+        GMX_LOG(mdlog.warning).appendTextFormatted("Applying core pinning offset %d", offset);
     }
 
     bool automatic = (hw_opt->thread_affinity == threadaffAUTO);
     bool validLayout
-        = get_thread_affinity_layout(fplog, cr, hwTop, nthread_node, automatic,
+        = get_thread_affinity_layout(fplog, mdlog, cr, hwTop, nthread_node, automatic,
                                      offset, &core_pinning_stride, &localityOrder);
     gmx::scoped_guard_sfree localityOrderGuard(localityOrder);
 
@@ -440,9 +441,9 @@ gmx_set_thread_affinity(FILE                        *fplog,
     }
     if (invalidWithinSimulation(cr, !allAffinitiesSet))
     {
-        md_print_warn(cr, fplog,
-                      "NOTE: Thread affinity setting failed. This can cause performance degradation.\n"
-                      "      If you think your settings are correct, ask on the gmx-users list.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                "NOTE: Thread affinity setting failed. This can cause performance degradation.\n"
+                "      If you think your settings are correct, ask on the gmx-users list.");
     }
 }
 
@@ -451,11 +452,11 @@ gmx_set_thread_affinity(FILE                        *fplog,
  * Note that this will only work on Linux as we use a GNU feature.
  */
 void
-gmx_check_thread_affinity_set(FILE            *fplog,
-                              const t_commrec *cr,
-                              gmx_hw_opt_t    *hw_opt,
-                              int  gmx_unused  nthreads_hw_avail,
-                              gmx_bool         bAfterOpenmpInit)
+gmx_check_thread_affinity_set(const gmx::MDLogger &mdlog,
+                              const t_commrec     *cr,
+                              gmx_hw_opt_t        *hw_opt,
+                              int  gmx_unused      nthreads_hw_avail,
+                              gmx_bool             bAfterOpenmpInit)
 {
     GMX_RELEASE_ASSERT(hw_opt, "hw_opt must be a non-NULL pointer");
 
@@ -472,7 +473,7 @@ gmx_check_thread_affinity_set(FILE            *fplog,
             if (!gmx_omp_check_thread_affinity(&message))
             {
                 /* TODO: with -pin auto we should only warn when using all cores */
-                md_print_warn(cr, fplog, "%s", message);
+                GMX_LOG(mdlog.warning).asParagraph().appendText(message);
                 sfree(message);
                 hw_opt->thread_affinity = threadaffOFF;
             }
@@ -547,14 +548,14 @@ gmx_check_thread_affinity_set(FILE            *fplog,
         {
             if (!bAfterOpenmpInit)
             {
-                md_print_warn(cr, fplog,
-                              "Non-default thread affinity set, disabling internal thread affinity");
+                GMX_LOG(mdlog.warning).asParagraph().appendText(
+                        "Non-default thread affinity set, disabling internal thread affinity");
             }
             else
             {
-                md_print_warn(cr, fplog,
-                              "Non-default thread affinity set probably by the OpenMP library,\n"
-                              "disabling internal thread affinity");
+                GMX_LOG(mdlog.warning).asParagraph().appendText(
+                        "Non-default thread affinity set probably by the OpenMP library,\n"
+                        "disabling internal thread affinity");
             }
             hw_opt->thread_affinity = threadaffOFF;
         }
@@ -563,9 +564,9 @@ gmx_check_thread_affinity_set(FILE            *fplog,
             /* Only warn once, at the last check (bAfterOpenmpInit==TRUE) */
             if (bAfterOpenmpInit)
             {
-                md_print_warn(cr, fplog,
-                              "Overriding thread affinity set outside %s\n",
-                              gmx::getProgramContext().displayName());
+                GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                        "Overriding thread affinity set outside %s",
+                        gmx::getProgramContext().displayName());
             }
         }
 
index 30c062d2f4ff7184ce9d65748505a43181dbb250..28c7acddafb821237a99ebff51adb9080516d444 100644 (file)
@@ -53,6 +53,7 @@ namespace gmx
 {
 
 class HardwareTopology;
+class MDLogger;
 
 class IThreadAffinityAccess
 {
@@ -71,6 +72,7 @@ class IThreadAffinityAccess
  */
 void
 gmx_set_thread_affinity(FILE                        *fplog,
+                        const gmx::MDLogger         &mdlog,
                         const t_commrec             *cr,
                         const gmx_hw_opt_t          *hw_opt,
                         const gmx::HardwareTopology &hwTop,
@@ -92,7 +94,7 @@ gmx_set_thread_affinity(FILE                        *fplog,
  * variables for setting the affinity are set.
  */
 void
-gmx_check_thread_affinity_set(FILE *fplog, const t_commrec *cr,
+gmx_check_thread_affinity_set(const gmx::MDLogger &mdlog, const t_commrec *cr,
                               gmx_hw_opt_t *hw_opt, int ncpus,
                               gmx_bool bAfterOpenmpInit);
 
index 548827df384d3c35edc81dea1c689b1d952a610f..7b9ab440a2dfc5b3be1a631a298d571ea900782d 100644 (file)
@@ -44,7 +44,6 @@
 
 #include <array>
 
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/mdtypes/commrec.h"
 #include "gromacs/timing/cyclecounter.h"
 #include "gromacs/timing/gpu_timing.h"
@@ -52,6 +51,7 @@
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/gmxmpi.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/snprintf.h"
 
@@ -710,7 +710,7 @@ static void print_header(FILE *fplog, int nrank_pp, int nth_pp, int nrank_pme, i
 }
 
 
-void wallcycle_print(FILE *fplog, int nnodes, int npme,
+void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int npme,
                      int nth_pp, int nth_pme, double realtime,
                      gmx_wallcycle_t wc, const WallcycleCounts &cyc_sum,
                      struct gmx_wallclock_gpu_t *gpu_t)
@@ -751,14 +751,15 @@ void wallcycle_print(FILE *fplog, int nnodes, int npme,
            timing data might still be sensible for some non-Jenkins
            run, than is lost from diagnosing Jenkins FP exceptions on
            runs about whose execution time we don't care. */
-        md_print_warn(NULL, fplog, "WARNING: A total of %f CPU cycles was recorded, so mdrun cannot print a time accounting\n", tot);
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "WARNING: A total of %f CPU cycles was recorded, so mdrun cannot print a time accounting",
+                tot);
         return;
     }
 
     if (wc->haveInvalidCount)
     {
-        md_print_warn(NULL, fplog, "%s\n",
-                      "NOTE: Detected invalid cycle counts, probably because threads moved between CPU cores that do not have synchronized cycle counters. Will not print the cycle accounting.");
+        GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: Detected invalid cycle counts, probably because threads moved between CPU cores that do not have synchronized cycle counters. Will not print the cycle accounting.");
         return;
     }
 
@@ -948,26 +949,26 @@ void wallcycle_print(FILE *fplog, int nnodes, int npme,
                         /* The user could have used -notunepme,
                          * but we currently can't check that here.
                          */
-                        md_print_warn(NULL, fplog,
-                                      "\nNOTE: The GPU has >25%% less load than the CPU. This imbalance causes\n"
-                                      "      performance loss. Maybe the domain decomposition limits the PME tuning.\n"
-                                      "      In that case, try setting the DD grid manually (-dd) or lowering -dds.");
+                        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                                "NOTE: The GPU has >25% less load than the CPU. This imbalance causes\n"
+                                "      performance loss. Maybe the domain decomposition limits the PME tuning.\n"
+                                "      In that case, try setting the DD grid manually (-dd) or lowering -dds.");
                     }
                     else
                     {
                         /* We should not end up here, unless the box is
                          * too small for increasing the cut-off for PME tuning.
                          */
-                        md_print_warn(NULL, fplog,
-                                      "\nNOTE: The GPU has >25%% less load than the CPU. This imbalance causes\n"
-                                      "      performance loss.");
+                        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                                "NOTE: The GPU has >25% less load than the CPU. This imbalance causes\n"
+                                "      performance loss.");
                     }
                 }
                 if (gpu_cpu_ratio > 1.2)
                 {
-                    md_print_warn(NULL, fplog,
-                                  "\nNOTE: The GPU has >20%% more load than the CPU. This imbalance causes\n"
-                                  "      performance loss, consider using a shorter cut-off and a finer PME grid.");
+                    GMX_LOG(mdlog.warning).asParagraph().appendText(
+                            "NOTE: The GPU has >20% more load than the CPU. This imbalance causes\n"
+                            "      performance loss, consider using a shorter cut-off and a finer PME grid.");
                 }
             }
         }
@@ -975,9 +976,9 @@ void wallcycle_print(FILE *fplog, int nnodes, int npme,
 
     if (wc->wc_barrier)
     {
-        md_print_warn(NULL, fplog,
-                      "MPI_Barrier was called before each cycle start/stop\n"
-                      "call, so timings are not those of real runs.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText(
+                "MPI_Barrier was called before each cycle start/stop\n"
+                "call, so timings are not those of real runs.");
     }
 
     if (wc->wcc[ewcNB_XF_BUF_OPS].n > 0 &&
@@ -987,29 +988,28 @@ void wallcycle_print(FILE *fplog, int nnodes, int npme,
         /* Only the sim master calls this function, so always print to stderr */
         if (wc->wcc[ewcDOMDEC].n == 0)
         {
-            md_print_warn(NULL, fplog,
-                          "NOTE: %d %% of the run time was spent in pair search,\n"
-                          "      you might want to increase nstlist (this has no effect on accuracy)\n",
-                          (int)(100*cyc_sum[ewcNS]/tot+0.5));
+            GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                    "NOTE: %d %% of the run time was spent in pair search,\n"
+                    "      you might want to increase nstlist (this has no effect on accuracy)\n",
+                    (int)(100*cyc_sum[ewcNS]/tot+0.5));
         }
         else
         {
-            md_print_warn(NULL, fplog,
-                          "NOTE: %d %% of the run time was spent in domain decomposition,\n"
-                          "      %d %% of the run time was spent in pair search,\n"
-                          "      you might want to increase nstlist (this has no effect on accuracy)\n",
-                          (int)(100*cyc_sum[ewcDOMDEC]/tot+0.5),
-                          (int)(100*cyc_sum[ewcNS]/tot+0.5));
+            GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                    "NOTE: %d %% of the run time was spent in domain decomposition,\n"
+                    "      %d %% of the run time was spent in pair search,\n"
+                    "      you might want to increase nstlist (this has no effect on accuracy)\n",
+                    (int)(100*cyc_sum[ewcDOMDEC]/tot+0.5),
+                    (int)(100*cyc_sum[ewcNS]/tot+0.5));
         }
     }
 
     if (cyc_sum[ewcMoveE] > tot*0.05)
     {
-        /* Only the sim master calls this function, so always print to stderr */
-        md_print_warn(NULL, fplog,
-                      "NOTE: %d %% of the run time was spent communicating energies,\n"
-                      "      you might want to use the -gcom option of mdrun\n",
-                      (int)(100*cyc_sum[ewcMoveE]/tot+0.5));
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "NOTE: %d %% of the run time was spent communicating energies,\n"
+                "      you might want to use the -gcom option of mdrun\n",
+                (int)(100*cyc_sum[ewcMoveE]/tot+0.5));
     }
 }
 
index d3c316da592d8554e736b503e20697b525e28546..e84243fe8ca5f5e75a8d6896ef2f2c8875e5b11e 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016, 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.
 
 #include "gromacs/utility/basedefinitions.h"
 
+struct t_commrec;
+
+namespace gmx
+{
+class MDLogger;
+}
+
 typedef struct gmx_wallcycle *gmx_wallcycle_t;
 typedef struct gmx_wallclock_gpu_t gmx_wallclock_gpu_t;
-struct t_commrec;
 
 typedef std::array<double, ewcNR+ewcsNR> WallcycleCounts;
 /* Convenience typedef */
@@ -57,7 +63,7 @@ WallcycleCounts wallcycle_sum(struct t_commrec *cr, gmx_wallcycle_t wc);
 /* Return a vector of the sum of cycle counts over the nodes in
    cr->mpi_comm_mysim. */
 
-void wallcycle_print(FILE *fplog, int nnodes, int npme,
+void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int npme,
                      int nth_pp, int nth_pme, double realtime,
                      gmx_wallcycle_t wc, const WallcycleCounts &cyc_sum,
                      struct gmx_wallclock_gpu_t *gpu_t);
index 1a29aba34579362e1b689cf0c2122c034a11e79d..f9f4f6d2759e69b5e95ae6f4ce575600dec1f7b5 100644 (file)
@@ -85,6 +85,12 @@ class LogEntryWriter
             entry_.text.append(text);
             return *this;
         }
+        //! Appends given text to the log entry.
+        LogEntryWriter &appendText(const std::string &text)
+        {
+            entry_.text.append(text);
+            return *this;
+        }
         //! Appends given text to the log entry, with printf-style formatting.
         LogEntryWriter &appendTextFormatted(const char *fmt, ...);
         //! Writes the log entry with empty lines before and after.
@@ -111,13 +117,14 @@ class LogWriteHelper
         //! Initializes a helper for writing to the given target.
         explicit LogWriteHelper(ILogTarget *target) : target_(target) {}
 
+        // Should be explicit, once that works in CUDA.
         /*! \brief
          * Returns whether anything needs to be written.
          *
          * Note that the return value is unintuitively `false` when the target
          * is active, to allow implementing ::GMX_LOG like it is now.
          */
-        explicit operator bool() const { return target_ == NULL; }
+        operator bool() const { return target_ == NULL; }
 
         /*! \brief
          * Writes the entry from the given writer to the log target.
@@ -150,11 +157,12 @@ class LogLevelHelper
         //! Initializes a helper for writing to the given target.
         explicit LogLevelHelper(ILogTarget *target) : target_(target) {}
 
+        // Both of the below should be explicit, once that works in CUDA.
         //! Returns whether the output for this log level goes anywhere.
-        explicit operator bool() const { return target_ != NULL; }
+        operator bool() const { return target_ != NULL; }
 
         //! Creates a helper for ::GMX_LOG.
-        explicit operator LogWriteHelper() const { return LogWriteHelper(target_); }
+        operator LogWriteHelper() const { return LogWriteHelper(target_); }
 
     private:
         ILogTarget *target_;
@@ -178,13 +186,13 @@ class MDLogger
 {
     public:
         //! Supported logging levels.
-        enum class LogLevel
+        enum LogLevel
         {
             Warning,
             Info
         };
         //! Number of logging levels.
-        static const int LogLevelCount = static_cast<int>(LogLevel::Info) + 1;
+        static const int LogLevelCount = static_cast<int>(Info) + 1;
 
         MDLogger();
         //! Creates a logger with the given targets.
index 92fa911eb42e08119a3cb688cadea70fab76148f..a00b569bb63b22e2371f87610a9e93e1b09caf06 100644 (file)
@@ -55,7 +55,6 @@
 #include "gromacs/ewald/pme.h"
 #include "gromacs/ewald/pme-load-balancing.h"
 #include "gromacs/fileio/trxio.h"
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/gmxlib/network.h"
 #include "gromacs/gmxlib/nrnb.h"
 #include "gromacs/gpu_utils/gpu_utils.h"
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/logger.h"
 #include "gromacs/utility/real.h"
 #include "gromacs/utility/smalloc.h"
 
@@ -151,7 +151,7 @@ static void checkNumberOfBondedInteractions(FILE *fplog, t_commrec *cr, int tota
     }
 }
 
-static void reset_all_counters(FILE *fplog, t_commrec *cr,
+static void reset_all_counters(FILE *fplog, const gmx::MDLogger &mdlog, t_commrec *cr,
                                gmx_int64_t step,
                                gmx_int64_t *step_rel, t_inputrec *ir,
                                gmx_wallcycle_t wcycle, t_nrnb *nrnb,
@@ -161,8 +161,9 @@ static void reset_all_counters(FILE *fplog, t_commrec *cr,
     char sbuf[STEPSTRSIZE];
 
     /* Reset all the counters related to performance over the run */
-    md_print_warn(cr, fplog, "step %s: resetting all time and cycle counters\n",
-                  gmx_step_str(step, sbuf));
+    GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+            "step %s: resetting all time and cycle counters",
+            gmx_step_str(step, sbuf));
 
     if (use_GPU(nbv))
     {
@@ -186,7 +187,7 @@ static void reset_all_counters(FILE *fplog, t_commrec *cr,
 }
 
 /*! \libinternal
-    \copydoc integrator_t (FILE *fplog, t_commrec *cr,
+    \copydoc integrator_t (FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
                            int nfile, const t_filenm fnm[],
                            const gmx_output_env_t *oenv, gmx_bool bVerbose,
                            int nstglobalcomm,
@@ -205,7 +206,8 @@ static void reset_all_counters(FILE *fplog, t_commrec *cr,
                            unsigned long Flags,
                            gmx_walltime_accounting_t walltime_accounting)
  */
-double gmx::do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[],
+double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog,
+                  int nfile, const t_filenm fnm[],
                   const gmx_output_env_t *oenv, gmx_bool bVerbose,
                   int nstglobalcomm,
                   gmx_vsite_t *vsite, gmx_constr_t constr,
@@ -326,7 +328,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[],
         nstglobalcomm     = 1;
     }
 
-    nstglobalcomm   = check_nstglobalcomm(fplog, cr, nstglobalcomm, ir);
+    nstglobalcomm   = check_nstglobalcomm(mdlog, nstglobalcomm, ir);
     bGStatEveryStep = (nstglobalcomm == 1);
 
     if (bRerunMD)
@@ -520,7 +522,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[],
                 !(Flags & MD_REPRODUCIBLE));
     if (bPMETune)
     {
-        pme_loadbal_init(&pme_loadbal, cr, fplog, ir, state->box,
+        pme_loadbal_init(&pme_loadbal, cr, mdlog, ir, state->box,
                          fr->ic, fr->pmedata, use_GPU(fr->nbv),
                          &bPMETunePrinting);
     }
@@ -786,7 +788,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[],
             /* PME grid + cut-off optimization with GPUs or PME nodes */
             pme_loadbal_do(pme_loadbal, cr,
                            (bVerbose && MASTER(cr)) ? stderr : NULL,
-                           fplog,
+                           fplog, mdlog,
                            ir, fr, state,
                            wcycle,
                            step, step_rel,
@@ -1758,7 +1760,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[],
                           "resetting counters later in the run, e.g. with gmx "
                           "mdrun -resetstep.", step);
             }
-            reset_all_counters(fplog, cr, step, &step_rel, ir, wcycle, nrnb, walltime_accounting,
+            reset_all_counters(fplog, mdlog, cr, step, &step_rel, ir, wcycle, nrnb, walltime_accounting,
                                use_GPU(fr->nbv) ? fr->nbv : NULL);
             wcycle_set_reset_counters(wcycle, -1);
             if (!(cr->duty & DUTY_PME))
@@ -1811,7 +1813,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[],
 
     if (bPMETune)
     {
-        pme_loadbal_done(pme_loadbal, cr, fplog, use_GPU(fr->nbv));
+        pme_loadbal_done(pme_loadbal, fplog, mdlog, use_GPU(fr->nbv));
     }
 
     done_shellfc(fplog, shellfc, step_rel);
index c5fc60c43c34a7ac3263962b9647a15f894d2685..a4ca7ae6b5218f5c3fdacd44c6d9d5c165e5641b 100644 (file)
@@ -44,7 +44,6 @@
 
 #include <algorithm>
 
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/hardware/cpuinfo.h"
 #include "gromacs/hardware/detecthardware.h"
 #include "gromacs/hardware/gpu_hw_info.h"
@@ -57,6 +56,7 @@
 #include "gromacs/topology/topology.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/logger.h"
 
 
 /* DISCLAIMER: All the atom count and thread numbers below are heuristic.
@@ -257,7 +257,7 @@ static int get_tmpi_omp_thread_division(const gmx_hw_info_t *hwinfo,
 }
 
 
-static int getMaxGpuUsable(FILE *fplog, const t_commrec *cr, const gmx_hw_info_t *hwinfo,
+static int getMaxGpuUsable(const gmx::MDLogger &mdlog, const gmx_hw_info_t *hwinfo,
                            int cutoff_scheme, gmx_bool bUseGpu)
 {
     /* This code relies on the fact that GPU are not detected when GPU
@@ -275,7 +275,7 @@ static int getMaxGpuUsable(FILE *fplog, const t_commrec *cr, const gmx_hw_info_t
         {
             if (hwinfo->gpu_info.n_dev_compatible > 1)
             {
-                md_print_warn(cr, fplog, "More than one compatible GPU is available, but GROMACS can only use one of them. Using a single thread-MPI rank.\n");
+                GMX_LOG(mdlog.warning).asParagraph().appendText("More than one compatible GPU is available, but GROMACS can only use one of them. Using a single thread-MPI rank.");
             }
             return 1;
         }
@@ -306,8 +306,7 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo,
                      gmx_hw_opt_t        *hw_opt,
                      const t_inputrec    *inputrec,
                      const gmx_mtop_t    *mtop,
-                     const t_commrec     *cr,
-                     FILE                *fplog,
+                     const gmx::MDLogger &mdlog,
                      gmx_bool             bUseGpu)
 {
     int                          nthreads_hw, nthreads_tot_max, nrank, ngpu;
@@ -320,7 +319,7 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo,
     if (inputrec->eI == eiLBFGS ||
         inputrec->coulombtype == eelEWALD)
     {
-        md_print_warn(cr, fplog, "The integration or electrostatics algorithm doesn't support parallel runs. Using a single thread-MPI rank.\n");
+        GMX_LOG(mdlog.warning).asParagraph().appendText("The integration or electrostatics algorithm doesn't support parallel runs. Using a single thread-MPI rank.");
         if (hw_opt->nthreads_tmpi > 1)
         {
             gmx_fatal(FARGS, "You asked for more than 1 thread-MPI rank, but an algorithm doesn't support that");
@@ -353,7 +352,7 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo,
         nthreads_tot_max = nthreads_hw;
     }
 
-    ngpu = getMaxGpuUsable(fplog, cr, hwinfo, inputrec->cutoff_scheme, bUseGpu);
+    ngpu = getMaxGpuUsable(mdlog, hwinfo, inputrec->cutoff_scheme, bUseGpu);
 
     if (inputrec->cutoff_scheme == ecutsGROUP)
     {
@@ -475,7 +474,7 @@ void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo,
                                         const gmx_hw_opt_t  *hw_opt,
                                         gmx_bool             bNtOmpOptionSet,
                                         t_commrec           *cr,
-                                        FILE                *fplog)
+                                        const gmx::MDLogger &mdlog)
 {
 #if GMX_OPENMP && GMX_MPI
     int         nth_omp_min, nth_omp_max, ngpu;
@@ -544,7 +543,7 @@ void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo,
 
             if (bNtOmpOptionSet)
             {
-                md_print_warn(cr, fplog, "NOTE: %s\n", buf);
+                GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted("NOTE: %s", buf);
             }
             else
             {
@@ -592,7 +591,7 @@ void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo,
              */
             if (bNtOmpOptionSet || (bEnvSet && nth_omp_min != nth_omp_max))
             {
-                md_print_warn(cr, fplog, "NOTE: %s\n", buf);
+                GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted("NOTE: %s", buf);
             }
             else
             {
@@ -610,12 +609,12 @@ void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo,
 #if !GMX_OPENMP && !GMX_MPI
     if (hwinfo->hardwareTopology->numberOfCores() > 1)
     {
-        md_print_warn(cr, fplog, "NOTE: GROMACS was compiled without OpenMP and (thread-)MPI support, can only use a single CPU core\n");
+        GMX_LOG(*mdlog).asParagraph().appendText("NOTE: GROMACS was compiled without OpenMP and (thread-)MPI support, can only use a single CPU core");
     }
 #else
     GMX_UNUSED_VALUE(hwinfo);
     GMX_UNUSED_VALUE(cr);
-    GMX_UNUSED_VALUE(fplog);
+    GMX_UNUSED_VALUE(mdlog);
 #endif
 
 #endif /* GMX_OPENMP && GMX_MPI */
index 4723cd203a38e9187193abcec2c402688ba9bcc3..9cde520897a7e91f3676931396a1e08cd872b146 100644 (file)
@@ -46,6 +46,11 @@ struct gmx_mtop_t;
 struct t_commrec;
 struct t_inputrec;
 
+namespace gmx
+{
+class MDLogger;
+}
+
 /* Return the number of threads to use for thread-MPI based on how many
  * were requested, which algorithms we're using,
  * and how many particles there are.
@@ -58,8 +63,7 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo,
                      gmx_hw_opt_t        *hw_opt,
                      const t_inputrec    *inputrec,
                      const gmx_mtop_t    *mtop,
-                     const t_commrec     *cr,
-                     FILE                *fplog,
+                     const gmx::MDLogger &mdlog,
                      gmx_bool             bUseGpu);
 
 /* Check if the number of OpenMP threads is within reasonable range
@@ -73,8 +77,8 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo,
 void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo,
                                         const gmx_hw_opt_t  *hw_opt,
                                         gmx_bool             bNtOmpOptionSet,
-                                        struct t_commrec    *cr,
-                                        FILE                *fplog);
+                                        t_commrec           *cr,
+                                        const gmx::MDLogger &mdlog);
 
 /* Checks we can do when we don't (yet) know the cut-off scheme */
 void check_and_update_hw_opt_1(gmx_hw_opt_t    *hw_opt,
index 590552fb4c53a71564a50c6a7cd2a8a6c9e18dfd..1ef4161814bac25f2ac23097114540e847dccc33 100644 (file)
@@ -62,7 +62,6 @@
 #include "gromacs/fileio/checkpoint.h"
 #include "gromacs/fileio/oenv.h"
 #include "gromacs/fileio/tpxio.h"
-#include "gromacs/gmxlib/md_logging.h"
 #include "gromacs/gmxlib/network.h"
 #include "gromacs/gpu_utils/gpu_utils.h"
 #include "gromacs/hardware/cpuinfo.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/filestream.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/gmxmpi.h"
+#include "gromacs/utility/logger.h"
+#include "gromacs/utility/loggerbuilder.h"
 #include "gromacs/utility/pleasecite.h"
 #include "gromacs/utility/smalloc.h"
 
@@ -596,13 +598,11 @@ static void prepare_verlet_scheme(FILE                           *fplog,
  *
  * with value passed on the command line (if any)
  */
-static void override_nsteps_cmdline(FILE            *fplog,
-                                    gmx_int64_t      nsteps_cmdline,
-                                    t_inputrec      *ir,
-                                    const t_commrec *cr)
+static void override_nsteps_cmdline(const gmx::MDLogger &mdlog,
+                                    gmx_int64_t          nsteps_cmdline,
+                                    t_inputrec          *ir)
 {
     assert(ir);
-    assert(cr);
 
     /* override with anything else than the default -2 */
     if (nsteps_cmdline > -2)
@@ -623,7 +623,7 @@ static void override_nsteps_cmdline(FILE            *fplog,
                     gmx_step_str(nsteps_cmdline, sbuf_steps));
         }
 
-        md_print_warn(cr, fplog, "%s\n", sbuf_msg);
+        GMX_LOG(mdlog.warning).asParagraph().appendText(sbuf_msg);
     }
     else if (nsteps_cmdline < -2)
     {
@@ -673,6 +673,22 @@ static integrator_t *my_integrator(unsigned int ei)
     }
 }
 
+//! Initializes the logger for mdrun.
+static gmx::LoggerOwner buildLogger(FILE *fplog, const t_commrec *cr)
+{
+    gmx::LoggerBuilder builder;
+    if (fplog != NULL)
+    {
+        builder.addTargetFile(gmx::MDLogger::LogLevel::Info, fplog);
+    }
+    if (cr == nullptr || SIMMASTER(cr))
+    {
+        builder.addTargetStream(gmx::MDLogger::LogLevel::Warning,
+                                &gmx::TextOutputFile::standardError());
+    }
+    return builder.build();
+}
+
 int mdrunner(gmx_hw_opt_t *hw_opt,
              FILE *fplog, t_commrec *cr, int nfile,
              const t_filenm fnm[], const gmx_output_env_t *oenv, gmx_bool bVerbose,
@@ -727,11 +743,16 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
     bForceUseGPU = (strncmp(nbpu_opt, "gpu", 3) == 0);
     bTryUseGPU   = (strncmp(nbpu_opt, "auto", 4) == 0) || bForceUseGPU;
 
+    // Here we assume that SIMMASTER(cr) does not change even after the
+    // threads are started.
+    gmx::LoggerOwner logOwner(buildLogger(fplog, cr));
+    gmx::MDLogger    mdlog(logOwner.logger());
+
     /* Detect hardware, gather information. This is an operation that is
      * global for this process (MPI rank). */
-    hwinfo = gmx_detect_hardware(fplog, cr, bTryUseGPU);
+    hwinfo = gmx_detect_hardware(mdlog, cr, bTryUseGPU);
 
-    gmx_print_detected_hardware(fplog, cr, hwinfo);
+    gmx_print_detected_hardware(fplog, cr, mdlog, hwinfo);
 
     if (fplog != NULL)
     {
@@ -763,7 +784,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
              * update the message text and the content of nbnxn_acceleration_supported.
              */
             if (bUseGPU &&
-                !nbnxn_gpu_acceleration_supported(fplog, cr, inputrec, bRerunMD))
+                !nbnxn_gpu_acceleration_supported(mdlog, inputrec, bRerunMD))
             {
                 /* Fallback message printed by nbnxn_acceleration_supported */
                 if (bForceUseGPU)
@@ -786,9 +807,9 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
 
             if (hwinfo->gpu_info.n_dev_compatible > 0)
             {
-                md_print_warn(cr, fplog,
-                              "NOTE: GPU(s) found, but the current simulation can not use GPUs\n"
-                              "      To use a GPU, set the mdp option: cutoff-scheme = Verlet\n");
+                GMX_LOG(mdlog.warning).asParagraph().appendText(
+                        "NOTE: GPU(s) found, but the current simulation can not use GPUs\n"
+                        "      To use a GPU, set the mdp option: cutoff-scheme = Verlet");
             }
 
             if (bForceUseGPU)
@@ -809,7 +830,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
     check_and_update_hw_opt_1(hw_opt, cr, npme);
 
     /* Early check for externally set process affinity. */
-    gmx_check_thread_affinity_set(fplog, cr,
+    gmx_check_thread_affinity_set(mdlog, cr,
                                   hw_opt, hwinfo->nthreads_hw_avail, FALSE);
 
 #if GMX_THREAD_MPI
@@ -830,7 +851,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
         hw_opt->nthreads_tmpi = get_nthreads_mpi(hwinfo,
                                                  hw_opt,
                                                  inputrec, mtop,
-                                                 cr, fplog, bUseGPU);
+                                                 mdlog, bUseGPU);
 
         if (hw_opt->nthreads_tmpi > 1)
         {
@@ -991,14 +1012,16 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
         }
     }
 
-    if (MASTER(cr) && (Flags & MD_APPENDFILES))
+    if (SIMMASTER(cr) && (Flags & MD_APPENDFILES))
     {
         gmx_log_open(ftp2fn(efLOG, nfile, fnm), cr,
                      Flags, &fplog);
+        logOwner = buildLogger(fplog, nullptr);
+        mdlog    = logOwner.logger();
     }
 
     /* override nsteps with value from cmdline */
-    override_nsteps_cmdline(fplog, nsteps_cmdline, inputrec, cr);
+    override_nsteps_cmdline(mdlog, nsteps_cmdline, inputrec);
 
     if (SIMMASTER(cr))
     {
@@ -1061,19 +1084,20 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
 #if GMX_MPI
     if (MULTISIM(cr))
     {
-        md_print_info(cr, fplog,
-                      "This is simulation %d out of %d running as a composite GROMACS\n"
-                      "multi-simulation job. Setup for this simulation:\n\n",
-                      cr->ms->sim, cr->ms->nsim);
+        GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
+                "This is simulation %d out of %d running as a composite GROMACS\n"
+                "multi-simulation job. Setup for this simulation:\n",
+                cr->ms->sim, cr->ms->nsim);
     }
-    md_print_info(cr, fplog, "Using %d MPI %s\n",
-                  cr->nnodes,
+    GMX_LOG(mdlog.warning).appendTextFormatted(
+            "Using %d MPI %s\n",
+            cr->nnodes,
 #if GMX_THREAD_MPI
-                  cr->nnodes == 1 ? "thread" : "threads"
+            cr->nnodes == 1 ? "thread" : "threads"
 #else
-                  cr->nnodes == 1 ? "process" : "processes"
+            cr->nnodes == 1 ? "process" : "processes"
 #endif
-                  );
+            );
     fflush(stderr);
 #endif
 
@@ -1083,7 +1107,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
     /* Check and update hw_opt for the number of MPI ranks */
     check_and_update_hw_opt_3(hw_opt);
 
-    gmx_omp_nthreads_init(fplog, cr,
+    gmx_omp_nthreads_init(mdlog, cr,
                           hwinfo->nthreads_hw_avail,
                           hw_opt->nthreads_omp,
                           hw_opt->nthreads_omp_pme,
@@ -1101,7 +1125,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
     if (bUseGPU)
     {
         /* Select GPU id's to use */
-        gmx_select_gpu_ids(fplog, cr, &hwinfo->gpu_info, bForceUseGPU,
+        gmx_select_gpu_ids(mdlog, cr, &hwinfo->gpu_info, bForceUseGPU,
                            &hw_opt->gpu_opt);
     }
     else
@@ -1112,11 +1136,11 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
 
     /* check consistency across ranks of things like SIMD
      * support and number of GPUs selected */
-    gmx_check_hw_runconf_consistency(fplog, hwinfo, cr, hw_opt, bUseGPU);
+    gmx_check_hw_runconf_consistency(mdlog, hwinfo, cr, hw_opt, bUseGPU);
 
     /* Now that we know the setup is consistent, check for efficiency */
     check_resource_division_efficiency(hwinfo, hw_opt, Flags & MD_NTOMPSET,
-                                       cr, fplog);
+                                       cr, mdlog);
 
     if (DOMAINDECOMP(cr))
     {
@@ -1150,7 +1174,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
         fr          = mk_forcerec();
         fr->hwinfo  = hwinfo;
         fr->gpu_opt = &hw_opt->gpu_opt;
-        init_forcerec(fplog, fr, fcd, inputrec, mtop, cr, box,
+        init_forcerec(fplog, mdlog, fr, fcd, inputrec, mtop, cr, box,
                       opt2fn("-table", nfile, fnm),
                       opt2fn("-tablep", nfile, fnm),
                       opt2fn("-tableb", nfile, fnm),
@@ -1225,7 +1249,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
          * - which indicates that probably the OpenMP library has changed it
          * since we first checked).
          */
-        gmx_check_thread_affinity_set(fplog, cr,
+        gmx_check_thread_affinity_set(mdlog, cr,
                                       hw_opt, hwinfo->nthreads_hw_avail, TRUE);
 
         int nthread_local;
@@ -1240,7 +1264,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
         }
 
         /* Set the CPU affinity */
-        gmx_set_thread_affinity(fplog, cr, hw_opt, *hwinfo->hardwareTopology,
+        gmx_set_thread_affinity(fplog, mdlog, cr, hw_opt, *hwinfo->hardwareTopology,
                                 nthread_local, nullptr);
     }
 
@@ -1320,7 +1344,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
         }
 
         /* Now do whatever the user wants us to do (how flexible...) */
-        my_integrator(inputrec->eI) (fplog, cr, nfile, fnm,
+        my_integrator(inputrec->eI) (fplog, cr, mdlog, nfile, fnm,
                                      oenv, bVerbose,
                                      nstglobalcomm,
                                      vsite, constr,
@@ -1357,7 +1381,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
     /* Finish up, write some stuff
      * if rerunMD, don't write last frame again
      */
-    finish_run(fplog, cr,
+    finish_run(fplog, mdlog, cr,
                inputrec, nrnb, wcycle, walltime_accounting,
                fr ? fr->nbv : NULL,
                EI_DYNAMICS(inputrec->eI) && !MULTISIM(cr));