FC2カウンター FPGAの部屋 2019年02月
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

keras_compressor を試してみる2

keras_compressor を試してみる1”の続き。

前回は、Distiller の次は、keras_compressor を試してみたいということで、Docker のビルドから起動、git clone と環境整備を行った。今回は、MNIST のトレーニングと圧縮、ファイン・チューニングを行う。

まずは、keras_compressor の examples/mnist ディレクトリに移動して、トレーニングを行うのだが、epoch 数が 100 だと終わらないので、10 に変更した。
cd example/mnist/
vim train.py

keras_compressor_10_190226.png

python train.py
でトレーニングを行った。test_accuracy は 0.9909 だった。
keras_compressor_11_190226.png

ログを示す。

root@7552a77f8bdb:/srv/keras_compressor/example/mnist# python train.py 
Using TensorFlow backend.
Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz
11493376/11490434 [==============================] - 3s 0us/step
11501568/11490434 [==============================] - 3s 0us/step
Train on 60000 samples, validate on 10000 samples
Epoch 1/10
2019-02-26 12:21:58.576138: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
60000/60000 [==============================] - 113s 2ms/step - loss: 0.2448 - acc: 0.9252 - val_loss: 0.0556 - val_acc: 0.9822
Epoch 2/10
60000/60000 [==============================] - 114s 2ms/step - loss: 0.0871 - acc: 0.9740 - val_loss: 0.0396 - val_acc: 0.9864
Epoch 3/10
60000/60000 [==============================] - 117s 2ms/step - loss: 0.0661 - acc: 0.9807 - val_loss: 0.0361 - val_acc: 0.9880
Epoch 4/10
60000/60000 [==============================] - 124s 2ms/step - loss: 0.0594 - acc: 0.9821 - val_loss: 0.0345 - val_acc: 0.9889
Epoch 5/10
60000/60000 [==============================] - 118s 2ms/step - loss: 0.0536 - acc: 0.9843 - val_loss: 0.0353 - val_acc: 0.9892
Epoch 6/10
60000/60000 [==============================] - 119s 2ms/step - loss: 0.0514 - acc: 0.9854 - val_loss: 0.0337 - val_acc: 0.9888
Epoch 7/10
60000/60000 [==============================] - 118s 2ms/step - loss: 0.0535 - acc: 0.9842 - val_loss: 0.0349 - val_acc: 0.9890
Epoch 8/10
60000/60000 [==============================] - 118s 2ms/step - loss: 0.0530 - acc: 0.9850 - val_loss: 0.0318 - val_acc: 0.9895
Epoch 9/10
60000/60000 [==============================] - 118s 2ms/step - loss: 0.0543 - acc: 0.9844 - val_loss: 0.0341 - val_acc: 0.9901
Epoch 10/10
60000/60000 [==============================] - 118s 2ms/step - loss: 0.0551 - acc: 0.9846 - val_loss: 0.0355 - val_acc: 0.9909
10000/10000 [==============================] - 5s 473us/step
('test accuracy: ', 0.9909)


なお、トレーニングの終了時に model_raw.h5 が生成された。

次に、圧縮を行った。
python compress.py
を実行するとエラーになった。
keras_compressor_12_190226.png

python3 compress.py
のようだが、こちらも

TypeError: 'NoneType' object is not callable

エラーだった。
keras_compressor_13_190226.png

だが、もう一度、
python3 compress.py
を実行すると正常に通ってしまった。
keras_compressor_14_190226.png

検索すると”TypeError: 'NoneType' object is not callableとエラーが発生した場合”が引っかかった。
それによると、学習させるスクリプトにバックエンドの追加と処理の終了時に

backend.clear_session()

呼び出すそうだ。
keras_compressor_15_190226.png

もう一度、
python3 compress.py
を実行すると通った。
keras_compressor_16_190226.png

圧縮では、 model_compressed.h5 が生成された。

次にファイン・チューニングを行った。
最初に、また epoch 数が多いので 10 個に変更した。
vim finetune.py
keras_compressor_17_190226.png

python3 finetune.py
keras_compressor_18_190226.png

ログを示す。

root@7552a77f8bdb:/srv/keras_compressor/example/mnist# python3 finetune.py
Using TensorFlow backend.
2019-02-26 13:19:58.359630: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
Train on 60000 samples, validate on 10000 samples
Epoch 1/10
60000/60000 [==============================] - 52s 867us/step - loss: 0.3731 - acc: 0.8887 - val_loss: 0.1206 - val_acc: 0.9643
Epoch 2/10
60000/60000 [==============================] - 52s 864us/step - loss: 0.1599 - acc: 0.9554 - val_loss: 0.0921 - val_acc: 0.9722
Epoch 3/10
60000/60000 [==============================] - 52s 862us/step - loss: 0.1333 - acc: 0.9626 - val_loss: 0.0773 - val_acc: 0.9769
Epoch 4/10
60000/60000 [==============================] - 52s 864us/step - loss: 0.1178 - acc: 0.9670 - val_loss: 0.0797 - val_acc: 0.9769
Epoch 5/10
60000/60000 [==============================] - 52s 867us/step - loss: 0.1074 - acc: 0.9703 - val_loss: 0.0770 - val_acc: 0.9766
Epoch 6/10
60000/60000 [==============================] - 52s 863us/step - loss: 0.0986 - acc: 0.9725 - val_loss: 0.0622 - val_acc: 0.9810
Epoch 7/10
60000/60000 [==============================] - 52s 869us/step - loss: 0.0958 - acc: 0.9729 - val_loss: 0.0650 - val_acc: 0.9813
Epoch 8/10
60000/60000 [==============================] - 52s 865us/step - loss: 0.0930 - acc: 0.9740 - val_loss: 0.0644 - val_acc: 0.9792
Epoch 9/10
60000/60000 [==============================] - 52s 865us/step - loss: 0.0875 - acc: 0.9756 - val_loss: 0.0607 - val_acc: 0.9829
Epoch 10/10
60000/60000 [==============================] - 52s 864us/step - loss: 0.0835 - acc: 0.9770 - val_loss: 0.0741 - val_acc: 0.
10000/10000 [==============================] - 2s 202us/step
test accuracy:  0.9793


ファイン・チューニングでは、model_finetuned.h5 が生成された。
  1. 2019年02月28日 04:30 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

keras_compressor を試してみる1

Distiller の次は、keras_compressor を試してみたい。
keras_compressor の元ネタは”モデル圧縮”で、そのGitHubが”DwangoMediaVillage/keras_compressor”だ。ドワンゴの方のようだ。

最初にDocker のDockerfile と build.sh, boot.sh, .bashrc を作成した。
keras_compressor_1_190226.png

Dockerfile を示す。

FROM gw000/keras

RUN apt-get update && apt-get install -y vim
RUN apt-get install -y python3-pip
RUN pip3 install keras
RUN pip3 install tensorflow
RUN pip3 install scikit-learn


build.sh を示す。

docker build -t keras_compressor .


boot.sh を示す。

docker run -ti --rm --name keras_compressorc compressor /bin/bash


.bashrc はUbntu 18.04 のデフォルトの .bashrc をそのまま使用している。

~/Docker ディレクトリの下に keras_compressor ディレクトリを作成してある。
./build.sh を実行した。なお、build.sh と boot.sh には実行権限を付与してある。
keras_compressor_2_190226.png

./boot.sh でコンテナを起動した。
keras_compressor_3_190226.png

他の端末で .bashrc をコンテナ内にコピーする。
cd Docker/keras_compressor/
docker ps
docker cp .bashrc 7552a77f8bdb:/srv

keras_compressor_4_190226.png

Docker コンテナの端末で、
ls -a
すると .bashrc が見えた。
source .bashrc
を行って、もう一度
ls -a
すると色が付いているのが見えた。
keras_compressor_5_190226.png

vim .barhrc で .bashrc を編集して、

export PYTHONPATH="$PYTHONPATH:/srv/keras_compressor/"

を追加する。PYTHONPATH に追加するわけだ。
keras_compressor_6_190226.png

終了後に再度
source .bashrc
keras_compressor_7_190226.png

keras_compressor の git clone を行う。
git clone https://github.com/nico-opendata/keras_compressor
keras_compressor_8_190226.png

keras_compressor ディレクトリに行って環境設定を行った。
cd keras_compressor/
pip install --upgrade .

keras_compressor_9_190226.png
  1. 2019年02月27日 05:36 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DeepLearningのモデル軽量化 Distiller を試す5

DeepLearningのモデル軽量化 Distiller を試す4”の続き。

GitHub のNervanaSystems/distiller の量子化サンプルをやってみよう。

Post-training quantization
ResNet20 for CIFAR10 を 8 ビットに量子化するサンプルだ。
python3 compress_classifier.py -a resnet20_cifar ../../../data.cifar10 --resume ../ssl/checkpoints/checkpoint_trained_dense.pth.tar --quantize-eval --evaluate
distiller_33_190225.png
distiller_34_190225.png

ログを示す。

root@f3527f089871:/workspace/distiller/examples/classifier_compression# python3 compress_classifier.py -a resnet20_cifar ../../../data.cifar10 --resume ../ssl/checkpoints/checkpoint_trained_dense.pth.tar --quantize-eval --evaluate
Log file for this run: /workspace/distiller/examples/classifier_compression/logs/2019.02.24-195538/2019.02.24-195538.log
==> using cifar10 dataset
=> creating resnet20_cifar model for CIFAR10

--------------------------------------------------------
Logging to TensorBoard - remember to execute the server:
> tensorboard --logdir='./logs'

=> loading checkpoint ../ssl/checkpoints/checkpoint_trained_dense.pth.tar
   best top@1: 92.540
