ONNXモデルの中間層出力を取得するアイデア
OpenCL/CUDAのスレッド間通信めも
CUDAとOpenCLでスレッド同士の通信でどうするんだっけ?と思って調べたことを自分用にメモ。
AMD(OpenCL)はshuffleがなさそう
- retval = sub_group_broadcast(value, thread_id)がある
- 特定の1つのthread_idからWavefront全体に値をわたせる
- 隣のスレッドと値を交換するshuffleみたいなのは無さそう
CUDAはshuffleがある
- __shfl_down()でスレッドIDの若番側へデータを送れる
- __shfl_up()でスレッドIDの大きな方へデータを送れる
- __shfl_xor()で2スレッド同士でデータ交換できる
__shfl_xorを使えばbitonic sort実装できそう、と思っていたらすでにあった
あとついでにメモ
ROCm Docker内でfind_package(OpenCL)に失敗した
- 使ったイメージはrocm2.9_ubuntu18.04_py3.6
- cmake v3.6.3(古いなぁ・・・)
cmake AMDAPPSDKROOT=/opt/rocm/opencl ..
だとエラー- exportしても同じ
- CMakeLists.txtで直接上書きしたら(当然だけど)OK
cmake_minimum_required(VERSION 3.6) set(OpenCL_INCLUDE_DIR /opt/rocm/opencl/include) set(OpenCL_LIBRARY /opt/rocm/opencl/lib/x86_64) find_package(OpenCL REQUIRED)
/usr/local/share/cmake-3.6/Modules/FindOpenCL.cmake
はこうなってた。AMDAPPSDKROOTを見に行くように見えるのだが・・・
find_path(OpenCL_INCLUDE_DIR NAMES CL/cl.h OpenCL/cl.h PATHS ENV "PROGRAMFILES(X86)" ENV AMDAPPSDKROOT ENV INTELOCLSDKROOT ENV NVSDKCOMPUTE_ROOT ENV CUDA_PATH ENV ATISTREAMSDKROOT PATH_SUFFIXES include OpenCL/common/inc "AMD APP/include")
YUY2のRAW画像を保存してPythonでRGB化
やったこと
- YUY2出力可能なUSBカメラをLinuxに接続
- ffmpegでRAW画像キャプチャしてファイル保存
- Pythonからnumpyで読み込み+OpenCVでRGBへ変換
- 正確にはBGRにしてファイル保存
キャプチャ(コマンドライン)
$ ffmpeg -f v4l2 -input_format yuyv422 -video_size 800x600 -framerate 30 -i /dev/video0 -vcodec rawvideo -pix_fmt yuyv422 -f image2 sample-%04d.png
- 画素数とフレームレートの数値は
ffmpeg -f v4l2 -list_formats all -i /dev/video0
で確認 - Windowsはたぶん
-f dshow
で-i "カメラデバイス名"
にしたらいける予感(動作未確認)
Python
import cv2 import numpy as np from pathlib import Path _IMG_SHAPE = (600, 800, 2) # 縦幅, 横幅, 8bit2つ # カレントディレクトリの.rawファイルをRGB変換してjpgで保存 for p in Path('.').glob('*.raw'): yuy2 = np.fromfile(str(p), dtype=np.uint8).reshape(_IMG_SHAPE) # YUY2のRAWファイルを8bitずつ読み出し+[600][800][2]に変形 bgr = cv2.cvtColor(yuy2, cv2.COLOR_YUV2BGR_YUY2) # YUY2からBGRへ変換 cv2.imwrite(str(p.with_suffix('.jpg')), bgr) # 拡張子をjpgにしてファイル保存
補足
KerasでLeakyReLUを使った
完全に自分用のメモ。KerasでLeakyReLUを使おうとしたら怒られたので正しい(?)書き方をメモしておく。
警告を食らったコード
import plaidml.keras plaidml.keras.install_backend() from keras.models import Sequential from keras.layers.core import Dense from keras.layers import LeakyReLU def make_mlp(): model = Sequential() model.add(Dense(256, activation=LeakyReLU(alpha=0.01), input_shape=(3,), kernel_initializer='he_normal')) model.add(Dense(3, activation='linear')) model.compile(optimizer='adam', loss='mean_squared_error', metrics=['mse']) return model
警告メッセージ
keras\plaidml-env\lib\site-packages\keras\activations.py:197: UserWarning: Do not pass a layer instance (such as LeakyReLU) as the activation argument of another layer. Instead, advanced activation layers should be used just like any other layer in a model.
identifier=identifier.__class__.__name__))
修正後のコード
def make_mlp(): model = Sequential() - model.add(Dense(256, activation=LeakyReLU(alpha=0.01), input_shape=(3,), kernel_initializer='he_normal')) + model.add(Dense(256, input_shape=(3,), kernel_initializer='he_normal')) + model.add(LeakyReLU(alpha=0.01)) model.add(Dense(3, activation='linear'))
XavierにTensorFlowをインストール。ついでにjupyter notebookも入れる
Jetson AGX XavierにTensorFlowとJupyter notebookをインストールしたのでメモ。
基本的に公式サイト*1とフォーラム*2に書いてある通り。
前提
JetPack-4.0インストール済みの状態から始める
インストール
# 熱くなるのでファン全開で冷やす ubuntu@jetson-0423018055036:~$ sudo ./jetson_clocks.sh # コンパイルが重いので本気を出させる ubuntu@jetson-0423018055036:~$ sudo nvpmodel -m 0 # pipを入れる。依存パッケージでpython3-devも入る ubuntu@jetson-0423018055036:~$ sudo apt-get install python3-pip # venv入れて環境を作る ubuntu@jetson-0423018055036:~$ sudo apt-get install python3-venv ubuntu@jetson-0423018055036:~$ python3 --version Python 3.6.6 ubuntu@jetson-0423018055036:~$ python3 -m venv py366env ubuntu@jetson-0423018055036:~$ source py366env/bin/activate (py366env) ubuntu@jetson-0423018055036:~$ pip install -U pip # TensorFlowを入れる (py366env) ubuntu@jetson-0423018055036:~$ pip install --extra-index-url https://developer.download.nvidia.com/compute/redist/jp40 tensorflow-gpu # matplotlibとkerasの依存パッケージを入れる (py366env) ubuntu@jetson-0423018055036:~$ deactivate # freetypeを入れるときにlibpng-devも一緒に入る ubuntu@jetson-0423018055036:~$ sudo apt-get install libfreetype6-dev ubuntu@jetson-0423018055036:~$ sudo apt-get install libhdf5-dev # KerasというよりSciPyの依存パッケージ ubuntu@jetson-0423018055036:~$ sudo apt-get install liblapacke-dev ubuntu@jetson-0423018055036:~$ sudo apt-get install gfortran ubuntu@jetson-0423018055036:~$ source py366env/bin/activate # matplotlibとKeras、Jupyterを入れる (py366env) ubuntu@jetson-0423018055036:~$ pip install matplotlib (py366env) ubuntu@jetson-0423018055036:~$ pip install -U keras==2.2.0 (py366env) ubuntu@jetson-0423018055036:~$ pip install jupyter
[2018/10/14 追記]
liblapack-devは「static version」らしい。ヘッダファイル類は「e」付きのliblapacke-devが正解っぽい。
Jupyterの初期設定
以前の記事*3とほぼ同じ。
差分は
c.NotebookApp.ip = '0.0.0.0'
と設定するところ。「*」だとエラーになる。参考*4
あとnotebookのアクセス先URLはXavierのホスト名でアクセスできるみたい。自分の環境だと以下のアドレスだった。
http://jetson-0423018055036:8888/
importできたので大丈夫そう。
Jetson AGX Xavier買いました
Jetson AGX Xavier、早期注文が可能になったのでさっそく買ってみた。不在だった荷物の引き取りに手間取ったので今日受け取ったけど、9/11に到着したみたい。
[2018/09/15 02:15追記]なんかGTC Japan以降、名称に「AGX」がつくようになったらしい。
JetPackのファイルダウンロード中なので所感とかそういうのを書いておこうと思う。
工場出荷の状態
Ubuntuはインストール済みの状態だった。ただ、起動させるとCUIが立ち上がってSSHで接続できない状態だった。
HDMIでディスプレイをつなぎ、付属の変換ケーブルでUSBキーボードをつないで作業した。
/home/nvidia/NVIDIA-INSTALLER/README.txtに書かれている通りにインストーラを実行してJetsonを再起動するとGUIモードで起動してSSHもつながった。
$ cd NVIDIA-INSTALLER $ sudo ./installer.sh
ただ、この状態だとCUDA Toolkitとかサンプルアプリとかが入ってない状態なので遊べない。結局JetPackを入れる感じになりそう。
nvpmodelのモード
/etc/nvpmodel.confの設定が書かれているっぽい。デフォルトはID=3「MODE_30W_ALL」ってモードでCPUは8コアともonlineだけど4つだけ1.2GHz設定、GPUは最大900MHz、EMC(メモリのバス?)は1.6GHz。DLAとPVAのクロックも設定されるっぽい。
tegrastatsを打つとこんな感じ。
RAM 2100/15820MB (lfb 3000x4MB) CPU [0%@1190,0%@1190,0%@1190,0%@1190,0%@1190,0%@1190,0%@1190,0%@1190] EMC_FREQ 0%@1600 GR3D_FREQ 0%@905 APE 150 MTS fg 0% bg 0% AO@33C GPU@32.5C Tboard@34C Tdiode@35.75C AUX@31.5C CPU@34C thermal@32.55C PMIC@100C GPU 619/619 CPU 309/309 SOC 1548/1548 CV 0/0 VDDRQ 0/0 SYS5V 1851/1851
CPUのクロック設定が4つしか入ってないのはなぜだろう。。。
一番本気っぽい設定はID=0「MAXN」でクロック設定が全部「-1」になってる。
MAXN is the NONE power model to release all constraints
ってことなので「特に制限しないモード」ってことだと思う。
cpuinfo
今気づいたけど、v8lってv8.1ってこと?XavierのCPUってv8.2じゃなかったっけ???
[2018/09/15 02:15追記]よく見たら「いち」じゃなくて「える」ですね。kernelソースを見たら取りうる値がv8bかv8lってことなのでlittle endianってことかな。
nvidia@jetson-0423018055036:~$ cat /proc/cpuinfo processor : 0 model name : ARMv8 Processor rev 0 (v8l) BogoMIPS : 62.50 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp CPU implementer : 0x4e CPU architecture: 8 CPU variant : 0x0 CPU part : 0x004 CPU revision : 0 MTS version : 42272872 processor : 1 model name : ARMv8 Processor rev 0 (v8l) BogoMIPS : 62.50 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp CPU implementer : 0x4e CPU architecture: 8 CPU variant : 0x0 CPU part : 0x004 CPU revision : 0 MTS version : 42272872 processor : 2 model name : ARMv8 Processor rev 0 (v8l) BogoMIPS : 62.50 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp CPU implementer : 0x4e CPU architecture: 8 CPU variant : 0x0 CPU part : 0x004 CPU revision : 0 MTS version : 42272872 processor : 3 model name : ARMv8 Processor rev 0 (v8l) BogoMIPS : 62.50 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp CPU implementer : 0x4e CPU architecture: 8 CPU variant : 0x0 CPU part : 0x004 CPU revision : 0 MTS version : 42272872 processor : 4 model name : ARMv8 Processor rev 0 (v8l) BogoMIPS : 62.50 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp CPU implementer : 0x4e CPU architecture: 8 CPU variant : 0x0 CPU part : 0x004 CPU revision : 0 MTS version : 42272872 processor : 5 model name : ARMv8 Processor rev 0 (v8l) BogoMIPS : 62.50 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp CPU implementer : 0x4e CPU architecture: 8 CPU variant : 0x0 CPU part : 0x004 CPU revision : 0 MTS version : 42272872 processor : 6 model name : ARMv8 Processor rev 0 (v8l) BogoMIPS : 62.50 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp CPU implementer : 0x4e CPU architecture: 8 CPU variant : 0x0 CPU part : 0x004 CPU revision : 0 MTS version : 42272872 processor : 7 model name : ARMv8 Processor rev 0 (v8l) BogoMIPS : 62.50 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp CPU implementer : 0x4e CPU architecture: 8 CPU variant : 0x0 CPU part : 0x004 CPU revision : 0 MTS version : 42272872
とりあえず今日はここまで。(ダウンロードエラーで止まっとる・・・)
Fancy Indexingが使えるリストを実装してみた
自分用のメモ。Pythonでlistにデータを入れてnumpyみたいにインデックスをリストでわたして取り出したいと思ったので作ってみた。
実装はこちら。
from collections import UserList #class FancyIndexingList(list): 2020/02/03修正。UserListを継承すべき class FancyIndexingList(UserList): def __getitem__(self, arg): if not isinstance(arg, list) and not isinstance(arg, tuple): return super().__getitem__(arg) indices = arg result = [self[i] for i in indices] return FancyIndexingList(result)
UserListを継承して__getitem__で引数がリストとタプルの時だけ自分で処理して他は全部親クラスに任せる。
Fancy Indexingは__getitem__の引数がそのままインデックスのリストになっているので、インデックス引きして新しいリストを作って返すだけ。
使うときはこんな感じ。
>>> sample = FancyIndexingList(range(10)) >>> sample [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> sample[2] 2 >>> sample[ [4, 2, 0] ] [4, 2, 0]
参考。
>>> class IndexingTest: ... def __getitem__(self, arg): ... print(type(arg)) ... >>> i = IndexingTest() >>> i[1] <class 'int'> >>> i[1, 2] <class 'tuple'> >>> i[ [0, 1] ] <class 'list'> >>> i[0:10:2] <class 'slice'>