From f88f7a9e745b335ee3e1d809ed5c6d641b5c2bd5 Mon Sep 17 00:00:00 2001 From: Lukas Krenz Date: Wed, 26 Jan 2022 16:29:59 +0100 Subject: [PATCH 1/6] Add initial support for Lua --- CMakeLists.txt | 29 +++++++- cmake/easiConfig.cmake.in | 5 ++ examples/4_lua.yaml | 14 ++++ include/easi/component/LuaMap.h | 35 +++++++++ include/easi/parser/YAMLComponentParsers.h | 5 ++ src/YAMLParser.cpp | 3 + src/component/LuaMap.cpp | 87 ++++++++++++++++++++++ src/parser/YAMLComponentParsers.cpp | 12 +++ tests/4_lua.cpp | 34 +++++++++ 9 files changed, 220 insertions(+), 4 deletions(-) create mode 100644 examples/4_lua.yaml create mode 100644 include/easi/component/LuaMap.h create mode 100644 src/component/LuaMap.cpp create mode 100644 tests/4_lua.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 24a1c1f..aaa9f8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,8 @@ set(IMPALAJIT_BACKEND original CACHE STRING "Which backend to use") set(IMPALAJIT_BACKEND_OPTIONS original llvm) set_property(CACHE IMPALAJIT_BACKEND PROPERTY STRINGS ${IMPALAJIT_BACKEND_OPTIONS}) +option(LUA "Use Lua" OFF) + function(check_parameter parameter_name value options) list(FIND options ${value} INDEX) @@ -30,7 +32,7 @@ function(check_parameter parameter_name value options) endfunction() check_parameter("IMPALAJIT_BACKEND" "${IMPALAJIT_BACKEND}" "${IMPALAJIT_BACKEND_OPTIONS}") - ### external packages ### +### external packages ### find_package(yaml-cpp 0.6 REQUIRED) find_package(OpenMP) @@ -43,6 +45,10 @@ if(IMPALAJIT) endif() endif() +if (LUA) + find_package(Lua REQUIRED) +endif() + if(ASAGI) find_package (PkgConfig REQUIRED) find_package (HDF5 REQUIRED COMPONENTS C HL) @@ -60,6 +66,7 @@ set(EASI_SOURCES src/component/DomainFilter.cpp src/component/EvalModel.cpp src/component/FunctionMap.cpp + src/component/LuaMap.cpp src/component/LayeredModelBuilder.cpp src/component/OptimalStress.cpp src/component/PolynomialMap.cpp @@ -94,6 +101,7 @@ target_link_libraries(easi if(${OpenMP_CXX_FOUND}) target_link_libraries(easi PRIVATE OpenMP::OpenMP_CXX) endif() + if(ASAGI) find_package(MPI REQUIRED) target_link_libraries(easi @@ -103,18 +111,25 @@ if(ASAGI) PkgConfig::NETCDF ) target_link_libraries(easi - PRIVATE + PUBLIC MPI::MPI_CXX ) - target_compile_definitions(easi PRIVATE -DEASI_USE_ASAGI) + target_compile_definitions(easi PRIVATE EASI_USE_ASAGI) endif() + if (IMPALAJIT) if (IMPALAJIT_BACKEND STREQUAL "llvm") target_link_libraries(easi PRIVATE llvm::impalajit) else() target_link_libraries(easi PRIVATE impalajit::impalajit) endif() - target_compile_definitions(easi PRIVATE -DEASI_USE_IMPALAJIT) + target_compile_definitions(easi PRIVATE EASI_USE_IMPALAJIT) +endif() + +if (LUA) + target_include_directories(easi PRIVATE ${LUA_INCLUDE_DIR}) + target_link_libraries(easi PRIVATE ${LUA_LIBRARIES}) + target_compile_definitions(easi PRIVATE EASI_USE_LUA) endif() target_include_directories(easi @@ -215,3 +230,9 @@ if(ASAGI) easi_add_test(101_asagi_nearest) endif () +if (LUA) + easi_add_test(4_lua) +endif() + + + diff --git a/cmake/easiConfig.cmake.in b/cmake/easiConfig.cmake.in index 90631f2..7fbd13b 100644 --- a/cmake/easiConfig.cmake.in +++ b/cmake/easiConfig.cmake.in @@ -1,6 +1,7 @@ @PACKAGE_INIT@ set(EASI_IMPALAJIT_BACKEND @IMPALAJIT_BACKEND@) set(EASI_IMPALAJIT @IMPALAJIT@) +set(EASI_LUA @LUA@) set(EASI_ASAGI @ASAGI@) include(CMakeFindDependencyMacro) @@ -16,6 +17,10 @@ if (EASI_IMPALAJIT) endif() endif() +if (EASI_LUA) + find_package(Lua REQUIRED) +endif() + if (EASI_ASAGI) find_dependency(PkgConfig) pkg_check_modules(ASAGI REQUIRED IMPORTED_TARGET asagi) diff --git a/examples/4_lua.yaml b/examples/4_lua.yaml new file mode 100644 index 0000000..ffdc6eb --- /dev/null +++ b/examples/4_lua.yaml @@ -0,0 +1,14 @@ +!Any +components: + - !GroupFilter + groups: [6,7,8] + components: !ConstantMap + map: + rho: 2500.0 + mu: 0.0 + lambda: 1.96e10 + - !LuaMap + map: + rho: return 1600. + 59.5 * (x[2] ^ (1./3.)) + mu: return 0. + lambda: return (260. + 30*math.sqrt(x[2]))^2. * (1600. + 59.5 * x[2] ^(1./3.) ) diff --git a/include/easi/component/LuaMap.h b/include/easi/component/LuaMap.h new file mode 100644 index 0000000..0591980 --- /dev/null +++ b/include/easi/component/LuaMap.h @@ -0,0 +1,35 @@ +#ifndef EASI_LUAMAP_H +#define EASI_LUAMAP_H + +#ifdef EASI_USE_LUA +#include "easi/component/Map.h" +#include "easi/util/FunctionWrapper.h" +#include "easi/util/Matrix.h" + +#include +#include +#include +#include + +namespace easi { +class LuaMap : public Map { +public: + typedef std::map OutMap; + + virtual ~LuaMap() {} + + void setMap(std::set const& in, OutMap const& functionMap); + +protected: + virtual Matrix map(Matrix& x); + +private: + double executeLua(Matrix x, unsigned coordIdx, unsigned funcIdx); + std::vector functionStrings; +}; + +} // namespace easi + +#endif // EASI_USE_LUA + +#endif diff --git a/include/easi/parser/YAMLComponentParsers.h b/include/easi/parser/YAMLComponentParsers.h index 6a642bc..f6d973d 100644 --- a/include/easi/parser/YAMLComponentParsers.h +++ b/include/easi/parser/YAMLComponentParsers.h @@ -8,6 +8,7 @@ #include "easi/component/DomainFilter.h" #include "easi/component/EvalModel.h" #include "easi/component/FunctionMap.h" +#include "easi/component/LuaMap.h" #include "easi/component/GroupFilter.h" #include "easi/component/LayeredModelBuilder.h" #include "easi/component/OptimalStress.h" @@ -57,6 +58,10 @@ void parse_AffineMap(AffineMap* component, YAML::Node const& node, std::set const& in, YAMLAbstractParser* parser); #endif +#ifdef EASI_USE_LUA +void parse_LuaMap(LuaMap* component, YAML::Node const& node, + std::set const& in, YAMLAbstractParser* parser); +#endif void parse_PolynomialMap(PolynomialMap* component, YAML::Node const& node, std::set const& in, YAMLAbstractParser* parser); void parse_SCECFile(SCECFile* component, YAML::Node const& node, std::set const& in, diff --git a/src/YAMLParser.cpp b/src/YAMLParser.cpp index 7c0a5bb..3a9b794 100644 --- a/src/YAMLParser.cpp +++ b/src/YAMLParser.cpp @@ -33,6 +33,9 @@ YAMLParser::YAMLParser(unsigned dimDomain, AsagiReader* externalAsagiReader, cha registerType("!AffineMap", parse_AffineMap); #ifdef EASI_USE_IMPALAJIT registerType("!FunctionMap", parse_FunctionMap); +#endif +#ifdef EASI_USE_LUA + registerType("!LuaMap", parse_LuaMap); #endif registerType("!SCECFile", parse_SCECFile); #ifdef EASI_USE_ASAGI diff --git a/src/component/LuaMap.cpp b/src/component/LuaMap.cpp new file mode 100644 index 0000000..89221d5 --- /dev/null +++ b/src/component/LuaMap.cpp @@ -0,0 +1,87 @@ +#include "easi/component/LuaMap.h" + +#ifdef EASI_USE_LUA +extern "C" { +#include +#include +#include +} + +#include +#include +#include +#include + +namespace easi { + +double LuaMap::executeLua(Matrix x, + unsigned coordIdx, + unsigned funcIdx) { + auto L = luaL_newstate(); + luaL_openlibs(L); + const auto& script = functionStrings[funcIdx]; + const auto status = luaL_loadstring(L, script.data()); + if (status) { + std::cerr + << "Couldn't load script: " + << lua_tostring(L, -1); + } + + // Setup input vector + lua_newtable(L); + for (int i = 0; i < 3; ++i) { + lua_pushnumber(L, i+1); + lua_pushnumber(L, x(coordIdx, i)); + lua_rawset(L, -3); + } + lua_setglobal(L, "x"); + + auto result = lua_pcall(L, 0, LUA_MULTRET, 0); + if (result != 0) { + std::cerr + << "error running script" + << lua_tostring(L, -1) + << std::endl; + } + + double number = lua_tonumber(L, -1); // Get top of stack + + std::cout << number << std::endl; + + lua_pop(L, 1); // remove number from stack + lua_close(L); + + return number; +} + +Matrix LuaMap::map(Matrix& x) { + + assert(x.cols() == dimDomain()); + + Matrix y(x.rows(), dimCodomain()); + for (unsigned i = 0; i < y.rows(); ++i) { + for (unsigned j = 0; j < y.cols(); ++j) { + y(i, j) = executeLua(x, i, j); + } + } + return y; +} + +void LuaMap::setMap(std::set const& in, OutMap const& functionMap) { + functionStrings.clear(); + std::vector functionDefinitions; + + for (const auto & it : functionMap) { + functionStrings.push_back(it.second); + } + std::set out; + for (auto const& kv : functionMap) { + out.insert(kv.first); + } + + setIn(in); + setOut(out); +} + +} // namespace easi +#endif // EASI_USE_LUA \ No newline at end of file diff --git a/src/parser/YAMLComponentParsers.cpp b/src/parser/YAMLComponentParsers.cpp index 5b11462..63caa41 100644 --- a/src/parser/YAMLComponentParsers.cpp +++ b/src/parser/YAMLComponentParsers.cpp @@ -145,6 +145,18 @@ void parse_FunctionMap(FunctionMap* component, YAML::Node const& node, } #endif +#ifdef EASI_USE_LUA +void parse_LuaMap(LuaMap* component, YAML::Node const& node, + std::set const& in, YAMLAbstractParser* parser) { + checkType(node, "map", {YAML::NodeType::Map}); + + LuaMap::OutMap out = node["map"].as(); + + component->setMap(in, out); + parse_Map(component, node, in, parser); +} +#endif + void parse_PolynomialMap(PolynomialMap* component, YAML::Node const& node, std::set const& in, YAMLAbstractParser* parser) { checkType(node, "map", {YAML::NodeType::Map}); diff --git a/tests/4_lua.cpp b/tests/4_lua.cpp new file mode 100644 index 0000000..63e4bd5 --- /dev/null +++ b/tests/4_lua.cpp @@ -0,0 +1,34 @@ +#include "easitest.h" +#include + +double rho(double y) { return 1600. + 59.5 * pow(y, 1. / 3.); } +double lambda(double y) { return pow(260. + 30 * sqrt(y), 2.) * (1600. + 59.5 * pow(y, 1. / 3.)); } + +int main(int argc, char** argv) { + assert(argc == 2); + + easi::Query query = createQuery<3>({{7, {0.0, 0.0, 0.0}}, + {5, {0.0, 10.0, 0.0}}, + {4, {0.0, 20.0, 0.0}}, + {3, {0.0, 25.0, 0.0}}}); + + auto material = elasticModel(argv[1], query); + + assert(equal(material[0].rho, 2500.0)); + assert(equal(material[0].mu, 0.0)); + assert(equal(material[0].lambda, 1.96e10)); + + assert(equal(material[1].rho, rho(10.0))); + assert(equal(material[1].mu, 0.0)); + assert(equal(material[1].lambda, lambda(10.0))); + + assert(equal(material[2].rho, rho(20.0))); + assert(equal(material[2].mu, 0.0)); + assert(equal(material[2].lambda, lambda(20.0))); + + assert(equal(material[3].rho, rho(25.0))); + assert(equal(material[3].mu, 0.0)); + assert(equal(material[3].lambda, lambda(25.0))); + + return 0; +} From b96623377f182d758ff696613dddaef647de8e3a Mon Sep 17 00:00:00 2001 From: Lukas Krenz Date: Mon, 7 Feb 2022 18:32:18 +0100 Subject: [PATCH 2/6] Use Lua function --- examples/4_lua.yaml | 15 ++++-- include/easi/component/LuaMap.h | 23 ++++++--- src/component/LuaMap.cpp | 77 ++++++++++++++++------------- src/parser/YAMLComponentParsers.cpp | 16 ++++-- 4 files changed, 82 insertions(+), 49 deletions(-) diff --git a/examples/4_lua.yaml b/examples/4_lua.yaml index ffdc6eb..681b8fa 100644 --- a/examples/4_lua.yaml +++ b/examples/4_lua.yaml @@ -8,7 +8,14 @@ components: mu: 0.0 lambda: 1.96e10 - !LuaMap - map: - rho: return 1600. + 59.5 * (x[2] ^ (1./3.)) - mu: return 0. - lambda: return (260. + 30*math.sqrt(x[2]))^2. * (1600. + 59.5 * x[2] ^(1./3.) ) + returns: ["rho", "mu", "lambda"] + function: | + function f (x) + io.write(x[1], " ", x[2], " ", x[3], "\n") + + return { + rho = 1600. + 59.5 * (x[2] ^ (1./3.)), + mu = 0, + lambda = (260. + 30*math.sqrt(x[2]))^2. * (1600. + 59.5 * x[2] ^(1./3.) ) + } + end diff --git a/include/easi/component/LuaMap.h b/include/easi/component/LuaMap.h index 0591980..a73210e 100644 --- a/include/easi/component/LuaMap.h +++ b/include/easi/component/LuaMap.h @@ -2,15 +2,19 @@ #define EASI_LUAMAP_H #ifdef EASI_USE_LUA -#include "easi/component/Map.h" -#include "easi/util/FunctionWrapper.h" -#include "easi/util/Matrix.h" - #include #include #include #include + + +#include "easi/component/Map.h" +#include "easi/util/FunctionWrapper.h" +#include "easi/util/Matrix.h" + +struct lua_State; + namespace easi { class LuaMap : public Map { public: @@ -18,14 +22,19 @@ class LuaMap : public Map { virtual ~LuaMap() {} - void setMap(std::set const& in, OutMap const& functionMap); + void setMap(const std::set& in, + const std::set& returns, + const std::string& function); protected: virtual Matrix map(Matrix& x); private: - double executeLua(Matrix x, unsigned coordIdx, unsigned funcIdx); - std::vector functionStrings; + double executeLuaFunction(Matrix x, unsigned coordIdx, unsigned funcIdx); + std::string function; + std::vector idxToNameMap; + + double getField(lua_State* L, const std::string& key); }; } // namespace easi diff --git a/src/component/LuaMap.cpp b/src/component/LuaMap.cpp index 89221d5..91e86f5 100644 --- a/src/component/LuaMap.cpp +++ b/src/component/LuaMap.cpp @@ -6,7 +6,6 @@ extern "C" { #include #include } - #include #include #include @@ -14,44 +13,42 @@ extern "C" { namespace easi { -double LuaMap::executeLua(Matrix x, - unsigned coordIdx, - unsigned funcIdx) { +double LuaMap::executeLuaFunction(Matrix xin, + unsigned coordIdx, + unsigned funcIdx) { auto L = luaL_newstate(); luaL_openlibs(L); - const auto& script = functionStrings[funcIdx]; - const auto status = luaL_loadstring(L, script.data()); + const auto status = luaL_dostring(L, function.data()); if (status) { std::cerr << "Couldn't load script: " << lua_tostring(L, -1); + std::abort(); } - // Setup input vector + double z; + + /* push functions and arguments */ lua_newtable(L); for (int i = 0; i < 3; ++i) { lua_pushnumber(L, i+1); - lua_pushnumber(L, x(coordIdx, i)); + lua_pushnumber(L, xin(coordIdx, i)); lua_rawset(L, -3); } + lua_pushstring(L, "test"); + lua_pushnumber(L, 42); + lua_rawset(L, -3); lua_setglobal(L, "x"); + lua_getglobal(L, "f"); /* function to be called */ + lua_getglobal(L, "x"); - auto result = lua_pcall(L, 0, LUA_MULTRET, 0); - if (result != 0) { + if (lua_pcall(L, 1, 1, 0) != 0) { std::cerr - << "error running script" - << lua_tostring(L, -1) - << std::endl; + << "Error running function f " + << lua_tostring(L, -1) + << std::endl; } - - double number = lua_tonumber(L, -1); // Get top of stack - - std::cout << number << std::endl; - - lua_pop(L, 1); // remove number from stack - lua_close(L); - - return number; + return getField(L, idxToNameMap[funcIdx]); } Matrix LuaMap::map(Matrix& x) { @@ -61,26 +58,36 @@ Matrix LuaMap::map(Matrix& x) { Matrix y(x.rows(), dimCodomain()); for (unsigned i = 0; i < y.rows(); ++i) { for (unsigned j = 0; j < y.cols(); ++j) { - y(i, j) = executeLua(x, i, j); + y(i,j) = executeLuaFunction(x, i, j); } } return y; } -void LuaMap::setMap(std::set const& in, OutMap const& functionMap) { - functionStrings.clear(); - std::vector functionDefinitions; - - for (const auto & it : functionMap) { - functionStrings.push_back(it.second); - } - std::set out; - for (auto const& kv : functionMap) { - out.insert(kv.first); - } - +void LuaMap::setMap(const std::set& in, + const std::set& out, + const std::string& newFunction) { setIn(in); setOut(out); + function = newFunction; + for (const auto& o : out) { + idxToNameMap.push_back(o); + } +} + +double LuaMap::getField(lua_State* L, const std::string& key) { + lua_pushstring(L, key.data()); + lua_gettable(L, -2); + if (!lua_isnumber(L, -1)) { + std::cerr + << "Tried key " + << key + << " but it did not return a number." + << std::endl; + } + const auto result = lua_tonumber(L, -1); + lua_pop(L, 1); + return result; } } // namespace easi diff --git a/src/parser/YAMLComponentParsers.cpp b/src/parser/YAMLComponentParsers.cpp index 63caa41..de4bd5b 100644 --- a/src/parser/YAMLComponentParsers.cpp +++ b/src/parser/YAMLComponentParsers.cpp @@ -148,11 +148,21 @@ void parse_FunctionMap(FunctionMap* component, YAML::Node const& node, #ifdef EASI_USE_LUA void parse_LuaMap(LuaMap* component, YAML::Node const& node, std::set const& in, YAMLAbstractParser* parser) { - checkType(node, "map", {YAML::NodeType::Map}); + checkType(node, "returns", {YAML::NodeType::Scalar, YAML::NodeType::Sequence}); + + std::set returns; + if (node["returns"].IsScalar()) { + returns.insert(node["returns"].as()); + } else { + const auto returnSeq = node["returns"].as>(); + returns.insert(returnSeq.begin(), returnSeq.end()); + } - LuaMap::OutMap out = node["map"].as(); + checkType(node, "function", {YAML::NodeType::Scalar}); - component->setMap(in, out); + const auto function = node["function"].as(); + + component->setMap(in, returns, function); parse_Map(component, node, in, parser); } #endif From 666052973d9e810a5151e7a887c1932be6047b39 Mon Sep 17 00:00:00 2001 From: Lukas Krenz Date: Tue, 8 Feb 2022 17:13:50 +0100 Subject: [PATCH 3/6] Optimize Lua by compiling just once --- examples/4_lua.yaml | 6 +-- include/easi/component/LuaMap.h | 12 ++--- src/component/LuaMap.cpp | 81 ++++++++++++++++++--------------- 3 files changed, 54 insertions(+), 45 deletions(-) diff --git a/examples/4_lua.yaml b/examples/4_lua.yaml index 681b8fa..7270511 100644 --- a/examples/4_lua.yaml +++ b/examples/4_lua.yaml @@ -14,8 +14,8 @@ components: io.write(x[1], " ", x[2], " ", x[3], "\n") return { - rho = 1600. + 59.5 * (x[2] ^ (1./3.)), - mu = 0, - lambda = (260. + 30*math.sqrt(x[2]))^2. * (1600. + 59.5 * x[2] ^(1./3.) ) + rho = 1600. + 59.5 * (x[2] ^ (1./3.)), + mu = 0, + lambda = (260. + 30*math.sqrt(x[2]))^2. * (1600. + 59.5 * x[2] ^(1./3.) ) } end diff --git a/include/easi/component/LuaMap.h b/include/easi/component/LuaMap.h index a73210e..05d0512 100644 --- a/include/easi/component/LuaMap.h +++ b/include/easi/component/LuaMap.h @@ -13,28 +13,28 @@ #include "easi/util/FunctionWrapper.h" #include "easi/util/Matrix.h" +// Forward declaration to avoid including all Lua headers struct lua_State; namespace easi { +double getField(lua_State* L, const std::string& key); + class LuaMap : public Map { public: - typedef std::map OutMap; - - virtual ~LuaMap() {} - void setMap(const std::set& in, const std::set& returns, const std::string& function); + ~LuaMap() override; protected: - virtual Matrix map(Matrix& x); + virtual Matrix map(Matrix& x) override; private: double executeLuaFunction(Matrix x, unsigned coordIdx, unsigned funcIdx); std::string function; std::vector idxToNameMap; + lua_State* luaState; - double getField(lua_State* L, const std::string& key); }; } // namespace easi diff --git a/src/component/LuaMap.cpp b/src/component/LuaMap.cpp index 91e86f5..9d02d01 100644 --- a/src/component/LuaMap.cpp +++ b/src/component/LuaMap.cpp @@ -13,42 +13,58 @@ extern "C" { namespace easi { +double getField(lua_State* L, const std::string& key) { + lua_pushstring(L, key.data()); + lua_gettable(L, -2); + if (!lua_isnumber(L, -1)) { + std::cerr + << "Tried key " + << key + << " but it did not return a number." + << std::endl; + } + const auto result = lua_tonumber(L, -1); + lua_pop(L, 1); + return result; +} + double LuaMap::executeLuaFunction(Matrix xin, unsigned coordIdx, unsigned funcIdx) { - auto L = luaL_newstate(); - luaL_openlibs(L); - const auto status = luaL_dostring(L, function.data()); - if (status) { - std::cerr - << "Couldn't load script: " - << lua_tostring(L, -1); - std::abort(); + if (!luaState) { + std::cout << "Init lua state" << std::endl; + luaState = luaL_newstate(); + luaL_openlibs(luaState); + const auto status = luaL_dostring(luaState, function.data()); + if (status) { + std::cerr + << "Couldn't load script: " + << lua_tostring(luaState, -1); + std::abort(); + } } - double z; - /* push functions and arguments */ - lua_newtable(L); + lua_newtable(luaState); for (int i = 0; i < 3; ++i) { - lua_pushnumber(L, i+1); - lua_pushnumber(L, xin(coordIdx, i)); - lua_rawset(L, -3); + lua_pushnumber(luaState, i+1); + lua_pushnumber(luaState, xin(coordIdx, i)); + lua_rawset(luaState, -3); } - lua_pushstring(L, "test"); - lua_pushnumber(L, 42); - lua_rawset(L, -3); - lua_setglobal(L, "x"); - lua_getglobal(L, "f"); /* function to be called */ - lua_getglobal(L, "x"); + lua_pushstring(luaState, "test"); + lua_pushnumber(luaState, 42); + lua_rawset(luaState, -3); + lua_setglobal(luaState, "x"); + lua_getglobal(luaState, "f"); /* function to be called */ + lua_getglobal(luaState, "x"); - if (lua_pcall(L, 1, 1, 0) != 0) { + if (lua_pcall(luaState, 1, 1, 0) != 0) { std::cerr << "Error running function f " - << lua_tostring(L, -1) + << lua_tostring(luaState, -1) << std::endl; } - return getField(L, idxToNameMap[funcIdx]); + return getField(luaState, idxToNameMap[funcIdx]); } Matrix LuaMap::map(Matrix& x) { @@ -75,20 +91,13 @@ void LuaMap::setMap(const std::set& in, } } -double LuaMap::getField(lua_State* L, const std::string& key) { - lua_pushstring(L, key.data()); - lua_gettable(L, -2); - if (!lua_isnumber(L, -1)) { - std::cerr - << "Tried key " - << key - << " but it did not return a number." - << std::endl; - } - const auto result = lua_tonumber(L, -1); - lua_pop(L, 1); - return result; +LuaMap::~LuaMap() { + if (luaState) { + lua_close(luaState); + } } + + } // namespace easi #endif // EASI_USE_LUA \ No newline at end of file From 16336635f84cab2f24770a4a96e62c8d9ce05bba Mon Sep 17 00:00:00 2001 From: Lukas Krenz Date: Tue, 8 Feb 2022 17:29:46 +0100 Subject: [PATCH 4/6] X only input, not global Make implementation a bit cleaner --- src/component/LuaMap.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/component/LuaMap.cpp b/src/component/LuaMap.cpp index 9d02d01..a7284e4 100644 --- a/src/component/LuaMap.cpp +++ b/src/component/LuaMap.cpp @@ -28,7 +28,7 @@ double getField(lua_State* L, const std::string& key) { return result; } -double LuaMap::executeLuaFunction(Matrix xin, +double LuaMap::executeLuaFunction(Matrix x, unsigned coordIdx, unsigned funcIdx) { if (!luaState) { @@ -44,19 +44,16 @@ double LuaMap::executeLuaFunction(Matrix xin, } } - /* push functions and arguments */ + // Push function and arguments to stack + lua_getglobal(luaState, "f"); // the function + + // Add table as input: x holds coordinates lua_newtable(luaState); for (int i = 0; i < 3; ++i) { lua_pushnumber(luaState, i+1); - lua_pushnumber(luaState, xin(coordIdx, i)); + lua_pushnumber(luaState, x(coordIdx, i)); lua_rawset(luaState, -3); } - lua_pushstring(luaState, "test"); - lua_pushnumber(luaState, 42); - lua_rawset(luaState, -3); - lua_setglobal(luaState, "x"); - lua_getglobal(luaState, "f"); /* function to be called */ - lua_getglobal(luaState, "x"); if (lua_pcall(luaState, 1, 1, 0) != 0) { std::cerr From 20fd89637603cfdddb31b6f927d3f22b0afd46c3 Mon Sep 17 00:00:00 2001 From: Lukas Krenz Date: Wed, 9 Feb 2022 11:33:08 +0100 Subject: [PATCH 5/6] Make clear that debug output is optional --- examples/4_lua.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/4_lua.yaml b/examples/4_lua.yaml index 7270511..d55f49f 100644 --- a/examples/4_lua.yaml +++ b/examples/4_lua.yaml @@ -11,7 +11,7 @@ components: returns: ["rho", "mu", "lambda"] function: | function f (x) - io.write(x[1], " ", x[2], " ", x[3], "\n") + io.write(x[1], " ", x[2], " ", x[3], "\n") -- optional debug output return { rho = 1600. + 59.5 * (x[2] ^ (1./3.)), From 27a3131cfbe0b04595625e02b3c80e1faab4e7af Mon Sep 17 00:00:00 2001 From: Lukas Krenz Date: Wed, 9 Feb 2022 11:33:35 +0100 Subject: [PATCH 6/6] Bump version --- CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aaa9f8e..91ab18e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,8 @@ project(easi) cmake_minimum_required(VERSION 3.13) set(EASI_VERSION_MAJOR 1) -set(EASI_VERSION_MINOR 0) -set(EASI_VERSION_PATCH 1) - +set(EASI_VERSION_MINOR 1) +set(EASI_VERSION_PATCH 0) include(GNUInstallDirs) include(CMakePackageConfigHelpers)