2023/10/31

scrcpy, linux

ref: 在 linux 上用的話,有提供 install_release.sh,
就 run 這個script 就會安裝到 /usr/local/bin
另外這個 script 也會自動 pull更新。
但是要注意的是。只能待在 master,不能checkout 特定 tag,不然會出現 client, server 版本不合的 Error

另外, ubuntu 上也提供 apt 安裝,但是版本太舊了 (1.2),有些新的Android OS (Android 12) 不能正確工作。

2023/10/30

build caffe for snpe

snpe 1.X 版 的 setup 好像比較簡單(?)

以 1.68 版來看。
snpe-caffe-to-dlc 是用 python3,加上其他onnx, pytorch 也都是用 python3。
所以 build caffe 得時候,要設定能 python3

可以參考這一個人 寫的 Makefile.config:
USE_CUDNN := 0
CPU_ONLY := 1
USE_OPENCV := 0
USE_LEVELDB := 0
USE_LMDB := 0
BLAS := open
ANACONDA_HOME := /opt/conda/envs/snpe
PYTHON_INCLUDE := $(ANACONDA_HOME)/include \
                $(ANACONDA_HOME)/include/python3.6m \
                $(ANACONDA_HOME)/lib/python3.6/site-packages/numpy/core/include
PYTHON_LIB := $(ANACONDA_HOME)/lib
PYTHON_LIBRARIES := boost_python36 python3.6m
WITH_PYTHON_LAYER := 1
INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/include/hdf5/serial
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/hdf5/serial
USE_NCCL := 0
USE_PKG_CONFIG := 0
BUILD_DIR := build
DISTRIBUTE_DIR := distribute
DEBUG := 0
TEST_GPUID := 0
Q ?= @
依照這個修改 Makefile.config 需要自己 build libboost_python.
參考另一個 caffe for python3 的說明。
library 改 boost_python3 就可以 make pycaffe OK



參考這一篇,用 conda install 的方式。
用 conda install caffe (python2.7.17) run snpe-caffe-to-dlc 是 failed:
$ snpe-caffe-to-dlc --input_network deploy.prototxt --caffe_bin mobilenet_iter_73000.caffemodel --output_path mobile_net.dlc
Encountered Error: ERROR_CAFFE_NOT_FOUND: Error loading caffe, Message: No module named 'caffe'. PYTHONPATH: 
['/home/charles-chang/snpe-1.68.0.3932/bin/x86_64-linux-clang', '/home/charles-chang/snpe-1.68.0.3932/models/alexnet/scripts', 
 '/home/charles-chang/snpe-1.68.0.3932/models/lenet/scripts', '/home/charles-chang/snpe-1.68.0.3932/lib/python', 
 '/home/charles-chang/qidk/Solutions/VisionSolution1-ObjectDetection/model', 
 '/usr/lib/python36.zip', '/usr/lib/python3.6', 
 '/usr/lib/python3.6/lib-dynload', 
 '/home/charles-chang/.local/lib/python3.6/site-packages', 
 '/usr/local/lib/python3.6/dist-packages', 
 '/usr/lib/python3/dist-packages']

Stack Trace:
Traceback (most recent call last):
  File "/home/charles-chang/snpe-1.68.0.3932/lib/python/qti/aisw/converters/caffe/caffe_to_ir.py", line 92, in convert
    import caffe
ModuleNotFoundError: No module named 'caffe'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/charles-chang/snpe-1.68.0.3932/bin/x86_64-linux-clang/snpe-caffe-to-dlc", line 46, in <module>
    graph = converter.convert()
  File "/home/charles-chang/snpe-1.68.0.3932/lib/python/qti/aisw/converters/caffe/caffe_to_ir.py", line 95, in convert
    raise Exception(code_to_message.get_error_message("ERROR_CAFFE_NOT_FOUND")(e.msg, str(sys.path)))
Exception: ERROR_CAFFE_NOT_FOUND: Error loading caffe, Message: No module named 'caffe'. PYTHONPATH: 
['/home/charles-chang/snpe-1.68.0.3932/bin/x86_64-linux-clang', 
 '/home/charles-chang/snpe-1.68.0.3932/models/alexnet/scripts',
 '/home/charles-chang/snpe-1.68.0.3932/models/lenet/scripts',
 '/home/charles-chang/snpe-1.68.0.3932/lib/python',
 '/home/charles-chang/qidk/Solutions/VisionSolution1-ObjectDetection/model',
 '/usr/lib/python36.zip', '/usr/lib/python3.6',
 '/usr/lib/python3.6/lib-dynload',
 '/home/charles-chang/.local/lib/python3.6/site-packages',
 '/usr/local/lib/python3.6/dist-packages',
 '/usr/lib/python3/dist-packages']