Loaded compression schedule from checkpoint (epoch 179)
=> loaded checkpoint '../ssl/checkpoints/checkpoint_trained_dense.pth.tar' (epoch 179)
Optimizer Type: <class 'torch.optim.sgd.SGD'>
Optimizer Args: {'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0.0001, 'nesterov': False}
Files already downloaded and verified
Files already downloaded and verified
Dataset sizes:
 training=45000
 validation=5000
 test=10000
Preparing model for quantization using PostTrainLinearQuantizer
Parameter 'conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.0.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.0.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.1.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.1.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.2.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.2.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.0.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.0.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.0.downsample.0.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.1.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.1.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.2.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.2.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.0.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.0.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.0.downsample.0.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.1.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.1.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.2.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.2.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'fc.wrapped_module.weight' will be quantized to 8 bits
Quantized model:

ResNetCifar(
  (conv1): RangeLinearQuantParamLayerWrapper(
    mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
    preset_activation_stats=False
    w_scale=67.0449, w_zero_point=0.0000
    (wrapped_module): Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  )
  (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (relu): ReLU(inplace)
  (layer1): Sequential(
    (0): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=107.7180, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=144.9845, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (1): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=180.5892, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=183.1618, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (2): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=122.4423, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=152.7345, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
  )
  (layer2): Sequential(
    (0): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=181.2943, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=238.1681, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
      (downsample): Sequential(
        (0): RangeLinearQuantParamLayerWrapper(
          mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
          preset_activation_stats=False
          w_scale=88.9728, w_zero_point=0.0000
          (wrapped_module): Conv2d(16, 32, kernel_size=(1, 1), stride=(2, 2), bias=False)
        )
        (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=206.7310, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=266.5453, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (2): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=152.4554, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=240.0073, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
  )
  (layer3): Sequential(
    (0): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=215.9280, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=235.3784, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
      (downsample): Sequential(
        (0): RangeLinearQuantParamLayerWrapper(
          mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
          preset_activation_stats=False
          w_scale=225.9492, w_zero_point=0.0000
          (wrapped_module): Conv2d(32, 64, kernel_size=(1, 1), stride=(2, 2), bias=False)
        )
        (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=261.7885, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=295.0370, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (2): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=212.4505, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=450.7900, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
  )
  (avgpool): AvgPool2d(kernel_size=8, stride=1, padding=0)
  (fc): RangeLinearQuantParamLayerWrapper(
    mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
    preset_activation_stats=False
    w_scale=83.8628, w_zero_point=0.0000
    base_b_scale=261.5564, base_b_zero_point=0.0000
    (wrapped_module): Linear(in_features=64, out_features=10, bias=True)
  )
)

--- test ---------------------
10000 samples (256 per mini-batch)
Test: [   10/   39]    Loss 0.350214    Top1 92.187500    Top5 99.687500    
Test: [   20/   39]    Loss 0.340852    Top1 92.167969    Top5 99.707031    
Test: [   30/   39]    Loss 0.351019    Top1 91.953125    Top5 99.661458    
Test: [   40/   39]    Loss 0.354121    Top1 91.770000    Top5 99.610000    
==> Top1: 91.770    Top5: 99.610    Loss: 0.354

Saving checkpoint to: logs/2019.02.24-195538/quantized_checkpoint.pth.tar

Log file for this run: /workspace/distiller/examples/classifier_compression/logs/2019.02.24-195538/2019.02.24-195538.log
root@f3527f089871:/workspace/distiller/examples/classifier_compression# 



スパース率を見てみよう。
まずは、resnet20_cifar ディレクトリを作成して、quantized_checkpoint.pth.tar をそこにコピーする。
mkdir resnet20_cifar
cp logs/2019.02.24-195538/quantized_checkpoint.pth.tar resnet20_cifar/


python3 compress_classifier.py --resume=resnet20_cifar/quantized_checkpoint.pth.tar -a=resnet20_cifar ../../../data.cifar10 --summary=sparsity
distiller_35_190225.png

ログを示す。

root@f3527f089871:/workspace/distiller/examples/classifier_compression# python3 compress_classifier.py --resume=resnet20_cifar/quantized_checkpoint.pth.tar -a=resnet20_cifar ../../../data.cifar10 --summary=sparsity
Log file for this run: /workspace/distiller/examples/classifier_compression/logs/2019.02.24-200303/2019.02.24-200303.log
==> using cifar10 dataset
=> creating resnet20_cifar model for CIFAR10

--------------------------------------------------------
Logging to TensorBoard - remember to execute the server:
> tensorboard --logdir='./logs'

=> loading checkpoint resnet20_cifar/quantized_checkpoint.pth.tar
   best top@1: 91.770
Loaded compression schedule from checkpoint (epoch 0)
Loaded quantizer metadata from the checkpoint
Preparing model for quantization using PostTrainLinearQuantizer
Parameter 'conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.0.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.0.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.1.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.1.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.2.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.2.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.0.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.0.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.0.downsample.0.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.1.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.1.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.2.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.2.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.0.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.0.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.0.downsample.0.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.1.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.1.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.2.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.2.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'fc.wrapped_module.weight' will be quantized to 8 bits
Quantized model:

ResNetCifar(
  (conv1): RangeLinearQuantParamLayerWrapper(
    mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
    preset_activation_stats=False
    w_scale=350.8756, w_zero_point=0.0000
    (wrapped_module): Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  )
  (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (relu): ReLU(inplace)
  (layer1): Sequential(
    (0): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=312.6898, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=271.3224, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (1): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=231.3102, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=301.7677, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (2): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=305.3219, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=282.7444, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
  )
  (layer2): Sequential(
    (0): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=390.4178, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=364.4760, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
      (downsample): Sequential(
        (0): RangeLinearQuantParamLayerWrapper(
          mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
          preset_activation_stats=False
          w_scale=167.9384, w_zero_point=0.0000
          (wrapped_module): Conv2d(16, 32, kernel_size=(1, 1), stride=(2, 2), bias=False)
        )
        (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=366.3052, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=382.9035, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (2): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=362.4750, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=391.2636, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
  )
  (layer3): Sequential(
    (0): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=537.1642, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=531.2303, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
      (downsample): Sequential(
        (0): RangeLinearQuantParamLayerWrapper(
          mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
          preset_activation_stats=False
          w_scale=193.8010, w_zero_point=0.0000
          (wrapped_module): Conv2d(32, 64, kernel_size=(1, 1), stride=(2, 2), bias=False)
        )
        (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=444.0079, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=544.6738, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (2): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=524.7949, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=514.5536, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
  )
  (avgpool): AvgPool2d(kernel_size=8, stride=1, padding=0)
  (fc): RangeLinearQuantParamLayerWrapper(
    mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
    preset_activation_stats=False
    w_scale=1020.4681, w_zero_point=0.0000
    base_b_scale=1211.1595, base_b_zero_point=0.0000
    (wrapped_module): Linear(in_features=64, out_features=10, bias=True)
  )
)

=> loaded checkpoint 'resnet20_cifar/quantized_checkpoint.pth.tar' (epoch 0)
Optimizer Type: <class 'torch.optim.sgd.SGD'>
Optimizer Args: {'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0.0001, 'nesterov': False}

Parameters:
+----+---------------------------------------------+----------------+---------------+----------------+------------+------------+----------+----------+----------+------------+----------+----------+------------+
|    | Name                                        | Shape          |   NNZ (dense) |   NNZ (sparse) |   Cols (%) |   Rows (%) |   Ch (%) |   2D (%) |   3D (%) |   Fine (%) |      Std |     Mean |   Abs-Mean |
|----+---------------------------------------------+----------------+---------------+----------------+------------+------------+----------+----------+----------+------------+----------+----------+------------|
|  0 | conv1.wrapped_module.weight                 | (16, 3, 3, 3)  |           432 |            423 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    2.08333 | 28.75588 | -0.63426 |   20.47685 |
|  1 | layer1.0.conv1.wrapped_module.weight        | (16, 16, 3, 3) |          2304 |           2202 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    4.42708 | 16.98713 | -1.12153 |   12.02691 |
|  2 | layer1.0.conv2.wrapped_module.weight        | (16, 16, 3, 3) |          2304 |           2260 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.90972 | 22.50954 | -0.29210 |   16.26259 |
|  3 | layer1.1.conv1.wrapped_module.weight        | (16, 16, 3, 3) |          2304 |           2255 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    2.12674 | 24.41840 | -2.58550 |   18.58637 |
|  4 | layer1.1.conv2.wrapped_module.weight        | (16, 16, 3, 3) |          2304 |           2260 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.90972 | 23.33428 | -0.94010 |   17.67795 |
|  5 | layer1.2.conv1.wrapped_module.weight        | (16, 16, 3, 3) |          2304 |           2247 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    2.47396 | 21.48796 | -1.00347 |   15.57726 |
|  6 | layer1.2.conv2.wrapped_module.weight        | (16, 16, 3, 3) |          2304 |           2248 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    2.43056 | 21.59341 |  0.07943 |   16.16710 |
|  7 | layer2.0.conv1.wrapped_module.weight        | (32, 16, 3, 3) |          4608 |           4528 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.73611 | 25.68778 | -0.13411 |   19.85069 |
|  8 | layer2.0.conv2.wrapped_module.weight        | (32, 32, 3, 3) |          9216 |           9076 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.51910 | 28.72585 | -1.76801 |   22.54427 |
|  9 | layer2.0.downsample.0.wrapped_module.weight | (32, 16, 1, 1) |           512 |            502 |    0.00000 |    0.00000 |  0.00000 |  1.95312 |  0.00000 |    1.95312 | 23.43659 | -0.99414 |   16.49414 |
| 10 | layer2.1.conv1.wrapped_module.weight        | (32, 32, 3, 3) |          9216 |           9013 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    2.20269 | 21.76668 | -2.07650 |   17.18414 |
| 11 | layer2.1.conv2.wrapped_module.weight        | (32, 32, 3, 3) |          9216 |           9042 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.88802 | 24.62638 | -1.73253 |   19.44021 |
| 12 | layer2.2.conv1.wrapped_module.weight        | (32, 32, 3, 3) |          9216 |           8967 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    2.70182 | 15.97449 | -1.79373 |   12.49447 |
| 13 | layer2.2.conv2.wrapped_module.weight        | (32, 32, 3, 3) |          9216 |           9031 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    2.00738 | 20.47896 | -0.12066 |   16.13780 |
| 14 | layer3.0.conv1.wrapped_module.weight        | (64, 32, 3, 3) |         18432 |          18093 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.83919 | 22.38574 | -1.24680 |   17.73107 |
| 15 | layer3.0.conv2.wrapped_module.weight        | (64, 64, 3, 3) |         36864 |          36218 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.75239 | 22.71294 | -1.07943 |   18.02051 |
| 16 | layer3.0.downsample.0.wrapped_module.weight | (64, 32, 1, 1) |          2048 |           2020 |    0.00000 |    0.00000 |  0.00000 |  1.36719 |  0.00000 |    1.36719 | 33.22110 | -2.75146 |   26.28564 |
| 17 | layer3.1.conv1.wrapped_module.weight        | (64, 64, 3, 3) |         36864 |          36239 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.69542 | 24.10124 | -1.99618 |   19.11982 |
| 18 | layer3.1.conv2.wrapped_module.weight        | (64, 64, 3, 3) |         36864 |          36213 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.76595 | 24.02485 | -2.30968 |   18.97195 |
| 19 | layer3.2.conv1.wrapped_module.weight        | (64, 64, 3, 3) |         36864 |          35969 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    2.42784 | 17.23314 | -1.77412 |   13.64255 |
| 20 | layer3.2.conv2.wrapped_module.weight        | (64, 64, 3, 3) |         36864 |          36093 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    2.09147 | 22.90270 | -0.40156 |   17.74607 |
| 21 | fc.wrapped_module.weight                    | (10, 64)       |           640 |            640 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    0.00000 | 48.12321 | -0.01875 |   41.37500 |
| 22 | Total sparsity:                             | -              |        270896 |         265539 |    0.00000 |    0.00000 |  0.00000 |  0.00000 |  0.00000 |    1.97751 |  0.00000 |  0.00000 |    0.00000 |
+----+---------------------------------------------+----------------+---------------+----------------+------------+------------+----------+----------+----------+------------+----------+----------+------------+
Total sparsity: 1.98


Log file for this run: /workspace/distiller/examples/classifier_compression/logs/2019.02.24-200303/2019.02.24-200303.log
root@f3527f089871:/workspace/distiller/examples/classifier_compression# 


modules を見てみよう。
python3 compress_classifier.py --resume=resnet20_cifar/quantized_checkpoint.pth.tar -a=resnet20_cifar ../../../data.cifar10 --summary=modules
distiller_36_190225.png

ログを示す。

root@f3527f089871:/workspace/distiller/examples/classifier_compression# python3 compress_classifier.py --resume=resnet20_cifar/quantized_checkpoint.pth.tar -a=resnet20_cifar ../../../data.cifar10 --summary=modules
Log file for this run: /workspace/distiller/examples/classifier_compression/logs/2019.02.24-200528/2019.02.24-200528.log
==> using cifar10 dataset
=> creating resnet20_cifar model for CIFAR10

--------------------------------------------------------
Logging to TensorBoard - remember to execute the server:
> tensorboard --logdir='./logs'

=> loading checkpoint resnet20_cifar/quantized_checkpoint.pth.tar
   best top@1: 91.770
Loaded compression schedule from checkpoint (epoch 0)
Loaded quantizer metadata from the checkpoint
Preparing model for quantization using PostTrainLinearQuantizer
Parameter 'conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.0.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.0.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.1.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.1.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.2.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer1.2.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.0.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.0.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.0.downsample.0.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.1.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.1.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.2.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer2.2.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.0.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.0.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.0.downsample.0.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.1.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.1.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.2.conv1.wrapped_module.weight' will be quantized to 8 bits
Parameter 'layer3.2.conv2.wrapped_module.weight' will be quantized to 8 bits
Parameter 'fc.wrapped_module.weight' will be quantized to 8 bits
Quantized model:

ResNetCifar(
  (conv1): RangeLinearQuantParamLayerWrapper(
    mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
    preset_activation_stats=False
    w_scale=343.7104, w_zero_point=0.0000
    (wrapped_module): Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  )
  (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (relu): ReLU(inplace)
  (layer1): Sequential(
    (0): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=299.4469, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=316.5102, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (1): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=333.9775, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=306.0066, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (2): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=304.4463, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=246.7246, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
  )
  (layer2): Sequential(
    (0): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=401.2170, w_zero_point=0.0000
        (wrapped_module): Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=405.1727, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
      (downsample): Sequential(
        (0): RangeLinearQuantParamLayerWrapper(
          mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
          preset_activation_stats=False
          w_scale=174.5428, w_zero_point=0.0000
          (wrapped_module): Conv2d(16, 32, kernel_size=(1, 1), stride=(2, 2), bias=False)
        )
        (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=346.6644, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=407.8266, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (2): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=337.9731, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=378.4581, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
  )
  (layer3): Sequential(
    (0): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=504.6201, w_zero_point=0.0000
        (wrapped_module): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=513.4936, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
      (downsample): Sequential(
        (0): RangeLinearQuantParamLayerWrapper(
          mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
          preset_activation_stats=False
          w_scale=212.4980, w_zero_point=0.0000
          (wrapped_module): Conv2d(32, 64, kernel_size=(1, 1), stride=(2, 2), bias=False)
        )
        (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=526.9995, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=486.5478, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
    (2): BasicBlock(
      (conv1): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=472.2161, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu1): ReLU()
      (conv2): RangeLinearQuantParamLayerWrapper(
        mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
        preset_activation_stats=False
        w_scale=459.6506, w_zero_point=0.0000
        (wrapped_module): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      )
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu2): ReLU()
    )
  )
  (avgpool): AvgPool2d(kernel_size=8, stride=1, padding=0)
  (fc): RangeLinearQuantParamLayerWrapper(
    mode=SYMMETRIC, num_bits_acts=8, num_bits_params=8, num_bits_accum=32, clip_acts=False, per_channel_wts=False
    preset_activation_stats=False
    w_scale=1017.0168, w_zero_point=0.0000
    base_b_scale=1095.1624, base_b_zero_point=0.0000
    (wrapped_module): Linear(in_features=64, out_features=10, bias=True)
  )
)

=> loaded checkpoint 'resnet20_cifar/quantized_checkpoint.pth.tar' (epoch 0)
Optimizer Type: <class 'torch.optim.sgd.SGD'>
Optimizer Args: {'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0.0001, 'nesterov': False}
Name                                  Type
------------------------------------  -----------
conv1.wrapped_module                  Conv2d
bn1                                   BatchNorm2d
relu                                  ReLU
layer1.0.conv1.wrapped_module         Conv2d
layer1.0.bn1                          BatchNorm2d
layer1.0.relu1                        ReLU
layer1.0.conv2.wrapped_module         Conv2d
layer1.0.bn2                          BatchNorm2d
layer1.0.relu2                        ReLU
layer1.1.conv1.wrapped_module         Conv2d
layer1.1.bn1                          BatchNorm2d
layer1.1.relu1                        ReLU
layer1.1.conv2.wrapped_module         Conv2d
layer1.1.bn2                          BatchNorm2d
layer1.1.relu2                        ReLU
layer1.2.conv1.wrapped_module         Conv2d
layer1.2.bn1                          BatchNorm2d
layer1.2.relu1                        ReLU
layer1.2.conv2.wrapped_module         Conv2d
layer1.2.bn2                          BatchNorm2d
layer1.2.relu2                        ReLU
layer2.0.conv1.wrapped_module         Conv2d
layer2.0.bn1                          BatchNorm2d
layer2.0.relu1                        ReLU
layer2.0.conv2.wrapped_module         Conv2d
layer2.0.bn2                          BatchNorm2d
layer2.0.relu2                        ReLU
layer2.0.downsample.0.wrapped_module  Conv2d
layer2.0.downsample.1                 BatchNorm2d
layer2.1.conv1.wrapped_module         Conv2d
layer2.1.bn1                          BatchNorm2d
layer2.1.relu1                        ReLU
layer2.1.conv2.wrapped_module         Conv2d
layer2.1.bn2                          BatchNorm2d
layer2.1.relu2                        ReLU
layer2.2.conv1.wrapped_module         Conv2d
layer2.2.bn1                          BatchNorm2d
layer2.2.relu1                        ReLU
layer2.2.conv2.wrapped_module         Conv2d
layer2.2.bn2                          BatchNorm2d
layer2.2.relu2                        ReLU
layer3.0.conv1.wrapped_module         Conv2d
layer3.0.bn1                          BatchNorm2d
layer3.0.relu1                        ReLU
layer3.0.conv2.wrapped_module         Conv2d
layer3.0.bn2                          BatchNorm2d
layer3.0.relu2                        ReLU
layer3.0.downsample.0.wrapped_module  Conv2d
layer3.0.downsample.1                 BatchNorm2d
layer3.1.conv1.wrapped_module         Conv2d
layer3.1.bn1                          BatchNorm2d
layer3.1.relu1                        ReLU
layer3.1.conv2.wrapped_module         Conv2d
layer3.1.bn2                          BatchNorm2d
layer3.1.relu2                        ReLU
layer3.2.conv1.wrapped_module         Conv2d
layer3.2.bn1                          BatchNorm2d
layer3.2.relu1                        ReLU
layer3.2.conv2.wrapped_module         Conv2d
layer3.2.bn2                          BatchNorm2d
layer3.2.relu2                        ReLU
avgpool                               AvgPool2d
fc.wrapped_module                     Linear

Log file for this run: /workspace/distiller/examples/classifier_compression/logs/2019.02.24-200528/2019.02.24-200528.log
root@f3527f089871:/workspace/distiller/examples/classifier_compression# 

  1. 2019年02月25日 05:21 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DeepLearningのモデル軽量化 Distiller を試す4

DeepLearningのモデル軽量化 Distiller を試す3”の続き。

DeepLearningのモデル軽量化 Distiller を試す2”でGradual Pruning をやってみたがうまく行かなかった。
@_tkato_ さんから修正情報をいただいたので、もう一度やってみよう。ありがとうございました。

最初にもう一度simplenet_cifar の学習を行った。
python3 compress_classifier.py --arch simplenet_cifar ../../../data.cifar10 -p 30 -j=1 --lr=0.01
distiller_26_190222.png

logs/2019.02.22-115332 ディレクトリのbest.pth.tar checkpoint.pth.tar をsimplenet_cifar ディレクトリに移動した。
cd logs/2019.02.22-115332/
cp best.pth.tar ../../simplenet_cifar/best.pth.tar
cp checkpoint.pth.tar ../../simplenet_cifar/checkpoint.pth.tar
cd ../..


simplenet_cifar.schedule_agp.yaml を修正した。修正した simplenet_cifar.schedule_agp.yaml を示す。

version: 1
pruners:
  conv1_pruner:
    class: 'AutomatedGradualPruner'
    initial_sparsity : 0.15
    final_sparsity: 0.3
    weights: ['conv1.weight']

  conv2_pruner:
    class: 'AutomatedGradualPruner'
    initial_sparsity : 0.15
    final_sparsity: 0.5
    weights: ['conv2.weight']

  fc_pruner:
    class: 'AutomatedGradualPruner'
    initial_sparsity : 0.15
    final_sparsity: 0.80
    weights: ['fc1.weight', 'fc2.weight','fc3.weight']

lr_schedulers:
  pruning_lr:
    class: StepLR
    step_size: 30
    gamma: 0.10

policies:
  - pruner:
      instance_name : 'conv1_pruner'
    starting_epoch: 1
    ending_epoch: 100
    frequency: 2

  - pruner:
      instance_name : 'conv2_pruner'
    starting_epoch: 1
    ending_epoch: 100
    frequency: 2

  - pruner:
      instance_name : 'fc_pruner'
    starting_epoch: 1
    ending_epoch: 100
    frequency: 2

  - lr_scheduler:
      instance_name: pruning_lr
    starting_epoch: 1
    ending_epoch: 100
    frequency: 1


学習したbest.pth.tar に対して、Gradual Pruningを実行した。
time python3 compress_classifier.py --arch simplenet_cifar ../../../data.cifar10 -p 50 --lr=0.001 --epochs=200 --resume=simplenet_cifar/best.pth.tar --compress=simplenet_cifar.schedule_agp.yaml
distiller_27_190222.png

今度はうまく行ったようだ。
TensorBoard の結果を示す。
distiller_28_190223.png
distiller_29_190223.png
distiller_30_190223.png

--summaryオプションをやってみよう。最初に学習したネットワークの --summary=sparsity の結果を示す。
distiller_31_190223.png

Total sparsity: 0.00 だった。

次に、Gradual Pruning 後のネットワークの --summary=sparsity の結果を示す。
distiller_32_190223.png

Total sparsity: 78.47 だった。うまく行っている。
  1. 2019年02月23日 05:48 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

Docker 上でDistiller のJupyter Notebook を立ち上げたらエラーになった

Docker 上でDistiller を試しているが、そこで、Jupyter Notebook のポートを開けてJupyter Notebook を起動したらエラーになった。

まずは、boot.sh に TCP ポートの 9999 番を開ける設定を追加した。

docker run -ti --rm --name distiller -p 6006:6006 -p 8888:8888 -v /home/masaaki/Docker/distiller/workspace/:/workspace/ pytorch0.4cuda9 /bin/bash



./boot.sh を起動して、
jupyter notebook &
でJupyter Notebook を起動した。
jupyter_note_docker_1_190222.png

OSError: [Errno 99] Cannot assign requested address

だった。
エラーを検索したところ、”Docker上のjupyter notebookが起動できなくなったら”がヒットした。この通りにトラブルシュートをやってみよう。

jupyter notebook --generate-config
を実行したところ

Writing default config to: /root/.jupyter/jupyter_notebook_config.py

だそうだ。

このファイルを編集する。
vim /root/.jupyter/jupyter_notebook_config.py

## The IP address the notebook server will listen on.
#c.NotebookApp.ip = 'localhost'

の下に、

c.NotebookApp.ip = '0.0.0.0'

を追加した。
jupyter_note_docker_2_190222.png

jupyter notebook &
で起動したら、

Running as root is not recommended. Use --allow-root to bypass.

と言われたので、
jupyter notebook --allow-root &
で起動した。
jupyter_note_docker_3_190222.png

Chome で localhost:8888 を見ると、Jupyter Notebook のログイン画面が表示されたので、起動画面にあるtoken(token=6920b1c5d584cb42ef2664202937fcaedfef76afb5e42be5 の token=を除いた部分)を入力したところ、Jupyter Notebook が使えるようになった。
jupyter_note_docker_4_190222.png

  1. 2019年02月22日 05:35 |
  2. Docker
  3. | トラックバック:0
  4. | コメント:0

DeepLearningのモデル軽量化 Distiller を試す3

DeepLearningのモデル軽量化 Distiller を試す2”の続き。

前回は、tkato さんの tkato's blog の”DistillerでDeepLearningのモデルを軽量化: Gradual Pruning編”を参考にsimplenet_cifar を学習し、Gradual Pruningのサンプルを動作させたが、YMAL ファイルに記述した Gradual Pruning は行われなかった。今回は、”DistillerでDeepLearningのモデルを軽量化: Gradual Pruning編”の残りをやってみよう。

--summaryオプションをやってみよう。
python3 compress_classifier.py --resume=simplenet_cifar/best.pth.tar -a=simplenet_cifar ../../../data.cifar10 --summary=sparsity
distiller_19_190221.png

Total sparsity: 0.00 だった。

python3 compress_classifier.py --resume=simplenet_cifar/best.pth.tar -a=simplenet_cifar ../../../data.cifar10 --summary=compute
distiller_20_190221.png

Total MACs: 651,720

python3 compress_classifier.py --resume=simplenet_cifar/checkpoint.pth.tar -a=simplenet_cifar ../../../data.cifar10 --summary=sparsity
distiller_21_190221.png

Total sparsity: 0.00 だったが、2 つ上の図と細部の値は異なる。

python3 compress_classifier.py --resume=simplenet_cifar/checkpoint.pth.tar -a=simplenet_cifar ../../../data.cifar10 --summary=compute
distiller_22_190221.png

Total MACs: 651,720 なので、2 つ上上と同じだ。
  1. 2019年02月22日 04:50 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DeepLearningのモデル軽量化 Distiller を試す2

DeepLearningのモデル軽量化 Distiller を試す1”の続き。

前回は、tkato さんの tkato's blog の”DistillerでDeepLearningのモデルを軽量化: Gradual Pruning編”を参考にして、DeepLearningのモデル軽量化 Distiller を試してみようと言うことで、git clone で Distiller をクローンした。今回は、simplenet_cifar を学習し、Gradual Pruningのサンプルを動作させてみよう。

実行環境を構築する。
cd distiller/
pip install -r requirements.txt

distiller_5_190219.png
distiller_6_190219.png

examples/classifier_compression ディレクトリに移動して、simplenet_cifar の学習を行う。
cd examples/classifier_compression/
python3 compress_classifier.py --arch simplenet_cifar ../../../data.cifar10 -p 30 -j=1 --lr=0.01

distiller_7_190219.png
distiller_8_190219.png

学習が正常に終了した。
なお、python3 compress_classifier.py -h つまりヘルプの表示結果を示す。

root@175abda804b7:/workspace/distiller/examples/classifier_compression# python compress_classifier.py -h
usage: compress_classifier.py [-h] [--arch ARCH] [-j N] [--epochs N] [-b N]
                              [--lr LR] [--momentum M] [--weight-decay W]
                              [--print-freq N] [--resume PATH] [-e]
                              [--pretrained]
                              [--activation-stats PHASE [PHASE ...]]
                              [--masks-sparsity] [--param-hist]
                              [--summary {sparsity,compute,model,modules,png,png_w_params,onnx}]
                              [--compress [COMPRESS]]
                              [--sense {element,filter,channel}]
                              [--sense-range SENSITIVITY_RANGE SENSITIVITY_RANGE SENSITIVITY_RANGE]
                              [--extras EXTRAS] [--deterministic]
                              [--gpus DEV_ID] [--cpu] [--name NAME]
                              [--out-dir OUTPUT_DIR]
                              [--validation-split VALIDATION_SPLIT]
                              [--effective-train-size EFFECTIVE_TRAIN_SIZE]
                              [--effective-valid-size EFFECTIVE_VALID_SIZE]
                              [--effective-test-size EFFECTIVE_TEST_SIZE]
                              [--confusion]
                              [--earlyexit_lossweights [EARLYEXIT_LOSSWEIGHTS [EARLYEXIT_LOSSWEIGHTS ...]]]
                              [--earlyexit_thresholds [EARLYEXIT_THRESHOLDS [EARLYEXIT_THRESHOLDS ...]]]
                              [--num-best-scores NUM_BEST_SCORES]
                              [--load-serialized] [--thinnify]
                              [--kd-teacher ARCH] [--kd-pretrained]
                              [--kd-resume PATH] [--kd-temperature TEMP]
                              [--kd-distill-wt WEIGHT]
                              [--kd-student-wt WEIGHT]
                              [--kd-teacher-wt WEIGHT]
                              [--kd-start-epoch EPOCH_NUM]
                              [--quantize-eval | --qe-calibration PORTION_OF_TEST_SET]
                              [--qe-mode QE_MODE] [--qe-bits-acts NUM_BITS]
                              [--qe-bits-wts NUM_BITS]
                              [--qe-bits-accum NUM_BITS] [--qe-clip-acts]
                              [--qe-no-clip-layers LAYER_NAME [LAYER_NAME ...]]
                              [--qe-per-channel] [--qe-stats-file PATH]
                              [--qe-config-file PATH] [--greedy]
                              [--greedy-ft-epochs GREEDY_FT_EPOCHS]
                              [--greedy-target-density GREEDY_TARGET_DENSITY]
                              [--greedy-pruning-step GREEDY_PRUNING_STEP]
                              [--greedy-finetuning-policy {constant,linear-grow}]
                              [--amc]
                              [--amc-protocol {mac-constrained,param-constrained,accuracy-guaranteed,mac-constrained-experimental}]
                              [--amc-ft-epochs AMC_FT_EPOCHS]
                              [--amc-save-chkpts]
                              [--amc-action-range AMC_ACTION_RANGE AMC_ACTION_RANGE]
                              [--amc-heatup-epochs AMC_HEATUP_EPOCHS]
                              [--amc-training-epochs AMC_TRAINING_EPOCHS]
                              [--amc-reward-frequency AMC_REWARD_FREQUENCY]
                              [--amc-target-density AMC_TARGET_DENSITY]
                              [--amc-agent-algo {ClippedPPO-continuous,ClippedPPO-discrete,DDPG,Random-policy}]
                              DIR

Distiller image classification model compression

positional arguments:
  DIR                   path to dataset

optional arguments:
  -h, --help            show this help message and exit
  --arch ARCH, -a ARCH  model architecture: alexnet | alexnet_bn | densenet121
                        | densenet161 | densenet169 | densenet201 |
                        inception_v3 | mobilenet | mobilenet_025 |
                        mobilenet_050 | mobilenet_075 | plain20_cifar |
                        preact_resnet101 | preact_resnet110_cifar |
                        preact_resnet110_cifar_conv_ds | preact_resnet152 |
                        preact_resnet18 | preact_resnet20_cifar |
                        preact_resnet20_cifar_conv_ds | preact_resnet32_cifar
                        | preact_resnet32_cifar_conv_ds | preact_resnet34 |
                        preact_resnet44_cifar | preact_resnet44_cifar_conv_ds
                        | preact_resnet50 | preact_resnet56_cifar |
                        preact_resnet56_cifar_conv_ds | resnet101 |
                        resnet101_earlyexit | resnet110_cifar_earlyexit |
                        resnet1202_cifar_earlyexit | resnet152 |
                        resnet152_earlyexit | resnet18 | resnet18_earlyexit |
                        resnet20_cifar | resnet20_cifar_earlyexit |
                        resnet32_cifar | resnet32_cifar_earlyexit | resnet34 |
                        resnet34_earlyexit | resnet44_cifar |
                        resnet44_cifar_earlyexit | resnet50 |
                        resnet50_earlyexit | resnet56_cifar |
                        resnet56_cifar_earlyexit | simplenet_cifar |
                        squeezenet1_0 | squeezenet1_1 | vgg11 | vgg11_bn |
                        vgg11_bn_cifar | vgg11_cifar | vgg13 | vgg13_bn |
                        vgg13_bn_cifar | vgg13_cifar | vgg16 | vgg16_bn |
                        vgg16_bn_cifar | vgg16_cifar | vgg19 | vgg19_bn |
                        vgg19_bn_cifar | vgg19_cifar (default: resnet18)
  -j N, --workers N     number of data loading workers (default: 4)
  --epochs N            number of total epochs to run
  -b N, --batch-size N  mini-batch size (default: 256)
  --lr LR, --learning-rate LR
                        initial learning rate
  --momentum M          momentum
  --weight-decay W, --wd W
                        weight decay (default: 1e-4)
  --print-freq N, -p N  print frequency (default: 10)
  --resume PATH         path to latest checkpoint (default: none)
  -e, --evaluate        evaluate model on validation set
  --pretrained          use pre-trained model
  --activation-stats PHASE [PHASE ...], --act-stats PHASE [PHASE ...]
                        collect activation statistics on phases: train, valid,
                        and/or test (WARNING: this slows down training)
  --masks-sparsity      print masks sparsity table at end of each epoch
  --param-hist          log the parameter tensors histograms to file (WARNING:
                        this can use significant disk space)
  --summary {sparsity,compute,model,modules,png,png_w_params,onnx}
                        print a summary of the model, and exit - options:
                        sparsity | compute | model | modules | png |
                        png_w_params | onnx
  --compress [COMPRESS]
                        configuration file for pruning the model (default is
                        to use hard-coded schedule)
  --sense {element,filter,channel}
                        test the sensitivity of layers to pruning
  --sense-range SENSITIVITY_RANGE SENSITIVITY_RANGE SENSITIVITY_RANGE
                        an optional parameter for sensitivity testing
                        providing the range of sparsities to test. This is
                        equivalent to creating sensitivities =
                        np.arange(start, stop, step)
  --extras EXTRAS       file with extra configuration information
  --deterministic, --det
                        Ensure deterministic execution for re-producible
                        results.
  --gpus DEV_ID         Comma-separated list of GPU device IDs to be used
                        (default is to use all available devices)
  --cpu                 Use CPU only. Flag not set => uses GPUs according to
                        the --gpus flag value.Flag set => overrides the --gpus
                        flag
  --name NAME, -n NAME  Experiment name
  --out-dir OUTPUT_DIR, -o OUTPUT_DIR
                        Path to dump logs and checkpoints
  --validation-split VALIDATION_SPLIT, --valid-size VALIDATION_SPLIT, --vs VALIDATION_SPLIT
                        Portion of training dataset to set aside for
                        validation
  --effective-train-size EFFECTIVE_TRAIN_SIZE, --etrs EFFECTIVE_TRAIN_SIZE
                        Portion of training dataset to be used in each epoch.
                        NOTE: If --validation-split is set, then the value of
                        this argument is applied AFTER the train-validation
                        split according to that argument
  --effective-valid-size EFFECTIVE_VALID_SIZE, --evs EFFECTIVE_VALID_SIZE
                        Portion of validation dataset to be used in each
                        epoch. NOTE: If --validation-split is set, then the
                        value of this argument is applied AFTER the train-
                        validation split according to that argument
  --effective-test-size EFFECTIVE_TEST_SIZE, --etes EFFECTIVE_TEST_SIZE
                        Portion of test dataset to be used in each epoch
  --confusion           Display the confusion matrix
  --earlyexit_lossweights [EARLYEXIT_LOSSWEIGHTS [EARLYEXIT_LOSSWEIGHTS ...]]
                        List of loss weights for early exits (e.g.
                        --earlyexit_lossweights 0.1 0.3)
  --earlyexit_thresholds [EARLYEXIT_THRESHOLDS [EARLYEXIT_THRESHOLDS ...]]
                        List of EarlyExit thresholds (e.g.
                        --earlyexit_thresholds 1.2 0.9)
  --num-best-scores NUM_BEST_SCORES
                        number of best scores to track and report (default: 1)
  --load-serialized     Load a model without DataParallel wrapping it
  --thinnify            physically remove zero-filters and create a smaller
                        model
  --greedy              greedy filter pruning
  --amc                 AutoML Compression

Knowledge Distillation Training Arguments:
  --kd-teacher ARCH     Model architecture for teacher model
  --kd-pretrained       Use pre-trained model for teacher
  --kd-resume PATH      Path to checkpoint from which to load teacher weights
  --kd-temperature TEMP, --kd-temp TEMP
                        Knowledge distillation softmax temperature
  --kd-distill-wt WEIGHT, --kd-dw WEIGHT
                        Weight for distillation loss (student vs. teacher soft
                        targets)
  --kd-student-wt WEIGHT, --kd-sw WEIGHT
                        Weight for student vs. labels loss
  --kd-teacher-wt WEIGHT, --kd-tw WEIGHT
                        Weight for teacher vs. labels loss
  --kd-start-epoch EPOCH_NUM
                        Epoch from which to enable distillation

Arguments controlling quantization at evaluation time ("post-training quantization"):
  --quantize-eval, --qe
                        Apply linear quantization to model before evaluation.
                        Applicable only if --evaluate is also set
  --qe-calibration PORTION_OF_TEST_SET
                        Run the model in evaluation mode on the specified
                        portion of the test dataset and collect statistics.
                        Ignores all other 'qe--*' arguments
  --qe-mode QE_MODE, --qem QE_MODE
                        Linear quantization mode. Choices: sym | asym_s |
                        asym_u
  --qe-bits-acts NUM_BITS, --qeba NUM_BITS
                        Number of bits for quantization of activations
  --qe-bits-wts NUM_BITS, --qebw NUM_BITS
                        Number of bits for quantization of weights
  --qe-bits-accum NUM_BITS
                        Number of bits for quantization of the accumulator
  --qe-clip-acts, --qeca
                        Enable clipping of activations using min/max values
                        averaging over batch
  --qe-no-clip-layers LAYER_NAME [LAYER_NAME ...], --qencl LAYER_NAME [LAYER_NAME ...]
                        List of layer names for which not to clip activations.
                        Applicable only if --qe-clip-acts is also set
  --qe-per-channel, --qepc
                        Enable per-channel quantization of weights (per output
                        channel)
  --qe-stats-file PATH  Path to YAML file with calibration stats. If not
                        given, dynamic quantization will be run (Note that not
                        all layer types are supported for dynamic
                        quantization)
  --qe-config-file PATH
                        Path to YAML file containing configuration for
                        PostTrainLinearQuantizer (if present, all other --qe*
                        arguments are ignored)

Greedy Pruning:
  --greedy-ft-epochs GREEDY_FT_EPOCHS
                        number of epochs to fine-tune each discovered network
  --greedy-target-density GREEDY_TARGET_DENSITY
                        target density of the network we are seeking
  --greedy-pruning-step GREEDY_PRUNING_STEP
                        size of each pruning step (as a fraction in [0..1])
  --greedy-finetuning-policy {constant,linear-grow}
                        policy used for determining how long to fine-tune

AutoML Compression Arguments:
  --amc-protocol {mac-constrained,param-constrained,accuracy-guaranteed,mac-constrained-experimental}
                        Compression-policy search protocol
  --amc-ft-epochs AMC_FT_EPOCHS
                        The number of epochs to fine-tune each discovered
                        network
  --amc-save-chkpts     Save checkpoints of all discovered networks
  --amc-action-range AMC_ACTION_RANGE AMC_ACTION_RANGE
                        Density action range (a_min, a_max)
  --amc-heatup-epochs AMC_HEATUP_EPOCHS
                        The number of epochs for heatup/exploration
  --amc-training-epochs AMC_TRAINING_EPOCHS
                        The number of epochs for training/exploitation
  --amc-reward-frequency AMC_REWARD_FREQUENCY
                        Reward computation frequency (measured in agent steps)
  --amc-target-density AMC_TARGET_DENSITY
                        Target density of the network we are seeking
  --amc-agent-algo {ClippedPPO-continuous,ClippedPPO-discrete,DDPG,Random-policy}
                        The agent algorithm to use
root@175abda804b7:/workspace/distiller/examples/classifier_compression# 


examples/classifier_compression ディレクトリで、simplenet_cifar ディレクトリを作成する。
logs/2019.02.19-092528 ディレクトリのbest.pth.tar checkpoint.pth.tar をsimplenet_cifar ディレクトリに移動する。
mkdir simplenet_cifar
cd logs/2019.02.19-092528/
mv best.pth.tar checkpoint.pth.tar ../../simplenet_cifar/
cd ../..
ls simplenet_cifar

distiller_9_190220.png

TensorBoardを起動して学習のログを表示する。
tensorboard --logdir='./logs' &

ホストのChrome で http://localhost:6006 を表示するとTensorBoard が表示された。
distiller_10_190220.png
distiller_11_190220.png
distiller_12_190220.png

Gradual Pruningのサンプルを動かすために、simplenet_cifar.schedule_agp.yaml ファイルを作成する。
ファイルの中身は”DistillerでDeepLearningのモデルを軽量化: Gradual Pruning編”からコピーさせていただいた。
vim simplenet_cifar.schedule_agp.yaml
distiller_14_190220.png

学習したbest.pth.tar に対して、Gradual Pruningを実行する。
time python3 compress_classifier.py --arch simplenet_cifar ../../../data.cifar10 -p 50 --lr=0.001 --epochs=200 --resume=simplenet_cifar/best.pth.tar --compress=simplenet_cifar.schedule_agp.yaml
distiller_15_190220.png

TensorBoard の結果を示す。
distiller_16_190220.png
distiller_17_190220.png
distiller_18_190220.png

層のsparsity に変化が無い。なぜだろうか?
Gradual Pruning がうまく行ってない?
  1. 2019年02月21日 04:52 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DeepLearningのモデル軽量化 Distiller を試す1

tkato さんの tkato's blog の”DistillerでDeepLearningのモデルを軽量化: Gradual Pruning編”を参考にして、DeepLearningのモデル軽量化 Distiller を試してみようと思う。

まずは、Docker で環境を構築する。
dockerhub のpytorch/pytorch の 0.4_cuda9_cudnn7 を使用する。

書いたDockerfile を示す。

FROM pytorch/pytorch:0.4_cuda9_cudnn7

RUN apt-get update && apt-get install -y vim


build.sh を示す。

docker build -t pytorch0.4cuda9 .


boot.sh を示す。

docker run -ti --rm --name distiller -p 6006:6006 -v /home/masaaki/Docker/distiller/workspace/:/workspace/ pytorch0.4cuda9 /bin/bash


Docker ディレクトリの下に distiller ディレクトリを作成し ./build.sh を起動した。
distiller_1_190219.png
distiller_2_190219.png

.boot.sh を実行して、Docker を起動した。
DistillerでDeepLearningのモデルを軽量化: Gradual Pruning編”を参考にして、Distiller を git clone する。
git clone https://github.com/NervanaSystems/distiller.git
distiller_4_190219.png
  1. 2019年02月20日 05:35 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

Docker 上のUbuntu 16.04 のPetaLinux 2018.2 でビルドしてみた3

Docker 上のUbuntu 16.04 のPetaLinux 2018.2 でビルドしてみた2”の続き。

前回は、uImage と BOOT.BIN を生成した。petalinux-boot には失敗してしまったが、Ultra96 をブートするに必要なファイルは揃った。そういう訳で、今回はMirco SD カードにファイルを書いてUltra96 でブートしてみよう。

最初に、必要なファイルはどれか?というと、”PetaLinux Tools Documentation Reference Guide UG1144 (v2018.2) June 6, 2018”の 38 ページの”Boot a PetaLinux Image on Hardware with SD Card”の”Steps to Boot a PetaLinux Image on Hardware with SD Card”によると

image.ub
BOOT.BIN

だということだ。

早速、8 GB のMicro SD カードにこの2つをコピーした。
PetaLinux_27_190218.png

gtk_term を立ち上げて、Serial Port のPort を /dev/ttyUSB1 に、Baud Rate を 115200 bps に設定した。
Ultra96 にMicrro SD カードを入れて電源ON 。
でも gtk_term 上に何も表示されない。。。

これは、UART0 に表示されてしまっているようだ。
stdin/stdou を psu_uart_0 から psu_uart_1 に変更する必要がある。

PetaLinux プロジェクトの初期化をやり直そう。
petalinux-config --get-hw-description=/home/masaaki/PetaLProj/cam_test_ov5642_182/cam_test_182.sdk/
menu-config が立ち上がったら、Subsystem AUTO Hardware Settings -> Serial Settings を選択した。
Primary stdin/stdout を psu_uart_1 に変更した。
PetaLinux_23_190218.png

先頭の画面に戻って Save を行ってから Exit した。
PetaLinux_24_190218.png

petalinux-config が終了した。
PetaLinux_25_190218.png

その後は手順に従って、BOOT.BIN をビルドする。
LANG=en_US.UTF-8 petalinux-build
LANG=en_US.UTF-8 petalinux-package --image -c kernel --format uImage
LANG=en_US.UTF-8 petalinux-package --boot --fsbl /home/masaaki/PetaLProj/cam_test_ov5642_182/components/plnx_workspace/fsbl/fsbl/Release/fsbl.elf --fpga /home/masaaki/PetaLProj/cam_test_ov5642_182/components/plnx_workspace/fsbl/fsbl_hwproj/cam_test_wrapper.bit --pmufw /home/masaaki/PetaLProj/cam_test_ov5642_182/images/linux/pmufw.elf --u-boot


BOOT.BIN と image.ub が生成された。
もう一度、Micro SD カードに書いて、Ultra96 に入れて電源ON 。
今度は、gtk_term にブートメッセージが表示された。
PetaLinux_26_190218.png

root の root でログインもできた。
PetaLinux_28_190219.png

ブートメッセージを示す。

sdhci@ff160000: 0 (SD)Card did not respond to voltage select!
mmc_init: -95, time 27

*** Warning - bad CRC, using default environment

In:    serial@ff010000
Out:   serial@ff010000
Err:   serial@ff010000
Board: Xilinx ZynqMP
Bootmode: SD_MODE
U-BOOT for cam_test_ov5642_182

Hit any key to stop autoboot:  0 
Device: sdhci@ff160000
Manufacturer ID: 3
OEM: 5344
Name: SL08G 
Tran Speed: 50000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 7.4 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes
reading image.ub
13407472 bytes read in 1046 ms (12.2 MiB/s)
## Loading kernel from FIT Image at 10000000 ...
   Using 'conf@system-top.dtb' configuration
   Trying 'kernel@1' kernel subimage
     Description:  Linux kernel
     Type:         Kernel Image
     Compression:  gzip compressed
     Data Start:   0x10000104
     Data Size:    6960376 Bytes = 6.6 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x00080000
     Entry Point:  0x00080000
     Hash algo:    sha1
     Hash value:   f7969295bb0009929ae004732e24833a06e81c68
   Verifying Hash Integrity ... sha1+ OK
## Loading ramdisk from FIT Image at 10000000 ...
   Using 'conf@system-top.dtb' configuration
   Trying 'ramdisk@1' ramdisk subimage
     Description:  petalinux-user-image
     Type:         RAMDisk Image
     Compression:  gzip compressed
     Data Start:   0x106ab1c0
     Data Size:    6413725 Bytes = 6.1 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: unavailable
     Entry Point:  unavailable
     Hash algo:    sha1
     Hash value:   6f3c1c7264cea1a5b391c6f6eefbeb190b3e9cf6
   Verifying Hash Integrity ... sha1+ OK
## Loading fdt from FIT Image at 10000000 ...
   Using 'conf@system-top.dtb' configuration
   Trying 'fdt@system-top.dtb' fdt subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x106a3700
     Data Size:    31225 Bytes = 30.5 KiB
     Architecture: AArch64
     Hash algo:    sha1
     Hash value:   a6944372b09e37df9457fdbb9be433c8088ff6e3
   Verifying Hash Integrity ... sha1+ OK
   Booting using the fdt blob at 0x106a3700
   Uncompressing Kernel Image ... OK
   Loading Ramdisk to 079e2000, end 07fffd9d ... OK
   Loading Device Tree to 00000000079d7000, end 00000000079e19f8 ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.14.0-xilinx-v2018.2 (oe-user@oe-host) (gcc version 7.2.0 (GCC)) #5 SMP Mon Feb 18 12:13:05 UTC 2019
[    0.000000] Boot CPU: AArch64 Processor [410fd034]
[    0.000000] Machine model: xlnx,zynqmp
[    0.000000] earlycon: cdns0 at MMIO 0x00000000ff010000 (options '115200n8')
[    0.000000] bootconsole [cdns0] enabled
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 256 MiB at 0x000000006fc00000
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] percpu: Embedded 21 pages/cpu @ffffffc07fe79000 s46488 r8192 d31336 u86016
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: enabling workaround for ARM erratum 845719
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 516867
[    0.000000] Kernel command line: earlycon clk_ignore_unused
[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
[    0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
[    0.000000] Memory: 1778840K/2096128K available (9980K kernel code, 644K rwdata, 3128K rodata, 512K init, 2168K bss, 55144K reserved, 262144K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     modules : 0xffffff8000000000 - 0xffffff8008000000   (   128 MB)
[    0.000000]     vmalloc : 0xffffff8008000000 - 0xffffffbebfff0000   (   250 GB)
[    0.000000]       .text : 0xffffff8008080000 - 0xffffff8008a40000   (  9984 KB)
[    0.000000]     .rodata : 0xffffff8008a40000 - 0xffffff8008d60000   (  3200 KB)
[    0.000000]       .init : 0xffffff8008d60000 - 0xffffff8008de0000   (   512 KB)
[    0.000000]       .data : 0xffffff8008de0000 - 0xffffff8008e81200   (   645 KB)
[    0.000000]        .bss : 0xffffff8008e81200 - 0xffffff800909f2b0   (  2169 KB)
[    0.000000]     fixed   : 0xffffffbefe7fd000 - 0xffffffbefec00000   (  4108 KB)
[    0.000000]     PCI I/O : 0xffffffbefee00000 - 0xffffffbeffe00000   (    16 MB)
[    0.000000]     vmemmap : 0xffffffbf00000000 - 0xffffffc000000000   (     4 GB maximum)
[    0.000000]               0xffffffbf00000000 - 0xffffffbf01bfc800   (    27 MB actual)
[    0.000000]     memory  : 0xffffffc000000000 - 0xffffffc07ff00000   (  2047 MB)
[    0.000000] Hierarchical RCU implementation.
[    0.000000]  RCU event tracing is enabled.
[    0.000000]  RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GIC: Adjusting CPU interface base to 0x00000000f902f000
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] arch_timer: cp15 timer(s) running at 100.00MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x171024ee1c, max_idle_ns: 440795203561 ns
[    0.000004] sched_clock: 56 bits at 100MHz, resolution 10ns, wraps every 4398046511100ns
[    0.008366] Console: colour dummy device 80x25
[    0.012620] console [tty0] enabled
[    0.015985] bootconsole [cdns0] disabled
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.14.0-xilinx-v2018.2 (oe-user@oe-host) (gcc version 7.2.0 (GCC)) #5 SMP Mon Feb 18 12:13:05 UTC 2019
[    0.000000] Boot CPU: AArch64 Processor [410fd034]
[    0.000000] Machine model: xlnx,zynqmp
[    0.000000] earlycon: cdns0 at MMIO 0x00000000ff010000 (options '115200n8')
[    0.000000] bootconsole [cdns0] enabled
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 256 MiB at 0x000000006fc00000
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] percpu: Embedded 21 pages/cpu @ffffffc07fe79000 s46488 r8192 d31336 u86016
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: enabling workaround for ARM erratum 845719
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 516867
[    0.000000] Kernel command line: earlycon clk_ignore_unused
[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
[    0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
[    0.000000] Memory: 1778840K/2096128K available (9980K kernel code, 644K rwdata, 3128K rodata, 512K init, 2168K bss, 55144K reserved, 262144K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     modules : 0xffffff8000000000 - 0xffffff8008000000   (   128 MB)
[    0.000000]     vmalloc : 0xffffff8008000000 - 0xffffffbebfff0000   (   250 GB)
[    0.000000]       .text : 0xffffff8008080000 - 0xffffff8008a40000   (  9984 KB)
[    0.000000]     .rodata : 0xffffff8008a40000 - 0xffffff8008d60000   (  3200 KB)
[    0.000000]       .init : 0xffffff8008d60000 - 0xffffff8008de0000   (   512 KB)
[    0.000000]       .data : 0xffffff8008de0000 - 0xffffff8008e81200   (   645 KB)
[    0.000000]        .bss : 0xffffff8008e81200 - 0xffffff800909f2b0   (  2169 KB)
[    0.000000]     fixed   : 0xffffffbefe7fd000 - 0xffffffbefec00000   (  4108 KB)
[    0.000000]     PCI I/O : 0xffffffbefee00000 - 0xffffffbeffe00000   (    16 MB)
[    0.000000]     vmemmap : 0xffffffbf00000000 - 0xffffffc000000000   (     4 GB maximum)
[    0.000000]               0xffffffbf00000000 - 0xffffffbf01bfc800   (    27 MB actual)
[    0.000000]     memory  : 0xffffffc000000000 - 0xffffffc07ff00000   (  2047 MB)
[    0.000000] Hierarchical RCU implementation.
[    0.000000]  RCU event tracing is enabled.
[    0.000000]  RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GIC: Adjusting CPU interface base to 0x00000000f902f000
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] arch_timer: cp15 timer(s) running at 100.00MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x171024ee1c, max_idle_ns: 440795203561 ns
[    0.000004] sched_clock: 56 bits at 100MHz, resolution 10ns, wraps every 4398046511100ns
[    0.008366] Console: colour dummy device 80x25
[    0.012620] console [tty0] enabled
[    0.015985] bootconsole [cdns0] disabled
[    0.019900] Calibrating delay loop (skipped), value calculated using timer frequency.. 200.00 BogoMIPS (lpj=400000)
[    0.019914] pid_max: default: 32768 minimum: 301
[    0.020034] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
[    0.020052] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
[    0.020816] ASID allocator initialised with 65536 entries
[    0.020874] Hierarchical SRCU implementation.
[    0.021167] EFI services will not be available.
[    0.021194] zynqmp_plat_init Platform Management API v1.0
[    0.021203] zynqmp_plat_init Trustzone version v1.0
[    0.021321] smp: Bringing up secondary CPUs ...
[    0.021605] Detected VIPT I-cache on CPU1
[    0.021645] CPU1: Booted secondary processor [410fd034]
[    0.021950] Detected VIPT I-cache on CPU2
[    0.021969] CPU2: Booted secondary processor [410fd034]
[    0.022258] Detected VIPT I-cache on CPU3
[    0.022276] CPU3: Booted secondary processor [410fd034]
[    0.022318] smp: Brought up 1 node, 4 CPUs
[    0.022351] SMP: Total of 4 processors activated.
[    0.022360] CPU features: detected feature: 32-bit EL0 Support
[    0.022372] CPU: All CPU(s) started at EL2
[    0.022390] alternatives: patching kernel code
[    0.023372] devtmpfs: initialized
[    0.026698] random: get_random_u32 called from bucket_table_alloc+0x108/0x260 with crng_init=0
[    0.026876] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.026900] futex hash table entries: 1024 (order: 5, 131072 bytes)
[    0.033084] xor: measuring software checksum speed
[    0.071993]    8regs     :  2303.000 MB/sec
[    0.112022]    8regs_prefetch:  2053.000 MB/sec
[    0.152052]    32regs    :  2830.000 MB/sec
[    0.192082]    32regs_prefetch:  2379.000 MB/sec
[    0.192090] xor: using function: 32regs (2830.000 MB/sec)
[    0.192186] pinctrl core: initialized pinctrl subsystem
[    0.192452] random: fast init done
[    0.192909] NET: Registered protocol family 16
[    0.193606] cpuidle: using governor menu
[    0.194006] vdso: 2 pages (1 code @ ffffff8008a46000, 1 data @ ffffff8008de4000)
[    0.194026] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.194670] DMA: preallocated 256 KiB pool for atomic allocations
[    0.225155] reset_zynqmp reset-controller: Xilinx zynqmp reset driver probed
[    0.225667] ARM CCI_400_r1 PMU driver probed
[    0.230165] zynqmp-pinctrl ff180000.pinctrl: zynqmp pinctrl initialized
[    0.238782] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.304374] raid6: int64x1  gen()   402 MB/s
[    0.372301] raid6: int64x1  xor()   446 MB/s
[    0.440423] raid6: int64x2  gen()   688 MB/s
[    0.508430] raid6: int64x2  xor()   603 MB/s
[    0.576452] raid6: int64x4  gen()  1042 MB/s
[    0.644510] raid6: int64x4  xor()   742 MB/s
[    0.712591] raid6: int64x8  gen()   980 MB/s
[    0.780603] raid6: int64x8  xor()   745 MB/s
[    0.848649] raid6: neonx1   gen()   726 MB/s
[    0.916709] raid6: neonx1   xor()   853 MB/s
[    0.984787] raid6: neonx2   gen()  1169 MB/s
[    1.052826] raid6: neonx2   xor()  1207 MB/s
[    1.120889] raid6: neonx4   gen()  1506 MB/s
[    1.188926] raid6: neonx4   xor()  1442 MB/s
[    1.256979] raid6: neonx8   gen()  1652 MB/s
[    1.325041] raid6: neonx8   xor()  1534 MB/s
[    1.325049] raid6: using algorithm neonx8 gen() 1652 MB/s
[    1.325056] raid6: .... xor() 1534 MB/s, rmw enabled
[    1.325065] raid6: using neon recovery algorithm
[    1.326150] SCSI subsystem initialized
[    1.326371] usbcore: registered new interface driver usbfs
[    1.326412] usbcore: registered new interface driver hub
[    1.326454] usbcore: registered new device driver usb
[    1.326528] media: Linux media interface: v0.10
[    1.326558] Linux video capture interface: v2.00
[    1.326607] pps_core: LinuxPPS API ver. 1 registered
[    1.326616] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    1.326640] PTP clock support registered
[    1.326678] EDAC MC: Ver: 3.0.0
[    1.327071] zynqmp-ipi ff9905c0.mailbox: Probed ZynqMP IPI Mailbox driver.
[    1.327233] FPGA manager framework
[    1.327355] fpga-region fpga-full: FPGA Region probed
[    1.327460] Advanced Linux Sound Architecture Driver Initialized.
[    1.327764] Bluetooth: Core ver 2.22
[    1.327799] NET: Registered protocol family 31
[    1.327807] Bluetooth: HCI device and connection manager initialized
[    1.327821] Bluetooth: HCI socket layer initialized
[    1.327831] Bluetooth: L2CAP socket layer initialized
[    1.327852] Bluetooth: SCO socket layer initialized
[    1.328414] clocksource: Switched to clocksource arch_sys_counter
[    1.328507] VFS: Disk quotas dquot_6.6.0
[    1.328564] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    1.332955] NET: Registered protocol family 2
[    1.333324] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
[    1.333443] TCP bind hash table entries: 16384 (order: 6, 262144 bytes)
[    1.333783] TCP: Hash tables configured (established 16384 bind 16384)
[    1.333890] UDP hash table entries: 1024 (order: 3, 32768 bytes)
[    1.333934] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
[    1.334079] NET: Registered protocol family 1
[    1.334300] RPC: Registered named UNIX socket transport module.
[    1.334310] RPC: Registered udp transport module.
[    1.334318] RPC: Registered tcp transport module.
[    1.334325] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    1.334438] Trying to unpack rootfs image as initramfs...
[    1.593990] Freeing initrd memory: 6260K
[    1.594473] hw perfevents: no interrupt-affinity property for /pmu, guessing.
[    1.594653] hw perfevents: enabled with armv8_pmuv3 PMU driver, 7 counters available
[    1.595523] audit: initializing netlink subsys (disabled)
[    1.595646] audit: type=2000 audit(1.579:1): state=initialized audit_enabled=0 res=1
[    1.596018] workingset: timestamp_bits=62 max_order=19 bucket_order=0
[    1.596843] NFS: Registering the id_resolver key type
[    1.596871] Key type id_resolver registered
[    1.596879] Key type id_legacy registered
[    1.596893] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    1.596918] jffs2: version 2.2. (NAND) (SUMMARY)  © 2001-2006 Red Hat, Inc.
[    1.624254] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 246)
[    1.624284] io scheduler noop registered
[    1.624293] io scheduler deadline registered
[    1.624315] io scheduler cfq registered (default)
[    1.624324] io scheduler mq-deadline registered
[    1.624333] io scheduler kyber registered
[    1.625770] xilinx-dpdma fd4c0000.dma: Xilinx DPDMA engine is probed
[    1.626207] xilinx-zynqmp-dma fd500000.dma: ZynqMP DMA driver Probe success
[    1.626359] xilinx-zynqmp-dma fd510000.dma: ZynqMP DMA driver Probe success
[    1.626510] xilinx-zynqmp-dma fd520000.dma: ZynqMP DMA driver Probe success
[    1.626667] xilinx-zynqmp-dma fd530000.dma: ZynqMP DMA driver Probe success
[    1.626821] xilinx-zynqmp-dma fd540000.dma: ZynqMP DMA driver Probe success
[    1.626977] xilinx-zynqmp-dma fd550000.dma: ZynqMP DMA driver Probe success
[    1.627149] xilinx-zynqmp-dma fd560000.dma: ZynqMP DMA driver Probe success
[    1.627306] xilinx-zynqmp-dma fd570000.dma: ZynqMP DMA driver Probe success
[    1.627529] xilinx-zynqmp-dma ffa80000.dma: ZynqMP DMA driver Probe success
[    1.627682] xilinx-zynqmp-dma ffa90000.dma: ZynqMP DMA driver Probe success
[    1.627829] xilinx-zynqmp-dma ffaa0000.dma: ZynqMP DMA driver Probe success
[    1.627983] xilinx-zynqmp-dma ffab0000.dma: ZynqMP DMA driver Probe success
[    1.628134] xilinx-zynqmp-dma ffac0000.dma: ZynqMP DMA driver Probe success
[    1.628286] xilinx-zynqmp-dma ffad0000.dma: ZynqMP DMA driver Probe success
[    1.628464] xilinx-zynqmp-dma ffae0000.dma: ZynqMP DMA driver Probe success
[    1.628620] xilinx-zynqmp-dma ffaf0000.dma: ZynqMP DMA driver Probe success
[    1.655925] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    1.659223] cacheinfo: Unable to detect cache hierarchy for CPU 0
[    1.663995] brd: module loaded
[    1.668278] loop: module loaded
[    1.669240] mtdoops: mtd device (mtddev=name/number) must be supplied
[    1.671407] libphy: Fixed MDIO Bus: probed
[    1.672554] tun: Universal TUN/TAP device driver, 1.6
[    1.672897] CAN device driver interface
[    1.673756] usbcore: registered new interface driver asix
[    1.673829] usbcore: registered new interface driver ax88179_178a
[    1.673862] usbcore: registered new interface driver cdc_ether
[    1.673895] usbcore: registered new interface driver net1080
[    1.673927] usbcore: registered new interface driver cdc_subset
[    1.673957] usbcore: registered new interface driver zaurus
[    1.674001] usbcore: registered new interface driver cdc_ncm
[    1.674389] xilinx-axipmon ffa00000.perf-monitor: Probed Xilinx APM
[    1.674863] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    1.674873] ehci-pci: EHCI PCI platform driver
[    1.675117] usbcore: registered new interface driver uas
[    1.675159] usbcore: registered new interface driver usb-storage
[    1.676094] rtc_zynqmp ffa60000.rtc: rtc core: registered ffa60000.rtc as rtc0
[    1.676154] i2c /dev entries driver
[    1.676909] cdns-i2c ff030000.i2c: 400 kHz mmio ff030000 irq 31
[    1.677181] IR NEC protocol handler initialized
[    1.677190] IR RC5(x/sz) protocol handler initialized
[    1.677198] IR RC6 protocol handler initialized
[    1.677206] IR JVC protocol handler initialized
[    1.677213] IR Sony protocol handler initialized
[    1.677220] IR SANYO protocol handler initialized
[    1.677228] IR Sharp protocol handler initialized
[    1.677235] IR MCE Keyboard/mouse protocol handler initialized
[    1.677243] IR XMP protocol handler initialized
[    1.678213] usbcore: registered new interface driver uvcvideo
[    1.678222] USB Video Class driver (1.1.1)
[    1.679547] cdns-wdt fd4d0000.watchdog: Xilinx Watchdog Timer at ffffff800913d000 with timeout 10s
[    1.679843] Bluetooth: HCI UART driver ver 2.3
[    1.679854] Bluetooth: HCI UART protocol H4 registered
[    1.679863] Bluetooth: HCI UART protocol BCSP registered
[    1.679891] Bluetooth: HCI UART protocol LL registered
[    1.679900] Bluetooth: HCI UART protocol ATH3K registered
[    1.679909] Bluetooth: HCI UART protocol Three-wire (H5) registered
[    1.679953] Bluetooth: HCI UART protocol Intel registered
[    1.679961] Bluetooth: HCI UART protocol QCA registered
[    1.680002] usbcore: registered new interface driver bcm203x
[    1.680038] usbcore: registered new interface driver bpa10x
[    1.680072] usbcore: registered new interface driver bfusb
[    1.680106] usbcore: registered new interface driver btusb
[    1.680115] Bluetooth: Generic Bluetooth SDIO driver ver 0.1
[    1.680169] usbcore: registered new interface driver ath3k
[    1.680299] EDAC MC: ECC not enabled
[    1.680512] EDAC DEVICE0: Giving out device to module zynqmp-ocm-edac controller zynqmp_ocm: DEV ff960000.memory-controller (INTERRUPT)
[    1.681546] sdhci: Secure Digital Host Controller Interface driver
[    1.681556] sdhci: Copyright(c) Pierre Ossman
[    1.681564] sdhci-pltfm: SDHCI platform and OF driver helper
[    1.724428] mmc0: SDHCI controller on ff160000.sdhci [ff160000.sdhci] using ADMA 64-bit
[    1.776413] mmc1: SDHCI controller on ff170000.sdhci [ff170000.sdhci] using ADMA 64-bit
[    1.783933] ledtrig-cpu: registered to indicate activity on CPUs
[    1.784114] usbcore: registered new interface driver usbhid
[    1.784122] usbhid: USB HID core driver
[    1.787429] fpga_manager fpga0: Xilinx ZynqMP FPGA Manager registered
[    1.788347] pktgen: Packet Generator for packet performance testing. Version: 2.75
[    1.790615] Netfilter messages via NETLINK v0.30.
[    1.790758] ip_tables: (C) 2000-2006 Netfilter Core Team
[    1.790929] Initializing XFRM netlink socket
[    1.791012] NET: Registered protocol family 10
[    1.791444] Segment Routing with IPv6
[    1.791495] ip6_tables: (C) 2000-2006 Netfilter Core Team
[    1.791684] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    1.792050] NET: Registered protocol family 17
[    1.792068] NET: Registered protocol family 15
[    1.792092] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[    1.792107] Ebtables v2.0 registered
[    1.792531] can: controller area network core (rev 20170425 abi 9)
[    1.792571] NET: Registered protocol family 29
[    1.792581] can: raw protocol (rev 20170425)
[    1.792589] can: broadcast manager protocol (rev 20170425 t)
[    1.792602] can: netlink gateway (rev 20170425) max_hops=1
[    1.792727] Bluetooth: RFCOMM TTY layer initialized
[    1.792740] Bluetooth: RFCOMM socket layer initialized
[    1.792760] Bluetooth: RFCOMM ver 1.11
[    1.792772] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    1.792779] Bluetooth: BNEP filters: protocol multicast
[    1.792791] Bluetooth: BNEP socket layer initialized
[    1.792800] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[    1.792814] Bluetooth: HIDP socket layer initialized
[    1.792975] 9pnet: Installing 9P2000 support
[    1.793001] Key type dns_resolver registered
[    1.793513] registered taskstats version 1
[    1.793913] Btrfs loaded, crc32c=crc32c-generic
[    1.800696] ff000000.serial: ttyPS1 at MMIO 0xff000000 (irq = 40, base_baud = 6249999) is a xuartps
[    1.801591] ff010000.serial: ttyPS0 at MMIO 0xff010000 (irq = 41, base_baud = 6249999) is a xuartps
[    1.868523] mmc0: error -110 whilst initialising SD card
[    3.337586] console [ttyPS0] enabled
[    3.342551] xilinx-psgtr fd400000.zynqmp_phy: Lane:1 type:8 protocol:4 pll_locked:yes
[    3.350727] PLL: shutdown
[    3.353395] PLL: shutdown
[    3.356361] PLL: enable
[    3.358861] PLL: shutdown
[    3.362304] PLL: enable
[    3.364779] xilinx-dp-snd-codec fd4a0000.zynqmp-display:zynqmp_dp_snd_codec0: Xilinx DisplayPort Sound Codec probed
[    3.375371] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm0: Xilinx DisplayPort Sound PCM probed
[    3.383332] xilinx-dp-snd-pcm zynqmp_dp_snd_pcm1: Xilinx DisplayPort Sound PCM probed
[    3.391671] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: xilinx-dp-snd-codec-dai <-> xilinx-dp-snd-codec-dai mapping ok
[    3.404056] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: xilinx-dp-snd-codec-dai <-> xilinx-dp-snd-codec-dai mapping ok
[    3.416734] xilinx-dp-snd-card fd4a0000.zynqmp-display:zynqmp_dp_snd_card: Xilinx DisplayPort Sound Card probed
[    3.426839] OF: graph: no port node found in /amba/zynqmp-display@fd4a0000
[    3.433741] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    3.440272] [drm] No driver support for vblank timestamp query.
[    3.446247] xlnx-drm xlnx-drm.0: bound fd4a0000.zynqmp-display (ops 0xffffff8008af7228)
[    3.475433] PLL: enable
[    3.596080] Console: switching to colour frame buffer device 128x48
[    3.621401] zynqmp-display fd4a0000.zynqmp-display: fb0:  frame buffer device
[    3.628740] [drm] Initialized xlnx 1.0.0 20130509 for fd4a0000.zynqmp-display on minor 0
[    3.636846] zynqmp-display fd4a0000.zynqmp-display: ZynqMP DisplayPort Subsystem driver probed
[    3.645796] dwc3-of-simple ff9d0000.usb0: dwc3_simple_set_phydata: Can't find usb3-phy
[    3.654849] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[    3.660325] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1
[    3.668220] xhci-hcd xhci-hcd.0.auto: hcc params 0x0238f625 hci version 0x100 quirks 0x22010010
[    3.676958] xhci-hcd xhci-hcd.0.auto: irq 46, io mem 0xfe200000
[    3.682987] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[    3.689759] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.696961] usb usb1: Product: xHCI Host Controller
[    3.701802] usb usb1: Manufacturer: Linux 4.14.0-xilinx-v2018.2 xhci-hcd
[    3.708500] usb usb1: SerialNumber: xhci-hcd.0.auto
[    3.713652] hub 1-0:1.0: USB hub found
[    3.717378] hub 1-0:1.0: 1 port detected
[    3.721459] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[    3.726927] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2
[    3.734623] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[    3.742780] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003
[    3.749550] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.756756] usb usb2: Product: xHCI Host Controller
[    3.761596] usb usb2: Manufacturer: Linux 4.14.0-xilinx-v2018.2 xhci-hcd
[    3.770526] usb usb2: SerialNumber: xhci-hcd.0.auto
[    3.777796] hub 2-0:1.0: USB hub found
[    3.783731] hub 2-0:1.0: 1 port detected
[    3.790031] dwc3 fe200000.dwc3: couldn't register cable notifier
[    3.798262] dwc3 fe200000.dwc3: failed to initialize dual-role
[    3.806361] platform fe200000.dwc3: runtime PM trying to suspend device but active child
[    3.816760] dwc3: probe of fe200000.dwc3 failed with error -22
[    3.825310] dwc3-of-simple ff9e0000.usb1: dwc3_simple_set_phydata: Can't find usb3-phy
[    3.836885] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[    3.844667] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 3
[    3.854984] xhci-hcd xhci-hcd.1.auto: hcc params 0x0238f625 hci version 0x100 quirks 0x22010010
[    3.866001] xhci-hcd xhci-hcd.1.auto: irq 49, io mem 0xfe300000
[    3.874267] usb usb3: New USB device found, idVendor=1d6b, idProduct=0002
[    3.883295] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.892734] usb usb3: Product: xHCI Host Controller
[    3.899800] usb usb3: Manufacturer: Linux 4.14.0-xilinx-v2018.2 xhci-hcd
[    3.908685] usb usb3: SerialNumber: xhci-hcd.1.auto
[    3.915983] hub 3-0:1.0: USB hub found
[    3.921863] hub 3-0:1.0: 1 port detected
[    3.928036] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[    3.935609] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 4
[    3.945405] usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
[    3.955680] usb usb4: New USB device found, idVendor=1d6b, idProduct=0003
[    3.964547] usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.973866] usb usb4: Product: xHCI Host Controller
[    3.980824] usb usb4: Manufacturer: Linux 4.14.0-xilinx-v2018.2 xhci-hcd
[    3.989600] usb usb4: SerialNumber: xhci-hcd.1.auto
[    3.996758] hub 4-0:1.0: USB hub found
[    4.002536] hub 4-0:1.0: 1 port detected
[    4.008615] dwc3 fe300000.dwc3: couldn't register cable notifier
[    4.016592] dwc3 fe300000.dwc3: failed to initialize dual-role
[    4.024416] platform fe300000.dwc3: runtime PM trying to suspend device but active child
[    4.034494] dwc3: probe of fe300000.dwc3 failed with error -22
[    4.043378] rtc_zynqmp ffa60000.rtc: setting system clock to 1970-01-01 00:00:08 UTC (8)
[    4.053601] clk: Not disabling unused clocks
[    4.059922] ALSA device list:
[    4.064865]   #0: DisplayPort monitor
[    4.071142] Freeing unused kernel memory: 512K
INIT: version 2.88 booting
Starting udev
[    4.193831] udevd[1702]: starting version 3.2.2
[    4.205490] udevd[1703]: starting eudev-3.2.2
Mon Feb 18 12:46:35 UTC 2019
Starting internet superserver: inetd.
Configuring packages on first boot....
 (This may take several minutes. Please do not power off the machine.)
Running postinst /etc/rpm-postinsts/100-sysvinit-inittab...
update-rc.d: /etc/init.d/run-postinsts exists during rc.d purge (continuing)
INIT: Entering runlevel: 5
Configuring network interfaces... Cannot find device "eth0"
Starting Dropbear SSH server: Generating key, this may take a while...
Public key portion is:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCUGFzO00efnXsncyQHUufMsAetLDsuUTWcifAJBzhnXPHcMZayHVUMxn93QVDtzEO+13NHy0mC5LY3uGb0e3PaZCF66aBR1yr7nHHeyxHbUMpm5TGBgbNhSP5kh4HYhCvKae3XZztuJlCxiYt76PkEjJ18bm2QDzePrN09nt5UooAhToGJ4I3aHdTPg5xH5gpQc6869OfaeUkJMnkoAvnYt5EOTaL6WV0fBH/pCUy2+Cs5ytqrBsJDmT4FTPnRrPY+ksm/JZ++5+O+x6u++g1PqqfM4yIZVglNY+hDdl0ArE7b7H6MjUaOwsnIwG4VlUX909APccrrfFWQ9xMzqDs/ root@cam_test_ov5642_182
Fingerprint: md5 6d:2f:72:10:6e:db:cc:32:d4:e4:fa:a4:b0:20:dd:f0
dropbear.
Starting syslogd/klogd: done
Starting tcf-agent: OK

PetaLinux 2018.2 cam_test_ov5642_182 /dev/ttyPS0

cam_test_ov5642_182 login: 

  1. 2019年02月19日 05:22 |
  2. PetaLinux
  3. | トラックバック:0
  4. | コメント:0

Docker 上のUbuntu 16.04 のPetaLinux 2018.2 でビルドしてみた2

Docker 上のUbuntu 16.04 のPetaLinux 2018.2 でビルドしてみた1”の続き。

前回は、”Ultra96-PYNQをビルドしてみた”のDocker Container にはPetaLinux 2018.2 がインストールしてあるので、試しにビルドを行うということで、petalinux-build までを行った。今回は残りのビルドをやっていこう。

まずは、前回までの cam_test_ov5642_182/images/linux ディレクトリの内容を示す。
PetaLinux_12_190216.png

uImage をビルドしよう。
petalinux-package --image -c kernel --format uImage
を実行した。エラーになった。やはり、ロケールのエラーだった。
PetaLinux_13_190216.png

LANG=en_US.UTF-8 petalinux-package --image -c kernel --format uImage
だと成功した。
PetaLinux_14_190216.png

cam_test_ov5642_182/images/linux ディレクトリの内容を示す。uImage がビルドできている。
PetaLinux_15_190216.png

ログを示す。

masaaki@d601aa5658aa:~/PetaLProj/cam_test_ov5642_182$ LANG=en_US.UTF-8 petalinux-package --image -c kernel --format uImage
SDK environment now set up; additionally you may now run devtool to perform development tasks.
Run devtool --help for further details.

### Shell environment set up for builds. ###

You can now run 'bitbake <target>'

Common targets are:
    core-image-minimal
    core-image-sato
    meta-toolchain
    meta-ide-support

You can also run generated qemu images with a command like 'runqemu qemux86'
NOTE: Starting bitbake server...
INFO: Adding user layer: /home/masaaki/PetaLProj/cam_test_ov5642_182/project-spec/meta-user
NOTE: Starting bitbake server...
INFO: generating uImage
INFO: bitbake -R /home/masaaki/PetaLProj/cam_test_ov5642_182/build/conf/kerneltype.conf virtual/kernel 
Parsing recipes: 100% |##########################################| Time: 0:01:25
Parsing of 2552 .bb files complete (0 cached, 2552 parsed). 3441 targets, 139 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
Initialising tasks: 100% |#######################################| Time: 0:00:06
Checking sstate mirror object availability: 100% |###############| Time: 0:00:09
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: fsbl: compiling from external source tree /home/masaaki/pkg/petalinux/tools/hsm/data/embeddedsw
NOTE: pmu-firmware: compiling from external source tree /home/masaaki/pkg/petalinux/tools/hsm/data/embeddedsw
WARNING: petalinux-user-image-1.0-r0 do_rootfs: [log_check] petalinux-user-image: found 1 warning message in the logfile:
[log_check] warning: %post(sysvinit-inittab-2.88dsf-r10.plnx_zynqmp) scriptlet failed, exit status 1

NOTE: Tasks Summary: Attempted 2383 tasks of which 2310 didn't need to be rerun and all succeeded.

Summary: There was 1 WARNING message shown.
masaaki@d601aa5658aa:~/PetaLProj/cam_test_ov5642_182



BOOT.bin をビルドしよう。
LANG=en_US.UTF-8 petalinux-package --boot --fsbl /home/masaaki/PetaLProj/cam_test_ov5642_182/components/plnx_workspace/fsbl/fsbl/Release/fsbl.elf --fpga /home/masaaki/PetaLProj/cam_test_ov5642_182/components/plnx_workspace/fsbl/fsbl_hwproj/cam_test_wrapper.bit --pmufw /home/masaaki/PetaLProj/cam_test_ov5642_182/images/linux/pmufw.elf --u-boot
を実行した。
PetaLinux_16_190216.png

BOOT.bin がビルドできている。
PetaLinux_17_190216.png

次にはビルドできたイメージをQEMU で起動してみよう。
まずは、prebuilt を作成する。
LANG=en_US.UTF-8 petalinux-package --prebuilt --fpga /home/masaaki/PetaLProj/cam_test_ov5642_182/components/plnx_workspace/fsbl/fsbl_hwproj/cam_test_wrapper.bit
PetaLinux_19_190217.png

pre-built ディレクトリが生成された。

システムのブートを行う。
petalinux-boot --qemu --prebuilt 3
PetaLinux_20_190217.png
PetaLinux_21_190217.png

ここで、キーボードの入力に反応しなくなった。
仕方がないので、CTRL-P, CTRL-Q でホストに制御を戻して、
docker ps
で docker のコンテナID を見てから
docker stop 722533dbc823
でコンテナを停止した。
もう一度、
docker ps
でみるとコンテナは消えていた。
PetaLinux_22_190217.png

ログを示す。

masaaki@722533dbc823:~/PetaLProj/cam_test_ov5642_182$ petalinux-boot --qemu --prebuilt 3
WARNING: Failed to load PMUFW, doesn't exist in prebuilts.See help to load custom PMUFW
petalinux-boot: line 1406: xxd: command not found
petalinux-boot: line 1417: xxd: command not found
petalinux-boot: line 1406: xxd: command not found
petalinux-boot: line 1417: xxd: command not found
petalinux-boot: line 1406: xxd: command not found
petalinux-boot: line 1417: xxd: command not found
INFO: No DTB has been specified, use the default one "/home/masaaki/PetaLProj/cam_test_ov5642_182/pre-built/linux/images/system.dtb".
INFO: No DTB has been specified, use the default one "/home/masaaki/PetaLProj/cam_test_ov5642_182/pre-built/linux/images/system.dtb".
INFO: Set QEMU tftp to /home/masaaki/PetaLProj/cam_test_ov5642_182/images/linux 
petalinux-qemu-boot: line 88: xxd: command not found
INFO: TCP PORT is free 
INFO: Starting aarch64 QEMU
INFO:  qemu-system-aarch64 -M arm-generic-fdt   -serial mon:stdio -serial /dev/null -display none -device loader,file=/tmp/tmp.ljJNJfCqew,cpu-num=0 -gdb tcp::9000 -dtb /home/masaaki/PetaLProj/cam_test_ov5642_182/pre-built/linux/images/system.dtb     -hw-dtb /home/masaaki/PetaLProj/cam_test_ov5642_182/images/linux/zynqmp-qemu-multiarch-arm.dtb -machine-path /tmp/tmp.bdgrcojgBS -global xlnx,zynqmp-boot.cpu-num=0 -global xlnx,zynqmp-boot.use-pmufw=true  -m 4G
qemu-system-aarch64: Failed to connect socket /tmp/tmp.bdgrcojgBS/qemu-rport-_pmu@0: No such file or directory
qemu-system-aarch64: info: QEMU waiting for connection on: disconnected:unix:/tmp/tmp.bdgrcojgBS/qemu-rport-_pmu@0,server

  1. 2019年02月18日 04:30 |
  2. PetaLinux
  3. | トラックバック:0
  4. | コメント:0

ファースト・マン(映画)を見てきました

昨日に続いて、ファースト・マン(映画)を見てきました。
やはり宇宙開発は失敗の歴史なんですよね。でも有人宇宙船で失敗していたのでは、人命が損なわれてしまいます。今ではこの開発方法は無理でしょうね。
昔のコンピュータで月着陸船をコントロールするのは無理ですよね。良くやってましたよね。今だったらAI使ってますよね。
  1. 2019年02月17日 16:24 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Docker 上のUbuntu 16.04 のPetaLinux 2018.2 でビルドしてみた1

Ultra96-PYNQをビルドしてみた”のDocker Container にはPetaLinux 2018.2 がインストールしてあるので、試しにビルドを行う。

まずは、Vivado 2018.2 のプロジェクトとそのプロジェクトの .sdk ディレクトリが必要だ。
秋月電子カメラモジュールOV5642を使う15(完成)”のOV5642 でBMP ファイルを取得できる Vivado 2018.2 のプロジェクトを対象とする。そのVivado 2018.2 プロジェクトは”秋月電子カメラモジュールOV5642を使う8(OV5642用Vivadoプロジェクト)”に書いてある。

参照するマニュアルは、”PetaLinux Tools Documentation Reference Guide UG1144 (v2018.2) June 6, 2018”。

PetaLinux Tools Documentation Reference Guide UG1144 (v2018.2) June 6, 2018”の 16 ページの”Table 2-4: Design Flow Overview”を引用する。
PetaLinux_18_190217.png

さてそれでは、ビルドしていこう。
最初にPetaLinux 2018.2 のプロジェクトを作成する。プロジェクト名は cam_test_ov5642_182 とした。
petalinux-create --type project --template zynqMP --name cam_test_ov5642_182
PetaLinux_1_190216.png

PetaLinux プロジェクトを生成したら、project-spec ディレクトリが生成された。

次に、 cam_test_182.sdk ディレクトリをPetaLinux プロジェクトにホストからコピーする必要がある。
docker ps
docker cp /home/masaaki/HDL/Ultra96/cam_test_ov5642_182/cam_test_182.sdk/cam_test_wrapper.hdf d601aa5658aa:/home/masaaki/PetaLProj/cam_test_ov5642_182

PetaLinux_2_190216.png

Docker 側に cam_test_182.sdk ディレクトリがコピーされた。
PetaLinux_3_190216.png

次にPetaLinux プロジェクトの初期化を行う。その際に、 cam_test_182.sdk ディレクトリを指定する。
petalinux-config --get-hw-description=/home/masaaki/PetaLProj/cam_test_ov5642_182/cam_test_182.sdk/
PetaLinux_4_190216.png

menu-config 画面が立ち上がった。
PetaLinux_5_190216.png

<Save>  を選択してリターン・キーを押した。

cam_test_ov5642_182/project-spec/configs/config にセーブする。
<ok>  を選択して、リターン・キーを押した。
PetaLinux_6_190216.png

もう一度メインの画面に戻って、<Exit>  を選択して、リターン・キーを押した。
PetaLinux_8_190216.png

Exit 画面が表示された。リターン・キーを押した。
PetaLinux_7_190216.png

petalinux-config が終了した。build, component ディレクトリが生成された。
PetaLinux_9_190216.png

petalinux-config のログを示す。

masaaki@d601aa5658aa:~/PetaLProj/cam_test_ov5642_182$ petalinux-config --get-hw-description=/home/masaaki/PetaLProj/cam_test_ov5642_182/cam_test_182.sdk/
INFO: Getting hardware description...
INFO: Rename cam_test_wrapper.hdf to system.hdf
[INFO] generating Kconfig for project
                                                                                
[INFO] menuconfig project
/home/masaaki/PetaLProj/cam_test_ov5642_182/build/misc/config/Kconfig.syshw:30:warning: defaults for choice values not supported
/home/masaaki/PetaLProj/cam_test_ov5642_182/build/misc/config/Kconfig:597:warning: config symbol defined without type


*** End of the configuration.
*** Execute 'make' to start the build or try 'make help'.

[INFO] sourcing bitbake
[INFO] generating plnxtool conf
[INFO] generating meta-plnx-generated layer
[INFO] generating machine configuration
[INFO] generating bbappends for project . This may take time ! 
[INFO] generating u-boot configuration files
                                                                                
[INFO] generating kernel configuration files
[INFO] generating kconfig for Rootfs
[INFO] oldconfig rootfs
[INFO] generating petalinux-user-image.bb
masaaki@d601aa5658aa:~/PetaLProj/cam_test_ov5642_182$


petalinux-build を行った。
petalinux-build
エラーが出てしまった。locale のエラーだった。
PetaLinux_10_190216.png

電気回路/zynq/Petalinux のビルドの言語設定が重要 LANG=C”を参照すると petalinux-build の前にLANG=C を付加するそうだ。
今回のロケールはen_US.UTF-8 なので、LANG=en_US.UTF-8 を前につけてみよう。
LANG=en_US.UTF-8 petalinux-build
これでビルドが成功した。
PetaLinux_11_190216.png

ログを示す。

masaaki@d601aa5658aa:~/PetaLProj/cam_test_ov5642_182$ LANG=C petalinux-build
[INFO] building project
[INFO] sourcing bitbake
INFO: bitbake petalinux-user-image
Please use a locale setting which supports UTF-8 (such as LANG=en_US.UTF-8).
Python can't change the filesystem locale after loading so we need a UTF-8 when Python starts or things won't work.
ERROR: Failed to build project
masaaki@d601aa5658aa:~/PetaLProj/cam_test_ov5642_182$ LANG=en_US.UTF-8 petalinux-build
[INFO] building project
[INFO] sourcing bitbake
INFO: bitbake petalinux-user-image
Loading cache: 100% |############################################| Time: 0:00:00
Loaded 3439 entries from dependency cache.
Parsing recipes: 100% |##########################################| Time: 0:00:04
Parsing of 2552 .bb files complete (2509 cached, 43 parsed). 3441 targets, 139 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
Initialising tasks: 100% |#######################################| Time: 0:00:08
Checking sstate mirror object availability: 100% |###############| Time: 0:00:14
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: fsbl: compiling from external source tree /home/masaaki/pkg/petalinux/tools/hsm/data/embeddedsw
NOTE: pmu-firmware: compiling from external source tree /home/masaaki/pkg/petalinux/tools/hsm/data/embeddedsw
WARNING: petalinux-user-image-1.0-r0 do_rootfs: [log_check] petalinux-user-image: found 1 warning message in the logfile:
[log_check] warning: %post(sysvinit-inittab-2.88dsf-r10.plnx_zynqmp) scriptlet failed, exit status 1

NOTE: Tasks Summary: Attempted 3115 tasks of which 2259 didn't need to be rerun and all succeeded.

Summary: There was 1 WARNING message shown.
INFO: Copying Images from deploy to images
INFO: Creating images/linux directory
NOTE: Failed to copy built images to tftp dir:  /tftpboot
[INFO] successfully built project
masaaki@d601aa5658aa:~/PetaLProj/cam_test_ov5642_182$ 

  1. 2019年02月17日 05:12 |
  2. PetaLinux
  3. | トラックバック:0
  4. | コメント:0

「7つの会議」と「フォルトゥナの瞳」(映画)を見たよ

インフルエンザになる前の先週土曜日に「7つの会議」を見ました。喜劇なのかな?と思いました。それなりに面白かったです。

インフルエンザが直ったので、今日は「フォルトナの瞳」を見てきました。こっちのほうが良かったですね。しかし、有村架純もだとは思わなかったです。。。
  1. 2019年02月16日 18:26 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Ultra96 のPYNQ リソースやhackstar.io のリソース

Ultra96-PYNQをビルドしてみた”ではUltra96-PYNQ のビルドが失敗してしまったが、Ultra96-PYNQ のイメージはあるのでやってみることができる。

Ultra96 and PYNQ Framework
いろいろなUltra96 のリソースがある。SD Card Images もあるのでUltra96 でPYNQ も試せる。

PYNQ: PYTHON PRODUCTIVITY ON ZYNQ
PYNQ のサイト
Development Boards
Ultra96 の情報もある。

hackstar.io のUltra96 ボードのリソース
hackstar.io のUltra96 ボードのいろいろなリソースがある。
中でも”Stereo Vision and LiDAR Powered Donkey Car”をやってみたい。
  1. 2019年02月16日 07:45 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Ultra96-PYNQをビルドしてみた

Docker でPetaLinux 2018.2 をインストールする”でDocker でUbuntu 16.04 にVivado 2018.2 をインストールしてPetaLinux 2018.2 をインストールすることができた。これでいよいよ目的だった。Avnet 社のAvnet/Ultra96-PYNQ をインストールすることができる。

最初に ./boot.sh でvivado182ub16 イメージを起動する。
環境を整備する。
source /home/masaaki/Xilinx/Vivado/2018.2/settings64.sh
source /home/masaaki/pkg/petalinux/settings.sh

docker_ce_41_190216.png
docker_ce_42_190216.png

PYNQ ディレクトリを作成し、PYNQ を git clone する。
mkdir PYNQ
cd PYNQ
git clone https://github.com/Xilinx/PYNQ.git PYNQ

docker_ce_43_190216.png

cd PYNQ
git checkout origin/image_v2.3

docker_ce_44_190216.png

cd sdbuild
make checkenv

docker_ce_45_190216.png
docker_ce_46_190216.png

エラー発生。
よく分からないので、PYNQ Image Building の scripts/setup_host.sh を走らせてみよう。
まずは、Ultra96 ボードのBSP をホストからコピーする。
docker ps
docker cp xilinx-ultra96-reva-v2018.2-final.bsp d601aa5658aa:/home/masaaki/PYNQ

docker_ce_47_190216.png

Docker 側にコピーされた。
docker_ce_48_190216.png

./scripts/setup_host.sh
を走らせる。
docker_ce_49_190216.png
docker_ce_50_190216.png

このビルドは成功した。

もう一度
make checkenv
docker_ce_51_190216.png

やはりエラーだった。。。
  1. 2019年02月16日 07:35 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Docker でPetaLinux 2018.2 をインストールする

Docker のUbuntu 16.04 イメージにVivado 2018.2 をインストールする2”のDocker イメージの vivado182ub16 にPetaLinux をインストールすることにした。

Xilinx 社のサポート -> ダウンロード -> エンベデッド開発の 2018.2 のWeb ページからPetaLinux 2018.2 インストーラー
PetaLinux 2018.2 インストーラー (TAR/GZIP - 6.15GB)をダウンロードした。ファイル名は、petalinux-v2018.2-final-installer.run だった。
./boot.sh を起動して、vivado182ub16c コンテナを起動した。
最初に、PetaLinux インストーラーのpetalinux-v2018.2-final-installer.run をvivado182ub16c コンテナにコピーした。
ホストの別の端末で、docker ps を実行して、コンテナのID を確認し、
docker cp petalinux-v2018.2-final-installer.run 6f49669c6591:/home/masaaki
を実行して、コンテナにコピーした。
docker_ce_39_190215.png

Docker のコンテナでは、PetaLinux インストーラーに実行パミッションを付加した。
chmod +x petalinux-v2018.2-final-installer.run
/home/masaaki の下にpkg/petalinux ディレクトリを作成した。
mkdir pkg
cd pkg
mkdir petalinux
cd

PetaLinux インストーラーを起動した。
./petalinux-v2018.2-final-installer.run /home/masaaki/pkg/petalinux/
インストーラーが動かなかった。そういえば必要なパッケージを全くインストールしていない。
PetaLinux Tools Documentation Reference Guide UG1144 (v2018.2) June 6, 2018 の”Setting up your Environment”の”Installation Requirements”のTable 2-1: Packages and Linux Workstation Environments 9 ページから 11 ページの表を見て、足りないパッケージを apt でインストールした。(後で、@osamu_takeuchi さんに教えていただいたのだが、”電気回路/zynq/Petalinux のビルドのインストール”のapt-get をコピペすれば良さそうだ。武内先生ありがとうございました。)

それで、もう一度PetaLinux インストーラーを起動した。
./petalinux-v2018.2-final-installer.run /home/masaaki/pkg/petalinux/
docker_ce_31_190214.png
docker_ce_32_190214.png

今度は libtool が無いと言われているのだが、libtool は apt でインストールしてある。
検索していたら、”PetaLinux doesn't see libtool, so it won't run”がヒット。それには、libtool-bin をインストールしろと書いてある。
sudo apt install libtool-bin

早速インストールして、ついでに”電気回路/zynq/Petalinux のビルドのインストール”のapt-get をすべて実行した)

