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)),)
|
||||
$(error 'pkg-config' not found, but is required to configure the KIM API)
|
||||
endif
|
||||
|
||||
kim_PREFIX := $(shell cat ../../lib/kim/kim-prefix.txt 2> /dev/null)
|
||||
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))
|
||||
|
||||
# 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_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)),)
|
||||
$(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
|
||||
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:
|
||||
|
|
|
@ -57,36 +57,55 @@
|
|||
|
||||
#include <mpi.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "kim_query.h"
|
||||
#include "comm.h"
|
||||
#include "error.h"
|
||||
#include "input.h"
|
||||
#include "variable.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
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)
|
||||
{
|
||||
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];
|
||||
property = arg[1];
|
||||
varname = arg[2];
|
||||
varname = arg[0];
|
||||
function = arg[1];
|
||||
|
||||
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
|
||||
// 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 (len == 1) {
|
||||
// TODO: store more detailed error message after \0 byte.
|
||||
error->all(FLERR,"Query of OpenKIM database failed");
|
||||
if (0 == strlen(value)) {
|
||||
char errmsg[512];
|
||||
|
||||
sprintf(errmsg,"OpenKIM query failed: %s",value+1);
|
||||
error->all(FLERR,errmsg);
|
||||
}
|
||||
|
||||
char **varcmd = new char*[3];
|
||||
|
@ -98,26 +117,119 @@ void KimQuery::command(int narg, char **arg)
|
|||
|
||||
delete[] varcmd;
|
||||
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;
|
||||
|
||||
// only run query from rank 0
|
||||
if (rank == 0) {
|
||||
// run the web query from rank 0 only
|
||||
|
||||
// fake query
|
||||
strcpy(value,(const char*)"4.25");
|
||||
if (rank == 0) {
|
||||
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);
|
||||
|
||||
// must make a proper copy of the query, as the stack allocation
|
||||
// will go out of scope
|
||||
// we must make a proper copy of the query, as the stack allocation
|
||||
// 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;
|
||||
retval = new char[len];
|
||||
strcpy(retval,value);
|
||||
if (value[0] == '[') {
|
||||
int len = strlen(value)-1;
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue