forked from lijiext/lammps
final touches to support compiling with libcurl transparently
This commit is contained in:
parent
7a8bb5baaf
commit
741a7fe630
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
# example for performing a query to the OpenKIM test database to retrieve
|
||||||
|
# a parameter to be used in the input. here it requests the aluminium
|
||||||
|
# lattice constant for a specific test used for a specific model and then
|
||||||
|
# assigns it to the variable 'latconst'
|
||||||
|
|
||||||
|
units metal
|
||||||
|
info variables out log
|
||||||
|
kim_query latconst get_test_result test=TE_156715955670_004 species=["Al"] model=MO_800509458712_001 prop=structure-cubic-crystal-npt keys=["a"] units=["angstrom"]
|
||||||
|
info variables out log
|
||||||
|
lattice fcc ${latconst}
|
|
@ -0,0 +1,34 @@
|
||||||
|
LAMMPS (16 Aug 2018)
|
||||||
|
|
||||||
|
# example for performing a query to the OpenKIM test database to retrieve
|
||||||
|
# a parameter to be used in the input. here it requests the aluminium
|
||||||
|
# lattice constant for a specific test used for a specific model and then
|
||||||
|
# assigns it to the variable 'latconst'
|
||||||
|
|
||||||
|
units metal
|
||||||
|
info variables out log
|
||||||
|
|
||||||
|
Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info
|
||||||
|
Printed on Mon Aug 20 18:44:24 2018
|
||||||
|
|
||||||
|
|
||||||
|
Variable information:
|
||||||
|
|
||||||
|
Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info
|
||||||
|
|
||||||
|
kim_query latconst get_test_result test=TE_156715955670_004 species=["Al"] model=MO_800509458712_001 prop=structure-cubic-crystal-npt keys=["a"] units=["angstrom"]
|
||||||
|
info variables out log
|
||||||
|
|
||||||
|
Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info
|
||||||
|
Printed on Mon Aug 20 18:44:24 2018
|
||||||
|
|
||||||
|
|
||||||
|
Variable information:
|
||||||
|
Variable[ 0]: latconst , style = string , def = 4.0320827961
|
||||||
|
|
||||||
|
Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info
|
||||||
|
|
||||||
|
lattice fcc ${latconst}
|
||||||
|
lattice fcc 4.0320827961
|
||||||
|
Lattice spacing in x,y,z = 4.03208 4.03208 4.03208
|
||||||
|
Total wall time: 0:00:00
|
|
@ -17,13 +17,18 @@
|
||||||
ifeq ($(strip $(shell pkg-config --version)),)
|
ifeq ($(strip $(shell pkg-config --version)),)
|
||||||
$(error 'pkg-config' not found, but is required to configure the KIM API)
|
$(error 'pkg-config' not found, but is required to configure the KIM API)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
kim_PREFIX := $(shell cat ../../lib/kim/kim-prefix.txt 2> /dev/null)
|
kim_PREFIX := $(shell cat ../../lib/kim/kim-prefix.txt 2> /dev/null)
|
||||||
kim_PREFIX := $(if $(kim_PREFIX),$(kim_PREFIX)/lib/pkgconfig,)
|
kim_PREFIX := $(if $(kim_PREFIX),$(kim_PREFIX)/lib/pkgconfig,)
|
||||||
kim_PREFIX := $(if $(shell printf -- "$${PKG_CONFIG_PATH}"),$(kim_PREFIX):$(shell printf -- "$${PKG_CONFIG_PATH}"),$(kim_PREFIX))
|
kim_PREFIX := $(if $(shell printf -- "$${PKG_CONFIG_PATH}"),$(kim_PREFIX):$(shell printf -- "$${PKG_CONFIG_PATH}"),$(kim_PREFIX))
|
||||||
|
|
||||||
|
# there is no usable libcurl installation
|
||||||
|
ifeq ($(shell curl-config --version 2> /dev/null),)
|
||||||
kim_SYSINC := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --cflags libkim-api-v2 2> /dev/null)
|
kim_SYSINC := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --cflags libkim-api-v2 2> /dev/null)
|
||||||
kim_SYSLIB := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --libs libkim-api-v2 2> /dev/null)
|
kim_SYSLIB := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --libs libkim-api-v2 2> /dev/null)
|
||||||
|
else
|
||||||
|
kim_SYSINC := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --cflags libkim-api-v2 2> /dev/null) $(shell curl-config --cflags) -DLMP_KIM_CURL
|
||||||
|
kim_SYSLIB := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --libs libkim-api-v2 2> /dev/null) $(shell curl-config --libs)
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(kim_SYSINC)),)
|
ifeq ($(strip $(kim_SYSINC)),)
|
||||||
$(error 'pkg-config' could not find an installed KIM API library.)
|
$(error 'pkg-config' could not find an installed KIM API library.)
|
||||||
|
|
|
@ -13,6 +13,12 @@ do the same thing by typing "python Install.py" from within this
|
||||||
directory, or you can do it manually by following the instructions
|
directory, or you can do it manually by following the instructions
|
||||||
below.
|
below.
|
||||||
|
|
||||||
|
As of KIM API version 2, the KIM package also provides a LAMMPS command
|
||||||
|
to perform queries through the OpenKIM web API. This feature requires
|
||||||
|
that the CURL library (libcurl) development package and its configuration
|
||||||
|
query tool, curl-config, are installed. The provided Makefile.lammps
|
||||||
|
is set up to automatically detect this.
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
Instructions:
|
Instructions:
|
||||||
|
|
|
@ -57,36 +57,55 @@
|
||||||
|
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
#include "kim_query.h"
|
#include "kim_query.h"
|
||||||
#include "comm.h"
|
#include "comm.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
static char *do_query(char *, char *, int, MPI_Comm);
|
#if defined(LMP_KIM_CURL)
|
||||||
|
|
||||||
|
struct WriteBuf {
|
||||||
|
char *dataptr;
|
||||||
|
size_t sizeleft;
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *do_query(char *, int, char **, int, MPI_Comm);
|
||||||
|
static size_t write_callback(void *, size_t, size_t, void *);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void KimQuery::command(int narg, char **arg)
|
void KimQuery::command(int narg, char **arg)
|
||||||
{
|
{
|
||||||
char *model, *property, *varname, *value;
|
char *varname, *function, *value;
|
||||||
|
|
||||||
if (narg != 3) error->all(FLERR,"Illegal kim_query command");
|
if (narg < 2) error->all(FLERR,"Illegal kim_query command");
|
||||||
|
|
||||||
model = arg[0];
|
varname = arg[0];
|
||||||
property = arg[1];
|
function = arg[1];
|
||||||
varname = arg[2];
|
|
||||||
|
|
||||||
value = do_query(model, property, comm->me, world);
|
#if defined(LMP_KIM_CURL)
|
||||||
|
|
||||||
|
value = do_query(function, narg-2, arg+2, comm->me, world);
|
||||||
|
|
||||||
// check for valid result
|
// check for valid result
|
||||||
|
// on error the content of "value" is a '\0' byte
|
||||||
|
// as the first element, and then the error message
|
||||||
|
// that was returned by the web server
|
||||||
|
|
||||||
int len = strlen(value) + 1;
|
if (0 == strlen(value)) {
|
||||||
if (len == 1) {
|
char errmsg[512];
|
||||||
// TODO: store more detailed error message after \0 byte.
|
|
||||||
error->all(FLERR,"Query of OpenKIM database failed");
|
sprintf(errmsg,"OpenKIM query failed: %s",value+1);
|
||||||
|
error->all(FLERR,errmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
char **varcmd = new char*[3];
|
char **varcmd = new char*[3];
|
||||||
|
@ -98,26 +117,119 @@ void KimQuery::command(int narg, char **arg)
|
||||||
|
|
||||||
delete[] varcmd;
|
delete[] varcmd;
|
||||||
delete[] value;
|
delete[] value;
|
||||||
|
#else
|
||||||
|
error->all(FLERR,"Cannot use 'kim_query' command when KIM package "
|
||||||
|
"is compiled without support for libcurl");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(LMP_KIM_CURL)
|
||||||
|
|
||||||
char *do_query(char *model, char *property, int rank, MPI_Comm comm)
|
// copy data to the user provided data structure, optionally in increments
|
||||||
|
|
||||||
|
size_t write_callback(void *data, size_t size, size_t nmemb, void *userp)
|
||||||
|
{
|
||||||
|
struct WriteBuf *buf = (struct WriteBuf *)userp;
|
||||||
|
size_t buffer_size = size*nmemb;
|
||||||
|
|
||||||
|
// copy chunks into the buffer for as long as there is space left
|
||||||
|
if (buf->sizeleft) {
|
||||||
|
size_t copy_this_much = buf->sizeleft;
|
||||||
|
if (copy_this_much > buffer_size)
|
||||||
|
copy_this_much = buffer_size;
|
||||||
|
memcpy(buf->dataptr, data, copy_this_much);
|
||||||
|
|
||||||
|
buf->dataptr += copy_this_much;
|
||||||
|
buf->sizeleft -= copy_this_much;
|
||||||
|
return copy_this_much;
|
||||||
|
}
|
||||||
|
return 0; // done
|
||||||
|
}
|
||||||
|
|
||||||
|
char *do_query(char *qfunction, int narg, char **arg, int rank, MPI_Comm comm)
|
||||||
{
|
{
|
||||||
char value[512], *retval;
|
char value[512], *retval;
|
||||||
|
|
||||||
// only run query from rank 0
|
// run the web query from rank 0 only
|
||||||
if (rank == 0) {
|
|
||||||
|
|
||||||
// fake query
|
if (rank == 0) {
|
||||||
strcpy(value,(const char*)"4.25");
|
CURL *handle;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
// set up and clear receive buffer
|
||||||
|
|
||||||
|
struct WriteBuf buf;
|
||||||
|
buf.dataptr = value;
|
||||||
|
buf.sizeleft = 511;
|
||||||
|
memset(value,0,512);
|
||||||
|
|
||||||
|
// create curl web query instance
|
||||||
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
handle = curl_easy_init();
|
||||||
|
|
||||||
|
if (handle) {
|
||||||
|
std::string url("https://query.openkim.org/api/");
|
||||||
|
url += qfunction;
|
||||||
|
|
||||||
|
std::string query(arg[0]);
|
||||||
|
for (int i=1; i < narg; ++i) {
|
||||||
|
query += '&';
|
||||||
|
query += arg[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LMP_DEBUG_CURL
|
||||||
|
curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LMP_NO_SSL_CHECK)
|
||||||
|
// disable verifying SSL certificate and host name
|
||||||
|
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
|
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
|
||||||
|
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
|
||||||
|
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, query.c_str());
|
||||||
|
|
||||||
|
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION,write_callback);
|
||||||
|
curl_easy_setopt(handle, CURLOPT_WRITEDATA,&buf);
|
||||||
|
|
||||||
|
// perform OpenKIM query and check for errors
|
||||||
|
res = curl_easy_perform(handle);
|
||||||
|
if (res != CURLE_OK) {
|
||||||
|
// on error we return an "empty" string but add error message after it
|
||||||
|
value[0]= '\0';
|
||||||
|
strcpy(value+1,curl_easy_strerror(res));
|
||||||
|
}
|
||||||
|
curl_easy_cleanup(handle);
|
||||||
|
}
|
||||||
|
curl_global_cleanup();
|
||||||
}
|
}
|
||||||
MPI_Bcast(value, 512, MPI_CHAR, 0, comm);
|
MPI_Bcast(value, 512, MPI_CHAR, 0, comm);
|
||||||
|
|
||||||
// must make a proper copy of the query, as the stack allocation
|
// we must make a proper copy of the query, as the stack allocation
|
||||||
// will go out of scope
|
// for "value" will go out of scope. a valid query has a '[' as
|
||||||
|
// the first character. skip over it (and the last character ']', too)
|
||||||
|
// an error messages starts with a '\0' character. copy that and
|
||||||
|
// the remaining string, as that is the error message.
|
||||||
|
|
||||||
int len = strlen(value) + 1;
|
if (value[0] == '[') {
|
||||||
retval = new char[len];
|
int len = strlen(value)-1;
|
||||||
strcpy(retval,value);
|
retval = new char[len];
|
||||||
|
value[len] = '\0';
|
||||||
|
strcpy(retval,value+1);
|
||||||
|
} else if (value[0] == '\0') {
|
||||||
|
int len = strlen(value+1)+2;
|
||||||
|
retval = new char[len];
|
||||||
|
retval[0] = '\0';
|
||||||
|
strcpy(retval+1,value+1);
|
||||||
|
} else {
|
||||||
|
// unknown response type. we should not get here.
|
||||||
|
// copy response without modifications.
|
||||||
|
int len = strlen(value)+1;
|
||||||
|
retval = new char[len];
|
||||||
|
strcpy(retval,value);
|
||||||
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue