Add Oliver Fleetwood as a contributor
[alexxy/gromacs.git] / src / gromacs / utility / binaryinformation.cpp
index 47798cd9e240c85fa746b75fe4b0b727461aba7d..a1bff11d524a2330f316d6605217e4feb219c3e2 100644 (file)
@@ -3,7 +3,8 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
+ * Copyright (c) 2018,2019,2020,2021, 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.
 
 #if GMX_FFT_FFTW3 || GMX_FFT_ARMPL_FFTW3
 // Needed for construction of the FFT library description string
-#include <fftw3.h>
+#    include <fftw3.h>
 #endif
 
-#ifdef HAVE_LIBMKL
-#include <mkl.h>
+#if HAVE_LIBMKL
+#    include <mkl.h>
 #endif
 
 #if HAVE_EXTRAE
-#include <extrae_user_events.h>
+#    include <extrae_user_events.h>
 #endif
 
 #if GMX_USE_HWLOC
-#include <hwloc.h>
+#    include <hwloc.h>
 #endif
 
 #include <cstdio>
@@ -85,6 +86,7 @@
 #include "gromacs/utility/textwriter.h"
 
 #include "cuda_version_information.h"
+#include "sycl_version_information.h"
 
 namespace
 {
@@ -98,60 +100,63 @@ int centeringOffset(int width, int length)
     return std::max(width - length, 0) / 2;
 }
 
-std::string formatCentered(int width, const char *text)
+std::string formatCentered(int width, const chartext)
 {
     const int offset = centeringOffset(width, std::strlen(text));
     return formatString("%*s%s", offset, "", text);
 }
 
