Skip to content

Commit

Permalink
feat: WASM typescript instead of javascript for vw wrapper (VowpalWab…
Browse files Browse the repository at this point in the history
  • Loading branch information
olgavrou authored May 19, 2023
1 parent 58bf074 commit 50041af
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 150 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ vowpalwabbit/parser/flatbuffer/generated/example_generated.h
test/flatbuffer/*.predict
test/flatbuffer/*.stderr
node_modules
wasm/vw-wasm.js
wasm/vw.js
wasm/package-lock.json

/.vs
Expand Down
2 changes: 2 additions & 0 deletions wasm/.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ example.js
node_modules
*.txt
*.cc
*.ts
!*.d.ts
4 changes: 2 additions & 2 deletions wasm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ if(VW_INSTALL)
message(FATAL_ERROR "Install not supported for WASM build" )
endif()

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/out/")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/dist/")

add_executable(vw-wasm wasm_wrapper.cc)
add_executable(vw-wasm src/wasm_wrapper.cc)
set_target_properties(vw-wasm PROPERTIES LINK_FLAGS "-fexceptions -s WASM=1 -s SINGLE_FILE=1 -s NO_DYNAMIC_EXECUTION=1 --bind -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s EXPORTED_FUNCTIONS=\"['_malloc', '_free']\" -s MODULARIZE=1 -s EXPORT_NAME=\"vwWasmModule\"")
target_link_libraries(vw-wasm PUBLIC vw_explore vw_core "-fexceptions")
71 changes: 7 additions & 64 deletions wasm/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Closes the logging stream. Logs a warning to the console if there is no logging
<a name="VWExampleLogger+logLineSync"></a>

### vwExampleLogger.logLineSync(log_file, line)
Takes a string and appends it to the log file. Line is logged in a synchronous manner.
Takes a string and appends it to the log file. Line is logged in a synchronous manner.
Every call to this function will open a new file handle, append the line and close the file handle.

**Kind**: instance method of [<code>VWExampleLogger</code>](#VWExampleLogger)
Expand Down Expand Up @@ -175,8 +175,8 @@ Can accept either or both string arguments and a model file.
<a name="Workspace+parse"></a>

### workspace.parse(line) ⇒
Parse a line of text into a VW example.
The example can then be used for prediction or learning.
Parse a line of text into a VW example.
The example can then be used for prediction or learning.
finishExample() must be called and then delete() on the example, when it is no longer needed.

**Kind**: instance method of [<code>Workspace</code>](#Workspace)
Expand Down Expand Up @@ -252,7 +252,7 @@ Takes a file location and stores the VW model in binary format in the file.

### workspace.getModelAsArray() ⇒ <code>Uint8Array</code>
Gets the VW model in binary format as a Uint8Array that can be saved to a file.
There is no need to delete or free the array returned by this function.
There is no need to delete or free the array returned by this function.
If the same array is however used to re-load the model into VW, then the array needs to be stored in wasm memory (see loadModelFromArray)

**Kind**: instance method of [<code>Workspace</code>](#Workspace)
Expand Down Expand Up @@ -281,7 +281,7 @@ The memory must be allocated via the WebAssembly module's _malloc function and s

| Param | Type | Description |
| --- | --- | --- |
| model_array_ptr | <code>\*</code> | the pre-loaded model's array pointer The memory must be allocated via the WebAssembly module's _malloc function and should later be freed via the _free function. |
| model_array_ptr | <code>number</code> | the pre-loaded model's array pointer The memory must be allocated via the WebAssembly module's _malloc function and should later be freed via the _free function. |
| model_array_len | <code>number</code> | the pre-loaded model's array length |

<a name="WorkspaceBase+delete"></a>
Expand All @@ -300,7 +300,6 @@ A Wrapper around the Wowpal Wabbit C++ library for Contextual Bandit exploration
**Extends**: <code>WorkspaceBase</code>

* [CbWorkspace](#CbWorkspace) ⇐ <code>WorkspaceBase</code>
* [new CbWorkspace([args_str], [model_file], [model_array])](#new_CbWorkspace_new)
* [.predict(example)](#CbWorkspace+predict) ⇒ <code>array</code>
* [.learn(example)](#CbWorkspace+learn)
* [.addLine(line)](#CbWorkspace+addLine)
Expand All @@ -317,62 +316,6 @@ A Wrapper around the Wowpal Wabbit C++ library for Contextual Bandit exploration
* [.loadModelFromArray(model_array_ptr, model_array_len)](#WorkspaceBase+loadModelFromArray)
* [.delete()](#WorkspaceBase+delete)

<a name="new_CbWorkspace_new"></a>

### new CbWorkspace([args_str], [model_file], [model_array])
Creates a new Vowpal Wabbit workspace for Contextual Bandit exploration algorithms.
Can accept either or both string arguments and a model file.

**Throws**:

- <code>Error</code> Throws an error if:
- no argument is provided
- both string arguments and a model file are provided, and the string arguments and arguments defined in the model clash
- both string arguments and a model array are provided, and the string arguments and arguments defined in the model clash
- both a model file and a model array are provided


| Param | Type | Description |
| --- | --- | --- |
| [args_str] | <code>string</code> | The arguments that are used to initialize Vowpal Wabbit (optional) |
| [model_file] | <code>string</code> | The path to the file where the model will be loaded from (optional) |
| [model_array] | <code>tuple</code> | The pre-loaded model's array pointer and length (optional). The memory must be allocated via the WebAssembly module's _malloc function and should later be freed via the _free function. |

**Example**
```js
const vwPromise = require('./vw.js');
// require returns a promise because we need to wait for the wasm module to be initialized

vwPromise.then((vw) => {
let model = new vw.CbWorkspace({ args_str: "--cb_explore_adf" });
let vwLogger = new vw.VWExampleLogger();

vwLogger.startLogStream("mylogfile.txt");

let example = {
text_context: `shared | s_1 s_2
| a_1 b_1 c_1
| a_2 b_2 c_2
| a_3 b_3 c_3`,
};

let prediction = model.predictAndSample(example);

example.labels = [{ action: prediction["action"], cost: 1.0, probability: prediction["score"] }];

model.learn(example);
vwLogger.logCBExampleToStream(example);

model.saveModelToFile("my_model.vw");
vwLogger.endLogStream();
model.delete();

let model2 = new vw.CbWorkspace({ model_file: "my_model.vw" });
console.log(model2.predict(example));
console.log(model2.predictAndSample(example));
model2.delete();
});
```
<a name="CbWorkspace+predict"></a>

### cbWorkspace.predict(example) ⇒ <code>array</code>
Expand Down Expand Up @@ -551,7 +494,7 @@ Takes a file location and stores the VW model in binary format in the file.

### cbWorkspace.getModelAsArray() ⇒ <code>Uint8Array</code>
Gets the VW model in binary format as a Uint8Array that can be saved to a file.
There is no need to delete or free the array returned by this function.
There is no need to delete or free the array returned by this function.
If the same array is however used to re-load the model into VW, then the array needs to be stored in wasm memory (see loadModelFromArray)

**Kind**: instance method of [<code>CbWorkspace</code>](#CbWorkspace)
Expand Down Expand Up @@ -580,7 +523,7 @@ The memory must be allocated via the WebAssembly module's _malloc function and s

| Param | Type | Description |
| --- | --- | --- |
| model_array_ptr | <code>\*</code> | the pre-loaded model's array pointer The memory must be allocated via the WebAssembly module's _malloc function and should later be freed via the _free function. |
| model_array_ptr | <code>number</code> | the pre-loaded model's array pointer The memory must be allocated via the WebAssembly module's _malloc function and should later be freed via the _free function. |
| model_array_len | <code>number</code> | the pre-loaded model's array length |

<a name="WorkspaceBase+delete"></a>
Expand Down
17 changes: 13 additions & 4 deletions wasm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@
"version": "0.0.1",
"description": "wasm bindings for vowpal wabbit",
"exports": {
"require": "./vw.js"
"require": "./dist/vw.js"
},
"main": "\"\"",
"main": "dist/vw.js",
"files": [
"dist/",
"src/**/*.ts",
"!src/**/*.cc"
],
"devDependencies": {
"@types/node": "^20.2.1",
"jsdoc-to-markdown": "^8.0.0",
"mocha": "^9.1.2"
"mocha": "^9.1.2",
"typescript": "^5.0.4"
},
"scripts": {
"postinstall": "npm run build",
"build": "tsc",
"test": "node --experimental-wasm-threads ./node_modules/mocha/bin/mocha --delay",
"docs": "jsdoc2md ./vw.js > documentation.md"
"docs": "jsdoc2md ./dist/vw.js > documentation.md"
},
"dependencies": {
"out": "^1.1.0"
Expand Down
Loading

0 comments on commit 50041af

Please sign in to comment.