Skip to content

Commit

Permalink
[OV JS] Expose Model.clone to Node.js Api
Browse files Browse the repository at this point in the history
Changes as part of this commit include:
* Add a ModelWrap::clone function:
  Calls the underlying Model.clone function
* Update the addon.ts file with the clone method
* Add unit tests for the clone Api

Resolves: openvinotoolkit#25402

Signed-off-by: Nashez Zubair <[email protected]>
  • Loading branch information
nashez committed Aug 1, 2024
1 parent a006253 commit da405fd
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/bindings/js/node/include/model_wrap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ class ModelWrap : public Napi::ObjectWrap<ModelWrap> {
*/
Napi::Value get_output_shape(const Napi::CallbackInfo& info);

/**
* @brief Returns a cloned model for the current model
* @param info Contains information about the environment and passed arguments
* @return Napi::Value Cloned model returned from the API
*/
Napi::Value clone(const Napi::CallbackInfo& info);

private:
std::shared_ptr<ov::Model> _model;
ov::Core _core;
Expand Down
4 changes: 4 additions & 0 deletions src/bindings/js/node/lib/addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ interface CoreConstructor {
* A user-defined model read by {@link Core.readModel}.
*/
interface Model {
/**
* It returns a cloned model
*/
clone(): Model;
/**
* It gets the friendly name for a model. If a friendly name is not set
* via {@link Model.setFriendlyName}, a unique model name is returned.
Expand Down
11 changes: 11 additions & 0 deletions src/bindings/js/node/src/model_wrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Napi::Function ModelWrap::get_class(Napi::Env env) {
InstanceMethod("setFriendlyName", &ModelWrap::set_friendly_name),
InstanceMethod("getFriendlyName", &ModelWrap::get_friendly_name),
InstanceMethod("getOutputShape", &ModelWrap::get_output_shape),
InstanceMethod("clone", &ModelWrap::clone),
InstanceAccessor<&ModelWrap::get_inputs>("inputs"),
InstanceAccessor<&ModelWrap::get_outputs>("outputs")});
}
Expand Down Expand Up @@ -171,3 +172,13 @@ Napi::Value ModelWrap::get_output_shape(const Napi::CallbackInfo& info) {
return info.Env().Undefined();
}
}

Napi::Value ModelWrap::clone(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
if (info.Length() > 0) {
reportError(env, "clone() does not accept any arguments.");
return env.Undefined();
}
return cpp_to_js(env, _model->clone());
}

18 changes: 18 additions & 0 deletions src/bindings/js/node/tests/unit/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { getModelPath } = require('./utils.js');
const testXml = getModelPath().xml;
const core = new ov.Core();
const model = core.readModelSync(testXml);
const clonedModel = model.clone();

describe('Node.js Model.isDynamic()', () => {
it('should return a boolean value indicating if the model is dynamic', () => {
Expand Down Expand Up @@ -112,3 +113,20 @@ describe('Model.getOutputSize()', () => {
assert.strictEqual(model.getOutputSize(), 1, 'Expected getOutputSize to return 1 for the default model');
});
});

describe('Model.clone()', () => {

it('should return an object of type model', () => {
assert.ok(clonedModel instanceof ov.Model, 'clone() should return a model');
});

it('should return a model that is a clone of the calling model', () => {
assert.deepStrictEqual(clonedModel, model, "Cloned Model should be exactly equal to the calling model");
});

it('should not accept any arguments', () => {
assert.throws(() => {
model.clone('unexpected argument');
}, /^Error: clone\(\) does not accept any arguments\.$/, 'Expected clone to throw an error when called with arguments');
});
});

0 comments on commit da405fd

Please sign in to comment.