Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable the C wrapper to extract model to memory and initialize model from memory #1189

Merged
merged 2 commits into from
Apr 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions vowpalwabbit/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,10 @@ const char* get_tag(example* ec)
size_t get_feature_number(example* ec)
{ return ec->num_features;
}

float get_confidence(example* ec)
{ return ec->confidence;
}
}

void initialize_examples(vw& all)
Expand Down
1 change: 1 addition & 0 deletions vowpalwabbit/vw.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ uint32_t* get_multilabel_predictions(example* ec, size_t& len);
size_t get_tag_length(example* ec);
const char* get_tag(example* ec);
size_t get_feature_number(example* ec);
float get_confidence(example* ec);
feature* get_features(vw& all, example* ec, size_t& feature_number);
void return_features(feature* f);

Expand Down
64 changes: 64 additions & 0 deletions vowpalwabbit/vwdll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ VW_DLL_MEMBER size_t VW_CALLING_CONV VW_GetFeatureNumber(VW_EXAMPLE e)
{ return VW::get_feature_number(static_cast<example*>(e));
}

VW_DLL_MEMBER float VW_CALLING_CONV VW_GetConfidence(VW_EXAMPLE e)
{ return VW::get_confidence(static_cast<example*>(e));
}

VW_DLL_MEMBER VW_FEATURE VW_CALLING_CONV VW_GetFeatures(VW_HANDLE handle, VW_EXAMPLE e, size_t* plen)
{ vw* pointer = static_cast<vw*>(handle);
return VW::get_features(*pointer, static_cast<example*>(e), *plen);
Expand Down Expand Up @@ -274,4 +278,64 @@ VW_DLL_MEMBER void VW_CALLING_CONV VW_SaveModel(VW_HANDLE handle)

return VW::save_predictor(*pointer, name);
}


class memory_io_buf : public io_buf
{
public:
memory_io_buf() : readOffset(0) {
files.push_back(-1); // this is a hack because buf will do nothing if files is empty
}

virtual ssize_t write_file(int file, const void* buf, size_t nbytes) {
auto byteBuf = reinterpret_cast<const char*>(buf);
data.insert(data.end(), &byteBuf[0], &byteBuf[nbytes]);
return nbytes;
}

virtual ssize_t read_file(int f, void* buf, size_t nbytes) {
nbytes = min(nbytes, data.size()-readOffset);
copy(data.data()+readOffset, data.data()+readOffset+nbytes, reinterpret_cast<char *>(buf));
readOffset += nbytes;
return nbytes;
}

char* GetDataPointer() {
return data.data();
}

size_t GetDataSize() const {
return data.size();
}

private:
vector<char> data;
size_t readOffset;
};

VW_DLL_MEMBER VW_HANDLE VW_CALLING_CONV VW_InitializeWithModel(const char * pstrArgs, const char * modelData, size_t modelDataSize)
{
unique_ptr<memory_io_buf> buf(new memory_io_buf);
buf->write_file(-1, modelData, modelDataSize);

vw* all = VW::initialize(string(pstrArgs), buf.get());
return static_cast<VW_HANDLE>(all);
}

VW_DLL_MEMBER void VW_CALLING_CONV VW_CopyModelData(VW_HANDLE handle, VW_IOBUF* outputBufferHandle, char** outputData, size_t* outputSize) {
vw* pointer = static_cast<vw*>(handle);

memory_io_buf* buf = new(memory_io_buf);
VW::save_predictor(*pointer, *buf);

*outputBufferHandle = buf;
*outputSize = buf->GetDataSize();
*outputData = buf->GetDataPointer();
}

VW_DLL_MEMBER void VW_CALLING_CONV VW_FreeIOBuf(VW_IOBUF bufferHandle) {
delete static_cast<memory_io_buf*>(bufferHandle);
}

}

5 changes: 5 additions & 0 deletions vowpalwabbit/vwdll.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ typedef void * VW_EXAMPLE;
typedef void * VW_LABEL;
typedef void * VW_FEATURE_SPACE;
typedef void * VW_FEATURE;
typedef void * VW_IOBUF;

const VW_HANDLE INVALID_VW_HANDLE = VW_TYPE_SAFE_NULL;
const VW_HANDLE INVALID_VW_EXAMPLE = VW_TYPE_SAFE_NULL;
Expand All @@ -65,6 +66,7 @@ const VW_HANDLE INVALID_VW_EXAMPLE = VW_TYPE_SAFE_NULL;
VW_DLL_MEMBER VW_HANDLE VW_CALLING_CONV VW_Initialize(const char16_t * pstrArgs);
#endif
VW_DLL_MEMBER VW_HANDLE VW_CALLING_CONV VW_InitializeA(const char * pstrArgs);
VW_DLL_MEMBER VW_HANDLE VW_CALLING_CONV VW_InitializeWithModel(const char * pstrArgs, const char * modelData, size_t modelDataSize);

VW_DLL_MEMBER void VW_CALLING_CONV VW_Finish_Passes(VW_HANDLE handle);
VW_DLL_MEMBER void VW_CALLING_CONV VW_Finish(VW_HANDLE handle);
Expand Down Expand Up @@ -93,6 +95,7 @@ VW_DLL_MEMBER float VW_CALLING_CONV VW_GetTopicPrediction(VW_EXAMPLE e, size_t i
VW_DLL_MEMBER size_t VW_CALLING_CONV VW_GetTagLength(VW_EXAMPLE e);
VW_DLL_MEMBER const char* VW_CALLING_CONV VW_GetTag(VW_EXAMPLE e);
VW_DLL_MEMBER size_t VW_CALLING_CONV VW_GetFeatureNumber(VW_EXAMPLE e);
VW_DLL_MEMBER float VW_CALLING_CONV VW_GetConfidence(VW_EXAMPLE e);
VW_DLL_MEMBER VW_FEATURE VW_CALLING_CONV VW_GetFeatures(VW_HANDLE handle, VW_EXAMPLE e, size_t* plen);
VW_DLL_MEMBER void VW_CALLING_CONV VW_ReturnFeatures(VW_FEATURE f);
#ifdef USE_CODECVT
Expand Down Expand Up @@ -120,6 +123,8 @@ VW_DLL_MEMBER size_t VW_CALLING_CONV VW_Num_Weights(VW_HANDLE handle);
VW_DLL_MEMBER size_t VW_CALLING_CONV VW_Get_Stride(VW_HANDLE handle);

VW_DLL_MEMBER void VW_CALLING_CONV VW_SaveModel(VW_HANDLE handle);
VW_DLL_MEMBER void VW_CALLING_CONV VW_CopyModelData(VW_HANDLE handle, VW_IOBUF* bufferHandle, char** outputData, size_t* outputSize);
VW_DLL_MEMBER void VW_CALLING_CONV VW_FreeIOBuf(VW_IOBUF bufferHandle);

#ifdef __cplusplus
}
Expand Down