PetaLinux インストーラーを起動した。
./petalinux-v2018.2-final-installer.run /home/masaaki/pkg/petalinux/
だいぶ進んだのだが、今度はlocale のエラーのようだ。
docker_ce_33_190214.png

次に検索したのが、”Linuxのlocaleがおかしくなっていた”だ。
export LC_ALL=C
export LANG=C
sudo dpkg-reconfigure locales

で locales がインストールしていないと言われた。
docker_ce_34_190214.png

sudo apt locals
sudo dpkg-reconfigure locales

で、en_US.UTF-8 に設定した。これはJP ではPetaLinux がインストールできなかったためだ。
docker_ce_35_190214.png

PetaLinux インストーラーを起動した。
./petalinux-v2018.2-final-installer.run /home/masaaki/pkg/petalinux/
これまた、だいぶ進んだのだが、今度は、 cpio が足りないというエラーだった。
docker_ce_36_190214.png

sudo apt install cpio
で、cpio をインストール後に、PetaLinux インストーラーを起動した。
./petalinux-v2018.2-final-installer.run /home/masaaki/pkg/petalinux/
docker_ce_37_190214.png

docker_ce_38_190214.png

やっとPetaLinux インストール完了。長かった。1日トラブルシュートにかかってしまった。

ホストの端末で、コンテナをイメージにコミットした。
docker commit vivado182ub16c vivado182ub16
docker_ce_40_190215.png

