From 3c6645d72d0215bf70e77f495786de961971bc45 Mon Sep 17 00:00:00 2001 From: Giovanni Bussi <giovanni.bussi@gmail.com> Date: Wed, 6 Sep 2017 12:58:46 +0200 Subject: [PATCH] Removed libmatheval I removed matheval everywhere in the code. Now, MATHEVAL (and CUSTOM) keywords are automatically using lepton (see #244). Notice that env var PLUMED_USE_LEPTON is now ignored. --- configure | 90 ------------------------- configure.ac | 4 -- src/core/CLToolMain.cpp | 3 - src/function/Matheval.cpp | 114 +++++++------------------------- src/tools/SwitchingFunction.cpp | 79 +--------------------- src/tools/SwitchingFunction.h | 10 --- 6 files changed, 25 insertions(+), 275 deletions(-) diff --git a/configure b/configure index d475becad..b47ddaa92 100755 --- a/configure +++ b/configure @@ -714,7 +714,6 @@ enable_external_lapack enable_external_blas enable_molfile_plugins enable_external_molfile_plugins -enable_matheval enable_zlib enable_readdir_r enable_cregex @@ -1383,7 +1382,6 @@ Optional Features: --enable-external-molfile-plugins enable search for external molfile_plugins, default: yes - --enable-matheval enable search for matheval, default: yes --enable-zlib enable search for zlib, default: yes --enable-readdir-r enable search for readdir_r (threadsafe), default: yes @@ -2764,24 +2762,6 @@ fi -matheval= -# Check whether --enable-matheval was given. -if test "${enable_matheval+set}" = set; then : - enableval=$enable_matheval; case "${enableval}" in - (yes) matheval=true ;; - (no) matheval=false ;; - (*) as_fn_error $? "wrong argument to --enable-matheval" "$LINENO" 5 ;; - esac -else - case "yes" in - (yes) matheval=true ;; - (no) matheval=false ;; - esac - -fi - - - zlib= # Check whether --enable-zlib was given. if test "${enable_zlib+set}" = set; then : @@ -6156,76 +6136,6 @@ $as_echo "$ac_cv_prog_cxx_openmp" >&6; } -if test $matheval == true ; then - - found=ko - ac_fn_cxx_check_header_mongrel "$LINENO" "matheval.h" "ac_cv_header_matheval_h" "$ac_includes_default" -if test "x$ac_cv_header_matheval_h" = xyes; then : - - ac_fn_cxx_check_func "$LINENO" "evaluator_create" "ac_cv_func_evaluator_create" -if test "x$ac_cv_func_evaluator_create" = xyes; then : - found=ok -else - - if test "${libsearch}" == true ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for evaluator_create in -lmatheval" >&5 -$as_echo_n "checking for evaluator_create in -lmatheval... " >&6; } -if ${ac_cv_lib_matheval_evaluator_create+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lmatheval $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char evaluator_create (); -int -main () -{ -return evaluator_create (); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_lib_matheval_evaluator_create=yes -else - ac_cv_lib_matheval_evaluator_create=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_matheval_evaluator_create" >&5 -$as_echo "$ac_cv_lib_matheval_evaluator_create" >&6; } -if test "x$ac_cv_lib_matheval_evaluator_create" = xyes; then : - LIBS="-lmatheval $LIBS" && found=ok -fi - - fi - - -fi - - -fi - - - if test $found == ok ; then - $as_echo "#define __PLUMED_HAS_MATHEVAL 1" >>confdefs.h - - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot enable __PLUMED_HAS_MATHEVAL" >&5 -$as_echo "$as_me: WARNING: cannot enable __PLUMED_HAS_MATHEVAL" >&2;} - fi - -fi if test $readdir_r == true ; then found=ko diff --git a/configure.ac b/configure.ac index ee30c401e..5c8065f4b 100644 --- a/configure.ac +++ b/configure.ac @@ -191,7 +191,6 @@ PLUMED_CONFIG_ENABLE([external_lapack],[external-lapack],[search for external la PLUMED_CONFIG_ENABLE([external_blas],[external-blas],[search for external blas],[yes]) PLUMED_CONFIG_ENABLE([molfile_plugins],[molfile-plugins],[use molfile_plugins],[yes]) PLUMED_CONFIG_ENABLE([external_molfile_plugins],[external-molfile-plugins],[search for external molfile_plugins],[yes]) -PLUMED_CONFIG_ENABLE([matheval],[matheval],[search for matheval],[yes]) PLUMED_CONFIG_ENABLE([zlib],[zlib],[search for zlib],[yes]) PLUMED_CONFIG_ENABLE([readdir_r],[readdir-r],[search for readdir_r (threadsafe)],[yes]) PLUMED_CONFIG_ENABLE([cregex],[cregex],[search for C regular expression],[yes]) @@ -549,9 +548,6 @@ fi # when configuring with --disable-openmp AC_OPENMP -if test $matheval == true ; then - PLUMED_CHECK_PACKAGE([matheval.h],[evaluator_create],[__PLUMED_HAS_MATHEVAL],[matheval]) -fi if test $readdir_r == true ; then PLUMED_CHECK_PACKAGE([dirent.h],[readdir_r],[__PLUMED_HAS_READDIR_R]) fi diff --git a/src/core/CLToolMain.cpp b/src/core/CLToolMain.cpp index cab6dc964..607a2d8fb 100644 --- a/src/core/CLToolMain.cpp +++ b/src/core/CLToolMain.cpp @@ -122,8 +122,6 @@ int CLToolMain::run(int argc, char **argv,FILE*in,FILE*out,Communicator& pc) { } else if(a=="--has-mpi") { if(Communicator::initialized()) return 0; else return 1; - } else if(a=="--has-matheval") { - return (config::hasMatheval()?0:1); } else if(a=="--has-cregex") { return (config::hasCregex()?0:1); } else if(a=="--has-dlopen") { @@ -203,7 +201,6 @@ int CLToolMain::run(int argc, char **argv,FILE*in,FILE*out,Communicator& pc) { " [help|-h|--help] : to print this help\n" " [--is-installed] : fails if plumed is not installed\n" " [--has-mpi] : fails if plumed is running without MPI\n" - " [--has-matheval] : fails if plumed is compiled without matheval\n" " [--has-dlopen] : fails if plumed is compiled without dlopen\n" " [--load LIB] : loads a shared object (typically a plugin library)\n" " [--standalone-executable] : tells plumed not to look for commands implemented as scripts\n" diff --git a/src/function/Matheval.cpp b/src/function/Matheval.cpp index a98b6bf48..64d112e14 100644 --- a/src/function/Matheval.cpp +++ b/src/function/Matheval.cpp @@ -22,10 +22,6 @@ #include "ActionRegister.h" #include "Function.h" -#ifdef __PLUMED_HAS_MATHEVAL -#include <matheval.h> -#endif - #include "lepton/Lepton.h" using namespace std; @@ -188,18 +184,14 @@ progression (S) and distance (Z) variables \cite perez2015atp. class Matheval : public Function { - const bool use_lepton; lepton::CompiledExpression expression; std::vector<lepton::CompiledExpression> expression_deriv; - void* evaluator; - vector<void*> evaluator_deriv; vector<string> var; string func; vector<double> values; vector<char*> names; public: explicit Matheval(const ActionOptions&); - ~Matheval(); void calculate(); static void registerKeywords(Keywords& keys); }; @@ -242,10 +234,7 @@ void Matheval::registerKeywords(Keywords& keys) { Matheval::Matheval(const ActionOptions&ao): Action(ao), Function(ao), - use_lepton(std::getenv("PLUMED_USE_LEPTON")), expression_deriv(getNumberOfArguments()), - evaluator(NULL), - evaluator_deriv(getNumberOfArguments(),NULL), values(getNumberOfArguments()), names(getNumberOfArguments()) { @@ -269,97 +258,42 @@ Matheval::Matheval(const ActionOptions&ao): for(unsigned i=0; i<var.size(); i++) log.printf(" %s",var[i].c_str()); log.printf("\n"); - if(use_lepton) { - log<<" WARNING: you are using lepton as a replacement for libmatheval\n"; - lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(leptonConstants); - log<<" function as parsed by lepton: "<<pe<<"\n"; - expression=pe.createCompiledExpression(); - for(auto &p: expression.getVariables()) { - if(std::find(var.begin(),var.end(),p)==var.end()) { - error("variable " + p + " is not defined"); - } - } - log<<" derivatives as computed by lepton:\n"; - for(unsigned i=0; i<getNumberOfArguments(); i++) { - lepton::ParsedExpression pe=lepton::Parser::parse(func).differentiate(var[i]).optimize(leptonConstants); - log<<" "<<pe<<"\n"; - expression_deriv[i]=pe.createCompiledExpression(); + lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(leptonConstants); + log<<" function as parsed by lepton: "<<pe<<"\n"; + expression=pe.createCompiledExpression(); + for(auto &p: expression.getVariables()) { + if(std::find(var.begin(),var.end(),p)==var.end()) { + error("variable " + p + " is not defined"); } - } else { -#ifdef __PLUMED_HAS_MATHEVAL - evaluator=evaluator_create(const_cast<char*>(func.c_str())); - if(!evaluator) error("There was some problem in parsing matheval formula "+func); - char **check_names; - int check_count; - evaluator_get_variables(evaluator,&check_names,&check_count); - if(check_count!=int(getNumberOfArguments())) { - string sc; - Tools::convert(check_count,sc); - error("Your function string contains "+sc+" arguments. This should be equal to the number of ARGs"); - } - for(unsigned i=0; i<getNumberOfArguments(); i++) { - bool found=false; - for(unsigned j=0; j<getNumberOfArguments(); j++) { - if(var[i]==check_names[j])found=true; - } - if(!found) - error("Variable "+var[i]+" cannot be found in your function string"); - } - for(unsigned i=0; i<getNumberOfArguments(); i++) - evaluator_deriv[i]=evaluator_derivative(evaluator,const_cast<char*>(var[i].c_str())); - log.printf(" function as parsed by matheval: %s\n", evaluator_get_string(evaluator)); - log.printf(" derivatives as computed by matheval:\n"); - for(unsigned i=0; i<var.size(); i++) log.printf(" %s\n",evaluator_get_string(evaluator_deriv[i])); -#else - error("MATHEVAL not available, please export PLUMED_USE_LEPTON=yes"); -#endif + } + log<<" derivatives as computed by lepton:\n"; + for(unsigned i=0; i<getNumberOfArguments(); i++) { + lepton::ParsedExpression pe=lepton::Parser::parse(func).differentiate(var[i]).optimize(leptonConstants); + log<<" "<<pe<<"\n"; + expression_deriv[i]=pe.createCompiledExpression(); } } void Matheval::calculate() { - if(use_lepton) { - for(unsigned i=0; i<getNumberOfArguments(); i++) { - try { - expression.getVariableReference(var[i])=getArgument(i); - } catch(PLMD::lepton::Exception& exc) { + for(unsigned i=0; i<getNumberOfArguments(); i++) { + try { + expression.getVariableReference(var[i])=getArgument(i); + } catch(PLMD::lepton::Exception& exc) { // this is necessary since in some cases lepton things a variable is not present even though it is present // e.g. func=0*x - } } - setValue(expression.evaluate()); - for(unsigned i=0; i<getNumberOfArguments(); i++) { - for(unsigned j=0; j<getNumberOfArguments(); j++) { - try { - expression_deriv[i].getVariableReference(var[j])=getArgument(j); - } catch(PLMD::lepton::Exception& exc) { + } + setValue(expression.evaluate()); + for(unsigned i=0; i<getNumberOfArguments(); i++) { + for(unsigned j=0; j<getNumberOfArguments(); j++) { + try { + expression_deriv[i].getVariableReference(var[j])=getArgument(j); + } catch(PLMD::lepton::Exception& exc) { // this is necessary since in some cases lepton things a variable is not present even though it is present // e.g. func=0*x - } } - setDerivative(i,expression_deriv[i].evaluate()); } - } else { -#ifdef __PLUMED_HAS_MATHEVAL - for(unsigned i=0; i<getNumberOfArguments(); i++) values[i]=getArgument(i); - for(unsigned i=0; i<getNumberOfArguments(); i++) names[i]=const_cast<char*>(var[i].c_str()); - setValue(evaluator_evaluate(evaluator,names.size(),&names[0],&values[0])); - for(unsigned i=0; i<getNumberOfArguments(); i++) { - setDerivative(i,evaluator_evaluate(evaluator_deriv[i],names.size(),&names[0],&values[0])); - } -#else - error("MATHEVAL not available, please export PLUMED_USE_LEPTON=yes"); -#endif - } -} - -Matheval::~Matheval() { - if(evaluator) { -#ifdef __PLUMED_HAS_MATHEVAL - evaluator_destroy(evaluator); - for(unsigned i=0; i<evaluator_deriv.size(); i++)evaluator_destroy(evaluator_deriv[i]); -#else - error("MATHEVAL not available, please export PLUMED_USE_LEPTON=yes"); -#endif + setDerivative(i,expression_deriv[i].evaluate()); } } diff --git a/src/tools/SwitchingFunction.cpp b/src/tools/SwitchingFunction.cpp index a7df6332e..168d8452f 100644 --- a/src/tools/SwitchingFunction.cpp +++ b/src/tools/SwitchingFunction.cpp @@ -26,10 +26,6 @@ #include <vector> #include <limits> -#ifdef __PLUMED_HAS_MATHEVAL -#include <matheval.h> -#endif - using namespace std; namespace PLMD { @@ -253,7 +249,7 @@ void SwitchingFunction::set(const std::string & definition,std::string& errormsg else if(name=="GAUSSIAN") type=gaussian; else if(name=="CUBIC") type=cubic; else if(name=="TANH") type=tanh; - else if((name=="MATHEVAL" || name=="CUSTOM") && std::getenv("PLUMED_USE_LEPTON")) { + else if((name=="MATHEVAL" || name=="CUSTOM")) { type=leptontype; std::string func; Tools::parse(data,"FUNC",func); @@ -265,34 +261,6 @@ void SwitchingFunction::set(const std::string & definition,std::string& errormsg expression_deriv.resize(OpenMP::getNumThreads()); for(auto & e : expression_deriv) e=ped.createCompiledExpression(); } -#ifdef __PLUMED_HAS_MATHEVAL - else if(name=="MATHEVAL" || name=="CUSTOM") { - type=matheval; - std::string func; - Tools::parse(data,"FUNC",func); - const unsigned nt=OpenMP::getNumThreads(); - plumed_assert(nt>0); - evaluator.resize(nt); - for(unsigned i=0; i<nt; i++) { - evaluator[i]=evaluator_create(const_cast<char*>(func.c_str())); - } - char **check_names; - int check_count; - evaluator_get_variables(evaluator[0],&check_names,&check_count); - if(check_count!=1) { - errormsg="wrong number of arguments in MATHEVAL switching function"; - return; - } - if(std::string(check_names[0])!="x") { - errormsg ="argument should be named 'x'"; - return; - } - evaluator_deriv.resize(nt); - for(unsigned i=0; i<nt; i++) { - evaluator_deriv[i]=evaluator_derivative(evaluator[i],const_cast<char*>("x")); - } - } -#endif else errormsg="cannot understand switching function type '"+name+"'"; if( !data.empty() ) { errormsg="found the following rogue keywords in switching function input : "; @@ -327,10 +295,6 @@ std::string SwitchingFunction::description() const { ostr<<"tanh"; } else if(type==leptontype) { ostr<<"lepton"; -#ifdef __PLUMED_HAS_MATHEVAL - } else if(type==matheval) { - ostr<<"matheval"; -#endif } else { plumed_merror("Unknown switching function type"); } @@ -345,10 +309,6 @@ std::string SwitchingFunction::description() const { ostr<<" dmax="<<dmax; } else if(type==leptontype) { ostr<<" func="<<lepton_func; -#ifdef __PLUMED_HAS_MATHEVAL - } else if(type==matheval) { - ostr<<" func="<<evaluator_get_string(evaluator[0]); -#endif } return ostr.str(); @@ -449,12 +409,6 @@ double SwitchingFunction::calculate(double distance,double&dfunc)const { } result=expression[t].evaluate(); dfunc=expression_deriv[t].evaluate(); -#ifdef __PLUMED_HAS_MATHEVAL - } else if(type==matheval) { - const unsigned it=OpenMP::getThreadNum(); - result=evaluator_evaluate_x(evaluator[it],rdist); - dfunc=evaluator_evaluate_x(evaluator_deriv[it],rdist); -#endif } else plumed_merror("Unknown switching function type"); // this is for the chain rule: dfunc*=invr0; @@ -511,18 +465,6 @@ SwitchingFunction::SwitchingFunction(const SwitchingFunction&sf): stretch(sf.stretch), shift(sf.shift) { -#ifdef __PLUMED_HAS_MATHEVAL - if(sf.evaluator.size()>0) { - const unsigned nt=OpenMP::getNumThreads(); - plumed_assert(nt>0); - evaluator.resize(nt); - evaluator_deriv.resize(nt); - for(unsigned i=0; i<nt; i++) { - evaluator[i]=evaluator_create(evaluator_get_string(sf.evaluator[0])); - evaluator_deriv[i]=evaluator_create(evaluator_get_string(sf.evaluator_deriv[0])); - } - } -#endif } SwitchingFunction & SwitchingFunction::operator=(const SwitchingFunction& sf) { @@ -545,18 +487,6 @@ SwitchingFunction & SwitchingFunction::operator=(const SwitchingFunction& sf) { dmax_2=sf.dmax_2; stretch=sf.stretch; shift=sf.shift; -#ifdef __PLUMED_HAS_MATHEVAL - if(sf.evaluator.size()>0) { - const unsigned nt=OpenMP::getNumThreads(); - plumed_assert(nt>0); - evaluator.resize(nt); - evaluator_deriv.resize(nt); - for(unsigned i=0; i<nt; i++) { - evaluator[i]=evaluator_create(evaluator_get_string(sf.evaluator[0])); - evaluator_deriv[i]=evaluator_create(evaluator_get_string(sf.evaluator_deriv[0])); - } - } -#endif return *this; } @@ -596,13 +526,6 @@ double SwitchingFunction::get_dmax2() const { return dmax_2; } -SwitchingFunction::~SwitchingFunction() { -#ifdef __PLUMED_HAS_MATHEVAL - for(unsigned i=0; i<evaluator.size(); i++) evaluator_destroy(evaluator[i]); - for(unsigned i=0; i<evaluator_deriv.size(); i++) evaluator_destroy(evaluator_deriv[i]); -#endif -} - } diff --git a/src/tools/SwitchingFunction.h b/src/tools/SwitchingFunction.h index 65c90e711..1536b786e 100644 --- a/src/tools/SwitchingFunction.h +++ b/src/tools/SwitchingFunction.h @@ -75,20 +75,10 @@ class SwitchingFunction { /// Lepton expression for derivative /// \warning Since lepton::CompiledExpression is mutable, a vector is necessary for multithreading! std::vector<lepton::CompiledExpression> expression_deriv; -/// Evaluator for matheval: -/// \warning Since evaluator is not thread safe, we should create one -/// evaluator per thread. - std::vector<void*> evaluator; -/// Evaluator for matheval: -/// \warning Since evaluator is not thread safe, we should create one -/// evaluator per thread. - std::vector<void*> evaluator_deriv; public: static void registerKeywords( Keywords& keys ); /// Constructor SwitchingFunction(); -/// Destructor - ~SwitchingFunction(); /// Copy constructor SwitchingFunction(const SwitchingFunction&); /// Assignment operator -- GitLab