integrate platform sub-namespace into source code and documentation
this updates function calls to functions that have been moved from the utils namepsace or the Info class to platform::
This commit is contained in:
@ -435,6 +435,8 @@ INPUT = @LAMMPS_SOURCE_DIR@/utils.cpp \
|
|||||||
@LAMMPS_SOURCE_DIR@/my_pool_chunk.cpp \
|
@LAMMPS_SOURCE_DIR@/my_pool_chunk.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/my_pool_chunk.h \
|
@LAMMPS_SOURCE_DIR@/my_pool_chunk.h \
|
||||||
@LAMMPS_SOURCE_DIR@/math_eigen.h \
|
@LAMMPS_SOURCE_DIR@/math_eigen.h \
|
||||||
|
@LAMMPS_SOURCE_DIR@/platform.h \
|
||||||
|
@LAMMPS_SOURCE_DIR@/platform.cpp \
|
||||||
|
|
||||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||||
|
|||||||
@ -18,4 +18,5 @@ of time and requests from the LAMMPS user community.
|
|||||||
Developer_plugins
|
Developer_plugins
|
||||||
Developer_unittest
|
Developer_unittest
|
||||||
Classes
|
Classes
|
||||||
|
Developer_platform
|
||||||
Developer_utils
|
Developer_utils
|
||||||
|
|||||||
140
doc/src/Developer_platform.rst
Normal file
140
doc/src/Developer_platform.rst
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
Platform abstraction functions
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
The ``platform`` sub-namespace inside the ``LAMMPS_NS`` namespace
|
||||||
|
provides a collection of wrapper and convenience functions and utilities
|
||||||
|
that perform common tasks for which platform specific code would be
|
||||||
|
required or for which a more high-level abstraction would be convenient
|
||||||
|
and reduce duplicated code. This reduces redundant implementations and
|
||||||
|
encourages consistent behavior and thus has some overlap with the
|
||||||
|
:doc:`"utils" sub-namespace <Developer_utils>`.
|
||||||
|
|
||||||
|
Time functions
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. doxygenfunction:: cputime
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: walltime
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
Platform information functions
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. doxygenfunction:: os_info
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: compiler_info
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: cxx_standard
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: openmp_standard
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: mpi_vendor
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: mpi_info
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
|
||||||
|
File and path functions and global constants
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. doxygenvariable:: filepathsep
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenvariable:: pathvarsep
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: guesspath
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: path_basename
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: path_join
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: file_is_readable
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: is_console
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: path_is_directory
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: current_directory
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: list_directory
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: chdir
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: mkdir
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: rmdir
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: unlink
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
Standard I/O function wrappers
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. doxygenfunction:: ftell
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: fseek
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: ftruncate
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: popen
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: pclose
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
Environment variable functions
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. doxygenfunction:: putenv
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: list_pathenv
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: find_exe_path
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
Dynamically loaded object or library functions
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. doxygenfunction:: dlopen
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: dlclose
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: dlsym
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
Compressed file I/O functions
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. doxygenfunction:: has_zip_extension
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: zip_read
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: zip_write
|
||||||
|
:project: progguide
|
||||||
@ -7,7 +7,9 @@ a collection of convenience functions and utilities that perform common
|
|||||||
tasks that are required repeatedly throughout the LAMMPS code like
|
tasks that are required repeatedly throughout the LAMMPS code like
|
||||||
reading or writing to files with error checking or translation of
|
reading or writing to files with error checking or translation of
|
||||||
strings into specific types of numbers with checking for validity. This
|
strings into specific types of numbers with checking for validity. This
|
||||||
reduces redundant implementations and encourages consistent behavior.
|
reduces redundant implementations and encourages consistent behavior and
|
||||||
|
thus has some overlap with the :doc:`"platform" sub-namespace
|
||||||
|
<Developer_platform>`.
|
||||||
|
|
||||||
I/O with status check and similar functions
|
I/O with status check and similar functions
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -143,21 +145,6 @@ and parsing files or arguments.
|
|||||||
.. doxygenfunction:: is_double
|
.. doxygenfunction:: is_double
|
||||||
:project: progguide
|
:project: progguide
|
||||||
|
|
||||||
File and path functions
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
.. doxygenfunction:: guesspath
|
|
||||||
:project: progguide
|
|
||||||
|
|
||||||
.. doxygenfunction:: path_basename
|
|
||||||
:project: progguide
|
|
||||||
|
|
||||||
.. doxygenfunction:: path_join
|
|
||||||
:project: progguide
|
|
||||||
|
|
||||||
.. doxygenfunction:: file_is_readable
|
|
||||||
:project: progguide
|
|
||||||
|
|
||||||
Potential file functions
|
Potential file functions
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@ -57,7 +57,7 @@ velocities. See the doc pages for the individual fixes and for the
|
|||||||
assign a temperature compute to a thermostatting fix.
|
assign a temperature compute to a thermostatting fix.
|
||||||
|
|
||||||
For example, you can apply a thermostat only to atoms in a spatial
|
For example, you can apply a thermostat only to atoms in a spatial
|
||||||
region by using it in conjuction with :doc:`compute temp/region
|
region by using it in conjunction with :doc:`compute temp/region
|
||||||
<compute_temp_region>`. Or you can apply a thermostat to only the x
|
<compute_temp_region>`. Or you can apply a thermostat to only the x
|
||||||
and z components of velocity by using it with :doc:`compute
|
and z components of velocity by using it with :doc:`compute
|
||||||
temp/partial <compute_temp_partial>`. Of you could thermostat only
|
temp/partial <compute_temp_partial>`. Of you could thermostat only
|
||||||
|
|||||||
@ -1135,6 +1135,7 @@ Germann
|
|||||||
Germano
|
Germano
|
||||||
gerolf
|
gerolf
|
||||||
Gerolf
|
Gerolf
|
||||||
|
getrusage
|
||||||
Gershgorin
|
Gershgorin
|
||||||
getter
|
getter
|
||||||
gettimeofday
|
gettimeofday
|
||||||
@ -1809,6 +1810,7 @@ lyon
|
|||||||
Lysogorskiy
|
Lysogorskiy
|
||||||
Lyulin
|
Lyulin
|
||||||
lz
|
lz
|
||||||
|
lzma
|
||||||
Maaravi
|
Maaravi
|
||||||
MACHDYN
|
MACHDYN
|
||||||
machdyn
|
machdyn
|
||||||
@ -2762,6 +2764,7 @@ REAXFF
|
|||||||
ReaxFF
|
ReaxFF
|
||||||
reaxff
|
reaxff
|
||||||
rebo
|
rebo
|
||||||
|
recurse
|
||||||
recursing
|
recursing
|
||||||
Ree
|
Ree
|
||||||
refactored
|
refactored
|
||||||
|
|||||||
@ -274,7 +274,7 @@ void DumpNetCDF::openfile()
|
|||||||
if (append_flag && !multifile) {
|
if (append_flag && !multifile) {
|
||||||
// Fixme! Perform checks if dimensions and variables conform with
|
// Fixme! Perform checks if dimensions and variables conform with
|
||||||
// data structure standard.
|
// data structure standard.
|
||||||
if (not utils::file_is_readable(filecurrent))
|
if (not platform::file_is_readable(filecurrent))
|
||||||
error->all(FLERR, "cannot append to non-existent file {}",filecurrent);
|
error->all(FLERR, "cannot append to non-existent file {}",filecurrent);
|
||||||
|
|
||||||
if (singlefile_opened) return;
|
if (singlefile_opened) return;
|
||||||
|
|||||||
@ -272,7 +272,7 @@ void DumpNetCDFMPIIO::openfile()
|
|||||||
if (append_flag && !multifile) {
|
if (append_flag && !multifile) {
|
||||||
// Fixme! Perform checks if dimensions and variables conform with
|
// Fixme! Perform checks if dimensions and variables conform with
|
||||||
// data structure standard.
|
// data structure standard.
|
||||||
if (not utils::file_is_readable(filecurrent))
|
if (not platform::file_is_readable(filecurrent))
|
||||||
error->all(FLERR, "cannot append to non-existent file {}", filecurrent);
|
error->all(FLERR, "cannot append to non-existent file {}", filecurrent);
|
||||||
|
|
||||||
MPI_Offset index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS];
|
MPI_Offset index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS];
|
||||||
|
|||||||
@ -270,7 +270,7 @@ void Bond::write_file(int narg, char **arg)
|
|||||||
// write out a line with "DATE:" and "UNITS:" tags
|
// write out a line with "DATE:" and "UNITS:" tags
|
||||||
// - if the file already exists, print a message about appending
|
// - if the file already exists, print a message about appending
|
||||||
// while printing the date and check that units are consistent.
|
// while printing the date and check that units are consistent.
|
||||||
if (utils::file_is_readable(table_file)) {
|
if (platform::file_is_readable(table_file)) {
|
||||||
std::string units = utils::get_potential_units(table_file,"table");
|
std::string units = utils::get_potential_units(table_file,"table");
|
||||||
if (!units.empty() && (units != update->unit_style)) {
|
if (!units.empty() && (units != update->unit_style)) {
|
||||||
error->one(FLERR,"Trying to append to a table file with UNITS: {} while units are {}",
|
error->one(FLERR,"Trying to append to a table file with UNITS: {} while units are {}",
|
||||||
|
|||||||
200
src/info.cpp
200
src/info.cpp
@ -282,7 +282,7 @@ void Info::command(int narg, char **arg)
|
|||||||
fmt::print(out,"Git info: {} / {} / {}\n",
|
fmt::print(out,"Git info: {} / {} / {}\n",
|
||||||
lmp->git_branch, lmp->git_descriptor,lmp->git_commit);
|
lmp->git_branch, lmp->git_descriptor,lmp->git_commit);
|
||||||
|
|
||||||
fmt::print(out,"\nOS information: {}\n\n",get_os_info());
|
fmt::print(out,"\nOS information: {}\n\n",platform::os_info());
|
||||||
|
|
||||||
fmt::print(out,"sizeof(smallint): {}-bit\n"
|
fmt::print(out,"sizeof(smallint): {}-bit\n"
|
||||||
"sizeof(imageint): {}-bit\n"
|
"sizeof(imageint): {}-bit\n"
|
||||||
@ -292,7 +292,7 @@ void Info::command(int narg, char **arg)
|
|||||||
sizeof(tagint)*8, sizeof(bigint)*8);
|
sizeof(tagint)*8, sizeof(bigint)*8);
|
||||||
|
|
||||||
fmt::print(out,"\nCompiler: {} with {}\nC++ standard: {}\n",
|
fmt::print(out,"\nCompiler: {} with {}\nC++ standard: {}\n",
|
||||||
get_compiler_info(),get_openmp_info(),get_cxx_info());
|
platform::compiler_info(),platform::openmp_standard(),platform::cxx_standard());
|
||||||
|
|
||||||
fputs("\nActive compile time flags:\n\n",out);
|
fputs("\nActive compile time flags:\n\n",out);
|
||||||
if (has_gzip_support()) fputs("-DLAMMPS_GZIP\n",out);
|
if (has_gzip_support()) fputs("-DLAMMPS_GZIP\n",out);
|
||||||
@ -353,7 +353,7 @@ void Info::command(int narg, char **arg)
|
|||||||
|
|
||||||
if (flags & COMM) {
|
if (flags & COMM) {
|
||||||
int major,minor;
|
int major,minor;
|
||||||
std::string version = get_mpi_info(major,minor);
|
std::string version = platform::mpi_info(major,minor);
|
||||||
|
|
||||||
fmt::print(out,"\nCommunication information:\n"
|
fmt::print(out,"\nCommunication information:\n"
|
||||||
"MPI library level: MPI v{}.{}\n"
|
"MPI library level: MPI v{}.{}\n"
|
||||||
@ -1266,200 +1266,6 @@ bool Info::has_accelerator_feature(const std::string &package,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
#define _INFOBUF_SIZE 256
|
|
||||||
|
|
||||||
std::string Info::get_os_info()
|
|
||||||
{
|
|
||||||
std::string buf;
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
DWORD fullversion,majorv,minorv,buildv=0;
|
|
||||||
|
|
||||||
fullversion = GetVersion();
|
|
||||||
majorv = (DWORD) (LOBYTE(LOWORD(fullversion)));
|
|
||||||
minorv = (DWORD) (HIBYTE(LOWORD(fullversion)));
|
|
||||||
if (fullversion < 0x80000000)
|
|
||||||
buildv = (DWORD) (HIWORD(fullversion));
|
|
||||||
|
|
||||||
buf = fmt::format("Windows {}.{} ({}) on ",majorv,minorv,buildv);
|
|
||||||
|
|
||||||
SYSTEM_INFO si;
|
|
||||||
GetSystemInfo(&si);
|
|
||||||
|
|
||||||
switch (si.wProcessorArchitecture) {
|
|
||||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
|
||||||
buf += "x86_64";
|
|
||||||
break;
|
|
||||||
case PROCESSOR_ARCHITECTURE_ARM:
|
|
||||||
buf += "arm";
|
|
||||||
break;
|
|
||||||
case PROCESSOR_ARCHITECTURE_IA64:
|
|
||||||
buf += "ia64";
|
|
||||||
break;
|
|
||||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
|
||||||
buf += "i386";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
buf += "(unknown)";
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
struct utsname ut;
|
|
||||||
uname(&ut);
|
|
||||||
|
|
||||||
// try to get OS distribution name, if available
|
|
||||||
std::string distro = ut.sysname;
|
|
||||||
if (utils::file_is_readable("/etc/os-release")) {
|
|
||||||
try {
|
|
||||||
TextFileReader reader("/etc/os-release","");
|
|
||||||
while (1) {
|
|
||||||
auto words = reader.next_values(0,"=");
|
|
||||||
if ((words.count() > 1) && (words.next_string() == "PRETTY_NAME")) {
|
|
||||||
distro += " " + utils::trim(words.next_string());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (std::exception &e) {
|
|
||||||
; // EOF but keyword not found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = fmt::format("{} {} on {}", distro, ut.release, ut.machine);
|
|
||||||
#endif
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Info::get_compiler_info()
|
|
||||||
{
|
|
||||||
std::string buf;
|
|
||||||
#if defined(__INTEL_LLVM_COMPILER)
|
|
||||||
constexpr double version = static_cast<double>(__INTEL_LLVM_COMPILER)*0.01;
|
|
||||||
buf = fmt::format("Intel LLVM C++ {:.1f} / {}", version, __VERSION__);
|
|
||||||
#elif defined(__ibmxl__)
|
|
||||||
buf = fmt::format("IBM XL C/C++ (Clang) {}.{}.{}",
|
|
||||||
__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__);
|
|
||||||
#elif defined(__clang__)
|
|
||||||
buf = fmt::format("Clang C++ {}", __VERSION__);
|
|
||||||
#elif defined(__PGI)
|
|
||||||
buf = fmt::format("PGI C++ {}.{}",__PGIC__, __PGIC_MINOR__);
|
|
||||||
#elif defined(__INTEL_COMPILER)
|
|
||||||
double version = static_cast<double>(__INTEL_COMPILER)*0.01;
|
|
||||||
buf = fmt::format("Intel Classic C++ {:.2f}.{} / {}", version,
|
|
||||||
__INTEL_COMPILER_UPDATE, __VERSION__);
|
|
||||||
#elif defined(__MINGW64__)
|
|
||||||
buf = fmt::format("MinGW-w64 64bit {}.{} / GNU C++ {}", __MINGW64_VERSION_MAJOR,
|
|
||||||
__MINGW64_VERSION_MINOR, __VERSION__);
|
|
||||||
#elif defined(__MINGW32__)
|
|
||||||
buf = fmt::format("MinGW-w64 32bit {}.{} / GNU C++ {}", __MINGW32_MAJOR_VERSION,
|
|
||||||
__MINGW32_MINOR_VERSION, __VERSION__);
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
buf = fmt::format("GNU C++ {}", __VERSION__);
|
|
||||||
#elif defined(_MSC_VER) && (_MSC_VER > 1920) && (_MSC_VER < 2000)
|
|
||||||
constexpr int major = _MSC_VER / 100;
|
|
||||||
constexpr int minor = _MSC_VER - major *100;
|
|
||||||
buf = fmt::format("Microsoft Visual Studio 20{}, C/C++ {}.{}", major, major-5, minor);
|
|
||||||
#else
|
|
||||||
buf = "(Unknown)";
|
|
||||||
#endif
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Info::get_openmp_info()
|
|
||||||
{
|
|
||||||
|
|
||||||
#if !defined(_OPENMP)
|
|
||||||
return "OpenMP not enabled";
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Supported OpenMP version corresponds to the release date of the
|
|
||||||
// specifications as posted at https://www.openmp.org/specifications/
|
|
||||||
|
|
||||||
#if _OPENMP > 202011
|
|
||||||
return "OpenMP newer than version 5.1";
|
|
||||||
#elif _OPENMP == 202011
|
|
||||||
return "OpenMP 5.1";
|
|
||||||
#elif _OPENMP == 201811
|
|
||||||
return "OpenMP 5.0";
|
|
||||||
#elif _OPENMP == 201611
|
|
||||||
return "OpenMP 5.0 preview 1";
|
|
||||||
#elif _OPENMP == 201511
|
|
||||||
return "OpenMP 4.5";
|
|
||||||
#elif _OPENMP == 201307
|
|
||||||
return "OpenMP 4.0";
|
|
||||||
#elif _OPENMP == 201107
|
|
||||||
return "OpenMP 3.1";
|
|
||||||
#elif _OPENMP == 200805
|
|
||||||
return "OpenMP 3.0";
|
|
||||||
#elif _OPENMP == 200505
|
|
||||||
return "OpenMP 2.5";
|
|
||||||
#elif _OPENMP == 200203
|
|
||||||
return "OpenMP 2.0";
|
|
||||||
#else
|
|
||||||
return "unknown OpenMP version";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Info::get_mpi_vendor() {
|
|
||||||
#if defined(MPI_STUBS)
|
|
||||||
return "MPI STUBS";
|
|
||||||
#elif defined(OPEN_MPI)
|
|
||||||
return "Open MPI";
|
|
||||||
#elif defined(MPICH_NAME)
|
|
||||||
return "MPICH";
|
|
||||||
#elif defined(I_MPI_VERSION)
|
|
||||||
return "Intel MPI";
|
|
||||||
#elif defined(PLATFORM_MPI)
|
|
||||||
return "Platform MPI";
|
|
||||||
#elif defined(HP_MPI)
|
|
||||||
return "HP MPI";
|
|
||||||
#elif defined(MSMPI_VER)
|
|
||||||
return "Microsoft MPI";
|
|
||||||
#else
|
|
||||||
return "Unknown MPI implementation";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Info::get_mpi_info(int &major, int &minor)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
#if (defined(MPI_VERSION) && (MPI_VERSION > 2)) || defined(MPI_STUBS)
|
|
||||||
static char version[MPI_MAX_LIBRARY_VERSION_STRING];
|
|
||||||
MPI_Get_library_version(version,&len);
|
|
||||||
#else
|
|
||||||
static char version[32];
|
|
||||||
strcpy(version,get_mpi_vendor().c_str());
|
|
||||||
len = strlen(version);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MPI_Get_version(&major,&minor);
|
|
||||||
if (len > 80) {
|
|
||||||
char *ptr = strchr(version+80,'\n');
|
|
||||||
if (ptr) *ptr = '\0';
|
|
||||||
}
|
|
||||||
return std::string(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Info::get_cxx_info()
|
|
||||||
{
|
|
||||||
#if __cplusplus > 202002L
|
|
||||||
return "newer than C++20";
|
|
||||||
#elif __cplusplus == 202002L
|
|
||||||
return "C++20";
|
|
||||||
#elif __cplusplus == 201703L
|
|
||||||
return "C++17";
|
|
||||||
#elif __cplusplus == 201402L
|
|
||||||
return "C++14";
|
|
||||||
#elif __cplusplus == 201103L
|
|
||||||
return "C++11";
|
|
||||||
#elif __cplusplus == 199711L
|
|
||||||
return "C++98";
|
|
||||||
#else
|
|
||||||
return "unknown";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Info::get_accelerator_info(const std::string &package)
|
std::string Info::get_accelerator_info(const std::string &package)
|
||||||
{
|
{
|
||||||
std::string mesg("");
|
std::string mesg("");
|
||||||
|
|||||||
@ -48,13 +48,6 @@ class Info : public Command {
|
|||||||
const std::string &);
|
const std::string &);
|
||||||
static bool has_gpu_device();
|
static bool has_gpu_device();
|
||||||
static std::string get_gpu_device_info();
|
static std::string get_gpu_device_info();
|
||||||
|
|
||||||
static std::string get_os_info();
|
|
||||||
static std::string get_compiler_info();
|
|
||||||
static std::string get_openmp_info();
|
|
||||||
static std::string get_mpi_vendor();
|
|
||||||
static std::string get_mpi_info(int &, int &);
|
|
||||||
static std::string get_cxx_info();
|
|
||||||
static std::string get_accelerator_info(const std::string &pkg = "");
|
static std::string get_accelerator_info(const std::string &pkg = "");
|
||||||
|
|
||||||
void get_memory_info(double *);
|
void get_memory_info(double *);
|
||||||
|
|||||||
@ -1340,14 +1340,14 @@ void LAMMPS::print_config(FILE *fp)
|
|||||||
const char *pkg;
|
const char *pkg;
|
||||||
int ncword, ncline = 0;
|
int ncword, ncline = 0;
|
||||||
|
|
||||||
fmt::print(fp,"OS: {}\n\n",Info::get_os_info());
|
fmt::print(fp,"OS: {}\n\n",platform::os_info());
|
||||||
|
|
||||||
fmt::print(fp,"Compiler: {} with {}\nC++ standard: {}\n",
|
fmt::print(fp,"Compiler: {} with {}\nC++ standard: {}\n",
|
||||||
Info::get_compiler_info(),Info::get_openmp_info(),
|
platform::compiler_info(),platform::openmp_standard(),
|
||||||
Info::get_cxx_info());
|
platform::cxx_standard());
|
||||||
|
|
||||||
int major,minor;
|
int major,minor;
|
||||||
std::string infobuf = Info::get_mpi_info(major,minor);
|
std::string infobuf = platform::mpi_info(major,minor);
|
||||||
fmt::print(fp,"MPI v{}.{}: {}\n\n",major,minor,infobuf);
|
fmt::print(fp,"MPI v{}.{}: {}\n\n",major,minor,infobuf);
|
||||||
|
|
||||||
fmt::print(fp,"Accelerator configuration:\n\n{}\n",
|
fmt::print(fp,"Accelerator configuration:\n\n{}\n",
|
||||||
|
|||||||
@ -4394,9 +4394,9 @@ void lammps_get_os_info(char *buffer, int buf_size)
|
|||||||
{
|
{
|
||||||
if (buf_size <=0) return;
|
if (buf_size <=0) return;
|
||||||
buffer[0] = buffer[buf_size-1] = '\0';
|
buffer[0] = buffer[buf_size-1] = '\0';
|
||||||
std::string txt = Info::get_os_info() + "\n";
|
std::string txt = platform::os_info() + "\n";
|
||||||
txt += Info::get_compiler_info();
|
txt += platform::compiler_info();
|
||||||
txt += " with " + Info::get_openmp_info() + "\n";
|
txt += " with " + platform::openmp_standard() + "\n";
|
||||||
strncpy(buffer, txt.c_str(), buf_size-1);
|
strncpy(buffer, txt.c_str(), buf_size-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1799,7 +1799,7 @@ void Pair::write_file(int narg, char **arg)
|
|||||||
// write out a line with "DATE:" and "UNITS:" tags
|
// write out a line with "DATE:" and "UNITS:" tags
|
||||||
// - if the file already exists, print a message about appending
|
// - if the file already exists, print a message about appending
|
||||||
// while printing the date and check that units are consistent.
|
// while printing the date and check that units are consistent.
|
||||||
if (utils::file_is_readable(table_file)) {
|
if (platform::file_is_readable(table_file)) {
|
||||||
std::string units = utils::get_potential_units(table_file,"table");
|
std::string units = utils::get_potential_units(table_file,"table");
|
||||||
if (!units.empty() && (units != update->unit_style)) {
|
if (!units.empty() && (units != update->unit_style)) {
|
||||||
error->one(FLERR,"Trying to append to a table file "
|
error->one(FLERR,"Trying to append to a table file "
|
||||||
|
|||||||
@ -224,7 +224,7 @@ std::string platform::os_info()
|
|||||||
buf = ut.sysname;
|
buf = ut.sysname;
|
||||||
|
|
||||||
#if 0 // disable until this is integrated into LAMMPS and TextFileReader becomes available
|
#if 0 // disable until this is integrated into LAMMPS and TextFileReader becomes available
|
||||||
if (utils::file_is_readable("/etc/os-release")) {
|
if (platform::file_is_readable("/etc/os-release")) {
|
||||||
try {
|
try {
|
||||||
TextFileReader reader("/etc/os-release","");
|
TextFileReader reader("/etc/os-release","");
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -275,7 +275,6 @@ std::string platform::cxx_standard()
|
|||||||
std::string platform::compiler_info()
|
std::string platform::compiler_info()
|
||||||
{
|
{
|
||||||
std::string buf = "(Unknown)";
|
std::string buf = "(Unknown)";
|
||||||
#if 0 // disable for now untile merged into LAMMPS and fmt:: becomes available
|
|
||||||
#if defined(__INTEL_LLVM_COMPILER)
|
#if defined(__INTEL_LLVM_COMPILER)
|
||||||
double version = static_cast<double>(__INTEL_LLVM_COMPILER)*0.01;
|
double version = static_cast<double>(__INTEL_LLVM_COMPILER)*0.01;
|
||||||
buf = fmt::format("Intel LLVM C++ {:.1f} / {}", version, __VERSION__);
|
buf = fmt::format("Intel LLVM C++ {:.1f} / {}", version, __VERSION__);
|
||||||
@ -304,7 +303,6 @@ std::string platform::compiler_info()
|
|||||||
buf = "Microsoft Visual Studio 20" + std::to_string(major) + ", C/C++ " + std::to_string(major-5) + "." + std::to_string(minor);
|
buf = "Microsoft Visual Studio 20" + std::to_string(major) + ", C/C++ " + std::to_string(major-5) + "." + std::to_string(minor);
|
||||||
#else
|
#else
|
||||||
buf = "(Unknown)";
|
buf = "(Unknown)";
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -543,9 +541,9 @@ void *platform::dlsym(void *handle, const std::string &symbol)
|
|||||||
|
|
||||||
/** On Linux the folder /proc/self/fd holds symbolic links to the actual
|
/** On Linux the folder /proc/self/fd holds symbolic links to the actual
|
||||||
* pathnames associated with each open file descriptor of the current process.
|
* pathnames associated with each open file descriptor of the current process.
|
||||||
* On macOS the same kind of information can be obtained using ``fcntl(fd,F_GETPATH,buf)``.
|
* On MacOS the same kind of information can be obtained using ``fcntl(fd,F_GETPATH,buf)``.
|
||||||
* On Windows we use ``GetFinalPathNameByHandleA()`` which is available with
|
* On Windows we use ``GetFinalPathNameByHandleA()`` which is available with
|
||||||
* Windows Vista and later. If the buffer is to small (< 16 bytes) a null pointer is returned.
|
* Windows Vista and later. If the buffer is too small (< 16 bytes) a null pointer is returned.
|
||||||
*
|
*
|
||||||
* This function is used to provide a filename with error messages in functions
|
* This function is used to provide a filename with error messages in functions
|
||||||
* where the filename is not passed as an argument, but the FILE * pointer. */
|
* where the filename is not passed as an argument, but the FILE * pointer. */
|
||||||
|
|||||||
@ -125,7 +125,7 @@ namespace platform {
|
|||||||
* after this call
|
* after this call
|
||||||
*
|
*
|
||||||
* \param handle handle to an opened shared object
|
* \param handle handle to an opened shared object
|
||||||
* \return 0 if succesful, non-zero of not */
|
* \return 0 if successful, non-zero of not */
|
||||||
|
|
||||||
int dlclose(void *handle);
|
int dlclose(void *handle);
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ namespace platform {
|
|||||||
|
|
||||||
/*! Try to detect pathname from FILE pointer.
|
/*! Try to detect pathname from FILE pointer.
|
||||||
*
|
*
|
||||||
* Currently only supported on Linux and macOS, otherwise will report "(unknown)".
|
* Currently only supported on Linux and MacOS, otherwise will report "(unknown)".
|
||||||
*
|
*
|
||||||
* \param fp FILE pointer struct from STDIO library for which we want to detect the name
|
* \param fp FILE pointer struct from STDIO library for which we want to detect the name
|
||||||
* \param buf storage buffer for pathname. output will be truncated if not large enough
|
* \param buf storage buffer for pathname. output will be truncated if not large enough
|
||||||
@ -193,7 +193,7 @@ namespace platform {
|
|||||||
* This provides a list of strings of the entries in the directory
|
* This provides a list of strings of the entries in the directory
|
||||||
* without the leading path name while also skipping over ".." and ".".
|
* without the leading path name while also skipping over ".." and ".".
|
||||||
*
|
*
|
||||||
* \param path path to directory
|
* \param dir path to directory
|
||||||
* \return vector with strings of all directory entries */
|
* \return vector with strings of all directory entries */
|
||||||
|
|
||||||
std::vector<std::string> list_directory(const std::string &dir);
|
std::vector<std::string> list_directory(const std::string &dir);
|
||||||
@ -203,7 +203,7 @@ namespace platform {
|
|||||||
* This function will traverse the list of directories in the PATH
|
* This function will traverse the list of directories in the PATH
|
||||||
* environment variable and look for the executable *cmd*. If the
|
* environment variable and look for the executable *cmd*. If the
|
||||||
* file exists and is executable the full path is returned as string,
|
* file exists and is executable the full path is returned as string,
|
||||||
* otherwise and emptry string is returned.
|
* otherwise and empty string is returned.
|
||||||
*
|
*
|
||||||
* On Windows the *cmd* string must not include and extension as
|
* On Windows the *cmd* string must not include and extension as
|
||||||
* this function will automatically append the extensions ".exe",
|
* this function will automatically append the extensions ".exe",
|
||||||
@ -268,7 +268,7 @@ namespace platform {
|
|||||||
|
|
||||||
int fseek(FILE *fp, bigint pos);
|
int fseek(FILE *fp, bigint pos);
|
||||||
|
|
||||||
/*! Truncate file to a given length and reposition file pointer
|
/*! Truncate file to a given length and re-position file pointer
|
||||||
*
|
*
|
||||||
* \param fp FILE pointer of the given file
|
* \param fp FILE pointer of the given file
|
||||||
* \param length length to which the file is being truncated to
|
* \param length length to which the file is being truncated to
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
#include "lammps.h" // IWYU pragma: export
|
#include "lammps.h" // IWYU pragma: export
|
||||||
#include "utils.h" // IWYU pragma: export
|
#include "utils.h" // IWYU pragma: export
|
||||||
#include "fmt/format.h" // IWYU pragma: export
|
#include "fmt/format.h" // IWYU pragma: export
|
||||||
|
#include "platform.h" // IWYU pragma: export
|
||||||
|
|
||||||
namespace LAMMPS_NS {
|
namespace LAMMPS_NS {
|
||||||
|
|
||||||
|
|||||||
@ -308,7 +308,7 @@ void ReadData::command(int narg, char **arg)
|
|||||||
|
|
||||||
// check if data file is available and readable
|
// check if data file is available and readable
|
||||||
|
|
||||||
if (!utils::file_is_readable(arg[0]))
|
if (!platform::file_is_readable(arg[0]))
|
||||||
error->all(FLERR,fmt::format("Cannot open file {}: {}",
|
error->all(FLERR,fmt::format("Cannot open file {}: {}",
|
||||||
arg[0], utils::getsyserror()));
|
arg[0], utils::getsyserror()));
|
||||||
|
|
||||||
|
|||||||
@ -540,8 +540,8 @@ std::string ReadRestart::file_search(const std::string &inpfile)
|
|||||||
{
|
{
|
||||||
// separate inpfile into dir + filename
|
// separate inpfile into dir + filename
|
||||||
|
|
||||||
auto dirname = utils::path_dirname(inpfile);
|
auto dirname = platform::path_dirname(inpfile);
|
||||||
auto filename = utils::path_basename(inpfile);
|
auto filename = platform::path_basename(inpfile);
|
||||||
|
|
||||||
// if filename contains "%" replace "%" with "base"
|
// if filename contains "%" replace "%" with "base"
|
||||||
|
|
||||||
@ -574,7 +574,7 @@ std::string ReadRestart::file_search(const std::string &inpfile)
|
|||||||
if (maxnum < 0) error->one(FLERR,"Found no restart file matching pattern");
|
if (maxnum < 0) error->one(FLERR,"Found no restart file matching pattern");
|
||||||
filename.replace(filename.find('*'),1,std::to_string(maxnum));
|
filename.replace(filename.find('*'),1,std::to_string(maxnum));
|
||||||
}
|
}
|
||||||
return utils::path_join(dirname,filename);
|
return platform::path_join(dirname,filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
|
|||||||
119
src/utils.cpp
119
src/utils.cpp
@ -165,44 +165,6 @@ std::string utils::getsyserror()
|
|||||||
return std::string(strerror(errno));
|
return std::string(strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** On Linux the folder /proc/self/fd holds symbolic links to the actual
|
|
||||||
* pathnames associated with each open file descriptor of the current process.
|
|
||||||
* On MacOS the same kind of information can be obtained using ``fcntl(fd,F_GETPATH,buf)``.
|
|
||||||
* On Windows we use ``GetFinalPathNameByHandleA()`` which is available with
|
|
||||||
* Windows Vista and later.
|
|
||||||
*
|
|
||||||
* This function is used to provide a filename with error messages in functions
|
|
||||||
* where the filename is not passed as an argument, but the FILE * pointer.
|
|
||||||
*/
|
|
||||||
const char *utils::guesspath(char *buf, int len, FILE *fp)
|
|
||||||
{
|
|
||||||
memset(buf, 0, len);
|
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
int fd = fileno(fp);
|
|
||||||
// get pathname from /proc or copy (unknown)
|
|
||||||
if (readlink(fmt::format("/proc/self/fd/{}", fd).c_str(), buf, len - 1) <= 0)
|
|
||||||
strncpy(buf, "(unknown)", len - 1);
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
int fd = fileno(fp);
|
|
||||||
char filepath[PATH_MAX];
|
|
||||||
if (fcntl(fd, F_GETPATH, filepath) != -1)
|
|
||||||
strncpy(buf, filepath, len - 1);
|
|
||||||
else
|
|
||||||
strncpy(buf, "(unknown)", len - 1);
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
char filepath[MAX_PATH];
|
|
||||||
HANDLE h = (HANDLE) _get_osfhandle(_fileno(fp));
|
|
||||||
if (GetFinalPathNameByHandleA(h, filepath, PATH_MAX, FILE_NAME_NORMALIZED) > 0)
|
|
||||||
strncpy(buf, filepath, len - 1);
|
|
||||||
else
|
|
||||||
strncpy(buf, "(unknown)", len - 1);
|
|
||||||
#else
|
|
||||||
strncpy(buf, "(unknown)", len - 1);
|
|
||||||
#endif
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read line into buffer. if line is too long keep reading until EOL or EOF
|
// read line into buffer. if line is too long keep reading until EOL or EOF
|
||||||
// but return only the first part with a newline at the end.
|
// but return only the first part with a newline at the end.
|
||||||
|
|
||||||
@ -256,7 +218,7 @@ void utils::sfgets(const char *srcname, int srcline, char *s, int size, FILE *fp
|
|||||||
std::string errmsg;
|
std::string errmsg;
|
||||||
|
|
||||||
// try to figure out the file name from the file pointer
|
// try to figure out the file name from the file pointer
|
||||||
if (!filename) filename = guesspath(buf, MAXPATHLENBUF, fp);
|
if (!filename) filename = platform::guesspath(fp, buf, MAXPATHLENBUF);
|
||||||
|
|
||||||
if (feof(fp)) {
|
if (feof(fp)) {
|
||||||
errmsg = "Unexpected end of file while reading file '";
|
errmsg = "Unexpected end of file while reading file '";
|
||||||
@ -285,7 +247,7 @@ void utils::sfread(const char *srcname, int srcline, void *s, size_t size, size_
|
|||||||
std::string errmsg;
|
std::string errmsg;
|
||||||
|
|
||||||
// try to figure out the file name from the file pointer
|
// try to figure out the file name from the file pointer
|
||||||
if (!filename) filename = guesspath(buf, MAXPATHLENBUF, fp);
|
if (!filename) filename = platform::guesspath(fp, buf, MAXPATHLENBUF);
|
||||||
|
|
||||||
if (feof(fp)) {
|
if (feof(fp)) {
|
||||||
errmsg = "Unexpected end of file while reading file '";
|
errmsg = "Unexpected end of file while reading file '";
|
||||||
@ -920,7 +882,7 @@ size_t utils::count_words(const std::string &text, const std::string &separators
|
|||||||
|
|
||||||
size_t utils::trim_and_count_words(const std::string &text, const std::string &separators)
|
size_t utils::trim_and_count_words(const std::string &text, const std::string &separators)
|
||||||
{
|
{
|
||||||
return utils::count_words(utils::trim_comment(text), separators);
|
return utils::count_words(trim_comment(text), separators);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -1065,71 +1027,6 @@ bool utils::is_id(const std::string &str)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
strip off leading part of path, return just the filename
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
std::string utils::path_basename(const std::string &path)
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
size_t start = path.find_last_of("/\\");
|
|
||||||
#else
|
|
||||||
size_t start = path.find_last_of('/');
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (start == std::string::npos) {
|
|
||||||
start = 0;
|
|
||||||
} else {
|
|
||||||
start += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.substr(start);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
Return only the leading part of a path, return just the directory
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
std::string utils::path_dirname(const std::string &path)
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
size_t start = path.find_last_of("/\\");
|
|
||||||
#else
|
|
||||||
size_t start = path.find_last_of('/');
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (start == std::string::npos) return ".";
|
|
||||||
|
|
||||||
return path.substr(0, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
join two paths
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
std::string utils::path_join(const std::string &a, const std::string &b)
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
return fmt::format("{}\\{}", a, b);
|
|
||||||
#else
|
|
||||||
return fmt::format("{}/{}", a, b);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
try to open file for reading
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
bool utils::file_is_readable(const std::string &path)
|
|
||||||
{
|
|
||||||
FILE *fp = fopen(path.c_str(), "r");
|
|
||||||
if (fp) {
|
|
||||||
fclose(fp);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
try to find potential file as specified by name
|
try to find potential file as specified by name
|
||||||
search current directory and the LAMMPS_POTENTIALS directory if
|
search current directory and the LAMMPS_POTENTIALS directory if
|
||||||
@ -1139,9 +1036,9 @@ bool utils::file_is_readable(const std::string &path)
|
|||||||
std::string utils::get_potential_file_path(const std::string &path)
|
std::string utils::get_potential_file_path(const std::string &path)
|
||||||
{
|
{
|
||||||
std::string filepath = path;
|
std::string filepath = path;
|
||||||
std::string filename = utils::path_basename(path);
|
std::string filename = platform::path_basename(path);
|
||||||
|
|
||||||
if (utils::file_is_readable(filepath)) {
|
if (platform::file_is_readable(filepath)) {
|
||||||
return filepath;
|
return filepath;
|
||||||
} else {
|
} else {
|
||||||
// try the environment variable directory
|
// try the environment variable directory
|
||||||
@ -1154,11 +1051,11 @@ std::string utils::get_potential_file_path(const std::string &path)
|
|||||||
Tokenizer dirs(var, ":");
|
Tokenizer dirs(var, ":");
|
||||||
#endif
|
#endif
|
||||||
while (dirs.has_next()) {
|
while (dirs.has_next()) {
|
||||||
auto pot = utils::path_basename(filepath);
|
auto pot = platform::path_basename(filepath);
|
||||||
auto dir = dirs.next();
|
auto dir = dirs.next();
|
||||||
filepath = utils::path_join(dir, pot);
|
filepath = platform::path_join(dir, pot);
|
||||||
|
|
||||||
if (utils::file_is_readable(filepath)) { return filepath; }
|
if (platform::file_is_readable(filepath)) { return filepath; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
src/utils.h
43
src/utils.h
@ -417,49 +417,6 @@ namespace utils {
|
|||||||
|
|
||||||
bool is_id(const std::string &str);
|
bool is_id(const std::string &str);
|
||||||
|
|
||||||
/*! Try to detect pathname from FILE pointer.
|
|
||||||
*
|
|
||||||
* Currently supported on Linux, MacOS, and Windows, otherwise will report "(unknown)".
|
|
||||||
*
|
|
||||||
* \param buf storage buffer for pathname. output will be truncated if not large enough
|
|
||||||
* \param len size of storage buffer. output will be truncated to this length - 1
|
|
||||||
* \param fp FILE pointer struct from STDIO library for which we want to detect the name
|
|
||||||
* \return pointer to the storage buffer, i.e. buf */
|
|
||||||
|
|
||||||
const char *guesspath(char *buf, int len, FILE *fp);
|
|
||||||
|
|
||||||
/*! Strip off leading part of path, return just the filename
|
|
||||||
*
|
|
||||||
* \param path file path
|
|
||||||
* \return file name */
|
|
||||||
|
|
||||||
std::string path_basename(const std::string &path);
|
|
||||||
|
|
||||||
/*! Return the directory part of a path. Return "." if empty
|
|
||||||
*
|
|
||||||
* \param path file path
|
|
||||||
* \return directory name */
|
|
||||||
|
|
||||||
std::string path_dirname(const std::string &path);
|
|
||||||
|
|
||||||
/*! Join two pathname segments
|
|
||||||
*
|
|
||||||
* This uses the forward slash '/' character unless LAMMPS is compiled
|
|
||||||
* for Windows where it used the equivalent backward slash '\\'.
|
|
||||||
*
|
|
||||||
* \param a first path
|
|
||||||
* \param b second path
|
|
||||||
* \return combined path */
|
|
||||||
|
|
||||||
std::string path_join(const std::string &a, const std::string &b);
|
|
||||||
|
|
||||||
/*! Check if file exists and is readable
|
|
||||||
*
|
|
||||||
* \param path file path
|
|
||||||
* \return true if file exists and is readable */
|
|
||||||
|
|
||||||
bool file_is_readable(const std::string &path);
|
|
||||||
|
|
||||||
/*! Determine full path of potential file. If file is not found in current directory,
|
/*! Determine full path of potential file. If file is not found in current directory,
|
||||||
* search directories listed in LAMMPS_POTENTIALS environment variable
|
* search directories listed in LAMMPS_POTENTIALS environment variable
|
||||||
*
|
*
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
// This software is distributed under the GNU General Public License.
|
// This software is distributed under the GNU General Public License.
|
||||||
|
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -785,8 +786,8 @@ int main(int argc, char **argv)
|
|||||||
std::string input_file;
|
std::string input_file;
|
||||||
if ((argc > 1) && (argv[1][0] != '-')) {
|
if ((argc > 1) && (argv[1][0] != '-')) {
|
||||||
--argc;
|
--argc;
|
||||||
input_file = utils::path_basename(argv[1]);
|
input_file = platform::path_basename(argv[1]);
|
||||||
chdir(utils::path_dirname(input_file).c_str());
|
chdir(platform::path_dirname(input_file).c_str());
|
||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i)
|
||||||
argv[i] = argv[i + 1];
|
argv[i] = argv[i + 1];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -316,7 +316,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -684,7 +684,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,6 @@
|
|||||||
#include "lammps.h"
|
#include "lammps.h"
|
||||||
#include "lattice.h"
|
#include "lattice.h"
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
#include "utils.h"
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
@ -631,7 +630,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -686,7 +686,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,6 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "utils.h"
|
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
|
|
||||||
#include "../testing/core.h"
|
#include "../testing/core.h"
|
||||||
@ -217,7 +216,7 @@ TEST_F(SimpleCommandsTest, Quit)
|
|||||||
TEST_FAILURE(".*ERROR: Expected integer .*", command("quit xxx"););
|
TEST_FAILURE(".*ERROR: Expected integer .*", command("quit xxx"););
|
||||||
|
|
||||||
// the following tests must be skipped with OpenMPI due to using threads
|
// the following tests must be skipped with OpenMPI due to using threads
|
||||||
if (Info::get_mpi_vendor() == "Open MPI") GTEST_SKIP();
|
if (platform::mpi_vendor() == "Open MPI") GTEST_SKIP();
|
||||||
ASSERT_EXIT(command("quit"), ExitedWithCode(0), "");
|
ASSERT_EXIT(command("quit"), ExitedWithCode(0), "");
|
||||||
ASSERT_EXIT(command("quit 9"), ExitedWithCode(9), "");
|
ASSERT_EXIT(command("quit 9"), ExitedWithCode(9), "");
|
||||||
}
|
}
|
||||||
@ -528,7 +527,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -517,7 +517,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -128,7 +128,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -325,7 +325,7 @@ TEST_F(LAMMPS_kokkos, InitMembers)
|
|||||||
TEST(LAMMPS_init, OpenMP)
|
TEST(LAMMPS_init, OpenMP)
|
||||||
{
|
{
|
||||||
if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP();
|
if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP();
|
||||||
if (Info::get_openmp_info() == "OpenMP not enabled") GTEST_SKIP();
|
if (platform::openmp_standard() == "OpenMP not enabled") GTEST_SKIP();
|
||||||
|
|
||||||
FILE *fp = fopen("in.lammps_empty", "w");
|
FILE *fp = fopen("in.lammps_empty", "w");
|
||||||
fputs("\n", fp);
|
fputs("\n", fp);
|
||||||
|
|||||||
@ -491,7 +491,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "lammps.h"
|
#include "lammps.h"
|
||||||
#include "molecule.h"
|
#include "molecule.h"
|
||||||
#include "utils.h"
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
@ -257,7 +256,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -326,7 +326,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -160,7 +160,7 @@ int main(int argc, char **argv)
|
|||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
|
||||||
std::cout << "Warning: using OpenMPI without exceptions. "
|
std::cout << "Warning: using OpenMPI without exceptions. "
|
||||||
"Death tests will be skipped\n";
|
"Death tests will be skipped\n";
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "lammps.h"
|
#include "lammps.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
@ -36,7 +37,7 @@ using ::testing::MatchesRegex;
|
|||||||
auto mesg = ::testing::internal::GetCapturedStdout(); \
|
auto mesg = ::testing::internal::GetCapturedStdout(); \
|
||||||
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
|
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
|
||||||
} else { \
|
} else { \
|
||||||
if (Info::get_mpi_vendor() != "Open MPI") { \
|
if (platform::mpi_vendor() != "Open MPI") { \
|
||||||
::testing::internal::CaptureStdout(); \
|
::testing::internal::CaptureStdout(); \
|
||||||
ASSERT_DEATH({__VA_ARGS__}, ""); \
|
ASSERT_DEATH({__VA_ARGS__}, ""); \
|
||||||
auto mesg = ::testing::internal::GetCapturedStdout(); \
|
auto mesg = ::testing::internal::GetCapturedStdout(); \
|
||||||
|
|||||||
@ -13,14 +13,12 @@
|
|||||||
|
|
||||||
#include "lmptype.h"
|
#include "lmptype.h"
|
||||||
#include "pointers.h"
|
#include "pointers.h"
|
||||||
#include "utils.h"
|
|
||||||
#include "tokenizer.h"
|
#include "tokenizer.h"
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstdio>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -721,54 +719,6 @@ TEST(Utils, boundsbig_case3)
|
|||||||
ASSERT_EQ(nhi, -1);
|
ASSERT_EQ(nhi, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Utils, guesspath)
|
|
||||||
{
|
|
||||||
char buf[256];
|
|
||||||
FILE *fp = fopen("test_guesspath.txt", "w");
|
|
||||||
#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)
|
|
||||||
const char *path = utils::guesspath(buf, sizeof(buf), fp);
|
|
||||||
ASSERT_THAT(path, EndsWith("test_guesspath.txt"));
|
|
||||||
#else
|
|
||||||
const char *path = utils::guesspath(buf, sizeof(buf), fp);
|
|
||||||
ASSERT_THAT(path, EndsWith("(unknown)"));
|
|
||||||
#endif
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Utils, path_join)
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
ASSERT_THAT(utils::path_join("c:\\parent\\folder", "filename"),
|
|
||||||
Eq("c:\\parent\\folder\\filename"));
|
|
||||||
#else
|
|
||||||
ASSERT_THAT(utils::path_join("/parent/folder", "filename"), Eq("/parent/folder/filename"));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Utils, path_basename)
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
ASSERT_THAT(utils::path_basename("c:\\parent\\folder\\filename"), Eq("filename"));
|
|
||||||
ASSERT_THAT(utils::path_basename("folder\\"), Eq(""));
|
|
||||||
ASSERT_THAT(utils::path_basename("c:/parent/folder/filename"), Eq("filename"));
|
|
||||||
#else
|
|
||||||
ASSERT_THAT(utils::path_basename("/parent/folder/filename"), Eq("filename"));
|
|
||||||
ASSERT_THAT(utils::path_basename("/parent/folder/"), Eq(""));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Utils, path_dirname)
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
ASSERT_THAT(utils::path_dirname("c:/parent/folder/filename"), Eq("c:/parent/folder"));
|
|
||||||
ASSERT_THAT(utils::path_dirname("c:\\parent\\folder\\filename"), Eq("c:\\parent\\folder"));
|
|
||||||
ASSERT_THAT(utils::path_dirname("c:filename"), Eq("."));
|
|
||||||
#else
|
|
||||||
ASSERT_THAT(utils::path_dirname("/parent/folder/filename"), Eq("/parent/folder"));
|
|
||||||
#endif
|
|
||||||
ASSERT_THAT(utils::path_dirname("filename"), Eq("."));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Utils, getsyserror)
|
TEST(Utils, getsyserror)
|
||||||
{
|
{
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
@ -792,16 +742,16 @@ TEST(Utils, potential_file)
|
|||||||
fputs("# CONTRIBUTOR: Pippo\n", fp);
|
fputs("# CONTRIBUTOR: Pippo\n", fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
ASSERT_TRUE(utils::file_is_readable("ctest1.txt"));
|
ASSERT_TRUE(platform::file_is_readable("ctest1.txt"));
|
||||||
ASSERT_TRUE(utils::file_is_readable("ctest2.txt"));
|
ASSERT_TRUE(platform::file_is_readable("ctest2.txt"));
|
||||||
ASSERT_FALSE(utils::file_is_readable("no_such_file.txt"));
|
ASSERT_FALSE(platform::file_is_readable("no_such_file.txt"));
|
||||||
|
|
||||||
ASSERT_THAT(utils::get_potential_file_path("ctest1.txt"), Eq("ctest1.txt"));
|
ASSERT_THAT(utils::get_potential_file_path("ctest1.txt"), Eq("ctest1.txt"));
|
||||||
ASSERT_THAT(utils::get_potential_file_path("no_such_file.txt"), Eq(""));
|
ASSERT_THAT(utils::get_potential_file_path("no_such_file.txt"), Eq(""));
|
||||||
|
|
||||||
const char *folder = getenv("LAMMPS_POTENTIALS");
|
const char *folder = getenv("LAMMPS_POTENTIALS");
|
||||||
if (folder != nullptr) {
|
if (folder != nullptr) {
|
||||||
std::string path = utils::path_join(folder, "Cu_u3.eam");
|
std::string path = platform::path_join(folder, "Cu_u3.eam");
|
||||||
EXPECT_THAT(utils::get_potential_file_path("Cu_u3.eam"), Eq(path));
|
EXPECT_THAT(utils::get_potential_file_path("Cu_u3.eam"), Eq(path));
|
||||||
EXPECT_THAT(utils::get_potential_units(path, "EAM"), Eq("metal"));
|
EXPECT_THAT(utils::get_potential_units(path, "EAM"), Eq("metal"));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user