-void printCopyright(gmx::TextWriter *writer)
+void printCopyright(gmx::TextWriterwriter)
 {
-    static const char * const Contributors[] = {
-        "Emile Apol",
-        "Rossen Apostolov",
-        "Paul Bauer",
-        "Herman J.C. Berendsen",
-        "Par Bjelkmar",
-        "Christian Blau",
-        "Viacheslav Bolnykh",
-        "Kevin Boyd",
-        "Aldert van Buuren",
-        "Rudi van Drunen",
-        "Anton Feenstra",
-        "Alan Gray",
-        "Gerrit Groenhof",
-        "Anca Hamuraru",
-        "Vincent Hindriksen",
-        "M. Eric Irrgang",
-        "Aleksei Iupinov",
-        "Christoph Junghans",
-        "Joe Jordan",
-        "Dimitrios Karkoulis",
-        "Peter Kasson",
-        "Jiri Kraus",
-        "Carsten Kutzner",
-        "Per Larsson",
-        "Justin A. Lemkul",
-        "Viveca Lindahl",
-        "Magnus Lundborg",
-        "Erik Marklund",
-        "Pascal Merz",
-        "Pieter Meulenhoff",
-        "Teemu Murtola",
-        "Szilard Pall",
-        "Sander Pronk",
-        "Roland Schulz",
-        "Michael Shirts",
-        "Alexey Shvetsov",
-        "Alfons Sijbers",
-        "Peter Tieleman",
-        "Jon Vincent",
-        "Teemu Virolainen",
-        "Christian Wennberg",
-        "Maarten Wolf",
-        "Artem Zhmurov"
-    };
-    static const char * const CopyrightText[] = {
+    // Contributors sorted alphabetically by last name
+    static const char* const Contributors[]  = { "Andrey Alekseenko",
+                                                "Emile Apol",
+                                                "Rossen Apostolov",
+                                                "Paul Bauer",
+                                                "Herman J.C. Berendsen",
+                                                "Par Bjelkmar",
+                                                "Christian Blau",
+                                                "Viacheslav Bolnykh",
+                                                "Kevin Boyd",
+                                                "Aldert van Buuren",
+                                                "Rudi van Drunen",
+                                                "Anton Feenstra",
+                                                "Oliver Fleetwood",
+                                                "Gaurav Garg",
+                                                "Gilles Gouaillardet",
+                                                "Alan Gray",
+                                                "Gerrit Groenhof",
+                                                "Anca Hamuraru",
+                                                "Vincent Hindriksen",
+                                                "M. Eric Irrgang",
+                                                "Aleksei Iupinov",
+                                                "Christoph Junghans",
+                                                "Joe Jordan",
+                                                "Dimitrios Karkoulis",
+                                                "Peter Kasson",
+                                                "Jiri Kraus",
+                                                "Carsten Kutzner",
+                                                "Per Larsson",
+                                                "Justin A. Lemkul",
+                                                "Viveca Lindahl",
+                                                "Magnus Lundborg",
+                                                "Erik Marklund",
+                                                "Pascal Merz",
+                                                "Pieter Meulenhoff",
+                                                "Teemu Murtola",
+                                                "Szilard Pall",
+                                                "Sander Pronk",
+                                                "Roland Schulz",
+                                                "Michael Shirts",
+                                                "Alexey Shvetsov",
+                                                "Alfons Sijbers",
+                                                "Peter Tieleman",
+                                                "Jon Vincent",
+                                                "Teemu Virolainen",
+                                                "Christian Wennberg",
+                                                "Maarten Wolf",
+                                                "Artem Zhmurov" };
+    static const char* const CopyrightText[] = {
         "Copyright (c) 1991-2000, University of Groningen, The Netherlands.",
         "Copyright (c) 2001-2019, The GROMACS development team at",
         "Uppsala University, Stockholm University and",
@@ -164,23 +169,24 @@ void printCopyright(gmx::TextWriter *writer)
 
     // TODO a centering behaviour of TextWriter could be useful here
     writer->writeLine(formatCentered(78, "GROMACS is written by:"));
-    for (int i = 0; i < NCONTRIBUTORS; )
+    for (int i = 0; i < NCONTRIBUTORS;)
     {
-        for (int j = 0; j < 4 && i < NCONTRIBUTORS; ++j, ++i)
+        for (int j = 0; j < 3 && i < NCONTRIBUTORS; ++j, ++i)
         {
-            const int            width = 18;
+            const int            width = 26;
             std::array<char, 30> buf;
             const int            offset = centeringOffset(width, strlen(Contributors[i]));
             GMX_RELEASE_ASSERT(static_cast<int>(strlen(Contributors[i])) + offset < gmx::ssize(buf),
                                "Formatting buffer is not long enough");
-            std::fill(buf.begin(), buf.begin()+offset, ' ');
-            std::strncpy(buf.data()+offset, Contributors[i], gmx::ssize(buf) - offset);
+            std::fill(buf.begin(), buf.begin() + offset, ' ');
+            std::strncpy(buf.data() + offset, Contributors[i], gmx::ssize(buf) - offset);
             writer->writeString(formatString(" %-*s", width, buf.data()));
         }
         writer->ensureLineBreak();
     }
     writer->writeLine(formatCentered(78, "and the project leaders:"));
-    writer->writeLine(formatCentered(78, "Mark Abraham, Berk Hess, Erik Lindahl, and David van der Spoel"));
+    writer->writeLine(
+            formatCentered(78, "Mark Abraham, Berk Hess, Erik Lindahl, and David van der Spoel"));
     writer->ensureEmptyLine();
     for (int i = 0; i < NCR; ++i)
     {
@@ -200,22 +206,22 @@ void printCopyright(gmx::TextWriter *writer)
     }
 }
 
-// Construct a string that describes the library that provides FFT support to this build
-const char *getFftDescriptionString()
+//! Construct a string that describes the library that provides CPU FFT support to this build
+const char* getCpuFftDescriptionString()
 {
 // Define the FFT description string
 #if GMX_FFT_FFTW3 || GMX_FFT_ARMPL_FFTW3
-#  if GMX_NATIVE_WINDOWS
+#    if GMX_NATIVE_WINDOWS
     // Don't buy trouble
     return "fftw3";
-#  else
+#    else
     // Use the version string provided by libfftw3
-#    if GMX_DOUBLE
+#        if GMX_DOUBLE
     return fftw_version;
-#    else
+#        else
     return fftwf_version;
+#        endif
 #    endif
-#  endif
 #endif
 #if GMX_FFT_MKL
     return "Intel MKL";
@@ -225,36 +231,79 @@ const char *getFftDescriptionString()
 #endif
 };
 
-void gmx_print_version_info(gmx::TextWriter *writer)
+//! Construct a string that describes the library that provides GPU FFT support to this build
+const char* getGpuFftDescriptionString()
+{
+    if (GMX_GPU)
+    {
+        if (GMX_GPU_CUDA)
+        {
+            return "cuFFT";
+        }
+        else if (GMX_GPU_OPENCL)
+        {
+            return "clFFT";
+        }
+        else if (GMX_GPU_SYCL)
+        {
+            return "unknown";
+        }
+        else
+        {
+            GMX_RELEASE_ASSERT(false, "Unknown GPU configuration");
+            return "impossible";
+        }
+    }
+    else
+    {
+        return "none";
+    }
+};
+
+void gmx_print_version_info(gmx::TextWriter* writer)
 {
     writer->writeLine(formatString("GROMACS version:    %s", gmx_version()));
-    const char *const git_hash = gmx_version_git_full_hash();
+    const charconst git_hash = gmx_version_git_full_hash();
     if (git_hash[0] != '\0')
     {
         writer->writeLine(formatString("GIT SHA1 hash:      %s", git_hash));
     }
-    const char *const base_hash = gmx_version_git_central_base_hash();
+    const charconst base_hash = gmx_version_git_central_base_hash();
     if (base_hash[0] != '\0')
     {
         writer->writeLine(formatString("Branched from:      %s", base_hash));
     }
-    const char *const releaseSourceChecksum = gmxReleaseSourceChecksum();
-    const char *const currentSourceChecksum = gmxCurrentSourceChecksum();
+    const charconst releaseSourceChecksum = gmxReleaseSourceChecksum();
+    const charconst currentSourceChecksum = gmxCurrentSourceChecksum();
     if (releaseSourceChecksum[0] != '\0')
     {
         if (std::strcmp(releaseSourceChecksum, "NoChecksumFile") == 0)
         {
-            writer->writeLine(formatString("The source code this program was compiled from has not been verified because the reference checksum was missing during compilation. This means you have an incomplete GROMACS distribution, please make sure to download an intact source distribution and compile that before proceeding."));
+            writer->writeLine(formatString(
+                    "The source code this program was compiled from has not been verified because "
+                    "the reference checksum was missing during compilation. This means you have an "
+                    "incomplete GROMACS distribution, please make sure to download an intact "
+                    "source distribution and compile that before proceeding."));
             writer->writeLine(formatString("Computed checksum: %s", currentSourceChecksum));
         }
         else if (std::strcmp(releaseSourceChecksum, "NoPythonAvailable") == 0)
         {
-            writer->writeLine(formatString("Build source could not be verified, because the checksum could not be computed."));
+            writer->writeLine(
+                    formatString("Build source could not be verified, because the checksum could "
+                                 "not be computed."));
         }
         else if (std::strcmp(releaseSourceChecksum, currentSourceChecksum) != 0)
         {
-            writer->writeLine(formatString("This program has been built from source code that has been altered and does not match the code released as part of the official GROMACS version %s. If you did not intend to use an altered GROMACS version, make sure to download an intact source distribution and compile that before proceeding.", gmx_version()));
-            writer->writeLine(formatString("If you have modified the source code, you are strongly encouraged to set your custom version suffix (using -DGMX_VERSION_STRING_OF_FORK) which will can help later with scientific reproducibility but also when reporting bugs."));
+            writer->writeLine(formatString(
+                    "This program has been built from source code that has been altered and does "
+                    "not match the code released as part of the official GROMACS version %s. If "
+                    "you did not intend to use an altered GROMACS version, make sure to download "
+                    "an intact source distribution and compile that before proceeding.",
+                    gmx_version()));
+            writer->writeLine(formatString(
+                    "If you have modified the source code, you are strongly encouraged to set your "
+                    "custom version suffix (using -DGMX_VERSION_STRING_OF_FORK) which will can "
+                    "help later with scientific reproducibility but also when reporting bugs."));
             writer->writeLine(formatString("Release checksum: %s", releaseSourceChecksum));
             writer->writeLine(formatString("Computed checksum: %s", currentSourceChecksum));
         }
@@ -268,26 +317,34 @@ void gmx_print_version_info(gmx::TextWriter *writer)
 #if GMX_DOUBLE
     writer->writeLine("Precision:          double");
 #else
-    writer->writeLine("Precision:          single");
+    writer->writeLine("Precision:          mixed");
 #endif
-    writer->writeLine(formatString("Memory model:       %u bit", static_cast<unsigned>(8*sizeof(void *))));
+    writer->writeLine(formatString("Memory model:       %u bit", static_cast<unsigned>(8 * sizeof(void*))));
 
 #if GMX_THREAD_MPI
     writer->writeLine("MPI library:        thread_mpi");
 #elif GMX_MPI
+#    if HAVE_CUDA_AWARE_MPI
+    writer->writeLine("MPI library:        MPI (CUDA-aware)");
+#    else
     writer->writeLine("MPI library:        MPI");
+#    endif
 #else
     writer->writeLine("MPI library:        none");
 #endif
 #if GMX_OPENMP
-    writer->writeLine(formatString("OpenMP support:     enabled (GMX_OPENMP_MAX_THREADS = %d)", GMX_OPENMP_MAX_THREADS));
+    writer->writeLine(formatString("OpenMP support:     enabled (GMX_OPENMP_MAX_THREADS = %d)",
+                                   GMX_OPENMP_MAX_THREADS));
 #else
     writer->writeLine("OpenMP support:     disabled");
 #endif
     writer->writeLine(formatString("GPU support:        %s", getGpuImplementationString()));
     writer->writeLine(formatString("SIMD instructions:  %s", GMX_SIMD_STRING));
-    writer->writeLine(formatString("FFT library:        %s", getFftDescriptionString()));
-    writer->writeLine(formatString("RDTSCP usage:       %s", HAVE_RDTSCP ? "enabled" : "disabled"));
+    writer->writeLine(formatString("CPU FFT library:    %s", getCpuFftDescriptionString()));
+    writer->writeLine(formatString("GPU FFT library:    %s", getGpuFftDescriptionString()));
+#if GMX_TARGET_X86
+    writer->writeLine(formatString("RDTSCP usage:       %s", GMX_USE_RDTSCP ? "enabled" : "disabled"));
+#endif
 #if GMX_USE_TNG
     writer->writeLine("TNG support:        enabled");
 #else
@@ -301,7 +358,8 @@ void gmx_print_version_info(gmx::TextWriter *writer)
 #if HAVE_EXTRAE
     unsigned major, minor, revision;
     Extrae_get_version(&major, &minor, &revision);
-    writer->writeLine(formatString("Tracing support:    enabled. Using Extrae-%d.%d.%d", major, minor, revision));
+    writer->writeLine(formatString(
+            "Tracing support:    enabled. Using Extrae-%d.%d.%d", major, minor, revision));
 #else
     writer->writeLine("Tracing support:    disabled");
 #endif
@@ -311,25 +369,38 @@ void gmx_print_version_info(gmx::TextWriter *writer)
      * them. Can wait for later, as the master branch has ready code to do all
      * that. */
     writer->writeLine(formatString("C compiler:         %s", BUILD_C_COMPILER));
-    writer->writeLine(formatString("C compiler flags:   %s", BUILD_CFLAGS));
+    writer->writeLine(formatString(
+            "C compiler flags:   %s %s", BUILD_CFLAGS, CMAKE_BUILD_CONFIGURATION_C_FLAGS));
     writer->writeLine(formatString("C++ compiler:       %s", BUILD_CXX_COMPILER));
-    writer->writeLine(formatString("C++ compiler flags: %s", BUILD_CXXFLAGS));
-#ifdef HAVE_LIBMKL
+    writer->writeLine(formatString(
+            "C++ compiler flags: %s %s", BUILD_CXXFLAGS, CMAKE_BUILD_CONFIGURATION_CXX_FLAGS));
+#if HAVE_LIBMKL
     /* MKL might be used for LAPACK/BLAS even if FFTs use FFTW, so keep it separate */
-    writer->writeLine(formatString("Linked with Intel MKL version %d.%d.%d.",
-                                   __INTEL_MKL__, __INTEL_MKL_MINOR__, __INTEL_MKL_UPDATE__));
+    writer->writeLine(formatString(
+            "Intel MKL version:  %d.%d.%d", __INTEL_MKL__, __INTEL_MKL_MINOR__, __INTEL_MKL_UPDATE__));
 #endif
-#if GMX_GPU == GMX_GPU_OPENCL
+#if GMX_GPU_OPENCL
     writer->writeLine(formatString("OpenCL include dir: %s", OPENCL_INCLUDE_DIR));
     writer->writeLine(formatString("OpenCL library:     %s", OPENCL_LIBRARY));
     writer->writeLine(formatString("OpenCL version:     %s", OPENCL_VERSION_STRING));
 #endif
-#if GMX_GPU == GMX_GPU_CUDA
+#if GMX_GPU_CUDA
     writer->writeLine(formatString("CUDA compiler:      %s", CUDA_COMPILER_INFO));
-    writer->writeLine(formatString("CUDA compiler flags:%s", CUDA_COMPILER_FLAGS));
+    writer->writeLine(formatString(
+            "CUDA compiler flags:%s %s", CUDA_COMPILER_FLAGS, CMAKE_BUILD_CONFIGURATION_CXX_FLAGS));
     writer->writeLine("CUDA driver:        " + gmx::getCudaDriverVersionString());
     writer->writeLine("CUDA runtime:       " + gmx::getCudaRuntimeVersionString());
 #endif
+#if GMX_SYCL_DPCPP
+    writer->writeLine(formatString("SYCL DPC++ flags:   %s", SYCL_DPCPP_COMPILER_FLAGS));
+    writer->writeLine("SYCL DPC++ version: " + gmx::getSyclCompilerVersion());
+#endif
+#if GMX_SYCL_HIPSYCL
+    writer->writeLine(formatString("hipSYCL launcher:   %s", SYCL_HIPSYCL_COMPILER_LAUNCHER));
+    writer->writeLine(formatString("hipSYCL flags:      %s", SYCL_HIPSYCL_COMPILER_FLAGS));
+    writer->writeLine(formatString("hipSYCL targets:    %s", SYCL_HIPSYCL_TARGETS));
+    writer->writeLine("hipSYCL version:    " + gmx::getSyclCompilerVersion());
+#endif
 }
 
 //! \endcond
@@ -339,45 +410,47 @@ void gmx_print_version_info(gmx::TextWriter *writer)
 namespace gmx
 {
 
-BinaryInformationSettings::BinaryInformationSettings()
-    : bExtendedInfo_(false), bCopyright_(false),
-      bProcessId_(false),
-      bGeneratedByHeader_(false), prefix_(""), suffix_("")
+BinaryInformationSettings::BinaryInformationSettings() :
+    bExtendedInfo_(false),
+    bCopyright_(false),
+    bProcessId_(false),
+    bGeneratedByHeader_(false),
+    prefix_(""),
+    suffix_("")
 {
 }
 
-void printBinaryInformation(FILE                  *fp,
-                            const IProgramContext &programContext)
+void printBinaryInformation(FILE* fp, const IProgramContext& programContext)
 {
     TextWriter writer(fp);
     printBinaryInformation(&writer, programContext, BinaryInformationSettings());
 }
 
-void printBinaryInformation(FILE                            *fp,
-                            const IProgramContext           &programContext,
-                            const BinaryInformationSettings &settings)
+void printBinaryInformation(FILE*                            fp,
+                            const IProgramContext&           programContext,
+                            const BinaryInformationSettingssettings)
 {
     try
     {
         TextWriter writer(fp);
         printBinaryInformation(&writer, programContext, settings);
     }
-    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
+    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
 }
 
-void printBinaryInformation(TextWriter                      *writer,
-                            const IProgramContext           &programContext,
-                            const BinaryInformationSettings &settings)
+void printBinaryInformation(TextWriter*                      writer,
+                            const IProgramContext&           programContext,
+                            const BinaryInformationSettingssettings)
 {
     // TODO Perhaps the writer could be configured with the prefix and
     // suffix strings from the settings?
-    const char *prefix          = settings.prefix_;
-    const char *suffix          = settings.suffix_;
-    const char *precisionString = "";
+    const charprefix          = settings.prefix_;
+    const charsuffix          = settings.suffix_;
+    const charprecisionString = "";
 #if GMX_DOUBLE
     precisionString = " (double precision)";
 #endif
-    const char *const name = programContext.displayName();
+    const charconst name = programContext.displayName();
     if (settings.bGeneratedByHeader_)
     {
         writer->writeLine(formatString("%sCreated by:%s", prefix, suffix));
@@ -385,10 +458,9 @@ void printBinaryInformation(TextWriter                      *writer,
     // TODO: It would be nice to know here whether we are really running a
     // Gromacs binary or some other binary that is calling Gromacs; we
     // could then print "%s is part of GROMACS" or some alternative text.
-    std::string title
-        = formatString(":-) GROMACS - %s, %s%s (-:", name, gmx_version(), precisionString);
-    const int   indent
-        = centeringOffset(78 - std::strlen(prefix) - std::strlen(suffix), title.length()) + 1;
+    std::string title = formatString(":-) GROMACS - %s, %s%s (-:", name, gmx_version(), precisionString);
+    const int indent =
+            centeringOffset(78 - std::strlen(prefix) - std::strlen(suffix), title.length()) + 1;
     writer->writeLine(formatString("%s%*c%s%s", prefix, indent, ' ', title.c_str(), suffix));
     writer->writeLine(formatString("%s%s", prefix, suffix));
     if (settings.bCopyright_)
@@ -402,10 +474,10 @@ void printBinaryInformation(TextWriter                      *writer,
         // necessary to read stuff above the copyright notice.
         // The line above the copyright notice puts the copyright notice is
         // context, though.
-        writer->writeLine(formatString("%sGROMACS:      %s, version %s%s%s", prefix, name,
-                                       gmx_version(), precisionString, suffix));
+        writer->writeLine(formatString(
+                "%sGROMACS:      %s, version %s%s%s", prefix, name, gmx_version(), precisionString, suffix));
     }
-    const char *const binaryPath = programContext.fullBinaryPath();
+    const charconst binaryPath = programContext.fullBinaryPath();
     if (!gmx::isNullOrEmpty(binaryPath))
     {
         writer->writeLine(formatString("%sExecutable:   %s%s", prefix, binaryPath, suffix));
@@ -413,8 +485,11 @@ void printBinaryInformation(TextWriter                      *writer,
     const gmx::InstallationPrefixInfo installPrefix = programContext.installationPrefix();
     if (!gmx::isNullOrEmpty(installPrefix.path))
     {
-        writer->writeLine(formatString("%sData prefix:  %s%s%s", prefix, installPrefix.path,
-                                       installPrefix.bSourceLayout ? " (source tree)" : "", suffix));
+        writer->writeLine(formatString("%sData prefix:  %s%s%s",
+                                       prefix,
+                                       installPrefix.path,
+                                       installPrefix.bSourceLayout ? " (source tree)" : "",
+                                       suffix));
     }
     const std::string workingDir = Path::getWorkingDirectory();
     if (!workingDir.empty())
@@ -425,11 +500,11 @@ void printBinaryInformation(TextWriter                      *writer,
     {
         writer->writeLine(formatString("%sProcess ID:   %d%s", prefix, gmx_getpid(), suffix));
     }
-    const char *const commandLine = programContext.commandLine();
+    const charconst commandLine = programContext.commandLine();
     if (!gmx::isNullOrEmpty(commandLine))
     {
-        writer->writeLine(formatString("%sCommand line:%s\n%s  %s%s",
-                                       prefix, suffix, prefix, commandLine, suffix));
+        writer->writeLine(formatString(
+                "%sCommand line:%s\n%s  %s%s", prefix, suffix, prefix, commandLine, suffix));
     }
     if (settings.bExtendedInfo_)
     {