看起來也是因為python3 的關係。

2023/10/27

qidk object detection : YoloNas and MobileSSD

ref: yolonas 的 project 提供一個 jupyter notebook 的檔案,需要 python3.6 以上,用torch 跟 onnx 做出 dlc
mobileSSD 則是在 readme中說明步驟,原來的 model 是 caffe。

for Android 的部分:
yolonas 提供一個 script,download 需要的opencv source和把convert 好的dlc 和 spne 的 so copy 到 source folder.
mobileSSD 在 reame 中有說明步驟。



Mobilenet SSD

mobilenetssd 是用 caffe,所以snpe 要裝好 caffe。
snpe 中各個framework 的 tool 都是獨立的。所以可以針對tool 開conda env.
我用 ubuntu18.04,用update-alternatives把系統 python 改成 python3 (3.6) 來做。

snpe 1.68 的 caffe converting tool : snpe-caffe-to-dlc 是 python script,script head 指定用 python3。
所以build caffe 時要設定 support python3。
依照build caffe for snpe,build 好標準版 caffe。
依照 mobilessd 的說明 download prototxt 跟 caffemodel,用 snpe-caffe-to-dlc 做轉換,出現 Error:
l$ snpe-caffe-to-dlc --input_network deploy.prototxt --caffe_bin mobilenet_iter_73000.caffemodel --output_path moblie_net.dlc
ERROR_CAFFE_CAFFE_PARSING_ERROR: Caffe could not parse deploy.prototxt: 2367:3 : Message type "caffe.LayerParameter" has no field named "permute_param".
INFO_CAFFE_CAFFE_INSTALLATION_ERROR: Caffe installation in use: /home/charles-chang/caffe/python/caffe/__init__.py
說caffe 不認識 permute_param 這個 layer。
應該要用caffe ssd這個版本的 caffe。
所以依照說說明,使用這個版本,checkout ssd,並且build for python3,修改的 Makefile:
$ git diff
diff --git a/Makefile b/Makefile
index 3fd68d1d..0789ae64 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,7 @@ LIB_BUILD_DIR := $(BUILD_DIR)/lib
 STATIC_NAME := $(LIB_BUILD_DIR)/lib$(LIBRARY_NAME).a
 DYNAMIC_VERSION_MAJOR          := 1
 DYNAMIC_VERSION_MINOR          := 0
-DYNAMIC_VERSION_REVISION       := 0-rc3
+DYNAMIC_VERSION_REVISION       := 0
 DYNAMIC_NAME_SHORT := lib$(LIBRARY_NAME).so
 #DYNAMIC_SONAME_SHORT := $(DYNAMIC_NAME_SHORT).$(DYNAMIC_VERSION_MAJOR)
 DYNAMIC_VERSIONED_NAME_SHORT := $(DYNAMIC_NAME_SHORT).$(DYNAMIC_VERSION_MAJOR).$(DYNAMIC_VERSION_MINOR).$(DYNAMIC_VERSION_REVISION)
@@ -178,7 +178,7 @@ ifneq ($(CPU_ONLY), 1)
        LIBRARIES := cudart cublas curand
 endif

-LIBRARIES += glog gflags protobuf boost_system boost_filesystem boost_regex m hdf5_hl hdf5
+LIBRARIES += glog gflags protobuf boost_system boost_filesystem boost_regex m hdf5_serial_hl hdf5_serial

 # handle IO dependencies
 USE_LEVELDB ?= 1
@@ -328,6 +328,12 @@ ifeq ($(USE_CUDNN), 1)
        COMMON_FLAGS += -DUSE_CUDNN
 endif

+# NCCL acceleration configuration
+ifeq ($(USE_NCCL), 1)
+       LIBRARIES += nccl
+       COMMON_FLAGS += -DUSE_NCCL
+endif
+
 # configure IO libraries
 ifeq ($(USE_OPENCV), 1)
        COMMON_FLAGS += -DUSE_OPENCV
@@ -571,7 +577,7 @@ $(STATIC_NAME): $(OBJS) | $(LIB_BUILD_DIR)
        @ echo AR -o $@
        $(Q)ar rcs $@ $(OBJS)

