From 64f5a686dbfb128b7dfce1d6d842ba976da8c22f Mon Sep 17 00:00:00 2001 From: Chris Dyer Date: Thu, 11 Oct 2012 21:57:18 -0400 Subject: add support for dlopen'd feature functions --- decoder/Makefile.am | 1 + decoder/cdec_ff.cc | 2 ++ decoder/ff.h | 1 + decoder/ff_external.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ decoder/ff_external.h | 26 +++++++++++++++++++++++ 5 files changed, 87 insertions(+) create mode 100644 decoder/ff_external.cc create mode 100644 decoder/ff_external.h (limited to 'decoder') diff --git a/decoder/Makefile.am b/decoder/Makefile.am index 4a98a4f1..28863dbe 100644 --- a/decoder/Makefile.am +++ b/decoder/Makefile.am @@ -33,6 +33,7 @@ libcdec_a_SOURCES = \ cfg.cc \ dwarf.cc \ ff_dwarf.cc \ + ff_external.cc \ rule_lexer.cc \ fst_translator.cc \ csplit.cc \ diff --git a/decoder/cdec_ff.cc b/decoder/cdec_ff.cc index b516c386..54f6e12b 100644 --- a/decoder/cdec_ff.cc +++ b/decoder/cdec_ff.cc @@ -18,6 +18,7 @@ #include "ff_charset.h" #include "ff_wordset.h" #include "ff_dwarf.h" +#include "ff_external.h" #ifdef HAVE_GLC #include @@ -69,6 +70,7 @@ void register_feature_functions() { ff_registry.Register("WordPairFeatures", new FFFactory); ff_registry.Register("WordSet", new FFFactory); ff_registry.Register("Dwarf", new FFFactory); + ff_registry.Register("External", new FFFactory); #ifdef HAVE_GLC ff_registry.Register("ContextCRF", new FFFactory); #endif diff --git a/decoder/ff.h b/decoder/ff.h index 6c22d39f..227787ca 100644 --- a/decoder/ff.h +++ b/decoder/ff.h @@ -27,6 +27,7 @@ typedef std::vector Features; // set of features ids // depends on context, you may also need to implement // FinalTraversalFeatures(...) class FeatureFunction { + friend class ExternalFeature; public: std::string name_; // set by FF factory using usage() bool debug_; // also set by FF factory checking param for immediate initial "debug" diff --git a/decoder/ff_external.cc b/decoder/ff_external.cc new file mode 100644 index 00000000..520e98b1 --- /dev/null +++ b/decoder/ff_external.cc @@ -0,0 +1,57 @@ +#include "ff_external.h" +#include "stringlib.h" + +#include + +using namespace std; + +ExternalFeature::ExternalFeature(const string& param) { + size_t pos = param.find(' '); + string nparam; + string file = param; + if (pos < param.size()) { + nparam = Trim(param.substr(pos + 1)); + file = param.substr(0, pos); + } + if (file.size() < 1) { + cerr << "External requires a path to a dynamic library!\n"; + abort(); + } + lib_handle = dlopen(file.c_str(), RTLD_LAZY); + if (!lib_handle) { + cerr << "dlopen reports: " << dlerror() << endl; + cerr << "Did you provide a full path to the dynamic library?\n"; + abort(); + } + FeatureFunction* (*fn)(const string&) = + (FeatureFunction* (*)(const string&))(dlsym(lib_handle, "create_ff")); + if (!fn) { + cerr << "dlsym reports: " << dlerror() << endl; + abort(); + } + ff_ext = (*fn)(nparam); +} + +ExternalFeature::~ExternalFeature() { + delete ff_ext; + dlclose(lib_handle); +} + +void ExternalFeature::PrepareForInput(const SentenceMetadata& smeta) { + ff_ext->PrepareForInput(smeta); +} + +void ExternalFeature::FinalTraversalFeatures(const void* context, + SparseVector* features) const { + ff_ext->FinalTraversalFeatures(context, features); +} + +void ExternalFeature::TraversalFeaturesImpl(const SentenceMetadata& smeta, + const Hypergraph::Edge& edge, + const std::vector& ant_contexts, + FeatureVector* features, + FeatureVector* estimated_features, + void* context) const { + ff_ext->TraversalFeaturesImpl(smeta, edge, ant_contexts, features, estimated_features, context); +} + diff --git a/decoder/ff_external.h b/decoder/ff_external.h new file mode 100644 index 00000000..283e58e8 --- /dev/null +++ b/decoder/ff_external.h @@ -0,0 +1,26 @@ +#ifndef _FFEXTERNAL_H_ +#define _FFEXTERNAL_H_ + +#include "ff.h" + +// dynamically loaded feature function +class ExternalFeature : public FeatureFunction { + public: + ExternalFeature(const std::string& param); + ~ExternalFeature(); + virtual void PrepareForInput(const SentenceMetadata& smeta); + virtual void FinalTraversalFeatures(const void* context, + SparseVector* features) const; + protected: + virtual void TraversalFeaturesImpl(const SentenceMetadata& smeta, + const Hypergraph::Edge& edge, + const std::vector& ant_contexts, + FeatureVector* features, + FeatureVector* estimated_features, + void* context) const; + private: + void* lib_handle; + FeatureFunction* ff_ext; +}; + +#endif -- cgit v1.2.3