Skip to content

Commit

Permalink
[Services] Remote model register
Browse files Browse the repository at this point in the history
 - Impelent registering model relotely
 - Add unit test

Signed-off-by: gichan2-jang <[email protected]>
  • Loading branch information
gichan-jang committed Jul 3, 2023
1 parent 81d1251 commit dbed546
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 2 deletions.
66 changes: 64 additions & 2 deletions c/src/ml-api-remote-service.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,21 @@ _mlrs_get_service_type (gchar * service_str)
return service_type;
}

/**
* @brief Get ml remote service activation type.
*/
static gboolean
_mlrs_parse_activate (gchar * activate)
{
gboolean ret = TRUE;

if (activate && g_ascii_strcasecmp (activate, "false") == 0) {
ret = FALSE;
}

return ret;
}

/**
* @brief Process ml remote service
*/
Expand All @@ -185,10 +200,48 @@ _mlrs_process_remote_service (nns_edge_data_h data_h)

switch (service_type) {
case ML_REMOTE_SERVICE_TYPE_MODEL_URL:
/** @todo Download the model file from given URL */
/** @todo Download the model file from given URL. wget? cURL? */
case ML_REMOTE_SERVICE_TYPE_MODEL_RAW:
/** @todo Save model file to given path and register the model */
{
guint version = -1;
gchar *description = NULL;
gchar *name = NULL;
gchar *current_dir = g_get_current_dir ();
gchar *dir_path = NULL;
gchar *model_path = NULL;
gchar *activate = NULL;
gboolean active_bool = TRUE;
GError *error = NULL;

nns_edge_data_get_info (data_h, "description", &description);
nns_edge_data_get_info (data_h, "name", &name);
nns_edge_data_get_info (data_h, "activate", &activate);
active_bool = _mlrs_parse_activate (activate);
_ml_logd ("current dir: %s, key: %s, model name:%s", current_dir,
service_key, name);

dir_path = g_build_path ("/", current_dir, service_key, NULL);
g_mkdir_with_parents (dir_path, 0755);
model_path = g_build_path ("/", current_dir, service_key, name, NULL);
if (!g_file_set_contents (model_path, (char *) data, data_len, &error)) {
_ml_loge ("Failed to write data to file: %s",
error ? error->message : "unknown error");
g_clear_error (&error);
}

/**
* @todo Hashing the path. Where is the default path to save the model file?
*/
ml_service_model_register (service_key, model_path,
active_bool, description, &version);
g_free (current_dir);
g_free (dir_path);
g_free (activate);
g_free (model_path);
g_free (description);
g_free (name);
break;
}
case ML_REMOTE_SERVICE_TYPE_PIPELINE_URL:
/** @todo Download the pipeline description from given URL */
case ML_REMOTE_SERVICE_TYPE_PIPELINE_RAW:
Expand Down Expand Up @@ -346,6 +399,9 @@ ml_remote_service_register (ml_service_h handle, ml_option_h option, void *data,
nns_edge_data_h data_h = NULL;
int ret = NNS_EDGE_ERROR_NONE;
gchar *service_str = NULL;
gchar *description = NULL;
gchar *name = NULL;
gchar *activate = NULL;

check_feature_state (ML_FEATURE_SERVICE);
check_feature_state (ML_FEATURE_INFERENCE);
Expand Down Expand Up @@ -382,6 +438,12 @@ ml_remote_service_register (ml_service_h handle, ml_option_h option, void *data,
nns_edge_data_set_info (data_h, "service-type", service_str);
ml_option_get (option, "service-key", (void **) &service_key);
nns_edge_data_set_info (data_h, "service-key", service_key);
ml_option_get (option, "description", (void **) &description);
nns_edge_data_set_info (data_h, "description", description);
ml_option_get (option, "name", (void **) &name);
nns_edge_data_set_info (data_h, "name", name);
ml_option_get (option, "activate", (void **) &activate);
nns_edge_data_set_info (data_h, "name", activate);

ret = nns_edge_data_add (data_h, data, data_len, NULL);
if (NNS_EDGE_ERROR_NONE != ret) {
Expand Down
143 changes: 143 additions & 0 deletions tests/capi/unittest_capi_remote_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,149 @@ TEST_F (MLRemoteService, registerInvalidParam_n)
EXPECT_EQ (ML_ERROR_NONE, status);
}


/**
* @brief use case of model registration using ml remote service.
*/
TEST_F (MLRemoteService, registerModel)
{
int status;

/**============= Prepare client ============= **/
ml_service_h client_h;
ml_option_h client_option_h = NULL;

status = ml_option_create (&client_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);

gchar *client_node_type = g_strdup ("remote_sender");
status = ml_option_set (client_option_h, "node-type", client_node_type, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);

gchar *client_dest_host = g_strdup ("127.0.0.1");
status = ml_option_set (client_option_h, "host", client_dest_host, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);

guint dest_port = 3000;
status = ml_option_set (client_option_h, "port", &dest_port, NULL);
EXPECT_EQ (ML_ERROR_NONE, status);

gchar *client_connect_type = g_strdup ("TCP");
status = ml_option_set (client_option_h, "connect-type", client_connect_type, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);

gchar *topic = g_strdup ("remote_service_test_topic");
status = ml_option_set (client_option_h, "topic", topic, NULL);
EXPECT_EQ (ML_ERROR_NONE, status);

status = ml_remote_service_create (client_option_h, &client_h);
EXPECT_EQ (ML_ERROR_NONE, status);

/**============= Prepare server ============= **/
ml_service_h server_h;
ml_option_h server_option_h = NULL;
status = ml_option_create (&server_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);

gchar *server_node_type = g_strdup ("remote_receiver");
status = ml_option_set (server_option_h, "node-type", server_node_type, g_free);

gchar *dest_host = g_strdup ("127.0.0.1");
status = ml_option_set (server_option_h, "dest-host", dest_host, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);

status = ml_option_set (server_option_h, "topic", topic, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);

status = ml_option_set (server_option_h, "dest-port", &dest_port, NULL);
EXPECT_EQ (ML_ERROR_NONE, status);

gchar *server_connect_type = g_strdup ("TCP");
status = ml_option_set (server_option_h, "connect-type", server_connect_type, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);

status = ml_remote_service_create (server_option_h, &server_h);
EXPECT_EQ (ML_ERROR_NONE, status);

/** Set service option */
const gchar *root_path = g_getenv ("MLAPI_SOURCE_ROOT_PATH");
/* ml_remote_service_register () requires absolute path to model, ignore this case. */
if (root_path == NULL)
return;

gchar *test_model = g_build_filename (root_path, "tests", "test_models",
"models", "mobilenet_v1_1.0_224_quant.tflite", NULL);
EXPECT_TRUE (g_file_test (test_model, G_FILE_TEST_EXISTS));

gchar *contents = NULL;
gsize len = 0;
EXPECT_TRUE (g_file_get_contents (test_model, &contents, &len, NULL));
g_message ("Model size: %zu", len);

ml_option_h remote_service_option_h = NULL;
status = ml_option_create (&remote_service_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);

gchar *service_key = g_strdup ("model_registration_test_key");
ml_option_set (remote_service_option_h, "service-key", service_key, g_free);

gchar *service_type = g_strdup ("model_raw");
ml_option_set (remote_service_option_h, "service-type", service_type, g_free);

gchar *activate = g_strdup ("true");
ml_option_set (remote_service_option_h, "activate", activate, g_free);

gchar *description = g_strdup ("temp descriptio for remote model register test");
ml_option_set (remote_service_option_h, "description", description, g_free);

gchar *name = g_strdup ("mobilenet_v1_1.0_224_quant.tflite");
ml_option_set (remote_service_option_h, "name", name, g_free);

status = ml_remote_service_register (client_h, remote_service_option_h, contents, len);
EXPECT_EQ (ML_ERROR_NONE, status);

/** Wait for the server to register the pipeline. */
g_usleep (1000000);

// Get model file
ml_option_h activated_model_option_h;
status = ml_service_model_get_activated (service_key, &activated_model_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);
EXPECT_NE (activated_model_option_h, nullptr);

gchar *activated_model_path;
status = ml_option_get (activated_model_option_h, "path", (void **) &activated_model_path);
EXPECT_EQ (ML_ERROR_NONE, status);
g_message ("Activated model path: %s", activated_model_path);

gchar *activated_model_contents = NULL;
gsize activated_model_len = 0;
EXPECT_TRUE (g_file_get_contents (activated_model_path,
&activated_model_contents, &activated_model_len, NULL));
g_message ("Model size: %zu", activated_model_len);
g_usleep (1000000);
EXPECT_EQ (len, activated_model_len);
EXPECT_EQ (memcmp (contents, activated_model_contents, len), 0);
g_message ("Compare done");
g_usleep (1000000);

g_free (contents);
g_free (test_model);
g_free (activated_model_contents);
status = ml_service_destroy (server_h);
EXPECT_EQ (ML_ERROR_NONE, status);
status = ml_service_destroy (client_h);
EXPECT_EQ (ML_ERROR_NONE, status);
status = ml_option_destroy (server_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);
status = ml_option_destroy (remote_service_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);
status = ml_option_destroy (client_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);
status = ml_option_destroy (activated_model_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);
}

/**
* @brief Main gtest
*/
Expand Down

0 comments on commit dbed546

Please sign in to comment.