-$(BUILD_DIR)/%.o: %.cpp | $(ALL_BUILD_DIRS)
+$(BUILD_DIR)/%.o: %.cpp $(PROTO_GEN_HEADER) | $(ALL_BUILD_DIRS)
        @ echo CXX $<
        $(Q)$(CXX) $< $(CXXFLAGS) -c -o $@ 2> $@.$(WARNS_EXT) \
                || (cat $@.$(WARNS_EXT); exit 1)
@@ -688,6 +694,6 @@ $(DISTRIBUTE_DIR): all py | $(DISTRIBUTE_SUBDIRS)
        install -m 644 $(DYNAMIC_NAME) $(DISTRIBUTE_DIR)/lib
        cd $(DISTRIBUTE_DIR)/lib; rm -f $(DYNAMIC_NAME_SHORT);   ln -s $(DYNAMIC_VERSIONED_NAME_SHORT) $(DYNAMIC_NAME_SHORT)
        # add python - it's not the standard way, indeed...
-       cp -r python $(DISTRIBUTE_DIR)/python
+       cp -r python $(DISTRIBUTE_DIR)/

 -include $(DEPS)
Makefile.config.example (其實要 copy 成 Makefile.config
diff --git a/Makefile.config.example b/Makefile.config.example
index eac93123..f82f01e4 100644
--- a/Makefile.config.example
+++ b/Makefile.config.example
@@ -31,21 +31,19 @@ CUDA_DIR := /usr/local/cuda
 # CUDA_DIR := /usr

 # CUDA architecture setting: going with all of them.
-# For CUDA < 6.0, comment the lines after *_35 for compatibility.
-CUDA_ARCH := -gencode arch=compute_20,code=sm_20 \
-             -gencode arch=compute_20,code=sm_21 \
-             -gencode arch=compute_30,code=sm_30 \
-             -gencode arch=compute_35,code=sm_35 \
-             -gencode arch=compute_50,code=sm_50 \
-             -gencode arch=compute_52,code=sm_52 \
-             -gencode arch=compute_61,code=sm_61
+# For CUDA < 6.0, comment the *_50 through *_61 lines for compatibility.
+# For CUDA < 8.0, comment the *_60 and *_61 lines for compatibility.
+# For CUDA >= 9.0, comment the *_20 and *_21 lines for compatibility.
+CUDA_ARCH := \
+               -gencode arch=compute_60,code=sm_60 \
+               -gencode arch=compute_61,code=sm_61 \
+               -gencode arch=compute_61,code=compute_61

 # BLAS choice:
 # atlas for ATLAS (default)
 # mkl for MKL
 # open for OpenBlas
-# BLAS := atlas
-BLAS := open
+BLAS := atlas
 # Custom (MKL/ATLAS/OpenBLAS) include and lib directories.
 # Leave commented to accept the defaults for your choice of BLAS
 # (which should work)!
@@ -63,19 +61,19 @@ BLAS := open

 # NOTE: this is required only if you will compile the python interface.
 # We need to be able to find Python.h and numpy/arrayobject.h.
-PYTHON_INCLUDE := /usr/include/python2.7 \
-               /usr/lib/python2.7/dist-packages/numpy/core/include
+#PYTHON_INCLUDE := /usr/include/python2.7 \
+#              /usr/lib/python2.7/dist-packages/numpy/core/include
 # Anaconda Python distribution is quite popular. Include path:
 # Verify anaconda location, sometimes it's in root.
-# ANACONDA_HOME := $(HOME)/anaconda2
+# ANACONDA_HOME := $(HOME)/anaconda
 # PYTHON_INCLUDE := $(ANACONDA_HOME)/include \
-               $(ANACONDA_HOME)/include/python2.7 \
-               $(ANACONDA_HOME)/lib/python2.7/site-packages/numpy/core/include \
+               # $(ANACONDA_HOME)/include/python2.7 \
+               # $(ANACONDA_HOME)/lib/python2.7/site-packages/numpy/core/include

 # Uncomment to use Python 3 (default is Python 2)
-# PYTHON_LIBRARIES := boost_python3 python3.5m
-# PYTHON_INCLUDE := /usr/include/python3.5m \
-#                 /usr/lib/python3.5/dist-packages/numpy/core/include
+ PYTHON_LIBRARIES := boost_python3 python3.6m
+ PYTHON_INCLUDE := /usr/include/python3.6m \
+                 /usr/lib/python3.6/dist-packages/numpy/core/include

 # We need to be able to find libpythonX.X.so or .dylib.
 PYTHON_LIB := /usr/lib
@@ -89,16 +87,20 @@ PYTHON_LIB := /usr/lib
 # WITH_PYTHON_LAYER := 1

 # Whatever else you find you need goes here.
-INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include
+INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/include/hdf5/serial/
 LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib

 # If Homebrew is installed at a non standard location (for example your home directory) and you use it for general dependencies
 # INCLUDE_DIRS += $(shell brew --prefix)/include
 # LIBRARY_DIRS += $(shell brew --prefix)/lib

+# NCCL acceleration switch (uncomment to build with NCCL)
+# https://github.com/NVIDIA/nccl (last tested version: v1.2.3-1+cuda8.0)
+# USE_NCCL := 1
+
 # Uncomment to use `pkg-config` to specify OpenCV library paths.
 # (Usually not necessary -- OpenCV libraries are normally installed in one of the above $LIBRARY_DIRS.)
-# USE_PKG_CONFIG := 1
+USE_PKG_CONFIG := 1

 # N.B. both build and distribute dirs are cleared on `make clean`
 BUILD_DIR := build



有關 snpe 做 MobiienetSSD 的,從 install(build caffe) ,train 到 convert to dlc 的步驟: 這個實際上是他門自己專案用的: 這個project clone 下來直接 build 就可以在 snapdragon 的手機上 run.
會先用 GPU 來 load model,失敗再用 CPU,在 pixel2 上 GPU 開啟失敗,只能用 CPU 啟動。
在 Qualcomm 的 QCS610 上,這個 snpe-release.aar 會 complain 不是 snapdragon,所以不 run
改用 snpe-1.63 版的 snpe-release.aar 和用這一版convert 的 dlc 來 build 就可以在 QCS610 上 run 了。
但是這樣在 pixel 2 上就 fail,說 permission 跟 so 有問題。

這個版本和qidk 的 mobilenetSSD 是用一樣的 model (prototxt, caffe bin),但是 qidk 的 example run 起來是 fail 的。
用 android studio 看,這個 dashcam 跟 infer output 要的 key 是 detectio_out,但是 qidk 要的是 detection_output_number_detection,
在 android studio 中watch infer 後的 output,key 只有 detection_out,大概就是 qidk 的 example 沒有偵測出物件的原因吧?

這一篇問題的回覆可以看到 infer 出來的結果。

2023/10/23

bookmarks : chrome develop mode,

就是用 F12 開啟 右邊的開發模式後,選 "console" tab,然後在 console 下:
document.body.contentEditable="true"

另外一個: 剛上一個一樣,F12 進入 development panel,選 console tab.
在 console 下:
document.body.innerText
按下Enter 後,內文就會被萃取出來,自己找到要的段落,copy 出來、就可以。


還有一種限制: 都一樣,進development mode, 選 console,然後輸入:
document.designMode='on'
就可以了。
上面這些方法選取之後,右鍵 選複製,有時候會跳出阻擋畫面,這時候可以改用 "Ctrl-X" 剪下,就不會碰到 "複製" 事件了。


用 disable javascript: F12 進入 developement mode,在 console 按下 Ctrl-Shift-P,出現 Run > 在這裡書入 JavaScript 就會看到下面有 Disable JavaScript - Debugger 出現,選他就可以。
這個模式好像不能退出 developement mode.不然就失效了。

2023/10/17

bookmark : yolonas custom data

先 clone 到 /mnt/hdd8t/charles-chang/ 下
先follow ref 第一個 link的。
conda create yolonas,然後 install -r requirement.txt,修好安裝的 error,另外 test run jupyter notebook 的import,把缺的裝起來。
download kaggle dataset,解開看一下。

2023/10/5

docker exec & docker attach

已經啟動,running 的 container,可以用 attatch 來取得他的控制權(?)
也可以用 exec 在container 中執行命令。

這兩個方法有蛇麼不同?

attach 的話,直接對應container 現在在 run 的 process,所以啟動時是run /bin/bash,就會進入這個啟動的 shell
exec 的話,會新開一個 process 來 run 你指定的 program,如果指定 /bin/bash,就會進入這個新 create 的 shell

所以在 exec /bin/bash 中 exit 的話,這個新開的 process terminate,container 依樣在 run。
可是 attach 的 /bin/bash 中 exit的話,container 就會整個 exit。