[ML] Fix test break for MLSingleshot
[Verification] Code compiles.
TCT passrate:
* ml-tizen 100%
* mlpipeline-tizen 100%
* mlsingleshot-tizen 100%
Change-Id: Ia2ebef7a46600537946f308be5375e274f40df46
[notification] Fixed log format
[Verification] Code compiles for aarch64
Change-Id: Id93e303e118af2e3153d84c253684330d463185a
[ML] Fix Coverity issues for fields initialization
[Verification] Code compiles without errors.
Change-Id: I37afb023e1844943b0a844594181c6bab8223678
Marcin Kaminski [Fri, 18 Feb 2022 19:20:32 +0000 (20:20 +0100)]
[ML][Train] Remove denial of Model modification
Changes:
- removed check and error reporting for setting new dataset
after Model has been compiled and trained as it should be possible
to train with new data.
Change-Id: I144b45979b83ccaa101cf356a393271fdc352a90
[version] 2.91
Change-Id: I94eaeb841518c62bedcd9ef2bc701502fb714c27
Piotr Kosko [Mon, 21 Feb 2022 11:37:42 +0000 (11:37 +0000)]
Merge "[ML] Train - added a test method for trained model" into tizen
[ML] Train - fix for virtual root
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-285
[Verification] Code compiles.
Checked in chrome console - save_path in run options now supports virtual roots.
Change-Id: I77d67875a73441d1638ffbeb99366ad6a7301957
[ML][Train] Fix of createModelWithConfiguration
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-285
Change-Id: I1483b69310f2bd942c2c5b4de35a903c1ee04549
[ML] Train - added a test method for trained model
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-285
[Verification] Code compiles without errors.
Verification method is available in JS console.
var trainsetFile = "documents/trainingSet.dat";
var validsetFile = "documents/valSet.dat";
// TODO should support virtual roots
var outputFile = "/home/owner/media/Documents/webapi_tizen_model.bin"
var m = tizen.ml.trainer.createModel()
var l1 = tizen.ml.trainer.createLayer("LAYER_IN")
l1.setProperty("input_shape", "1:1:62720")
l1.setProperty("normalization", "true")
l1.setProperty("name", "inputlayer")
m.addLayer(l1)
var l2 = tizen.ml.trainer.createLayer("LAYER_FC")
l2.setProperty("unit", "10")
l2.setProperty("activation", "softmax")
l2.setProperty("bias_initializer", "zeros")
l2.setProperty("weight_regularizer", "l2norm")
l2.setProperty("weight_regularizer_constant", "0.005")
l2.setProperty("weight_initializer", "xavier_uniform")
l2.setProperty("name", "fc1")
l2.setProperty("input_layers", "inputlayer")
m.addLayer(l2)
var opt = tizen.ml.trainer.createOptimizer("OPTIMIZER_ADAM")
opt.setProperty("learning_rate", "0.0001")
opt.setProperty("decay_rate", "0.96")
opt.setProperty("decay_steps", "1000")
opt.setProperty("beta1", "0.002")
opt.setProperty("beta2", "0.001")
opt.setProperty("epsilon", "1e-7")
m.setOptimizer(opt);
var dataset = tizen.ml.trainer.createFileDataset(trainsetFile, validsetFile, /*no test file*/);
dataset.setProperty("buffer_size", "100", "MODE_TRAIN");
dataset.setProperty("buffer_size", "100", "MODE_VALID");
m.setDataset(dataset);
var compileOpts = {
loss: "cross", batch_size: "16"
}
m.compile(compileOpts);
var runOpts = {
epochs: "2", save_path: outputFile
}
m.run(runOpts, (s) => {
console.log("success");
console.log("Test result: " + m._checkMetrics(2.163000, 2.267410, 16.666700));
}, (e) => console.log("error " + JSON.stringify(e)));
Change-Id: I4760fe341f58f84c985c6e4e4b609bafe36fb4be
Marcin Kaminski [Fri, 28 Jan 2022 20:18:41 +0000 (21:18 +0100)]
[ML][Training] Thread-safe locks
Changes:
- mutex added to model object to lock single model
when compiling or in training
- mutex added for synchronizing models map operations
between dispose() and run()
Change-Id: I56f80d5beb9f0d93f346d64849bea5aa583e506d
Piotr Kosko [Mon, 14 Feb 2022 07:34:18 +0000 (07:34 +0000)]
Merge "[Notification] Add API for using buttons and a text input in a notification and getting block state" into tizen
[version] 2.90
Change-Id: I844ced5d5ce7a857201a7019038448c30aafa695
Piotr Kosko [Thu, 10 Feb 2022 08:32:14 +0000 (08:32 +0000)]
Merge changes Ia619a69d,Id35d552c,Ib71d21b2,I2f45bb44 into tizen
* changes:
[ML][Training] Dataset.setProperty() refactoring
[ML][Training] Object destruction implementation
[ML][Training] Model saving to file
[ML][Training] Model implementation
Marcin Kaminski [Fri, 21 Jan 2022 18:44:41 +0000 (19:44 +0100)]
[ML][Training] Dataset.setProperty() refactoring
Changes:
- enum DatasetMode added
- Dataset.setProperty() expanded with 'mode' param to match C API design
Change-Id: Ia619a69d6367c2624fff9d402e6a3505ce33f14b
Marcin Kaminski [Sat, 15 Jan 2022 18:09:31 +0000 (19:09 +0100)]
[ML][Training] Object destruction implementation
Changes:
- dispose() function added to Model, Layer, Dataset and Optimizer
- C++/C layer for dispose implemented
- additional wrapper objects for storing state/relations between objects
Change-Id: Id35d552c5bdf4840a176eeb85ad1bc4114c01ccb
Marcin Kaminski [Sat, 15 Jan 2022 13:00:35 +0000 (14:00 +0100)]
[ML][Training] Model saving to file
Changes:
- implementation of Model.saveToFile() method for saving model
on storage for re-use
- new enum for model saving selection
- minor change in dataset creation (path prefix removal)
Change-Id: Ib71d21b2d4a61e2ff2ed8e8b4f983acaeaa02408
[Archive] Support for global paths in tizen.archive methods
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-286
[TCT] 5 failures - TCT need to be updated.
Change-Id: Ibdbf1c48468bb0648c2dd107cc2f42b506fe73df
Marcin Kaminski [Wed, 15 Dec 2021 18:34:35 +0000 (19:34 +0100)]
[ML][Training] Model implementation
Implementation of Model methods:
- addLayer()
- setOptimizer()
- setDataset()
- summarize()
- compile()
- run() - uhnandled exception to be checked
Minor fix in Dataset creation and property setting.
Change-Id: I2f45bb449a34d0d959411a5120aee8c1e6a39da5
Piotr Kosko [Thu, 3 Feb 2022 10:54:23 +0000 (10:54 +0000)]
Merge changes Icb18546a,Iddb1630b,Ifae36542,I836832a9,I25df0e3e into tizen
* changes:
[ML][Training] Updating code to native API changes
Add Generator from paths
[ML Trainier] Add create, setProperty and model's methods
Add C stubs for ML Trainer API
[Ml][Trainer] Add JS stubs for ML Trainer API
[version] 2.89
Change-Id: I8a797091d9d78091faaf4f7f2fe4d4e546a02e21
[SPEC] Fixed logic of build for aarch64
[Verification] Build for armv7l and aarch64 is successful
Change-Id: Ib90656c58f0c4f2dbb0e90f6ddac1069cafa1575
Marcin Bialek [Mon, 3 Jan 2022 09:40:45 +0000 (10:40 +0100)]
[Notification] Add API for using buttons and a text input in a notification and getting block state
To add buttons tizen.NotificationButton can be used. It allows setting text, an image and an action. An array of buttons can be provided as a value for
"buttons" key in InputInitDict. To use a text input, an object with proper values can be provided as a value for "textInput" key. To get notifications
block state, tizen.notification.getBlockState() function can be used.
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-284
[Verification] Features have been tested with an example application which uses new API.
Change-Id: I0d3d2110b3cf37d17e4cf632d18263f493606653
[Messaging] Prevent crash of using released structure mail_data_final
In line 296, there is the usage:
mail_data_final->thread_id = mail_data_final->mail_id;
but if retries loop above reaches limit, then the structure is relased,
so using it causes crash.
To prevent it, we release data on the beginning of the next iteration of
a loop.
[Verification] TCT passrate:
messaging-email - 100%.
Change-Id: I4751e5509271f28ab803e0ef10a90ff10d61ec10
Marcin Kaminski [Wed, 10 Nov 2021 09:31:50 +0000 (10:31 +0100)]
[ML][Training] Updating code to native API changes
Native C++ API cannot be used so this commit removes
all dependencies on ccapi-machine-learning-training
library and C++ headers.
Functions and objects that were using C++ objects
ported to C handlers and functions.
[Verification] Code compiles without errors and tizen.ml is available
Change-Id: Icb18546ab1a72f729b9405f736e5c270ad0be3a8
Rafal Walczyna [Fri, 2 Jul 2021 11:06:16 +0000 (13:06 +0200)]
Add Generator from paths
original change: https://review.tizen.org/gerrit/261785
Change-Id: Iddb1630b9d93f961703083903e97ef455d60b7aa
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Mon, 7 Jun 2021 13:26:42 +0000 (15:26 +0200)]
[ML Trainier] Add create, setProperty and model's methods
original change: https://review.tizen.org/gerrit/259417
Tested partially
Change-Id: Ifae3654265a391228a090200f8877aaba5be83a9
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Mon, 7 Jun 2021 09:29:07 +0000 (11:29 +0200)]
Add C stubs for ML Trainer API
original change: https://review.tizen.org/gerrit/259416
Change-Id: I836832a9a71fb8a07c4063a25939f159a0d321d6
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Mon, 24 May 2021 13:42:29 +0000 (15:42 +0200)]
[Ml][Trainer] Add JS stubs for ML Trainer API
original change: https://review.tizen.org/gerrit/258708
Change-Id: I25df0e3e8a5a50dc8f2b3020c07519f1317d466b
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
[Common] Changes TaskQueue to thread_local storage duration
This change is to prevent issues with accessing same TaskQueue object by
several threads in multi-thread service model introduced in Tizen 6.5.
Similar change -
https://review.tizen.org/gerrit/#/c/platform/core/api/webapi-plugins/+/263367/
[Verification] executed all automatic TCT - 100% passrate.
Change-Id: I0c8ac1d7ffe1a9fad08eda6e2129abf659cbe9db
Marcin Bialek [Mon, 8 Nov 2021 12:19:28 +0000 (13:19 +0100)]
Use thread_local (instead of static) storage duration due to thread safety issue.
Similar issue:
605574a932c7ddac63bb394d520178d332ed05dc
[Verification] TCT tests and a sample application.
Change-Id: I988fb82763999751ce56d77847013506fea5875c
Pawel Wasowski [Fri, 24 Sep 2021 08:07:15 +0000 (10:07 +0200)]
[version] 2.88
Change-Id: I7ebf1b81237f2e9bd3dae16cc16bb3d1fad266d1
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Sangjung Woo [Fri, 24 Sep 2021 07:38:09 +0000 (16:38 +0900)]
[ML][Single] Fix the crash issue in single API
Before closing the singleshot handle, the output tensor data is freed.
Since inference internally is going on, this situation could cause the
segmentation fault in sub-plugin part. This patch fixes that bug.
Change-Id: I690b4ef941e981353f3809cc56a1f2089ef2a4e5
Signed-off-by: Sangjung Woo <sangjung.woo@samsung.com>
Piotr Kosko [Fri, 10 Sep 2021 07:19:33 +0000 (07:19 +0000)]
Merge "[Playerutil] Removed dependency to EWK by using XWALK Extension" into tizen
Piotr Kosko [Fri, 10 Sep 2021 07:18:54 +0000 (07:18 +0000)]
Merge "[common] Use thread_local (instead of static) objects for access checks" into tizen
[Playerutil] Removed dependency to EWK by using XWALK Extension
Related native change:
https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/249379/
Change-Id: Ie1088d64b84b9f2087be20531e6852d62f754f21
Pawel Wasowski [Wed, 1 Sep 2021 07:10:42 +0000 (09:10 +0200)]
[common] Use thread_local (instead of static) objects for access checks
Beginning with Tizen 6.5, a new web service app model has been
introduced. Each service is now a thread of the "master" service
process, instead of having the whole process for its disposal, as it
used to be earlier.
To control privileges of particular services, we need to initialize
the cynara and related objects for each thread separately. Thus we
make them thread_local (one instance per thread) instead of static
(one instance per process).
Similarily, we make RequestStoragePrivilegeChecker thread_local,
so that each app will create its own instance of such object.
[Verification] The code was tested manually in a web service app.
Before this commit, all web services were using the same smack label to
initialize cynara object (the label of the thread that first
initialized the static objects).
Now, each thread initializes cynara with its own smack label.
Each thread uses separate RequestStoragePrivilegeChecker.
Change-Id: I5e6ffae05ed12e60d09c23fdbdc462a6022e926b
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Piotr Kosko [Thu, 9 Sep 2021 07:56:37 +0000 (07:56 +0000)]
Merge "Add CreateTaskQueue for early initialization" into tizen
Piotr Kosko [Thu, 9 Sep 2021 06:40:27 +0000 (06:40 +0000)]
Merge "[ml] Add customRequirement to tizen.ml.checkNNFWAvailability" into tizen
DongHyun Song [Fri, 3 Sep 2021 01:50:24 +0000 (10:50 +0900)]
Add CreateTaskQueue for early initialization
This API will be used by global wrt-service (thread model)
This singleton TaskQueue instance should have smack label same as
pid's smack label.
After a service app is launched, this TaskQueue thread has app's
smack label. Then, smack violation might be happened.
Thus, to initialize early before app creation, this patch exposes
CreateTaskQueue() funtion for WebRuntime.
Change-Id: I108bed31dbf0dbd1b54a6781530b95618584b0f8
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
[version] 2.87
Change-Id: Icf0e0e40ade36eda7af543472d4dbe2e96b8ec78
[ML] Added binary communication in getTensorRawData()
[Verification]
TCT passrate for tct-ml, tct-mlpipeline and tct-single 100% passrate
Performance results tested with below scenario for
224x224x3 tensor size (TM1 device):
var tries = 100;
var sum = 0;
var tensorsInfo = new tizen.ml.TensorsInfo();
tensorsInfo.addTensorInfo("tensor", "UINT8", [224, 224, 3]);
var tensorsData = tensorsInfo.getTensorsData();
var start = new Date();
tensorsData.setTensorRawData(0, rgb);
for (var i = 0; i < tries; ++i) {
var start = new Date();
tensorsData.getTensorRawData(0)
var end = new Date();
sum += end-start;
}
console.log ("Average time is: " + (sum / tries) );
BEFORE: Average time is: 139.53
AFTER: Average time is: 5.93
Change-Id: I47f369319744e64c3bd961eb7dda4ad8823b1494
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
Signed-off-by: Piotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics <p.kosko@samsung.com>
Pawel Wasowski [Tue, 31 Aug 2021 12:24:44 +0000 (14:24 +0200)]
[ml] Add customRequirement to tizen.ml.checkNNFWAvailability
ACR: TWDAPI-282
[Verification] Tested on TM1 in Chrome DevTools with the snippets below
tizen.ml.checkNNFWAvailability("TENSORFLOW_LITE", "CPU") // true
tizen.ml.checkNNFWAvailability("TENSORFLOW_LITE", "CPU",
'test custom requirement'); // true
The native implementation is not ready and returns the same value
whether the customRequirement is passed or not. That's why
tizen.ml.checkNNFWAvailability also returns "true" twice above
Change-Id: I971a5f49d4ea389ad953c28fc08da21bafb59ee2
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Pawel Wasowski [Mon, 23 Aug 2021 14:07:59 +0000 (16:07 +0200)]
[Common] Add synchronization to privilege checking
common::tools::CheckAccess() can be called from multiple threads in the
same time. (This happens in web service apps, which now are running as
separate threads of a single process.)
This commit adds synchronization of the access of this function's static
resources.
[Verification] Code compiles. The code works fine in a single-threaded
app
Change-Id: I4af0715d3605284bf82b2abe207dabe024986d25
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[version] 2.86
Change-Id: I6374110425bcd28f1faba2ae44574d629314268a
Pawel Wasowski [Wed, 4 Aug 2021 16:16:42 +0000 (18:16 +0200)]
[Iotcon] Add NotSupportedError to initialize()
ACR: TWDAPI-279
[Verification] After disabling iotcon support in
/etc/config/model-config.xml, tizen.iotcon.initialize() throws
NotSupportedError, as expected.
Auto tct-iotcon-tizen-tests pass rate: 100% (with the iotcon support
enabled in model-config.xml)
No tct-iotcon-tizen-tests are run when the iotcon support is disabled
in model-config.xml
Change-Id: I41be8376bcc1bca5b919daa0a5d0a9651b14d335
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Piotr Kosko [Fri, 20 Aug 2021 12:31:49 +0000 (12:31 +0000)]
Merge "[Common] Added caching custom virutal paths" into tizen
Piotr Kosko [Fri, 20 Aug 2021 12:31:41 +0000 (12:31 +0000)]
Merge "[ACR][secure element] extension of listener" into tizen
[Common] Added caching custom virutal paths
This change is related to:
https://review.tizen.org/gerrit/#/c/platform/core/api/webapi-plugins/+/260943/
As in some scenarios (when new storage is mounted) webapi clears cache,
there is a need to restore custom virtual paths which are set with
setVirtualPath() method.
[Verification] Code compiles without errors.
Change-Id: I9dde4025526936e8988ff610f70894d4dbb00e60
[ACR][secure element] extension of listener
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-281
[Verification] Code compiles without errors.
Change-Id: I853f62f2250cf486c2a215970a2ba94299f04bb4
MyungJoo Ham [Mon, 9 Aug 2021 03:06:36 +0000 (12:06 +0900)]
[ML] Update NNFWType name of TRIx NPU Series
SRNPU is an unofficial name of TRIx NPU series.
Update the name with the official name.
Fortuately "SRNPU" was first introduced with Tizen 6.5 releases.
We have decided to expose the official name of these NPU series of
TRIV and TRIA series, which are exposed via a common NPU-Engine
low-level driver: "TRIx-Engine".
Note that in some commercial products with TRIx NPU series,
the low-level drivers might be not available to applications.
In such cases, high-level drivers (with less hardware control)
that wrap the low-level drivers will be provided (e.g., VD-AIFW).
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-280
Change-Id: I7385749ec94981c3a89fe918d548d2fc582594bd
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Pawel Wasowski [Fri, 6 Aug 2021 15:00:22 +0000 (17:00 +0200)]
[common] Add the definition of a legacy messaging interface
This recent change that introduced new binary messaging interfaces,
replacing XW_MESSAGING_INTERFACE_1 with XW_MESSAGING_INTERFACE_2.
This chang broken the build of webapi-plugins-teec project, which depends
on the declaration of the legacy interface.
This commit fixes this problem, by adding the legacy interface back
to XW_Extension.h.
[Verification] webapi-plugins builds. webapi-plugins-teec builds,
when webapi-plugins built with this change is installed in GBS root.
Change-Id: Ia057a8e9ea9d51e06616a0ad16dc28b3ea342d8c
[version] 2.85
Change-Id: I2524f9fcf99cf55054f69bf6da38b3404ba2e98e
[ml][single] Implemented communication in ML API
[Verification] Performance increased in Chromium console.
TCT passrate - 100%
Change-Id: I7079ec1a690696dc4acc5d827920603e3a12e9ab
[extension] Binary messanger implementation added
[verification] Code compiles without errors.
Change-Id: If98eaf371ffbb47a2bf39978f9529307a9e9b06f
Pawel Wasowski [Wed, 4 Aug 2021 14:49:28 +0000 (16:49 +0200)]
[ML][Single] Fix invokeAsync
invokeAsync implementation did not should copy the input TensorsData
object, as it was supposed to. This commit adds copying
[Verification] Tested with the snippet below several times - the outputs
of invoke and invokeAsync were always identical:
var tensorsData;
var model;
function errorCallback(error)
{
console.log("Error during invokeAsync: " + error.message);
}
function isSameArray(a, b) {
if(a.length != b.length) {
return false;
}
for(var i=0 ; i<a.length ; i++) {
if(a[i] != b[i]) {
return false;
}
}
return true;
}
function successCallback(tensorsDataOut)
{
var asyncResult = tensorsDataOut.getTensorRawData(0).data;
var syncResultTD = model.invoke(tensorsData);
var syncResult = syncResultTD.getTensorRawData(0).data;
if (isSameArray(syncResult, asyncResult)) {
console.log('Sync and async versions of invoke returned the same output');
} else {
console.error('Outputs of sync and async invoke versions differ!');
}
}
function run_test () {
model = tizen.ml.single.openModel("wgt-package/models/mobilenet_v1_1.0_224_quant.tflite", null, null, "TENSORFLOW_LITE", "ANY");
var tensorsInfo = new tizen.ml.TensorsInfo();
tensorsInfo.addTensorInfo("tensor", "UINT8", [224, 224, 3]);
tensorsData = tensorsInfo.getTensorsData();
var randomData = Array.from({length: 224 * 224 * 3}, () => Math.floor(Math.random() * 255));
var rgb = new Uint8Array(randomData);
tensorsData.setTensorRawData(0, rgb);
model.invokeAsync(tensorsData, successCallback, errorCallback);
};
Change-Id: Iff0d39ca6be9e1c5d2ff3c9f9fc3d061d49377c5
Pawel Wasowski [Thu, 15 Jul 2021 13:03:15 +0000 (15:03 +0200)]
[Alarm] Don't raise an error when an alarm without TYPE is found
tizen.alarm.get() and tizen.alarm.getAll() used to fail when alarms
without "TYPE" property in related app_control existed.
This commit returns such alarms as JS Alarm objects.
[Verification] tct-alarm-tizen-tests (auto): 100 %
I've tested in Chrome DevTools debugger, that when an alarm without
"type" property comes to JS, a valid "Alarm" object is created
(I don't provide any test code snippet, because it required stopping
app in the debugger).
Change-Id: I4b5bcea75509f454bd17b787c080417849720f5a
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[version] 2.84
Change-Id: Iaeb9f2c1ce570ad109ea4a5c34a512b4a328442e
[Filesystem] Change setVirtualPath method to be not enumerable
Feature of setVirtualPath is needed for proper handling virtual paths
in thread service model - related change:
https://review.tizen.org/gerrit/gitweb?p=platform/core/api/webapi-plugins.git;a=commit;h=
4870490975f9cbfa3eb16cc892f3593cb74b6668
[Verification] Code compiles without errors. Code was properly
formatted.
Checked in chrome console - setVirtualPath is not iterable, but still
accessible.
Change-Id: Ia3d2720cd1267d0a4d002538f319cfd993e83d4a
DongHyun Song [Wed, 7 Jul 2021 08:47:14 +0000 (17:47 +0900)]
Support setVirtualPath for thread-model wrt-service
thread-model wrt-service runs all service application on worker
thread as daemon process.
For the virtual path resolving, it cannot get service application's
path. i.e. /home/owner/apps_rw/{service_app_pkgid}/data, becuase
wrt-service is org.tizen.chromium-efl package.
Thus, setting virtual path will be set by wrt-service framework
before each node worker thread started.
- node worker has own V8 context
Change-Id: I8dd5e524584ebe71416c86c1e8648a2c4cfc4b94
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
DongHyun Song [Wed, 7 Jul 2021 08:47:14 +0000 (17:47 +0900)]
Support setVirtualPath for thread-model wrt-service
thread-model wrt-service runs all service application on worker
thread as daemon process.
For the virtual path resolving, it cannot get service application's
path. i.e. /home/owner/apps_rw/{service_app_pkgid}/data, becuase
wrt-service is org.tizen.chromium-efl package.
Thus, setting virtual path will be set by wrt-service framework
before each node worker thread started.
- node worker has own V8 context
Change-Id: I8dd5e524584ebe71416c86c1e8648a2c4cfc4b94
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
[Filesystem] Fixed Blob to Uint8Array conversion
Fix inspired by this answer: https://stackoverflow.com/a/
63920556/
11502478
[Verification] in Chrome console:
// assume having wav file on the device
input = tizen.filesystem.openFile("documents/sample1.wav", "r")
blob = input.readBlob() /// Blob {size: 1073218, type: ""}
output = tizen.filesystem.openFile("documents/sample1_output.wav", "w")
output.writeBlob(blob)
output.close()
output_test = tizen.filesystem.openFile("documents/sample1_output.wav", "r")
blob_test = output_test.readBlob() /// Blob {size: 1073218, type: ""}
console.log("Verification passed: " + (blob.size === blob_test.size))
input.close()
output_test.close()
TCT (filesystem, deprecated) passrate 100%
Change-Id: I5e4beea31d69430e9dbe44a7899cf675e779c7f8
[version] 2.83
Change-Id: Ie9ee7bcf4b480406921ec878717b5592dd0cc9a5
Piotr Kosko [Mon, 28 Jun 2021 05:55:56 +0000 (05:55 +0000)]
Merge "[ML][Single] Added InvokeAsync() implementation" into tizen
Piotr Kosko [Mon, 28 Jun 2021 05:55:48 +0000 (05:55 +0000)]
Merge "[Application] Enable system events listener" into tizen
[ML][Single] Added InvokeAsync() implementation
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-278
[Verification] Code compiles without errors.
TCT passrate of existing APIs didn't change.
Checked in chrome console with below snippets:
// initialize test data
model = tizen.ml.single.openModel("documents/model.tflite");
var tensorsInfo = new tizen.ml.TensorsInfo();
tensorsInfo.addTensorInfo("tensor", "UINT8", [3, 224, 224]);
var tensorsData = tensorsInfo.getTensorsData();
var tensorsInfoInvalid = new tizen.ml.TensorsInfo();
tensorsInfoInvalid.addTensorInfo("tensor", "UINT8", [3, 125, 125]);
var tensorsDataInvalid = tensorsInfoInvalid.getTensorsData();
function errorCallback(error) {
console.log(error);
}
function successCallback(tensorsDataOut) {
console.log("Inference finished successfully");
console.log(tensorsDataOut.getTensorRawData(0));
tensorsDataOut.dispose();
}
// success
// test1
model.invokeAsync(tensorsData, successCallback, errorCallback);
// test2
model.invokeAsync(tensorsData, successCallback);
// errors
// test3
model.invokeAsync(tensorsData); // TypeMismatchError - sync
// test4
model.invokeAsync(null, successCallback); // TypeMismatchError - sync
// test5
model.invokeAsync(tensorsDataInvalid, successCallback, errorCallback); // AbortError - async
// test6
model.setTimeout(1)
model.invokeAsync(tensorsData, successCallback, errorCallback); // TimeoutError - async
// clear tensorsData
tensorsData.dispose();
tensorsInfo.dispose();
// test7 - use of disposed tesnsorsData
model.invokeAsync(tensorsData, successCallback, errorCallback); // AbortError - sync
// clear other data
tensorsDataInvalid.dispose();
tensorsInfoInvalid.dispose();
model.close();
Change-Id: I59900d7bab9a76939e27d68cb2bcd5434f446b3d
[version] 2.82
Change-Id: I851cb3ea68068d0ea2fa38ac5eac19ca0a5904c1
Rafal Walczyna [Mon, 14 Jun 2021 09:17:33 +0000 (11:17 +0200)]
[ML] Add new HWType and NNFWType enums
[XWALK-2312]
[TWDAPI-277]
Tested also with code:
var HWType = ["ANY", "NPU_SLSI"];
var NNFWType = ["ANY", "NNTR_INF", "PYTORCH", "SRNPU", "VD_AIFW"];
HWType.forEach(hw => {
NNFWType.forEach(nnfw => {
console.log(nnfw + ", " + hw + ": " + tizen.ml.checkNNFWAvailability(nnfw, hw))
});
});
[Verification] 100% passrate
Change-Id: I9257240d1596c2b017581997b488a01447385060
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
[version] 2.81
Change-Id: I5225e6004d027167b720b9f1fcd1d213a9840769
[Filesystem] Use non-static worker instead of singleton TaskQueue
In filesystem webapi, TaskQueue is a singleton instance used by
multiple FilesystemInstance. With thread model web service
applications, there might be smack violation because each service
app (thread) try to use same worker.
This commit resolves problem by changing usage of singleton TaskQueue to
a member worker owned by FilesystemInstance.
Commit keeps two separated workers for better operation
performance:
- global_worker queues 'global' operations on fielsystem instance e.g.
opening files, rename, move etc.
- file_worker queues only file operation as reading
Above design prevents to block 'quick' global operations in case of
long-lasting file reading/writing operation in background.
[Verification] Code compiles without errors.
Filesystem TCT passrate 100%.
Change-Id: Idf0bd1915f67b64a65fcc1afc2e17d011bb5b918
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
Signed-off-by: Piotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics <p.kosko@samsung.com>
Rafal Walczyna [Mon, 24 May 2021 13:02:02 +0000 (15:02 +0200)]
[Tools] Force clang-format version to 3.9
Using version newer than 3.9 results in a lot of format changes.
As user may want to use newer clang-format version for different
projects, script has been changed to use clang-format-3.9 executable.
[Verification] No change in C++ formatting
Change-Id: I4f569644549db8104bb39efc6bc1eca23ac6bbd6
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Piotr Kosko [Thu, 20 May 2021 06:18:23 +0000 (06:18 +0000)]
Merge "[Bluetooth] Fix Coverity issue" into tizen
Piotr Kosko [Thu, 20 May 2021 06:17:59 +0000 (06:17 +0000)]
Merge "[nfc] Fixing memory management for messages and records" into tizen
Piotr Kosko [Thu, 20 May 2021 04:28:08 +0000 (04:28 +0000)]
Merge "[ML][common] Fix a Coverity issue" into tizen
Piotr Kosko [Thu, 20 May 2021 04:26:20 +0000 (04:26 +0000)]
Merge "[mediacontroller] Fixing Coverity issues" into tizen
Pawel Wasowski [Wed, 19 May 2021 09:56:25 +0000 (11:56 +0200)]
[Bluetooth] Fix Coverity issue
Coverity issue numbers:
1227417
1227505
1229055
[Verification] Code compiles
Change-Id: Ie05e4184cf200b69615b2e4ba92d3d5cb291d4d0
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[nfc] Fixing memory management for messages and records
Should fix Coverity issues:
* 1227523
* 1227594
* 1228259
* 1228588
* 1229210
* 1229523
* 1229587
[Verification] Code compiles without errors.
Change-Id: I07813a855ce2d335fe783956a7af6f340a314602
[mediacontroller] Fixing Coverity issues
Fixes: 1192721
Change-Id: I1bd564b935d35f0586e174869f7df10cd0cc705b
Pawel Wasowski [Tue, 18 May 2021 14:11:12 +0000 (16:11 +0200)]
[ML][common] Fix a Coverity issue
Coverity issue numver: 1229783
This commit fixes a potential memory leak.
[Verification] The code compiles (it's hard to provoke the code to enter
the problematic branch, so the new code wasn't executed)
Change-Id: Id560ffdffc18ff6bbf2bc987e8e0ad6853b2cdb6
Pawel Wasowski [Mon, 29 Mar 2021 14:24:08 +0000 (16:24 +0200)]
[ML] Remove unneccessary comments and already resolved TODOs
[Verification] Code compiles
Change-Id: I4ccd17dcee4cc1344c739d20492c93f94f08545e
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Pawel Wasowski [Thu, 25 Mar 2021 10:42:12 +0000 (11:42 +0100)]
[ML][Pipeline] Prevent a crash in ~CustomFilter and unregister failures
This commit fixes a crash that used to follow the sequence below:
1. ~CustomFilter() is called, but native
ml_pipeline_custom_easy_filter_unregister()
fails to unregister the filter. CustomFilter is
removed, but a pointer to this object (now defunct)
is still kept in CustomFilter::valid_filters_ container.
2. LockRequestIdToJSResponseMutexIfFilterIsNotWaitingForJSResponses,
that iterates over valid_filters_ accesses the destroyed object
and thus crashes the app.
This commit also changes the order of destruction of Pipeline and
CustomFilter objects managed by Web API. Pipeline objects should
be destroyed first.
[Verification] Tested in Chrome DevTools with the snippets below, works
fine.
inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo("3D", "UINT8", [4, 20, 15, 1]);
outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo("flat", "UINT8", [1200]);
filterCB = function (input, output) {
console.log('hello');
tizen.ml.pipeline.unregisterCustomFilter("flattenFilter");
console.log('bye');
}
retValue = tizen.ml.pipeline.registerCustomFilter("flattenFilter", filterCB,
inputTI, outputTI,
console.warn);
pipelineDefinition = "videotestsrc num-buffers=3 " +
"! video/x-raw,width=20,height=15,format=BGRA " +
"! tensor_converter " +
"! tensor_filter framework=custom-easy model=flattenFilter "
+ "! fakesink";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.start();
// hello
// WebAPIException {name: "AbortError", message:
// "CustomFilter has thrown exception: InvalidStateErr CustomFilter has
// thrown exception: InvalidStateError: The custom filter is processing
// data now. Stop the pipeline to unregister the filter."}
// <no deadlock>
///////////////////////////////////////////////////////////////////////////
inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo("3D", "UINT8", [4, 20, 15, 1]);
outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo("ti1", "UINT8", [1200]);
customFilter = function (input, output) {
try {
inputTI.dispose();
outputTI.dispose();
pipeline.stop();
pipeline.dispose();
} catch (err) {
console.warn(err);
}
}
tizen.ml.pipeline.registerCustomFilter("flattenFilter", customFilter, inputTI, outputTI);
pipelineDefinition = "videotestsrc num-buffers=3 " +
"! video/x-raw,width=20,height=15,format=BGRA " +
"! tensor_converter " +
"! tensor_filter framework=custom-easy model=flattenFilter " +
"! fakesink";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.start();
// WebAPIException {name: "InvalidStateError",
// message: "Pipeline cannot be disposed when at least one custom filter
// is currently processing data.",
// <no deadlock>
///////////////////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
// <CustomFilter and SinkListener callbacks' outputs 3 times>
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario; ignore the data
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return 1; // ignore data
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// Custom filter called
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - CustomFilter returns an error
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return -1;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Invalid CustomFilterOutput.status
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return 123;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// InvalidValuesError,
// message: "CustomFilterOutput.status === 1 is the only legal positive value"
////////////////////////////////////////////////////////////
// Check if {input, output}.dispose() and input.setTensorRawData()
// have any effect
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
// dispose should have no efect
input.dispose();
console.log('input count: ' + input.tensorsInfo.count);
// dispose should have no efect
input.dispose();
console.log('output count: ' + output.tensorsInfo.count);
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
// this call should have no effect
input.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
Change-Id: I4c5b773203239321de5826b5e4908c50cd84b7d6
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Piotr Kosko [Wed, 24 Mar 2021 09:50:41 +0000 (09:50 +0000)]
Merge "[Common][ML] Fixing SVACE issues and code formatting" into tizen
[Archive] Fixed Coverity issue
Issue id: 1218132
[Verification]
Code compiles, TCT passrate 100%.
Coverity showed no issues:
https://analysishub.sec.samsung.net/service/analyses/418348
Change-Id: I5d28891a7b2c3b42237c661474ea88d00e028184
Rafal Walczyna [Tue, 23 Mar 2021 14:32:25 +0000 (15:32 +0100)]
[ML][single] Change InvalidValues to TypeMismatch
In case when no arguments are provided, TypeMismatch should be thrown.
Verification: Tested in google chrome console.
Change-Id: Iab1f606c8a731c096dd93f5e38b0ec4c9b6beb6f
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
[Common][ML] Fixing SVACE issues and code formatting
[SVACE] 1222586, 1222593
[Verification] Code compiles without errors.
Change-Id: Ibf34be9edb25f1b4e61e8480c9b6ad42262d42a4
Piotr Kosko [Fri, 19 Mar 2021 06:03:37 +0000 (06:03 +0000)]
Merge "[ML][single] Fix SingleShot.input attribute change" into tizen
Rafal Walczyna [Thu, 18 Mar 2021 14:08:32 +0000 (15:08 +0100)]
[ML][single] Fix SingleShot.input attribute change
Changing input attribute should enable invoking model with different tensor.
User should not be able to modify or dispose input by direct call.
Change is only possible by replacing whole object.
Code:
var ti1 = new tizen.ml.TensorsInfo()
ti1.addTensorInfo("three", "FLOAT32", [1, 1, 1, 1])
var td1 = ti1.getTensorsData(0);
var ti3 = new tizen.ml.TensorsInfo()
ti3.addTensorInfo("three", "FLOAT32", [3, 1, 1, 1])
var td3 = ti3.getTensorsData(0);
var model = tizen.ml.single.openModel("documents/add.tflite", null, null, "ANY", "ANY", false)
model.invoke(td1)
model.input = ti3
model.invoke(td3)
[Verification] Tested in Google Chrome console
Change-Id: Iac17fd72d7e417d30bad983f6c349bd5e5ef05ed
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Piotr Kosko [Thu, 18 Mar 2021 12:56:33 +0000 (12:56 +0000)]
Merge "[ML][Pipeline] Prevent deadlock in CustomFilter" into tizen
Pawel Wasowski [Mon, 15 Mar 2021 15:52:07 +0000 (16:52 +0100)]
[ML][Pipeline] Prevent deadlock in CustomFilter
ACR: TWDAPI-274
A deadlock could happen in 2 scenarios:
1. An attempt of unregistering a CustomFilter from its callback, (i.e.
calling tizen.ml.pipeline.unregisterCustomFilter('xxx') from xxx's
CustomFilter callback).
2. An attempt of disposing the pipeline using a CustomFilter which is
currently processing data.
This commit fixes the problems.
[Verification] Tested in Chrome DevTools with the snippets below, works
fine.
inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo("3D", "UINT8", [4, 20, 15, 1]);
outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo("flat", "UINT8", [1200]);
filterCB = function (input, output) {
console.log('hello');
tizen.ml.pipeline.unregisterCustomFilter("flattenFilter");
console.log('bye');
}
retValue = tizen.ml.pipeline.registerCustomFilter("flattenFilter", filterCB,
inputTI, outputTI,
console.warn);
pipelineDefinition = "videotestsrc num-buffers=3 " +
"! video/x-raw,width=20,height=15,format=BGRA " +
"! tensor_converter " +
"! tensor_filter framework=custom-easy model=flattenFilter "
+ "! fakesink";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.start();
// hello
// WebAPIException {name: "AbortError", message:
// "CustomFilter has thrown exception: InvalidStateErr CustomFilter has
// thrown exception: InvalidStateError: The custom filter is processing
// data now. Stop the pipeline to unregister the filter."}
// <no deadlock>
///////////////////////////////////////////////////////////////////////////
inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo("3D", "UINT8", [4, 20, 15, 1]);
outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo("ti1", "UINT8", [1200]);
customFilter = function (input, output) {
try {
inputTI.dispose();
outputTI.dispose();
pipeline.stop();
pipeline.dispose();
} catch (err) {
console.warn(err);
}
}
tizen.ml.pipeline.registerCustomFilter("flattenFilter", customFilter, inputTI, outputTI);
pipelineDefinition = "videotestsrc num-buffers=3 " +
"! video/x-raw,width=20,height=15,format=BGRA " +
"! tensor_converter " +
"! tensor_filter framework=custom-easy model=flattenFilter " +
"! fakesink";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.start();
// WebAPIException {name: "InvalidStateError",
// message: "Pipeline cannot be disposed when at least one custom filter
// is currently processing data.",
// <no deadlock>
///////////////////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
// <CustomFilter and SinkListener callbacks' outputs 3 times>
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario; ignore the data
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return 1; // ignore data
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// Custom filter called
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - CustomFilter returns an error
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return -1;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Invalid CustomFilterOutput.status
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return 123;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// InvalidValuesError,
// message: "CustomFilterOutput.status === 1 is the only legal positive value"
////////////////////////////////////////////////////////////
// Check if {input, output}.dispose() and input.setTensorRawData()
// have any effect
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
// dispose should have no efect
input.dispose();
console.log('input count: ' + input.tensorsInfo.count);
// dispose should have no efect
input.dispose();
console.log('output count: ' + output.tensorsInfo.count);
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
// this call should have no effect
input.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
Change-Id: Id6cda7782e3065248b2f2c5f859ca2af07c108a6
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Pawel Wasowski [Wed, 17 Mar 2021 17:26:29 +0000 (18:26 +0100)]
[ML][Pipeline] Remove InvalidValuesError from createPipeline
ACR: TWDAPI-274
This commit removes InvalidValuesError from the list of valid
tizen.ml.pipeline.createPipeline() exceptions, because we cannot
reliably detect, when a pipeline description is invalid.
Instead, AbortError with custom message, suggesting that the
description may be invalid, will be used.
[Verification] Tested in Chrome DevTools with the snippets below, works
fine
// Invalid pipeline definition
var pipeline_def = "invalid";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
// WebAPIException {name: "AbortError", message: "Could not create pipeline:
// invalid pipeline description or an internal error"}
//////////////////////////////////////////////////////////////////////
// Valid pipeline definition
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
// dispose should have no efect
input.dispose();
console.log('input count: ' + input.tensorsInfo.count);
// dispose should have no efect
input.dispose();
console.log('output count: ' + output.tensorsInfo.count);
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
// this call should have no effect
input.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// pipeline starts properly
Change-Id: If8d08160cb98b3acc34812f47b2741c2cce83cd8
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[version] 2.80
Change-Id: I70978ba74a8a100745631723bdccd66239b7224e
Piotr Kosko [Mon, 15 Mar 2021 06:05:05 +0000 (06:05 +0000)]
Merge "[ML][Pipeline] Fix issues reported by TCT team" into tizen
Pawel Wasowski [Fri, 12 Mar 2021 14:32:18 +0000 (15:32 +0100)]
[ML][Pipeline] Fix issues reported by TCT team
Fixed problems:
- Pipeline::{getNodeInfo, getSwitch, getValve}: throw TypeMismatchError
when no argument is passed
- NodeInfo::setProperty: throw TypeMismatchError, instead of AbortError
when value type is other than expected
- Pipeline::unregisterSinkListener: throw InvalidValuesError when sink
has not been registered
[Verification] Code was tested with the snippets below and worked fine
///// checking problems with getNodeInfo, getSwitch, getValve,
///// and unregisterSinkListener
var pipelineDefinition = "videotestsrc name=vsrc is-live=true " +
"! videoconvert " +
"! videoscale name=vscale " +
"! video/x-raw,format=RGBx,width=224,height=224,framerate=60/1 " +
"! tensor_converter " +
"! valve name=valvex " +
"! input-selector name=is01 " +
"! tensor_sink name=sinkx";
var pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.getNodeInfo();
// TypeMismatchError
pipeline.getSwitch();
// TypeMismatchError
pipeline.getValve();
// TypeMismatchError
pipeline.unregisterSinkListener('test')
// InvalidValuesError
///// checking problem with setProperty
pipelineDefinition = "videotestsrc name=vsrc is-live=true " +
"! videoconvert " +
"! videoscale name=vscale " +
"! video/x-raw,format=RGBx,width=224,height=224,framerate=60/1 " +
"! tensor_converter " +
"! valve name=valvex " +
"! input-selector name=is01 " +
"! tensor_sink name=sinkx";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
nodeInfo = pipeline.getNodeInfo("vsrc");
nodeInfo.setProperty("is-live", "DOUBLE", NaN);
// TypeMismatchError
Change-Id: I25438b037e0a2dd2f91f8d9b398cffcaf457386b
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Rafal Walczyna [Fri, 12 Mar 2021 12:23:06 +0000 (13:23 +0100)]
[ML][Single] Fix issues that came out after TCT tests
- SingleShot.openModel should throw TypeError when no arguments provided
[Verification] Tested in chrome-dev console
Change-Id: I13b7946aa90f86ff4becccb9834b76d4f6bf6d22
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Piotr Kosko [Fri, 12 Mar 2021 10:17:40 +0000 (10:17 +0000)]
Merge "[ML][Pipeline] Invalidate CustomFilter arguments after return" into tizen
Pawel Wasowski [Wed, 10 Mar 2021 12:38:22 +0000 (13:38 +0100)]
[ML][Pipeline] Invalidate CustomFilter arguments after return
ACR: TWDAPI-274
This commit makes input and output of a JS CustomFilter act as if they
were disposed after the callback's return.
[Verification] Change was tested in Chrome DevTools with the snippets
below. It works fine.
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
console.log(input);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// TensorsData {_id: 0, _tensorsInfo: TensorsInfo, _disposable: false}
// PAUSED
pipeline.start()
// CustomFilter is called 3 times
inputFromCustomFilter.getTensorRawData(0)
inputFromCustomFilter.tensorsInfo
outputFromCustomFilter.getTensorRawData(0)
outputFromCustomFilter.tensorsInfo
// The 4 lines above result in the following exception
// WebAPIException {name: "AbortError", message: "TensorsData is disposed"}
// as expected
//////////////////////////////////////////////////////////////////////////
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var inputTD = inputTI.getTensorsData()
inputTD.dispose()
inputTD.tensorsInfo
inputTD.getTensorRawData(0)
// The 2 lines above result in the following exception
// WebAPIException {name: "AbortError", message: "TensorsData is disposed"}
// as expected - the behavior of TensorsData.dispose() did not change
Change-Id: Ib6c6afc4bb09ad2ce04bb85650b79868e9923b7b
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Rafal Walczyna [Fri, 12 Mar 2021 07:55:42 +0000 (08:55 +0100)]
[ML][Common] Fix issues that came out after TCT tests
- tizen.ml.single and tizen.ml.prototype should be not writable
- TensorsInfo.addTensorsInfo should return newly added tensors info id
- ValidateBufferForTensorsData issue
[Verification] Tested in chromium console
Change-Id: I9ba7e074c79ffc7acb4de32a87a42db6c5f22beb
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Piotr Kosko [Fri, 12 Mar 2021 05:32:20 +0000 (05:32 +0000)]
Merge "[ML] Change InvalidValuesError to TypeMismatchError for no args" into tizen
Piotr Kosko [Fri, 12 Mar 2021 05:25:37 +0000 (05:25 +0000)]
Merge "[MediaController] Add guards to map of playlists' handles" into tizen
Rafal Walczyna [Thu, 11 Mar 2021 14:06:57 +0000 (15:06 +0100)]
[ML] Change InvalidValuesError to TypeMismatchError for no args
When function is called without args, converter throws TypeError.
This commit unifies it.
code_format has been also applied.
[Verification] Builts successful, tested in chrome console
Change-Id: I032fd3f78e06b561ae472cdbbafe3bcf4092a6d9
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Tue, 9 Mar 2021 11:00:50 +0000 (12:00 +0100)]
[MediaController] Add guards to map of playlists' handles
Previously only mc_server handle were guarded by mutexes.
Playlist also needs one.
[Verification] Tested on TM1, tct-mediacontroller pass 100% x 10, no issue occurred.
Change-Id: I155cc4f2dd87d4b1237537532105b7c251689279
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>