これでDocker イメージにコンテナを書き込めたので、次に起動した時にPetaLinux がインストール済みになる。

最後にPetaLinux のインストールログを貼っておく。

masaaki@6f49669c6591:~$ ./petalinux-v2018.2-final-installer.run /home/masaaki/pkg/petalinux/
INFO: Checking installer checksum...
INFO: Extracting PetaLinux installer...

LICENSE AGREEMENTS

PetaLinux SDK contains software from a number of sources.  Please review
the following licenses and indicate your acceptance of each to continue.

You do not have to accept the licenses, however if you do not then you may 
not use PetaLinux SDK.

Use PgUp/PgDn to navigate the license viewer, and press 'q' to close

Press Enter to display the license agreements
Do you accept Xilinx End User License Agreement? [y/N] > y
Do you accept Webtalk Terms and Conditions? [y/N] > y
Do you accept Third Party End User License Agreement? [y/N] > y
INFO: Checking installation environment requirements...
INFO: Checking free disk space
INFO: Checking installed tools
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 302: [: ==: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 304: [: ==: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 306: [: ==: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 251: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 251: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 251: [: =: unary operator expected
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 219: [: =: unary operator expected
INFO: Checking installed development libraries
/tmp/tmp.fW4nO5GJRg/./tools/common/petalinux/utils/petalinux-env-check: line 388: [: ==: unary operator expected
INFO: Checking network and other services
WARNING: No tftp server found - please refer to "PetaLinux SDK Installation Guide" for its impact and solution
INFO: Installing PetaLinux...
*********************************************
WARNING: PetaLinux installation directory: /home/masaaki/pkg/petalinux//. is not empty!
*********************************************
Please input "y" to continue to install PetaLinux in that directory?[n]y
INFO: Checking PetaLinux installer integrity...
INFO: Installing PetaLinux SDK to "/home/masaaki/pkg/petalinux//."
................................................................................................................................................................................................................................................................................INFO: Installing aarch64 Yocto SDK to "/home/masaaki/pkg/petalinux//./components/yocto/source/aarch64"...
PetaLinux Extensible SDK installer version 2018.2
=================================================
You are about to install the SDK to "/home/masaaki/pkg/petalinux/components/yocto/source/aarch64". Proceed[Y/n]? Y
Extracting SDK................................done
Setting it up...
Extracting buildtools...
done
SDK has been successfully set up and is ready to be used.
Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
 $ . /home/masaaki/pkg/petalinux/components/yocto/source/aarch64/environment-setup-aarch64-xilinx-linux
INFO: Installing arm Yocto SDK to "/home/masaaki/pkg/petalinux//./components/yocto/source/arm"...
PetaLinux Extensible SDK installer version 2018.2
=================================================
You are about to install the SDK to "/home/masaaki/pkg/petalinux/components/yocto/source/arm". Proceed[Y/n]? Y
Extracting SDK..............................done
Setting it up...
Extracting buildtools...
done
SDK has been successfully set up and is ready to be used.
Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
 $ . /home/masaaki/pkg/petalinux/components/yocto/source/arm/environment-setup-cortexa9hf-neon-xilinx-linux-gnueabi
INFO: Installing microblaze_full Yocto SDK to "/home/masaaki/pkg/petalinux//./components/yocto/source/microblaze_full"...
PetaLinux Extensible SDK installer version 2018.2
=================================================
You are about to install the SDK to "/home/masaaki/pkg/petalinux/components/yocto/source/microblaze_full". Proceed[Y/n]? Y
Extracting SDK.............................done
Setting it up...
Extracting buildtools...
done
SDK has been successfully set up and is ready to be used.
Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
 $ . /home/masaaki/pkg/petalinux/components/yocto/source/microblaze_full/environment-setup-microblazeel-v10.0-bs-cmp-re-mh-div-xilinx-linux
INFO: Installing microblaze_lite Yocto SDK to "/home/masaaki/pkg/petalinux//./components/yocto/source/microblaze_lite"...
PetaLinux Extensible SDK installer version 2018.2
=================================================
You are about to install the SDK to "/home/masaaki/pkg/petalinux/components/yocto/source/microblaze_lite". Proceed[Y/n]? Y
Extracting SDK.............................done
Setting it up...
Extracting buildtools...
done
SDK has been successfully set up and is ready to be used.
Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
 $ . /home/masaaki/pkg/petalinux/components/yocto/source/microblaze_lite/environment-setup-microblazeel-v10.0-bs-cmp-re-ml-xilinx-linux
INFO: PetaLinux SDK has been installed to /home/masaaki/pkg/petalinux//.
masaaki@6f49669c6591:~$ 

  1. 2019年02月15日 04:30 |
  2. Docker
  3. | トラックバック:0
  4. | コメント:0

Docker のUbuntu 16.04 イメージにVivado 2018.2 をインストールする2

Docker のUbuntu 16.04 イメージにVivado 2018.2 をインストールする”の続き。

前回は、”Docker でGUIを立ち上げる+sudoを使う方法”のDocker イメージにVivado 2018.2 をインストールして、インプリメンテーションすることができたが、Docker イメージが 38.8 GB となり、コンテナをイメージに書き戻すのが21分かかってしまった。今回はこれを解消するために -v オプションで共有ファイルシステムを使用して、Docker 上でのホーム・ディレクトリをホストのディレクトリにマップすることにより、イメージの容量を減らしてみよう。
なお、-v オプションはツィッターで@aster_ism さんに教えていただいた。ありがとうございました。

まずは、Docker ファイルはほとんど変更がないが、net-tools, gedit, nautilus を最初から apt-get でインストールするように変更した。

FROM ubuntu:16.04
 
RUN apt-get update && apt-get install -y x11-apps
RUN apt-get install -y sudo
RUN apt-get install -y net-tools gedit nautilus
 
# Replace 1000 with your user / group id
ARG uid=1000
ARG gid=1000
RUN groupadd -g ${uid} masaaki && \
    useradd -u ${gid} -g masaaki -G sudo -r masaaki && \
    mkdir /home/masaaki && \
    chown ${uid}:${gid} -R /home/masaaki

RUN echo 'Defaults visiblepw'             >> /etc/sudoers
RUN echo 'masaaki ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER masaaki
WORKDIR /home/masaaki


次に、build.sh を示す。

docker build -t vivado182ub16 .


boot.sh を示す。

docker run -ti --rm --name vivado182ub16c -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix -v /home/masaaki/Docker/vivado182ub16/masaaki:/home/masaaki vivado182ub16 /bin/bash


付け加えたのは、-v オプションでホストの/home/masaaki/Docker/vivado182ub16/masaaki をDocker 上の/home/masaaki としてマップしたことだ。

ホストの/home/masaaki/Docker/vivado182ub16 ディレクトリ上で ./build.sh を使ってDocker イメージを生成して、 ./boot.sh で走らせた。
Docker 上で、 mkdir Xilinx すると、ホストの/home/masaaki/Docker/vivado182ub16/masaaki ディレクトリでXilinx ディレクトリが作成された。うまく行っている。
docker_ce_25_190213.png

docker_ce_26_190213.png

ここからは、”Docker のUbuntu 16.04 イメージにVivado 2018.2 をインストールする”と同じやり方でVivado 2018.2 をインストールした。Vivado 2018.2 では同様のexample も走らせて、ビットストリームを生成できた。
docker_ce_27_190214.png

docker_ce_28_190214.png

ホストの/home/masaaki/Docker/vivado182ub16 ディレクトリを見ると、ホーム・ディレクトリの情報が保存されている。安心した。
docker_ce_30_190214.png

Docker を exit してから、ホストで docker image ls をして、イメージの大きさを見た。
docker_ce_29_190214.png

前回(ubuntu16gui)のイメージの容量は 38.8 GB だが、今回(vivado182ub16)のイメージの容量は 693 MB だった。今回のイメージの容量の方が少なく。コンテナからイメージへの変換時間も短いので、実用に使えそうだ。

ブログへのコメントで、sudo ではなく、gosu を使うようにとのメッセージが来ていたので、試してみようと思う。

  1. 2019年02月14日 04:54 |
  2. Docker
  3. | トラックバック:0
  4. | コメント:0

Docker のUbuntu 16.04 イメージにVivado 2018.2 をインストールする

Docker でGUIを立ち上げる+sudoを使う方法”のDocker イメージにVivado 2018.2 をインストールして、インプリメンテーションしてみよう。

最初に、Xilinx 社のVivado 2018.2 のWebインストーラーの Xilinx_Vivado_SDK_Web_2018.2_0614_1954_Lin64.bin をXilinx 社のサイトからダウンロードした。
Xilinx_Vivado_SDK_Web_2018.2_0614_1954_Lin64.bin をDocker 上のUbuntu 16.04 のコンテナにコピーする必要がある。そこで参考にさせていただいたのが、”Docker のホストとコンテナ間でファイルをやり取りする”だ。
Docker cp でホストからコンテナ、コンテナからホストにファイルをコピーできるととのこと。これは具合が良い。
まずは、コンテナを起動してから docker ps でコンテナIDを取得する。
docker cp Xilinx_Vivado_SDK_Web_2018.2_0614_1954_Lin64.bin <コンテナID>:/home/masaaki
コマンドでコンテナの /home/masaaki ディレクトリにコピーした。
docker_ce_8_190211.png

Ubuntu 16.04 のコンテナ側に Xilinx_Vivado_SDK_Web_2018.2_0614_1954_Lin64.bin がコピーできたので、Vivado をインストールするためのXilinx ディレクトリを作成して、 Xilinx_Vivado_SDK_Web_2018.2_0614_1954_Lin64.bin にWrite パーミッションを与えた。
mkdri Xilinx
chmod +x ./Xilinx_Vivado_SDK_Web_2018.2_0614_1954_Lin64.bin

docker_ce_9_190211.png

Xilinx_Vivado_SDK_Web_2018.2_0614_1954_Lin64.bin を起動した。
./Xilinx_Vivado_SDK_Web_2018.2_0614_1954_Lin64.bin
docker_ce_10_190211.png

Vivado インストーラーが立ち上がった。
docker_ce_11_190211.png

Vivado WebPACK を選択した。
docker_ce_12_190211.png

デバイス選択。デフォルトとした。
docker_ce_13_190211.png

インストールパス。
docker_ce_14_190211.png

Summary.
docker_ce_15_190211.png

インストール開始。
docker_ce_16_190211.png

インストール終了。成功した。
docker_ce_17_190211.png

そういえば .bashrc が無かったので、ホストのUbuntu 18.04 の .bashrc を持ってきた。
source .bashrc
Vivado 2018.2 の settings64.sh を起動した。
source /home/masaaki/Xilinx/Vivado/2018.2/settings64.sh
Vivado 2018.2 を起動した。
./vivado
docker_ce_18_190211.png

Vivado GUI が起動した。
Zynq UltraScale+ MPSoC のサンプルデザインを選択した。
docker_ce_19_190213.png

論理合成、インプリメンテーション、ビットストリームの生成を行った。
docker_ce_20_190213.png

ハードウェアをエクスポートして、SDK を起動した。うまく行っている。
docker_ce_21_190213.png

ホスト上で docker image ls でイメージを見ると、イメージが 38.8 GB に膨れ上がっている。
docker_ce_22_190213.png

ホスト上で
docker commit ubuntu16gui ubuntu16gui
でコンテナをイメージに書き込んだ。書き込み時間は 21 分程度で結構長かった。

コンテナを exit で終了した。
docker_ce_23_190213.png

ホスト上で、docker system prune で余計なイメージを削除した。
docker_ce_24_190213.png
  1. 2019年02月13日 07:04 |
  2. Docker
  3. | トラックバック:0
  4. | コメント:1

Docker でGUIを立ち上げる+sudoを使う方法

Docker でGUIを立ち上げる方法は@basaro_k さんのツィートから知ったのだが、”Docker で GUI アプリケーションを実行する方法”を参考にした。Docker でGUI アプリケーションを実行するやり方についてはこの記事を参考にして欲しい。

Docker で sudo を使用するには、”Dockerコンテナ内にsudoユーザを追加する”を参考にして行った。

Ubuntu 18.04 のホーム・ディレクトリの下にDocker ディレクトリを作り、その下に ubuntu16gui ディレクトリを作成した。
ubuntu16gui ディレクトリにDockerfile を作成した。
Docker ファイルを示す。

FROM ubuntu:16.04
 
RUN apt-get update && apt-get install -y x11-apps
RUN apt-get install -y sudo
 
# Replace 1000 with your user / group id
ARG uid=1000
ARG gid=1000
RUN groupadd -g ${uid} masaaki && \
    useradd -u ${gid} -g masaaki -G sudo -r masaaki && \
    mkdir /home/masaaki && \
    chown ${uid}:${gid} -R /home/masaaki

RUN echo 'Defaults visiblepw'             >> /etc/sudoers
RUN echo 'masaaki ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER masaaki
WORKDIR /home/masaaki


build.sh を示す。

docker build -t ubuntu16gui .


ubuntu16gui イメージを作成する。

boot.sh を示す。

docker run -ti --rm --name ubuntu16gui -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix ubuntu16gui /bin/bash


./build.sh を起動して ubuntu16gui イメージを生成した。
./boot.sh を起動した。
nautilus & を起動したが、 command not found だった。
sudo apt install nautilus を実行した。
docker_ce_3_190211.png

もう一度、nautilus & を起動した。
docker_ce_4_190211.png

nautilus が起動した。
docker_ce_5_190211.png

ここで、ubuntu16gui イメージのコンテナから exit すると、インストールしたnautilus が無くなってしまう。

ubuntu16gui イメージに nautilus を追加したのだが、起動する時に --rm オプションが付いているので、ubuntu16gui イメージのコンテナから exit するとコンテナも切られてしまう。よって、 nautilus を追加した状態で exit する前に別の端末でコンテナをubuntu16gui イメージに書き戻す。
docker commit ubuntu16gui ubuntu16gui docker commit <コンテナ名> <イメージ名>
docker_ce_6_190211.png

nautilus を追加した状態で ubuntu16gui イメージに書き戻しておくと、次に ubuntu16gui イメージを起動した時に、そのまま nautilus を起動することができる。
docker_ce_7_190211.png
  1. 2019年02月12日 08:28 |
  2. Docker
  3. | トラックバック:0
  4. | コメント:1

Ubuntu 18.04 に Docker CE をインストールする

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化”に従って、職場のUbuntu 16.04 にDocker CE(無料のコミュニティ・エディション)をインストールしたのだが、家のUbuntu 18.04 にインストールしたところ、エラーになってしまった。

docker をインストールしていって、下のテスト用コマンドを入れたところでエラーが発生した。
docker container run ubuntu:latest /bin/echo ‘Hello world’

エラーの内容を下に示す。

docker container run ubuntu:latest /bin/echo ‘Hello world’
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.39/containers/create: dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.


パーミッションが無いと言われている。
ネットで検索すると”「Got permission denied while trying to connect to the Docker daemon socket」への対応”が見つかったので、そのとおりにコマンドを入れてみた。
grep -i docker /etc/group
sudo gpasswd -a masaaki docker
grep -i docker /etc/group

一旦ユーザーをログアウトしてから、もう一度ログインして、
docker container run ubuntu:latest /bin/echo ‘Hello world’
を実行したところ、エラーが治らなかった。
docker_ce_1_190209.png

次に、”Dockerを一般ユーザで実行する”を見つけたので、そのとおりにやってみた。
sudo groupadd docker
sudo usermod -g docker masaaki
sudo /bin/systemctl restart docker.service


終了後に、今度は再起動した。再起動後にdocker のテスト用コマンドを実行した。
docker container run ubuntu:latest /bin/echo ‘Hello world’
docker_ce_2_190209.png

うまく行った。

masaaki@masaaki-H110M4-M01:~$ docker container run ubuntu:latest /bin/echo ‘Hello world’
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
6cf436f81810: Pull complete
987088a85b96: Pull complete
b4624b3efe06: Pull complete
d42beb8ded59: Pull complete
Digest: sha256:7a47ccc3bbe8a451b500d2b53104868b46d60ee8f5b35a24b41a86077c650210
Status: Downloaded newer image for ubuntu:latest
‘Hello world’

  1. 2019年02月10日 04:40 |
  2. Docker
  3. | トラックバック:0
  4. | コメント:0

カメラ画像をDisplayPortに出力する9(アプリを作成、完成)

カメラ画像をDisplayPortに出力する8(Ultra96 での準備)”の続き。

前回は、Ultra96 上のDebian で、デバイスツリーを生成して、アプリケーションを動作させる下準備を行った。今回は、カメラ画像をDisplayPort に出力するためのアプリケーション・ソフトを作成して、Ultra96 のDisplayPort でカメラ画像を表示しよう。

まずは、アプリケーション・ソフトを作成しよう。ベースにするのは、”秋月電子カメラモジュールOV5642を使う15(完成)”の cam_cap_ov5642.cpp だ。これを元に、DisplayPort に出力するために追加したIP の制御を書き加えた。
g++_opencv コマンドでコンパイルした。
g++_opencv cam_dp_ov5642.cpp

なお、g++_opencv コマンドに関しては、”Ultra96 のDebianにインストールしたOpenCV-3.4.3のC++サンプルデザインをコンパイル”を参照のこと。

次に、DisplayPort の設定用のバッチファイルの disp_pattern.sh を用意した。

#!/bin/bash

sudo ./memwrite fd4ab070 54
sudo ./memwrite fd4aa00c 01


アルファブレンドの値をすべてカメラ画像を表示するように調整してある。これだとプロンプトは表示されない。

さて、XGA 画面のディスプレイに表示してみよう。
./lddtovary.sh
./cam_dp_ov5642
./disp_pattern.sh

cam_displayport_44_190209.png

XGA 解像度のディスプレイ画面にカメラ画像を表示できた。
cam_displayport_46_190209.jpg

次に、HD 画面にカメラ画像を表示しよう。Ultra96 が電源ON 状態だとXGA になったままなので、一旦 reboot を行った。
./lddtovary.sh
./cam_dp_ov5642 -r 2
./disp_pattern.sh

cam_displayport_45_190209.png

HD 解像度のディスプレイ画面にカメラ画像を表示できた。
cam_displayport_47_190209.jpg

現在のUltra96 のDebian の ~/examples/cam_dp ディレクトリの内容を示す。
cam_displayport_48_190209.png

cam_dp_ov5642.cpp は cam_cap_ov5642.cpp が元になっているので、w コマンドでカメラ画像を保存することが出来る。
最後に、 cam_dp_ov5642.cpp を貼っておく。

// cam_dp_ov5642.cpp (for Ultra96)
// 2018/12/14 by marsee
//
// This software converts the left and right of the camera image to BMP file.
// -b : bmp file name
// -n : Start File Number
// -h : help
//
// 2018/12/20 : completed.
// I am using the SVGA driver register setting of https://github.com/virajkanwade/rk3188_android_kernel/blob/master/drivers/media/video/ov5642.c
// 2018/12/22 : fixed
// 2018/12/30 : ov5642_inf_axis[0] fixed
// 2019/02/06 : for DisplayPort

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

#define PIXEL_NUM_OF_BYTES    4
#define NUMBER_OF_WRITE_FRAMES  3

#define SVGA_HORIZONTAL_PIXELS  800
#define SVGA_VERTICAL_LINES     600
#define SVGA_ALL_DISP_ADDRESS   (SVGA_HORIZONTAL_PIXELS * SVGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define SVGA_3_PICTURES         (SVGA_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)

#define XGA_HORIZONTAL_PIXELS  1024
#define XGA_VERTICAL_LINES     768
#define XGA_ALL_DISP_ADDRESS   (XGA_HORIZONTAL_PIXELS * XGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define XGA_3_PICTURES         (XGA_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)

#define HD_HORIZONTAL_PIXELS  1920
#define HD_VERTICAL_LINES     1080
#define HD_ALL_DISP_ADDRESS   (HD_HORIZONTAL_PIXELS * HD_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define HD_3_PICTURES         (HD_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)

int WriteBMPfile(char *bmp_file, volatile unsigned int *frame_buffer, int active_frame, int resolution);

void cam_i2c_init(volatile unsigned *ov5642_axi_iic) {
    ov5642_axi_iic[64] = 0x2; // reset tx fifo ,address is 0x100, i2c_control_reg
    ov5642_axi_iic[64] = 0x1; // enable i2c
}

void cam_i2x_write_sync(void) {
    // unsigned c;

    // c = *cam_i2c_rx_fifo;
    // while ((c & 0x84) != 0x80)
    // c = *cam_i2c_rx_fifo; // No Bus Busy and TX_FIFO_Empty = 1
    usleep(1000);
}

void cam_i2c_write(volatile unsigned *ov5642_axi_iic, unsigned int device_addr, unsigned int write_addr, unsigned int write_data){
    ov5642_axi_iic[66] = 0x100 | (device_addr & 0xfe); // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
    ov5642_axi_iic[66] = (write_addr >> 8) & 0xff;  // address upper byte
    ov5642_axi_iic[66] = write_addr & 0xff;           // address lower byte
    ov5642_axi_iic[66] = 0x200 | (write_data & 0xff);      // data
    cam_i2x_write_sync();
}

int cam_reg_set(volatile unsigned *axi_iic, unsigned int device_addr);

int main(int argc, char *argv[]){
    int opt;
    int c, help_flag=0;
    char bmp_fn[256] = "bmp_file";
    char  attr[1024];
    unsigned long  phys_addr;
    int file_no = -1;
    int fd1, fd2, fd3, fd4, fd5, fd6, fd10, fd11;
    volatile unsigned int *ov5642_inf_axis, *axi_iic, *disp_dmar_axis, *vflip_dma_write;
    volatile unsigned int *axi_gpio_0, *axi_gpio_1;
    volatile unsigned int *frame_buffer;
    int active_frame;
    int resolution;
    int all_disp_addr;
    
    resolution = 1; // XGA
    while ((opt=getopt(argc, argv, "b:n:h:r:")) != -1){
        switch (opt){
            case 'b':
                strcpy(bmp_fn, optarg);
                break;
            case 'n':
                file_no = atoi(optarg);
                printf("file_no = %d\n", file_no+1);
                break;
            case 'r':
                resolution = atoi(optarg);
                break;
            case 'h':
                help_flag = 1;
                break;
        }
    }
    if(resolution == 0){
        printf("SVGA\n");
    } else if(resolution == 1){
        printf("XGA\n");
    } else {
        printf("HD\n");
    }

    if (help_flag == 1){ // help
        printf("Usage : cam_capture [-b <bmp file name>] [-n <Start File Number>] [-h]\n");
        printf("         -r [0|1|2](0:SVGA, 1:XGA, 2:HD)\n");
        exit(0);
    }
       
    // all_disp_addr
    switch(resolution){
        case 0 :
            all_disp_addr = SVGA_ALL_DISP_ADDRESS;
            break;
        case 1 :
            all_disp_addr = XGA_ALL_DISP_ADDRESS;
            break;
        default : // 2
            all_disp_addr = HD_ALL_DISP_ADDRESS;
            break;
    }
    
    // ov5642_inf_axis-uio IP
    fd1 = open("/dev/uio1", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd1 < 1){
        fprintf(stderr, "/dev/uio1 (ov5642_inf_axis) open error\n");
        exit(-1);
    }
    ov5642_inf_axis = (volatile unsigned *)mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
    if (!ov5642_inf_axis){
        fprintf(stderr, "ov5642_inf_axis mmap error\n");
        exit(-1);
    }
    
    // axi_iic-uio IP
    fd2 = open("/dev/uio2", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd2 < 1){
        fprintf(stderr, "/dev/uio2 (axi_iic) open error\n");
        exit(-1);
    }
    axi_iic = (volatile unsigned int *)mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
    if (!axi_iic){
        fprintf(stderr, "axi_iic mmap error\n");
        exit(-1);
    }

    // disp_dmar_axis-uio IP
    fd3 = open("/dev/uio3", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd3 < 1){
        fprintf(stderr, "/dev/uio3 (disp_dmar_axis) open error\n");
        exit(-1);
    }
    disp_dmar_axis = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
    if (!disp_dmar_axis){
        fprintf(stderr, "disp_dmar_axis mmap error\n");
        exit(-1);
    }

    // vflip_dma_write-uio IP
    fd4 = open("/dev/uio4", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd4 < 1){
        fprintf(stderr, "/dev/uio4 (vflip_dma_write) open error\n");
        exit(-1);
    }
    vflip_dma_write = (volatile unsigned int *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
    if (!vflip_dma_write){
        fprintf(stderr, "vflip_dma_write mmap error\n");
        exit(-1);
    }

    // axi_gpio_0-uio IP (init_done output)
    fd5 = open("/dev/uio5", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd5 < 1){
        fprintf(stderr, "/dev/uio5 (axi_gpio_0) open error\n");
        exit(-1);
    }
    axi_gpio_0 = (volatile unsigned int *)mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd5, 0);
    if (!axi_gpio_0){
        fprintf(stderr, "axi_gpio_0 mmap error\n");
        exit(-1);
    }

    // axi_gpio_1-uio IP (active_frame input)
    fd6 = open("/dev/uio6", O_RDWR|O_SYNC); // Read/Write, The chache is disable
    if (fd6 < 1){
        fprintf(stderr, "/dev/uio6 (axi_gpio_1) open error\n");
        exit(-1);
    }
    axi_gpio_1 = (volatile unsigned int *)mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd6, 0);
    if (!axi_gpio_1){
        fprintf(stderr, "axi_gpio_1 mmap error\n");
        exit(-1);
    }
    
    
    // udmabuf4
    fd10 = open("/dev/udmabuf4", O_RDWR | O_SYNC); // frame_buffer, The chache is disabled. 
    if (fd10 == -1){
        fprintf(stderr, "/dev/udmabuf4 open error\n");
        exit(-1);
    }
    frame_buffer = (volatile unsigned int *)mmap(NULL, all_disp_addr*NUMBER_OF_WRITE_FRAMES, PROT_READ|PROT_WRITE, MAP_SHARED, fd10, 0);
    if (!frame_buffer){
        fprintf(stderr, "frame_buffer4 mmap error\n");
        exit(-1);
    }
    
    // phys_addr of udmabuf4
    fd11 = open("/sys/class/udmabuf/udmabuf4/phys_addr", O_RDONLY);
    if (fd11 == -1){
        fprintf(stderr, "/sys/class/udmabuf/udmabuf4/phys_addr open error\n");
        exit(-1);
    }
    read(fd11, attr, 1024);
    sscanf(attr, "%lx", &phys_addr);  
    close(fd11);
    printf("phys_addr = %x\n", (int)phys_addr);
    
    // vflip_dma_write start
    vflip_dma_write[6] = phys_addr; // fb0
    vflip_dma_write[8] = phys_addr+all_disp_addr; // fb1
    vflip_dma_write[10] = phys_addr+2*all_disp_addr; // fb2
    vflip_dma_write[12] = resolution;
    vflip_dma_write[0] = 0x1; // start
    vflip_dma_write[0] = 0x80; // EnableAutoRestart
       
    // CMOS Camera initialize, ov5642
    cam_i2c_init(axi_iic);
    
    cam_reg_set(axi_iic, 0x78); // OV5642 register set

    ov5642_inf_axis[0] = phys_addr; // ov5642 AXI4-Stream Start
    ov5642_inf_axis[1] = 0;
 
     // disp_dmar_axis start
    disp_dmar_axis[4] = phys_addr; // fb0
    disp_dmar_axis[6] = phys_addr+all_disp_addr; // fb1
    disp_dmar_axis[8] = phys_addr+2*all_disp_addr; // fb2
    disp_dmar_axis[10] = resolution;
    axi_gpio_0[0] = 1; // disp_dmar_axis start(init_done = 1)
    
    char bmp_file[256];

    // All 0 set
    int all_disp_frame_index = all_disp_addr/PIXEL_NUM_OF_BYTES*NUMBER_OF_WRITE_FRAMES;
    for (int i=0; i<all_disp_frame_index; i++){
        frame_buffer[i] = 0x0;
    }
    
    // w - writed the left and right eye's bmp files.  q - exit.
    c = getc(stdin);
    while(c != 'q'){
        switch ((char)c) {
            case 'w' : // w - writed a bmp files.
                // writed the frame buffer
                file_no++;
                sprintf(bmp_file, "%s%d.bmp", bmp_fn, file_no);
                active_frame = (int)(axi_gpio_1[0] & 0x3); // Data signal of active_frame_V
                WriteBMPfile(bmp_file, frame_buffer, active_frame, resolution);
                
                printf("file No. = %d\n", file_no);

                break;
            case 'e' : // e - writed a same bmp files.
                // writed the frame buffer
                if (file_no == -1)
                    file_no = 0;
                
                sprintf(bmp_file, "%s%d.bmp", bmp_fn, file_no);
                active_frame = (int)(axi_gpio_1[0] & 0x3); // Data signal of active_frame_V
                WriteBMPfile(bmp_file, frame_buffer, active_frame, resolution);
                
                printf("file No. = %d\n", file_no);

                break;
        }
        c = getc(stdin);
    }
    
    munmap((void *)ov5642_inf_axis, 0x1000);
    munmap((void *)axi_iic, 0x1000);
    munmap((void *)disp_dmar_axis, 0x10000);
    munmap((void *)vflip_dma_write, 0x10000);
    munmap((void *)axi_gpio_0, 0x1000);
    munmap((void *)axi_gpio_1, 0x1000);
    munmap((void *)frame_buffer, all_disp_addr*3);
    
    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);
    close(fd5);
    close(fd6);
    close(fd10);
    
    return(0);
}

int WriteBMPfile(char *bmp_file, volatile unsigned int *frame_buffer, int active_frame, int resolution){
    int read_frame;
    int img_width, img_height;
    
    if (active_frame == 0)
        read_frame = 2;
    else if (active_frame == 1)
        read_frame = 0;
    else // active_frame == 2
        read_frame = 1;
        
    switch(resolution){
        case 0 :
            img_width = SVGA_HORIZONTAL_PIXELS;
            img_height = SVGA_VERTICAL_LINES;
            break;
        case 1 :
            img_width = XGA_HORIZONTAL_PIXELS;
            img_height = XGA_VERTICAL_LINES;
            break;
        default : // case 2 :
            img_width = HD_HORIZONTAL_PIXELS;
            img_height = HD_VERTICAL_LINES;
            break;
    }
    
    int offset_addr = read_frame * img_width * img_height;
    
    cv::Mat img(img_height, img_width, CV_8UC3);

    cv::Mat_<cv::Vec3b> dst_vec3b = cv::Mat_<cv::Vec3b>(img);
    for(int y=0; y<img.rows; y++){
        for(int x=0; x<img.cols; x++){
            cv::Vec3b pixel;
            int rgb = frame_buffer[offset_addr+y*img.cols+x];
            pixel[0] = (rgb & 0xff); // blue
            pixel[1] = (rgb & 0xff00) >> 8; // green
            pixel[2] = (rgb & 0xff0000) >> 16; // red
            dst_vec3b(y,x) = pixel;
        }
    }
    
    cv::imwrite(bmp_file, img);
    
    return(0);
}

int cam_reg_set(volatile unsigned *axi_iic, unsigned int device_addr){
    cam_i2c_write(axi_iic, device_addr, 0x3103, 0x93);
    cam_i2c_write(axi_iic, device_addr, 0x3008, 0x82);
    cam_i2c_write(axi_iic, device_addr, 0x3017, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x3018, 0xfc);
    cam_i2c_write(axi_iic, device_addr, 0x3810, 0xc2);
    cam_i2c_write(axi_iic, device_addr, 0x3615, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x3000, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3001, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3002, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3003, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3000, 0xf8);
    cam_i2c_write(axi_iic, device_addr, 0x3001, 0x48);
    cam_i2c_write(axi_iic, device_addr, 0x3002, 0x5c);
    cam_i2c_write(axi_iic, device_addr, 0x3003, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3004, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3005, 0xb7);
    cam_i2c_write(axi_iic, device_addr, 0x3006, 0x43);
    cam_i2c_write(axi_iic, device_addr, 0x3007, 0x37);
    cam_i2c_write(axi_iic, device_addr, 0x3011, 0x08); // 0x08 - 15fps, 0x10 - 30fps
    cam_i2c_write(axi_iic, device_addr, 0x3010, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x460c, 0x22);
    cam_i2c_write(axi_iic, device_addr, 0x3815, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x370d, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x370c, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x3602, 0xfc);
    cam_i2c_write(axi_iic, device_addr, 0x3612, 0xff);
    cam_i2c_write(axi_iic, device_addr, 0x3634, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3613, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3605, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x3621, 0x09);
    cam_i2c_write(axi_iic, device_addr, 0x3622, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3604, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x3603, 0xa7);
    cam_i2c_write(axi_iic, device_addr, 0x3603, 0x27);
    cam_i2c_write(axi_iic, device_addr, 0x4000, 0x21);
    cam_i2c_write(axi_iic, device_addr, 0x401d, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3600, 0x54);
    cam_i2c_write(axi_iic, device_addr, 0x3605, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x3606, 0x3f);
    cam_i2c_write(axi_iic, device_addr, 0x3c01, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5000, 0x4f);
    cam_i2c_write(axi_iic, device_addr, 0x5020, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5181, 0x79);
    cam_i2c_write(axi_iic, device_addr, 0x5182, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5185, 0x22);
    cam_i2c_write(axi_iic, device_addr, 0x5197, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5001, 0xff);
    cam_i2c_write(axi_iic, device_addr, 0x5500, 0x0a);
    cam_i2c_write(axi_iic, device_addr, 0x5504, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5505, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x5080, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x300e, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x4610, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x471d, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x4708, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x3710, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x3632, 0x41);
    cam_i2c_write(axi_iic, device_addr, 0x3702, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x3620, 0x37);
    cam_i2c_write(axi_iic, device_addr, 0x3631, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x3808, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3809, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x380a, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x380b, 0xe0);
    cam_i2c_write(axi_iic, device_addr, 0x380e, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x380f, 0xd0);
    cam_i2c_write(axi_iic, device_addr, 0x501f, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5000, 0x4f);
    cam_i2c_write(axi_iic, device_addr, 0x4300, 0x61); // RGB565
    cam_i2c_write(axi_iic, device_addr, 0x3503, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3501, 0x73);
    cam_i2c_write(axi_iic, device_addr, 0x3502, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x350b, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3503, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3824, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x3501, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x3502, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x350b, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x380c, 0x0c);
    cam_i2c_write(axi_iic, device_addr, 0x380d, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x380e, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x380f, 0xe8);
    cam_i2c_write(axi_iic, device_addr, 0x3a0d, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x3a0e, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x3818, 0xc1);
    cam_i2c_write(axi_iic, device_addr, 0x3705, 0xdb);
    cam_i2c_write(axi_iic, device_addr, 0x370a, 0x81);
    cam_i2c_write(axi_iic, device_addr, 0x3801, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x3621, 0xc7);
    cam_i2c_write(axi_iic, device_addr, 0x3801, 0x50);
    cam_i2c_write(axi_iic, device_addr, 0x3803, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x3827, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x3810, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3804, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x3805, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5682, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x5683, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3806, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x3807, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x5686, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x5687, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3a00, 0x78);
    cam_i2c_write(axi_iic, device_addr, 0x3a1a, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x3a13, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a18, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a19, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x3a08, 0x12);
    cam_i2c_write(axi_iic, device_addr, 0x3a09, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3a0a, 0x0f);
    cam_i2c_write(axi_iic, device_addr, 0x3a0b, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x3004, 0xff);
    cam_i2c_write(axi_iic, device_addr, 0x350c, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x350d, 0xd0);
    cam_i2c_write(axi_iic, device_addr, 0x3500, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3501, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3502, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x350a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x350b, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3503, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x528a, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x528b, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x528c, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x528d, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x528e, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x528f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5290, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5292, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5293, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5294, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5295, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5296, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5297, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5298, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5299, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x529a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529b, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x529c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529d, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x529e, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529f, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3a0f, 0x3c);
    cam_i2c_write(axi_iic, device_addr, 0x3a10, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a1b, 0x3c);
    cam_i2c_write(axi_iic, device_addr, 0x3a1e, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a11, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x3a1f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x3030, 0x0b);
    cam_i2c_write(axi_iic, device_addr, 0x3a02, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a03, 0x7d);
    cam_i2c_write(axi_iic, device_addr, 0x3a04, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a14, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a15, 0x7d);
    cam_i2c_write(axi_iic, device_addr, 0x3a16, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3a00, 0x78);
    cam_i2c_write(axi_iic, device_addr, 0x3a08, 0x09);
    cam_i2c_write(axi_iic, device_addr, 0x3a09, 0x60);
    cam_i2c_write(axi_iic, device_addr, 0x3a0a, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3a0b, 0xd0);
    cam_i2c_write(axi_iic, device_addr, 0x3a0d, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x3a0e, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x5193, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x3620, 0x57);
    cam_i2c_write(axi_iic, device_addr, 0x3703, 0x98);
    cam_i2c_write(axi_iic, device_addr, 0x3704, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x589b, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x589a, 0xc5);
    cam_i2c_write(axi_iic, device_addr, 0x528a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x528b, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x528c, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x528d, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x528e, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x528f, 0x28);
    cam_i2c_write(axi_iic, device_addr, 0x5290, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5292, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5293, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5294, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5295, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5296, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5297, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5298, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5299, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x529a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529b, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x529c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529d, 0x28);
    cam_i2c_write(axi_iic, device_addr, 0x529e, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529f, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5282, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5300, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5301, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5302, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5303, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x530c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x530d, 0x0c);
    cam_i2c_write(axi_iic, device_addr, 0x530e, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x530f, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5310, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5311, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5308, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5309, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5304, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5305, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5306, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5307, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5314, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5315, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5319, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5316, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5317, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5318, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5380, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5381, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5382, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5383, 0x4e);
    cam_i2c_write(axi_iic, device_addr, 0x5384, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5385, 0x0f);
    cam_i2c_write(axi_iic, device_addr, 0x5386, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5387, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5388, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5389, 0x15);
    cam_i2c_write(axi_iic, device_addr, 0x538a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538b, 0x31);
    cam_i2c_write(axi_iic, device_addr, 0x538c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538d, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538e, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538f, 0x0f);
    cam_i2c_write(axi_iic, device_addr, 0x5390, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5391, 0xab);
    cam_i2c_write(axi_iic, device_addr, 0x5392, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5393, 0xa2);
    cam_i2c_write(axi_iic, device_addr, 0x5394, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5480, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5481, 0x21);
    cam_i2c_write(axi_iic, device_addr, 0x5482, 0x36);
    cam_i2c_write(axi_iic, device_addr, 0x5483, 0x57);
    cam_i2c_write(axi_iic, device_addr, 0x5484, 0x65);
    cam_i2c_write(axi_iic, device_addr, 0x5485, 0x71);
    cam_i2c_write(axi_iic, device_addr, 0x5486, 0x7d);
    cam_i2c_write(axi_iic, device_addr, 0x5487, 0x87);
    cam_i2c_write(axi_iic, device_addr, 0x5488, 0x91);
    cam_i2c_write(axi_iic, device_addr, 0x5489, 0x9a);
    cam_i2c_write(axi_iic, device_addr, 0x548a, 0xaa);
    cam_i2c_write(axi_iic, device_addr, 0x548b, 0xb8);
    cam_i2c_write(axi_iic, device_addr, 0x548c, 0xcd);
    cam_i2c_write(axi_iic, device_addr, 0x548d, 0xdd);
    cam_i2c_write(axi_iic, device_addr, 0x548e, 0xea);
    cam_i2c_write(axi_iic, device_addr, 0x548f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5490, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x5491, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5492, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5493, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5494, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x5495, 0x60);
    cam_i2c_write(axi_iic, device_addr, 0x5496, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5497, 0xb8);
    cam_i2c_write(axi_iic, device_addr, 0x5498, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5499, 0x86);
    cam_i2c_write(axi_iic, device_addr, 0x549a, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x549b, 0x5b);
    cam_i2c_write(axi_iic, device_addr, 0x549c, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x549d, 0x3b);
    cam_i2c_write(axi_iic, device_addr, 0x549e, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x549f, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x54a0, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x54a1, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x54a2, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54a3, 0xed);
    cam_i2c_write(axi_iic, device_addr, 0x54a4, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54a5, 0xc5);
    cam_i2c_write(axi_iic, device_addr, 0x54a6, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54a7, 0xa5);
    cam_i2c_write(axi_iic, device_addr, 0x54a8, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54a9, 0x6c);
    cam_i2c_write(axi_iic, device_addr, 0x54aa, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54ab, 0x41);
    cam_i2c_write(axi_iic, device_addr, 0x54ac, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54ad, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x54ae, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x54af, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x3406, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5192, 0x04); // 0x04
    cam_i2c_write(axi_iic, device_addr, 0x5191, 0xf8); // 0xf8
    cam_i2c_write(axi_iic, device_addr, 0x5193, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x5194, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x5195, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x518d, 0x3d);
    cam_i2c_write(axi_iic, device_addr, 0x518f, 0x54);
    cam_i2c_write(axi_iic, device_addr, 0x518e, 0x3d);
    cam_i2c_write(axi_iic, device_addr, 0x5190, 0x54);
    cam_i2c_write(axi_iic, device_addr, 0x518b, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x518c, 0xbd);
    cam_i2c_write(axi_iic, device_addr, 0x5187, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5188, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5189, 0x6e);
    cam_i2c_write(axi_iic, device_addr, 0x518a, 0x68);
    cam_i2c_write(axi_iic, device_addr, 0x5186, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x5181, 0x50);
    cam_i2c_write(axi_iic, device_addr, 0x5184, 0x25);
    cam_i2c_write(axi_iic, device_addr, 0x5182, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5183, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5184, 0x25);
    cam_i2c_write(axi_iic, device_addr, 0x5185, 0x24);
    cam_i2c_write(axi_iic, device_addr, 0x5025, 0x82);
    cam_i2c_write(axi_iic, device_addr, 0x5583, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5584, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5580, 0x02); // 0x02
    cam_i2c_write(axi_iic, device_addr, 0x3633, 0x07);
    cam_i2c_write(axi_iic, device_addr, 0x3702, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x3703, 0xb2);
    cam_i2c_write(axi_iic, device_addr, 0x3704, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x370b, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x370d, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3620, 0x52);
    cam_i2c_write(axi_iic, device_addr, 0x3c00, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5001, 0xFF);
    cam_i2c_write(axi_iic, device_addr, 0x5282, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5300, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5301, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5302, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5303, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x530c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x530d, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x530e, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x530f, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5310, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5311, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5308, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5309, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5304, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5305, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5306, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5307, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5314, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5315, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5319, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5316, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5317, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5318, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5500, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5502, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5503, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x5504, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5505, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x5025, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5300, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5301, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5302, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5303, 0x7c);
    cam_i2c_write(axi_iic, device_addr, 0x530c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x530d, 0x0c);
    cam_i2c_write(axi_iic, device_addr, 0x530e, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x530f, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5310, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5311, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5308, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5309, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5304, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5305, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5306, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5307, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5314, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5315, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x5319, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5316, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5317, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5318, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5380, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5381, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5382, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5383, 0x1f);
    cam_i2c_write(axi_iic, device_addr, 0x5384, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5385, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x5386, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5387, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5388, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5389, 0xE1);
    cam_i2c_write(axi_iic, device_addr, 0x538A, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538B, 0x2B);
    cam_i2c_write(axi_iic, device_addr, 0x538C, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538D, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538E, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x538F, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5390, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5391, 0xB3);
    cam_i2c_write(axi_iic, device_addr, 0x5392, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5393, 0xA6);
    cam_i2c_write(axi_iic, device_addr, 0x5394, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5480, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5481, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5482, 0x2a);
    cam_i2c_write(axi_iic, device_addr, 0x5483, 0x49);
    cam_i2c_write(axi_iic, device_addr, 0x5484, 0x56);
    cam_i2c_write(axi_iic, device_addr, 0x5485, 0x62);
    cam_i2c_write(axi_iic, device_addr, 0x5486, 0x6c);
    cam_i2c_write(axi_iic, device_addr, 0x5487, 0x76);
    cam_i2c_write(axi_iic, device_addr, 0x5488, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x5489, 0x88);
    cam_i2c_write(axi_iic, device_addr, 0x548a, 0x96);
    cam_i2c_write(axi_iic, device_addr, 0x548b, 0xa2);
    cam_i2c_write(axi_iic, device_addr, 0x548c, 0xb8);
    cam_i2c_write(axi_iic, device_addr, 0x548d, 0xcc);
    cam_i2c_write(axi_iic, device_addr, 0x548e, 0xe0);
    cam_i2c_write(axi_iic, device_addr, 0x548f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5490, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x5491, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x5492, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x5493, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5494, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x5495, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x5496, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x5497, 0x48);
    cam_i2c_write(axi_iic, device_addr, 0x5498, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x5499, 0x26);
    cam_i2c_write(axi_iic, device_addr, 0x549a, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x549b, 0xb);
    cam_i2c_write(axi_iic, device_addr, 0x549c, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x549d, 0xee);
    cam_i2c_write(axi_iic, device_addr, 0x549e, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x549f, 0xd8);
    cam_i2c_write(axi_iic, device_addr, 0x54a0, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a1, 0xc7);
    cam_i2c_write(axi_iic, device_addr, 0x54a2, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a3, 0xb3);
    cam_i2c_write(axi_iic, device_addr, 0x54a4, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a5, 0x90);
    cam_i2c_write(axi_iic, device_addr, 0x54a6, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a7, 0x62);
    cam_i2c_write(axi_iic, device_addr, 0x54a8, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54a9, 0x27);
    cam_i2c_write(axi_iic, device_addr, 0x54aa, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54ab, 0x09);
    cam_i2c_write(axi_iic, device_addr, 0x54ac, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x54ad, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x54ae, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x54af, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x54b0, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54b1, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x54b2, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54b3, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x54b4, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x54b5, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x54b6, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x54b7, 0xdf);
    cam_i2c_write(axi_iic, device_addr, 0x5583, 0x5d);
    cam_i2c_write(axi_iic, device_addr, 0x5584, 0x5d);
    cam_i2c_write(axi_iic, device_addr, 0x5580, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x5587, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5588, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x558a, 0x09);
    cam_i2c_write(axi_iic, device_addr, 0x5589, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5000, 0xcf);
    cam_i2c_write(axi_iic, device_addr, 0x5800, 0x48);
    cam_i2c_write(axi_iic, device_addr, 0x5801, 0x31);
    cam_i2c_write(axi_iic, device_addr, 0x5802, 0x21);
    cam_i2c_write(axi_iic, device_addr, 0x5803, 0x1b);
    cam_i2c_write(axi_iic, device_addr, 0x5804, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5805, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x5806, 0x29);
    cam_i2c_write(axi_iic, device_addr, 0x5807, 0x38);
    cam_i2c_write(axi_iic, device_addr, 0x5808, 0x26);
    cam_i2c_write(axi_iic, device_addr, 0x5809, 0x17);
    cam_i2c_write(axi_iic, device_addr, 0x580a, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x580b, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x580c, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x580d, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x580e, 0x13);
    cam_i2c_write(axi_iic, device_addr, 0x580f, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5810, 0x15);
    cam_i2c_write(axi_iic, device_addr, 0x5811, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5812, 0x8);
    cam_i2c_write(axi_iic, device_addr, 0x5813, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x5814, 0x4);
    cam_i2c_write(axi_iic, device_addr, 0x5815, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x5816, 0x9);
    cam_i2c_write(axi_iic, device_addr, 0x5817, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5818, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5819, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x581a, 0x4);
    cam_i2c_write(axi_iic, device_addr, 0x581b, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x581c, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x581d, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x581e, 0x6);
    cam_i2c_write(axi_iic, device_addr, 0x581f, 0x9);
    cam_i2c_write(axi_iic, device_addr, 0x5820, 0x12);
    cam_i2c_write(axi_iic, device_addr, 0x5821, 0xb);
    cam_i2c_write(axi_iic, device_addr, 0x5822, 0x4);
    cam_i2c_write(axi_iic, device_addr, 0x5823, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5824, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5825, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x5826, 0x6);
    cam_i2c_write(axi_iic, device_addr, 0x5827, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x5828, 0x17);
    cam_i2c_write(axi_iic, device_addr, 0x5829, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x582a, 0x9);
    cam_i2c_write(axi_iic, device_addr, 0x582b, 0x6);
    cam_i2c_write(axi_iic, device_addr, 0x582c, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x582d, 0x6);
    cam_i2c_write(axi_iic, device_addr, 0x582e, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x582f, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5830, 0x28);
    cam_i2c_write(axi_iic, device_addr, 0x5831, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5832, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5833, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5834, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5835, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x5836, 0x15);
    cam_i2c_write(axi_iic, device_addr, 0x5837, 0x1d);
    cam_i2c_write(axi_iic, device_addr, 0x5838, 0x6e);
    cam_i2c_write(axi_iic, device_addr, 0x5839, 0x39);
    cam_i2c_write(axi_iic, device_addr, 0x583a, 0x27);
    cam_i2c_write(axi_iic, device_addr, 0x583b, 0x1f);
    cam_i2c_write(axi_iic, device_addr, 0x583c, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x583d, 0x23);
    cam_i2c_write(axi_iic, device_addr, 0x583e, 0x2f);
    cam_i2c_write(axi_iic, device_addr, 0x583f, 0x41);
    cam_i2c_write(axi_iic, device_addr, 0x5840, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5841, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5842, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5843, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5844, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5845, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5846, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5847, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5848, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5849, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x584a, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x584b, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x584c, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x584d, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x584e, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x584f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5850, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5851, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x5852, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x5853, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5854, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5855, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5856, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5857, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x5858, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x5859, 0xe);
    cam_i2c_write(axi_iic, device_addr, 0x585a, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x585b, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x585c, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x585d, 0xa);
    cam_i2c_write(axi_iic, device_addr, 0x585e, 0x9);
    cam_i2c_write(axi_iic, device_addr, 0x585f, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5860, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x5861, 0xb);
    cam_i2c_write(axi_iic, device_addr, 0x5862, 0xd);
    cam_i2c_write(axi_iic, device_addr, 0x5863, 0x7);
    cam_i2c_write(axi_iic, device_addr, 0x5864, 0x17);
    cam_i2c_write(axi_iic, device_addr, 0x5865, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5866, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5867, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x5868, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x5869, 0x12);
    cam_i2c_write(axi_iic, device_addr, 0x586a, 0x1b);
    cam_i2c_write(axi_iic, device_addr, 0x586b, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x586c, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x586d, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x586e, 0x18);
    cam_i2c_write(axi_iic, device_addr, 0x586f, 0x1f);
    cam_i2c_write(axi_iic, device_addr, 0x5870, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x5871, 0x16);
    cam_i2c_write(axi_iic, device_addr, 0x5872, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x5873, 0xf);
    cam_i2c_write(axi_iic, device_addr, 0x5874, 0x13);
    cam_i2c_write(axi_iic, device_addr, 0x5875, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x5876, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x5877, 0x17);
    cam_i2c_write(axi_iic, device_addr, 0x5878, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5879, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x587a, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x587b, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x587c, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x587d, 0x1c);
    cam_i2c_write(axi_iic, device_addr, 0x587e, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x587f, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5880, 0x1b);
    cam_i2c_write(axi_iic, device_addr, 0x5881, 0x1f);
    cam_i2c_write(axi_iic, device_addr, 0x5882, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5883, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5884, 0x1d);
    cam_i2c_write(axi_iic, device_addr, 0x5885, 0x1e);
    cam_i2c_write(axi_iic, device_addr, 0x5886, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x5887, 0x1a);
    cam_i2c_write(axi_iic, device_addr, 0x528a, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x528b, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x528c, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x528d, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x528e, 0x40);
    cam_i2c_write(axi_iic, device_addr, 0x528f, 0x50);
    cam_i2c_write(axi_iic, device_addr, 0x5290, 0x60);
    cam_i2c_write(axi_iic, device_addr, 0x5292, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5293, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x5294, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5295, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5296, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5297, 0x08);
    cam_i2c_write(axi_iic, device_addr, 0x5298, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5299, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x529a, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529b, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x529c, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529d, 0x28);
    cam_i2c_write(axi_iic, device_addr, 0x529e, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x529f, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x5282, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5680, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5681, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5682, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x5683, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5684, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5685, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x5686, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x5687, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x5180, 0xff);
    cam_i2c_write(axi_iic, device_addr, 0x5181, 0x52);
    cam_i2c_write(axi_iic, device_addr, 0x5182, 0x11);
    cam_i2c_write(axi_iic, device_addr, 0x5183, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5184, 0x25);
    cam_i2c_write(axi_iic, device_addr, 0x5185, 0x24);
    cam_i2c_write(axi_iic, device_addr, 0x5186, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5187, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5188, 0x14);
    cam_i2c_write(axi_iic, device_addr, 0x5189, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x518a, 0x60);
    cam_i2c_write(axi_iic, device_addr, 0x518b, 0xa2);
    cam_i2c_write(axi_iic, device_addr, 0x518c, 0x9c);
    cam_i2c_write(axi_iic, device_addr, 0x518d, 0x36);
    cam_i2c_write(axi_iic, device_addr, 0x518e, 0x34);
    cam_i2c_write(axi_iic, device_addr, 0x518f, 0x54);
    cam_i2c_write(axi_iic, device_addr, 0x5190, 0x4c);
    cam_i2c_write(axi_iic, device_addr, 0x5191, 0xf8);
    cam_i2c_write(axi_iic, device_addr, 0x5192, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x5193, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x5194, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x5195, 0xf0);
    cam_i2c_write(axi_iic, device_addr, 0x5196, 0x03);
    cam_i2c_write(axi_iic, device_addr, 0x5197, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x5198, 0x05);
    cam_i2c_write(axi_iic, device_addr, 0x5199, 0x2f);
    cam_i2c_write(axi_iic, device_addr, 0x519a, 0x04);
    cam_i2c_write(axi_iic, device_addr, 0x519b, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x519c, 0x06);
    cam_i2c_write(axi_iic, device_addr, 0x519d, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x519e, 0xa0);
    cam_i2c_write(axi_iic, device_addr, 0x3a0f, 0x3c);
    cam_i2c_write(axi_iic, device_addr, 0x3a10, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a1b, 0x3c);
    cam_i2c_write(axi_iic, device_addr, 0x3a1e, 0x30);
    cam_i2c_write(axi_iic, device_addr, 0x3a11, 0x70);
    cam_i2c_write(axi_iic, device_addr, 0x3a1f, 0x10);
    cam_i2c_write(axi_iic, device_addr, 0x3800, 0x1);
    cam_i2c_write(axi_iic, device_addr, 0x3801, 0x50);
    cam_i2c_write(axi_iic, device_addr, 0x3802, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x3803, 0x8);
    cam_i2c_write(axi_iic, device_addr, 0x3804, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x3805, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x3806, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x3807, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3808, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x3809, 0x20);
    cam_i2c_write(axi_iic, device_addr, 0x380a, 0x2);
    cam_i2c_write(axi_iic, device_addr, 0x380b, 0x58);
    cam_i2c_write(axi_iic, device_addr, 0x380c, 0xc);
    cam_i2c_write(axi_iic, device_addr, 0x380d, 0x80);
    cam_i2c_write(axi_iic, device_addr, 0x380e, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x380f, 0xe8);
    cam_i2c_write(axi_iic, device_addr, 0x5001, 0x7f);
    cam_i2c_write(axi_iic, device_addr, 0x5680, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5681, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5682, 0x5);
    cam_i2c_write(axi_iic, device_addr, 0x5683, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5684, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5685, 0x0);
    cam_i2c_write(axi_iic, device_addr, 0x5686, 0x3);
    cam_i2c_write(axi_iic, device_addr, 0x5687, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x5687, 0xc0);
    cam_i2c_write(axi_iic, device_addr, 0x3815, 0x02);
    cam_i2c_write(axi_iic, device_addr, 0x3503, 0x00);
    cam_i2c_write(axi_iic, device_addr, 0x3818, 0x81); // No Mirror
    cam_i2c_write(axi_iic, device_addr, 0x3621, 0xa7);
    
    cam_i2c_write(axi_iic, device_addr, 0x4740, 0x21);
    
    cam_i2c_write(axi_iic, device_addr, 0x501e, 0x2a);
    cam_i2c_write(axi_iic, device_addr, 0x5002, 0x78);
    cam_i2c_write(axi_iic, device_addr, 0x501f, 0x01);
    cam_i2c_write(axi_iic, device_addr, 0x4300, 0x61);
    
    return(0);
}

  1. 2019年02月09日 05:21 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

カメラ画像をDisplayPortに出力する8(Ultra96 での準備)

カメラ画像をDisplayPortに出力する7(ブロックデザインの変更)”の続き。

前回は、init_done 信号用と active_frame をキャプチャするための axi_gpio を 2 つ追加した。今回は、Ultra96 上のDebian で、デバイスツリーを生成して、アプリケーションを動作させる下準備を行う。

Ultra96 の電源をON して、Debian を起動した。
examples ディレクトリ下に cam_dp ディレクトリを作成した。
カメラ画像をDisplayPortに出力する7(binファイルの生成)”で生成したbin ファイルを SFTP でUltra96 の cam_dp ディレクトリにアップロードした。

デバイスツリーのソースを作成した。fpga-load.dts, fclk01-zynqmp.dts, cam_dp.dts
fpga-load.dts を貼っておく。

/dts-v1/;
/ {
    fragment@0 {
        target-path = "/fpga-full";
        __overlay__ {
            firmware-name = "cam_dp_wrapper.bin";
        };
    };
};


fclk01-zynqmp.dts を貼っておく。

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/amba";
        __overlay__ {
            fclk0 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&clk 0x47>;
                insert-rate   = "200000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
            
            fclk1 {
                compatible    = "ikwzm,fclkcfg-0.10.a";
                clocks        = <&clk 0x48>;
                insert-rate   = "24000000";
                insert-enable = <1>;
                remove-rate   = "1000000";
                remove-enable = <0>;
            };
        };
    };
};


cam_dp.dts を貼っておく。

/dts-v1/;/plugin/;
/ {
    fragment@0 {
        target-path = "/amba_pl@0";
        #address-cells = <2>;
        #size-cells = <2>;

        __overlay__ {
            #address-cells = <2>;
            #size-cells = <2>;

            mt9d111_inf_axis-uio {
                compatible = "generic-uio";
                reg = <0x0 0xA0010000 0x0 0x1000>;
            };
            
            axi_iic-uio {
                compatible = "generic-uio";
                reg = <0x0 0xA0011000 0x0 0x1000>;
            };
            
            disp_dmar_axis-uio {
                compatible = "generic-uio";
                reg = <0x0 0xA0000000 0x0 0x10000>;
            };

            vflip_dma_write-uio {
                compatible = "generic-uio";
                reg = <0x0 0xA0020000 0x0 0x10000>;
            };

            axi_gpio_0-uio {
                compatible = "generic-uio";
                reg = <0x0 0xA0012000 0x0 0x1000>;
            };
            
            axi_gpio_1-uio {
                compatible = "generic-uio";
                reg = <0x0 0xA0013000 0x0 0x1000>;
            };
            
            cam_dp-udmabuf4 {
                compatible  = "ikwzm,udmabuf-0.10.a";
                device-name = "udmabuf4";
                size = <0x02000000>;
            };
        };
    };
};


cam_displayport_27_190205.png

デバイスツリーのコンパイル用スクリプトの dtc_script.sh を作成した。
dtc_script.sh を示す。

#!/bin/bash

dtc -I dts -O dtb -o fpga-load.dtb fpga-load.dts
dtc -I dts -O dtb -o fclk01-zynqmp.dtb fclk01-zynqmp.dts
dtc -I dts -O dtb -o cam_dp.dtb cam_dp.dts


./dtc_script.sh を起動して、dtb ファイルを作成した。
cam_displayport_28_190205.png

cam_displayport_29_190205.png

デバイスツリーのロード用スクリプト lddtovary.sh と削除用スクリプトの rmdtovary.sh を作成した。
lddtovary.sh を示す。

!/bin/bash

sudo mkdir /config/device-tree/overlays/fpga
sudo cp fpga-load.dtb /config/device-tree/overlays/fpga/dtbo
sudo mkdir /config/device-tree/overlays/fclk01-zynqmp
sudo cp fclk01-zynqmp.dtb /config/device-tree/overlays/fclk01-zynqmp/dtbo
sudo mkdir /config/device-tree/overlays/cam_dp
sudo cp cam_dp.dtb /config/device-tree/overlays/cam_dp/dtbo

sleep 0.5
sudo chmod 666 /dev/uio*
sudo chmod 666 /dev/udmabuf4


rmdtovary.sh を示す。

#!/bin/bash

sudo rmdir /config/device-tree/overlays/cam_dp/
sudo rmdir /config/device-tree/overlays/fclk01-zynqmp
sudo rmdir /config/device-tree/overlays/fpga/


./lddtovary.sh を起動した。
cam_displayport_30_190205.png

./lddtovary.sh を起動したときのシリアルポートの出力を示す。
cam_displayport_31_190205.png
  1. 2019年02月08日 04:27 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

Zynq UltraScale+ MPSoC のDisplayPort のLiveVideo のピクセルデータ

どうやらZynq UltraScale+ MPSoC のDisplayPort のLiveVideo のピクセルデータの色のビットフィールドが間違っていたようだ。

その証拠に、テスト・パターン生成回路 pattern_gen_axis が生成していたテスト・パターンは下図のような画像なのだが、
HLS_Disp_Cont_22_150607.jpg

Ultra96のDisplayPortを使用するためのプロジェクトを作成する5(HD解像度のテストパターン)”で表示されたテスト・パターンはこれだった。
DisplayPort_test_121_19027.jpg

どうもテスト・パターンが表示されたことで安心してしまい、色が違っていることに気が付かなかった。
これを比べると、Red がBlue にGreen がRed に、そして、Blue がGreen に変更されている。つまり、LiveVideo のビット・フィールドはRGB ではなくBRG となっているようだ。

Zynq UltraScale+ Device Technical Reference Manual UG1085 (v1.9) January 17, 2019”の931 ページの Table 33-3: Live Video Format を引用する。
cam_displayport_43_190207.png

これによると、ビット・フィールドはRGB のはずなのだが。。。実際はBRG のようだ。

従って、axis2video_out IP のVerilog HDL コードを修正する必要がある。具体的には、

assign disp_pixel = {pfifo_dout[23:16], 4'd0, pfifo_dout[15:8], 4'd0, pfifo_dout[7:0], 4'd0};

assign disp_pixel = {pfifo_dout[7:0], 4'd0, pfifo_dout[23:16], 4'd0, pfifo_dout[15:8], 4'd0}; //BRG

に修正する。
  1. 2019年02月07日 05:14 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

カメラ画像をDisplayPortに出力する7(ブロックデザインの変更)

カメラ画像をDisplayPortに出力する7(binファイルの生成)”の続き。

前回は、ハードウェアをエクスポートして、SDK を立ち上げてbin ファイルを生成した。今回は、Ultra96 のDebian 上で動作するC 言語のアプリケーション・ソフトを作っていたところ、display 側の disp_dmar_axis IP がフレームバッファのアドレスを設定する前に動作する可能性があることがわかった。そこで、 disp_dmar_axis IP を起動する axis2video_out IP の init_done を制御する axi_gpio_0 を挿入することにした。更に active_frame もプロセッサが知る必要があるということで、axi_gpio_1 も追加することにした。

新しい cam_dp ブロックデザインを示す。active_frame の値を入力する axi_gpio_1 が追加されている。
cam_displayport_42_190206.png

camera 階層を示す。
cam_displayport_37_190206.png

display 階層を示す。 axi_gpio_0 を追加した。
cam_displayport_37_190206.png

Address Editor を示す。
cam_displayport_39_190206.png

論理合成、インプリメンテーション、ビットストリームの生成を行った。結果を示す。
cam_displayport_40_190206.png
cam_displayport_41_190206.png

ハードウェアをエクスポートして、SDK を立ち上げてbin ファイルを生成した。
  1. 2019年02月06日 04:29 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

カメラ画像をDisplayPortに出力する7(binファイルの生成)

カメラ画像をDisplayPortに出力する6(Vivado プロジェクト)”の続き。

前回は、使用するIP が揃ったので、Vivado 2018.3 でプロジェクトを作成し、論理合成、インプリメンテーション、ビットストリームの生成を行った。今回は、ハードウェアをエクスポートして、SDK を立ち上げてbin ファイルを生成した。

前回は、Vivado 2018.3 でビットストリームの生成ができたところからのスタートなので、まずはハードウェアをエクスポートして、HDF ファイルを生成した。
次にSDK を立ち上げてcam_dp_wrapper_hw_platform_0 ディレクトリが生成された。
cam_dp_wrapper_hw_platform_0 ディレクトリには、cam_dp_wrapper.bit が生成されている。
cam_displayport_32_190205.png

cam_dp_wrapper_hw_platform_0 ディレクトリの cam_dp_wrapper.bit を cam_dp_183.sdk ディレクトリにコピーした。

cam_dp_wrapper.bif を作成した。

all:
{
    [destination_device = pl] cam_dp_wrapper.bit
}


bin ファイルを作成するためのスクリプトの bootgen.sh を作成した。

#!/bin/bash
bootgen -image cam_dp_wrapper.bif -arch zynqmp -w -o cam_dp_wrapper.bin


./bootgen.sh で起動すると、cam_dp_wrapper.bin が生成された。
cam_displayport_26_190205.png

cam_displayport_33_190205.png
  1. 2019年02月05日 04:42 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

カメラ画像をDisplayPortに出力する6(Vivado プロジェクト)

カメラ画像をDisplayPortに出力する5(disp_dmar_aixs の2)”の続き。

前回は、Read 側のDMA の disp_dmar_axis IP のC シミュレーション、C コードの合成、C/RTL 協調シミュレーション、Export RTL を行った。今回は、使用するIP が揃ったので、Vivado 2018.3 でプロジェクトを作成しよう。

(2019/02/06 :修正)ブロックデザインを変更しました。詳しくは、”カメラ画像をDisplayPortに出力する7(ブロックデザインの変更)”をご覧ください。

Vivado 2018.3 で、cam_dp プロジェクトを作成した。
cam_displayport_20_190204.png

cam_dp ブロックデザインを生成した。階層デザインにして、camera 階層と display 階層を作った。
cam_displayport_21_190204.png

camera 階層がこれだ。
cam_displayport_22_190204.png

display 階層。
cam_displayport_23_190204.png

Address Editor を示す。
cam_displayport_26_190204.png

制約ファイルの cam_dp.xdc を示す。

set_property PACKAGE_PIN G7 [get_ports pclk]
set_property PACKAGE_PIN G6 [get_ports {cam_data[7]}]
set_property PACKAGE_PIN D5 [get_ports {cam_data[6]}]
set_property PACKAGE_PIN E6 [get_ports {cam_data[5]}]
set_property PACKAGE_PIN C7 [get_ports {cam_data[4]}]
set_property PACKAGE_PIN E5 [get_ports {cam_data[3]}]
set_property PACKAGE_PIN B6 [get_ports {cam_data[2]}]
set_property PACKAGE_PIN D6 [get_ports {cam_data[1]}]
set_property PACKAGE_PIN C5 [get_ports {cam_data[0]}]


set_property PACKAGE_PIN G5 [get_ports href]
set_property PACKAGE_PIN F7 [get_ports standby]
set_property PACKAGE_PIN F8 [get_ports vsync]
set_property PACKAGE_PIN A7 [get_ports xck]

set_property PACKAGE_PIN D7 [get_ports iic_rtl_scl_io]
set_property PACKAGE_PIN F6 [get_ports iic_rtl_sda_io]

create_clock -period 13.700 -name pclk -waveform {0.000 6.850} [get_ports pclk]
set_input_delay -clock [get_clocks pclk] 10.800 [get_ports {{cam_data[0]} {cam_data[1]} {cam_data[2]} {cam_data[3]} {cam_data[4]} {cam_data[5]} {cam_data[6]} {cam_data[7]} href pclk vsync}]

set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets pclk_IBUF_inst/O]

set_property IOSTANDARD LVCMOS18 [get_ports {cam_data[7]}]
set_property IOSTANDARD LVCMOS18 [get_ports {cam_data[6]}]
set_property IOSTANDARD LVCMOS18 [get_ports {cam_data[5]}]
set_property IOSTANDARD LVCMOS18 [get_ports {cam_data[4]}]
set_property IOSTANDARD LVCMOS18 [get_ports {cam_data[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {cam_data[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {cam_data[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {cam_data[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports pclk]
set_property IOSTANDARD LVCMOS18 [get_ports href]
set_property IOSTANDARD LVCMOS18 [get_ports standby]
set_property IOSTANDARD LVCMOS18 [get_ports vsync]
set_property IOSTANDARD LVCMOS18 [get_ports xck]

set_property IOSTANDARD LVCMOS18 [get_ports iic_rtl_scl_io]
set_property IOSTANDARD LVCMOS18 [get_ports iic_rtl_sda_io]

set_false_path -from [get_clocks clk_pl_0] -to [get_clocks pclk]
set_false_path -from [get_clocks pclk] -to [get_clocks clk_pl_0]

create_clock -period 6.734 -name disp_clk -waveform {0.000 3.367} [get_pins cam_dp_i/zynq_ultra_ps_e_0/dp_video_ref_clk]

set_false_path -from [get_clocks clk_pl_0] -to [get_clocks disp_clk]
set_false_path -from [get_clocks disp_clk] -to [get_clocks clk_pl_0]


論理合成、インプリメンテーション、ビットストリームの生成を行った。結果を示す。
cam_displayport_24_190204.png
cam_displayport_25_190204.png
  1. 2019年02月04日 05:30 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

カメラ画像をDisplayPortに出力する5(disp_dmar_aixs の2)

カメラ画像をDisplayPortに出力する4(disp_dmar_aixs の1)”の続き。

前回は、Read 側のDMA の disp_dmar_axis IP のコードを貼った。今回は、C シミュレーション、C コードの合成、C/RTL 協調シミュレーション、Export RTL を行う。

最初に、C シミュレーションから行った。
cam_displayport_10_190202.png

dmar_result.bmp が生成されている。
cam_displayport_13_190202.png

これで問題ない。

次に、C コードの合成を行った。結果を示す。
cam_displayport_11_190202.png
cam_displayport_12_190202.png

問題なさそうだ。

disp_dmar_fb1 のインスタンスを表示した。
cam_displayport_19_190202.png

C/RTL 協調シミュレーションを行った。
cam_displayport_14_190202.png

483622 / 480000 ≒ 1.01 クロック/ピクセルなので性能的には問題なさそうだ。

C/RTL 協調シミュレーションの波形を示す。
cam_displayport_15_190202.png

拡大してみよう。
cam_displayport_16_190202.png

outs_TVALID と outs_TREADY を見ると、どちらもほとんど 1 にアサートされているので、スループット的には問題なさそうだ。

もっと拡大してみよう。
cam_displayport_17_190202.png

Export RTL を行った。
cam_displayport_18_190202.png

CP achieved post-implementation は 3.018 ns で問題なさそうだ。
  1. 2019年02月03日 06:15 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0

カメラ画像をDisplayPortに出力する4(disp_dmar_aixs の1)

カメラ画像をDisplayPortに出力する3(vflip_dma_write2 の2)”の続き。

前回は、vflip_dma_write2 プロジェクトで、C シミュレーション、C コードの合成、C/RTL 協調シミュレーション、Export RTL を行った。今回は、Read 側のDMA の disp_dmar_axis IP を作成しよう。

まずは、ソースコードを貼っておく。

disp_dmar_axis.h から貼っておく。

// disp_dmar_axis.h
// 2019/02/01 by marsee
//

#ifndef __DISP_DMAR_AXIS_H__
#define __DISP_DMAR_AXIS_H__

#include "ap_axi_sdata.h"
#include "hls_video.h"

#define SVGA_WIDTH 800
#define SVGA_HEIGHT 600

#define XGA_WIDTH 1024
#define XGA_HEIGHT 768

#define HD_WIDTH 1920
#define HD_HEIGHT 1080

#define RESO_SVGA 0
#define RESO_XGA 1
#define RESO_HD  2

typedef hls::stream<ap_axiu<32,1,1,1> > AXI_STREAM;
typedef ap_axiu<32,1,1,1> AP_AXIU32;
typedef hls::Scalar<3, unsigned char> RGB_PIXEL;
typedef hls::Mat<HD_HEIGHT, HD_WIDTH, HLS_8UC3> RGB_IMAGE;
typedef hls::Mat<HD_HEIGHT, HD_WIDTH, HLS_8UC1> GRAY_IMAGE;

#endif


disp_dmar_axis.cpp を貼っておく。

// disp_dmar_axis.cpp
// 2019/02/01 by marsee
//

#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>

#include "disp_dmar_axis.h"

int disp_dmar_fb0(volatile ap_int<32> *fb0, AXI_STREAM &outs, int max_width, int max_height);
int disp_dmar_fb1(volatile ap_int<32> *fb1, AXI_STREAM &outs, int max_width, int max_height);
int disp_dmar_fb2(volatile ap_int<32> *fb2, AXI_STREAM &outs, int max_width, int max_height);

int disp_dmar_axis(volatile ap_int<32> *fb0, volatile ap_int<32> *fb1, volatile ap_int<32> *fb2,
        AXI_STREAM &outs, ap_uint<32> &resolution, ap_uint<2> &active_frame){
#pragma HLS INTERFACE ap_ctrl_hs port=return
#pragma HLS INTERFACE ap_none port=active_frame
#pragma HLS INTERFACE s_axilite port=resolution
#pragma HLS INTERFACE axis register both port=outs
#pragma HLS INTERFACE m_axi depth=480000 port=fb2 offset=slave
#pragma HLS INTERFACE m_axi depth=480000 port=fb1 offset=slave
#pragma HLS INTERFACE m_axi depth=480000 port=fb0 offset=slave

    AP_AXIU32 pix;
    int max_width, max_height;

    switch((int)resolution){
        case 0: // SVGA
            max_width = SVGA_WIDTH;
            max_height = SVGA_HEIGHT;
            break;
        case 1: // XGA
            max_width = XGA_WIDTH;
            max_height = XGA_HEIGHT;
            break;
        default: // HD
            max_width = HD_WIDTH;
            max_height = HD_HEIGHT;
            break;
    }

    if (active_frame == (ap_uint<2>)0)
        disp_dmar_fb2(fb2, outs, max_width, max_height);
    else if (active_frame == (ap_uint<2>)1)
        disp_dmar_fb0(fb0, outs, max_width, max_height);
    else
        disp_dmar_fb1(fb1, outs, max_width, max_height);
    return(0);
}

int disp_dmar_fb0(volatile ap_int<32> *fb0, AXI_STREAM &outs, int max_width, int max_height){
    AP_AXIU32 pix;

    LOOP_Y0: for (int y=0; y<max_height; y++){
#pragma HLS LOOP_TRIPCOUNT min=600 max=1080 avg=768
        LOOP_X0: for (int x=0; x<max_width; x++){
#pragma HLS LOOP_TRIPCOUNT min=800 max=1920 avg=1024
#pragma HLS PIPELINE II=1
            pix.data = fb0[(y*max_width)+x];

            if (x==0 && y==0)
                pix.user = 1;
            else
                pix.user = 0;

            if (x == max_width-1)
                pix.last = 1;
            else
                pix.last = 0;

            outs << pix;
        }
    }
    return(0);
}

int disp_dmar_fb1(volatile ap_int<32> *fb1, AXI_STREAM &outs, int max_width, int max_height){
    AP_AXIU32 pix;

    LOOP_Y1: for (int y=0; y<max_height; y++){
#pragma HLS LOOP_TRIPCOUNT min=600 max=1080 avg=768
        LOOP_X1: for (int x=0; x<max_width; x++){
#pragma HLS LOOP_TRIPCOUNT min=800 max=1920 avg=1024
#pragma HLS PIPELINE II=1
            pix.data = fb1[(y*max_width)+x];

            if (x==0 && y==0)
                pix.user = 1;
            else
                pix.user = 0;

            if (x == max_width-1)
                pix.last = 1;
            else
                pix.last = 0;

            outs << pix;
        }
    }
    return(0);
}

int disp_dmar_fb2(volatile ap_int<32> *fb2, AXI_STREAM &outs, int max_width, int max_height){
    AP_AXIU32 pix;

    LOOP_Y2: for (int y=0; y<max_height; y++){
#pragma HLS LOOP_TRIPCOUNT min=600 max=1080 avg=768
        LOOP_X2: for (int x=0; x<max_width; x++){
#pragma HLS LOOP_TRIPCOUNT min=800 max=1920 avg=1024
#pragma HLS PIPELINE II=1
            pix.data = fb2[(y*max_width)+x];

            if (x==0 && y==0)
                pix.user = 1;
            else
                pix.user = 0;

            if (x == max_width-1)
                pix.last = 1;
            else
                pix.last = 0;

            outs << pix;
        }
    }
    return(0);
}


disp_dmar_axis_tb.cpp を貼っておく。

// disp_dmar_axis_tb.cpp
// 2019/02/01 by marsee
//

#include <ap_int.h>
#include <hls_stream.h>
#include <iostream>
#include <fstream>
#include "hls_opencv.h"

#include "disp_dmar_axis.h"

int disp_dmar_axis(volatile ap_int<32> *fb0, volatile ap_int<32> *fb1, volatile ap_int<32> *fb2,
        AXI_STREAM &outs, ap_uint<32> &resolution, ap_uint<2> &active_frame);

#define NUM_FRAME_BUFFER 3
#define FB_NUMBER 0

int main(){
    using namespace cv;

    AXI_STREAM outs;
    AP_AXIU32 pix;
    ap_uint<32> *frame_buffer;
    
    // OpenCV で 画像を読み込む
    Mat src = imread("bmp_file0.bmp");

    // 画像をセーブするメモリをアロケート
    if ((frame_buffer =(ap_uint<32> *)malloc(NUM_FRAME_BUFFER * sizeof(ap_int<32>) * (src.cols * src.rows))) == NULL){
        fprintf(stderr, "Can't allocate frame_buffer0 ~ 2\n");
        exit(1);
    }
    
    // Mat フォーマットからフレームバッファに画像をロード
    Mat_<Vec3b> src_vec3b = Mat_<Vec3b>(src);
    for(int i=0; i<NUM_FRAME_BUFFER; i++){
        for(int y=0; y<src.rows; y++){
            for(int x=0; x<src.cols; x++){
                Vec3b pixel;
                pixel = src_vec3b(y,x);
                int rgb = ((int)(pixel(2))<<16) + ((int)(pixel(1))<<8) + pixel(0);
                frame_buffer[(src.cols*src.rows)*i + (src.cols*y) + x] = rgb;
            }
        }
    }
    
    ap_uint<2> fb_number = FB_NUMBER;
    ap_uint<32> resolution = RESO_SVGA;
    disp_dmar_axis((volatile ap_int<32> *)frame_buffer,
        (volatile ap_int<32> *)&frame_buffer[src.cols * src.rows],
        (volatile ap_int<32> *)&frame_buffer[2 * (src.cols * src.rows)],
        outs, resolution, fb_number);
        
    // AXI4 Stream から Mat フォーマットに変換しファイルに書き込み
    Mat dst(src.rows, src.cols, CV_8UC3);
    Mat_<Vec3b> dst_vec3b = Mat_<Vec3b>(dst);
    for(int y=0; y<dst.rows; y++){
        for(int x=0; x<dst.cols; x++){
            outs >> pix;
            int rgb = pix.data;
            //int rgb = frame_buffer[(src.cols*y) + x];
            Vec3b pixel;
            pixel[0] = (rgb & 0xff); // blue
            pixel[1] = (rgb & 0xff00) >> 8; // green
            pixel[2] = (rgb & 0xff0000) >> 16; // red
            dst_vec3b(y,x) = pixel;
        }
    }

    imwrite("dmar_result.bmp", dst);
    
    free(frame_buffer);
    return(0);
}


Vivado HLS 2018.3 で disp_dmar_axis プロジェクトを作成した。
cam_displayport_9_190202.png
  1. 2019年02月02日 04:06 |
  2. Ultra96
  3. | トラックバック:0
  4. | コメント:0