add kimplugin source and CMake based build support
This commit is contained in:
@ -262,3 +262,24 @@ A plugin may be registered under an existing style name. In that case
|
||||
the plugin will override the existing code. This can be used to modify
|
||||
the behavior of existing styles or to debug new versions of them without
|
||||
having to re-compile or re-install all of LAMMPS.
|
||||
|
||||
Compiling plugins
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Plugins need to be compiled with the same compilers and libraries
|
||||
(e.g. MPI) and compilation settings (MPI on/off, OpenMP, integer sizes)
|
||||
as the LAMMPS executable and library. Otherwise the plugin will likely
|
||||
not load due to mismatches in the function signatures (LAMMPS is C++ so
|
||||
scope, type, and number of arguments are encoded into the symbol names
|
||||
and thus differences in them will lead to failed plugin load commands.
|
||||
Compilation of the plugin can be done managed via both, CMake or
|
||||
traditional GNU makefiles. Some examples that can be used as a template
|
||||
are in the ``examples/plugins`` folder. The CMake script code has some
|
||||
small adjustments to allow building he plugins for running unit tests
|
||||
with them. Another example that converts the KIM package into a plugin
|
||||
can be found in the ``examples/kim/plugin`` folder. No changes to the
|
||||
sources of the KIM package themselves are needed; only the plugin
|
||||
interface and loader code needs to be added. This example only supports
|
||||
building with CMake, but is probably a more typical example. To compile
|
||||
you need to run CMake with -DLAMMPS_SOURCE_DIR=<path/to/lammps/src/folder>.
|
||||
Other configuration setting are identical to those for compiling LAMMPS.
|
||||
|
||||
@ -70,12 +70,11 @@ Restrictions
|
||||
""""""""""""
|
||||
|
||||
The *plugin* command is part of the PLUGIN package. It is
|
||||
only enabled if LAMMPS was built with that package.
|
||||
See the :doc:`Build package <Build_package>` page for
|
||||
more info. Plugins are not available on Windows.
|
||||
only enabled if LAMMPS was built with that package. See
|
||||
the :doc:`Build package <Build_package>` page for more info.
|
||||
|
||||
If plugins access functions or classes from a package, LAMMPS must
|
||||
have been compiled with that package included.
|
||||
If plugins access functions or classes from a package,
|
||||
LAMMPS must have been compiled with that package included.
|
||||
|
||||
Plugins are dependent on the LAMMPS binary interface (ABI)
|
||||
and particularly the MPI library used. So they are not guaranteed
|
||||
|
||||
109
examples/kim/plugin/CMakeLists.txt
Normal file
109
examples/kim/plugin/CMakeLists.txt
Normal file
@ -0,0 +1,109 @@
|
||||
##########################################
|
||||
# CMake build system for plugin examples.
|
||||
# The is meant to be used as a template for plugins that are
|
||||
# distributed independent from the LAMMPS package.
|
||||
##########################################
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
# enforce out-of-source build
|
||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
message(FATAL_ERROR "In-source builds are not allowed. You must create and use a build directory. "
|
||||
"Please remove CMakeCache.txt and CMakeFiles first.")
|
||||
endif()
|
||||
|
||||
project(kimplugin VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
set(LAMMPS_SOURCE_DIR "" CACHE PATH "Location of LAMMPS sources folder")
|
||||
if(NOT LAMMPS_SOURCE_DIR)
|
||||
message(FATAL_ERROR "Must set LAMMPS_SOURCE_DIR")
|
||||
endif()
|
||||
|
||||
# by default, install into $HOME/.local (not /usr/local),
|
||||
# so that no root access (and sudo) is needed
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "Default install path" FORCE)
|
||||
endif()
|
||||
|
||||
# ugly hacks for MSVC which by default always reports an old C++ standard in the __cplusplus macro
|
||||
# and prints lots of pointless warnings about "unsafe" functions
|
||||
if(MSVC)
|
||||
add_compile_options(/Zc:__cplusplus)
|
||||
add_compile_options(/wd4244)
|
||||
add_compile_options(/wd4267)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
# C++11 is required
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Need -restrict with Intel compilers
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -restrict")
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include(CheckIncludeFileCXX)
|
||||
include(LAMMPSInterfaceCXX)
|
||||
|
||||
##########################
|
||||
# building the plugins
|
||||
|
||||
add_library(kimplugin MODULE kimplugin.cpp ${LAMMPS_SOURCE_DIR}/KIM/pair_kim.cpp
|
||||
${LAMMPS_SOURCE_DIR}/KIM/fix_store_kim.cpp ${LAMMPS_SOURCE_DIR}/KIM/kim_command.cpp
|
||||
${LAMMPS_SOURCE_DIR}/KIM/kim_init.cpp ${LAMMPS_SOURCE_DIR}/KIM/kim_interactions.cpp
|
||||
${LAMMPS_SOURCE_DIR}/KIM/kim_param.cpp ${LAMMPS_SOURCE_DIR}/KIM/kim_property.cpp
|
||||
${LAMMPS_SOURCE_DIR}/KIM/kim_query.cpp ${LAMMPS_SOURCE_DIR}/KIM/kim_units.cpp)
|
||||
target_link_libraries(kimplugin PRIVATE lammps)
|
||||
target_include_directories(kimplugin PRIVATE ${LAMMPS_SOURCE_DIR}/KIM)
|
||||
set_target_properties(kimplugin PROPERTIES PREFIX "" SUFFIX ".so")
|
||||
|
||||
set(KIM-API_MIN_VERSION 2.1.3)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
if(KIM-API_FOUND AND KIM-API_VERSION VERSION_GREATER_EQUAL 2.2.0)
|
||||
# For kim-api >= 2.2.0
|
||||
find_package(KIM-API 2.2.0 CONFIG REQUIRED)
|
||||
target_link_libraries(kimplugin PRIVATE KIM-API::kim-api)
|
||||
else()
|
||||
# For kim-api 2.1.3 (consistent with previous version of this file)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(KIM-API REQUIRED IMPORTED_TARGET libkim-api>=${KIM-API_MIN_VERSION})
|
||||
target_link_libraries(kimplugin PRIVATE PkgConfig::KIM-API)
|
||||
endif()
|
||||
|
||||
##########################
|
||||
# need libcurl
|
||||
find_package(CURL)
|
||||
if(CURL_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.12)
|
||||
target_include_directories(kimplugin PRIVATE ${CURL_INCLUDE_DIRS})
|
||||
target_link_libraries(kimplugin PRIVATE ${CURL_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(kimplugin PRIVATE CURL::libcurl)
|
||||
endif()
|
||||
target_compile_definitions(kimplugin PRIVATE -DLMP_KIM_CURL)
|
||||
set(LMP_DEBUG_CURL OFF CACHE STRING "Set libcurl verbose mode on/off. If on, it displays a lot of verbose information about its operations.")
|
||||
mark_as_advanced(LMP_DEBUG_CURL)
|
||||
if(LMP_DEBUG_CURL)
|
||||
target_compile_definitions(kimplugin PRIVATE -DLMP_DEBUG_CURL)
|
||||
endif()
|
||||
set(LMP_NO_SSL_CHECK OFF CACHE STRING "Tell libcurl to not verify the peer. If on, the connection succeeds regardless of the names in the certificate. Insecure - Use with caution!")
|
||||
mark_as_advanced(LMP_NO_SSL_CHECK)
|
||||
if(LMP_NO_SSL_CHECK)
|
||||
target_compile_definitions(kimplugin PRIVATE -DLMP_NO_SSL_CHECK)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# MacOS seems to need this
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||
set_target_properties(kimplugin PROPERTIES LINK_FLAGS "-Wl,-undefined,dynamic_lookup")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
# tell CMake to export all symbols to a .dll on Windows with special case for MinGW cross-compilers
|
||||
set_target_properties(kimplugin.so PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set_target_properties(kimplugin PROPERTIES LINK_FLAGS "-Wl,--export-all-symbols")
|
||||
endif()
|
||||
else()
|
||||
set_target_properties(kimplugin PROPERTIES LINK_FLAGS "-rdynamic")
|
||||
endif()
|
||||
88
examples/kim/plugin/LAMMPSInterfaceCXX.cmake
Normal file
88
examples/kim/plugin/LAMMPSInterfaceCXX.cmake
Normal file
@ -0,0 +1,88 @@
|
||||
# Cmake script code to define the LAMMPS C++ interface
|
||||
# settings required for building LAMMPS plugins
|
||||
|
||||
################################################################################
|
||||
# helper function
|
||||
function(validate_option name values)
|
||||
string(TOLOWER ${${name}} needle_lower)
|
||||
string(TOUPPER ${${name}} needle_upper)
|
||||
list(FIND ${values} ${needle_lower} IDX_LOWER)
|
||||
list(FIND ${values} ${needle_upper} IDX_UPPER)
|
||||
if(${IDX_LOWER} LESS 0 AND ${IDX_UPPER} LESS 0)
|
||||
list_to_bulletpoints(POSSIBLE_VALUE_LIST ${${values}})
|
||||
message(FATAL_ERROR "\n########################################################################\n"
|
||||
"Invalid value '${${name}}' for option ${name}\n"
|
||||
"\n"
|
||||
"Possible values are:\n"
|
||||
"${POSSIBLE_VALUE_LIST}"
|
||||
"########################################################################")
|
||||
endif()
|
||||
endfunction(validate_option)
|
||||
|
||||
#################################################################################
|
||||
# LAMMPS C++ interface. We only need the header related parts.
|
||||
add_library(lammps INTERFACE)
|
||||
target_include_directories(lammps INTERFACE ${LAMMPS_SOURCE_DIR})
|
||||
if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND CMAKE_CROSSCOMPILING)
|
||||
target_link_libraries(lammps INTERFACE ${CMAKE_BINARY_DIR}/../liblammps.dll.a)
|
||||
endif()
|
||||
################################################################################
|
||||
# MPI configuration
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
set(MPI_CXX_SKIP_MPICXX TRUE)
|
||||
find_package(MPI QUIET)
|
||||
option(BUILD_MPI "Build MPI version" ${MPI_FOUND})
|
||||
else()
|
||||
option(BUILD_MPI "Build MPI version" OFF)
|
||||
endif()
|
||||
|
||||
if(BUILD_MPI)
|
||||
find_package(MPI REQUIRED)
|
||||
option(LAMMPS_LONGLONG_TO_LONG "Workaround if your system or MPI version does not recognize 'long long' data types" OFF)
|
||||
if(LAMMPS_LONGLONG_TO_LONG)
|
||||
target_compile_definitions(lammps INTERFACE -DLAMMPS_LONGLONG_TO_LONG)
|
||||
endif()
|
||||
target_link_libraries(lammps INTERFACE MPI::MPI_CXX)
|
||||
else()
|
||||
target_include_directories(lammps INTERFACE "${LAMMPS_SOURCE_DIR}/STUBS")
|
||||
endif()
|
||||
|
||||
set(LAMMPS_SIZES "smallbig" CACHE STRING "LAMMPS integer sizes (smallsmall: all 32-bit, smallbig: 64-bit #atoms #timesteps, bigbig: also 64-bit imageint, 64-bit atom ids)")
|
||||
set(LAMMPS_SIZES_VALUES smallbig bigbig smallsmall)
|
||||
set_property(CACHE LAMMPS_SIZES PROPERTY STRINGS ${LAMMPS_SIZES_VALUES})
|
||||
validate_option(LAMMPS_SIZES LAMMPS_SIZES_VALUES)
|
||||
string(TOUPPER ${LAMMPS_SIZES} LAMMPS_SIZES)
|
||||
target_compile_definitions(lammps INTERFACE -DLAMMPS_${LAMMPS_SIZES})
|
||||
|
||||
################################################################################
|
||||
# detect if we may enable OpenMP support by default
|
||||
set(BUILD_OMP_DEFAULT OFF)
|
||||
find_package(OpenMP QUIET)
|
||||
if(OpenMP_FOUND)
|
||||
check_include_file_cxx(omp.h HAVE_OMP_H_INCLUDE)
|
||||
if(HAVE_OMP_H_INCLUDE)
|
||||
set(BUILD_OMP_DEFAULT ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(BUILD_OMP "Build with OpenMP support" ${BUILD_OMP_DEFAULT})
|
||||
|
||||
if(BUILD_OMP)
|
||||
find_package(OpenMP REQUIRED)
|
||||
check_include_file_cxx(omp.h HAVE_OMP_H_INCLUDE)
|
||||
if(NOT HAVE_OMP_H_INCLUDE)
|
||||
message(FATAL_ERROR "Cannot find the 'omp.h' header file required for full OpenMP support")
|
||||
endif()
|
||||
|
||||
if (((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0)) OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "PGI") OR
|
||||
((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0)) OR
|
||||
((CMAKE_CXX_COMPILER_ID STREQUAL "Intel") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0)))
|
||||
# GCC 9.x and later plus Clang 10.x and later implement strict OpenMP 4.0 semantics for consts.
|
||||
# Intel 18.0 was tested to support both, so we switch to OpenMP 4+ from 19.x onward to be safe.
|
||||
target_compile_definitions(lammps INTERFACE -DLAMMPS_OMP_COMPAT=4)
|
||||
else()
|
||||
target_compile_definitions(lammps INTERFACE -DLAMMPS_OMP_COMPAT=3)
|
||||
endif()
|
||||
target_link_libraries(lammps INTERFACE OpenMP::OpenMP_CXX)
|
||||
endif()
|
||||
54
examples/kim/plugin/kimplugin.cpp
Normal file
54
examples/kim/plugin/kimplugin.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
#include "lammpsplugin.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "pair_kim.h"
|
||||
#include "fix_store_kim.h"
|
||||
#include "kim_command.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
static Pair *pair_kim_creator(LAMMPS *lmp)
|
||||
{
|
||||
return new PairKIM(lmp);
|
||||
}
|
||||
|
||||
static Fix *fix_store_kim_creator(LAMMPS *lmp, int argc, char **argv)
|
||||
{
|
||||
return new FixStoreKIM(lmp, argc, argv);
|
||||
}
|
||||
|
||||
static Command *kim_command_creator(LAMMPS *lmp)
|
||||
{
|
||||
return new KimCommand(lmp);
|
||||
}
|
||||
|
||||
extern "C" void lammpsplugin_init(void *lmp, void *handle, void *regfunc)
|
||||
{
|
||||
lammpsplugin_t plugin;
|
||||
lammpsplugin_regfunc register_plugin = (lammpsplugin_regfunc) regfunc;
|
||||
|
||||
// register kim pair style
|
||||
plugin.version = LAMMPS_VERSION;
|
||||
plugin.style = "pair";
|
||||
plugin.name = "kim";
|
||||
plugin.info = "KIM plugin pair style v1.0";
|
||||
plugin.author = "Axel Kohlmeyer (akohlmey@gmail.com)";
|
||||
plugin.creator.v1 = (lammpsplugin_factory1 *) &pair_kim_creator;
|
||||
plugin.handle = handle;
|
||||
(*register_plugin)(&plugin, lmp);
|
||||
|
||||
// register fix STORE/KIM only need to update changed fields
|
||||
plugin.style = "fix";
|
||||
plugin.name = "STORE/KIM";
|
||||
plugin.info = "Internal settings storage for KIM fix style v1.0";
|
||||
plugin.creator.v2 = (lammpsplugin_factory2 *) &fix_store_kim_creator;
|
||||
(*register_plugin)(&plugin, lmp);
|
||||
|
||||
// register KIM command
|
||||
plugin.style = "command";
|
||||
plugin.name = "kim";
|
||||
plugin.info = "kim command style v1.0";
|
||||
plugin.creator.v1 = (lammpsplugin_factory1 *) &kim_command_creator;
|
||||
(*register_plugin)(&plugin, lmp);
|
||||
}
|
||||
Reference in New Issue
Block a user