ひでみのアイデア帳

くだらないことなんだけど、忘れないために・・・

ARM Compute Library

https://developer.arm.com/technologies/compute-library

Zynq向けにARM Compute Libraryをビルドしてみた。

$ git clone git://github.com/ARM-software/ComputeLibrary
$ cd ComputeLibrary
$ sudo apt install scons
$ scons debug=1 neon=1 opencl=0 arch=armv7a

そしたら、次のように"ERROR: Compiler not found"になりました。

そりゃ、クロスコンパイラを指定していないからエラーになるわな。

$ scons debug=1 neon=1 opencl=0 arch=armv7a
scons: Reading SConscript files ...
ERROR: Compiler not found
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build
scons: `.' is up to date.
scons: done building targets.

archで指定できるのは次の4つである。

armv7a、arm64-v8a、arm64-v8.2-a、x86

x86版ビルド

だったら、まず、x86版でもビルドしてみよう。

Intel CPUでビルドする場合はx86を指定して次のように実行する。

たぶん、ライブラリを試すようなんだと思う。

% scons debug=1 neon=0 opencl=0 arch=x86

ビルドすると次のようにライブラリが出来上がる。

$ ls build/
libarm_compute-static.a  libarm_compute_core-static.a  src
libarm_compute.so        libarm_compute_core.so

どうやってクロスコンパイルすればいい?

とりあえず、ヘルプを見る。

$ scons --help
scons: Reading SConscript files ...
ERROR: Compiler not found
scons: done reading SConscript files.

debug: Debug (default=0) (0|1)
    default: 0
    actual: 0

asserts: Enable asserts (This flag is forced to 1 for debug=1) (default=0) (0|1)
    default: 0
    actual: 0

arch: Target Architecture (default=armv7a) (armv7a|arm64-v8a|arm64-v8.2-a|x86)
    default: armv7a
    actual: armv7a

os: Target OS (default=linux) (linux|android|bare_metal)
    default: linux
    actual: linux

build: Build type: (default=cross_compile) (native|cross_compile)
    default: cross_compile
    actual: cross_compile

Werror: Enable/disable the -Werror compilation flag (Default=1) (0|1)
    default: 1
    actual: 1

opencl: Enable OpenCL support(Default=1) (0|1)
    default: 1
    actual: 1

neon: Enable Neon support(Default=0) (0|1)
    default: 0
    actual: 0

embed_kernels: Embed OpenCL kernels in library binary(Default=0) (0|1)
    default: 0
    actual: 0

Use scons -H for help about command-line options.

どうも、ヘルプは"-H"だったらしい・・・

$ scons -H
usage: scons [OPTION] [TARGET] ...

SCons Options:
  -b, -d, -e, -m, -S, -t, -w, --environment-overrides, --no-keep-going,
  --no-print-directory, --print-directory, --stop, --touch
                              Ignored for compatibility.
  -c, --clean, --remove       Remove specified targets and dependencies.
  -C DIR, --directory=DIR     Change to DIR before doing anything.
  --cache-debug=FILE          Print CacheDir debug info to FILE.
  --cache-disable, --no-cache
                              Do not retrieve built targets from CacheDir.
  --cache-force, --cache-populate
                              Copy already-built targets into the CacheDir.
  --cache-readonly            Do not update CacheDir with built targets.
  --cache-show                Print build actions for files from CacheDir.
  --config=MODE               Controls Configure subsystem: auto, force,
                                cache.
  -D                          Search up directory tree for SConstruct,
                                build all Default() targets.
  --debug=TYPE                Print various types of debugging information:
                                count, duplicate, explain, findlibs, includes,
                                memoizer, memory, objects, pdb, prepare,
                                presub, stacktrace, time.
  --diskcheck=TYPE            Enable specific on-disk checks.
  --duplicate=DUPLICATE       Set the preferred duplication methods. Must be
                                one of hard-soft-copy, soft-hard-copy,
                                hard-copy, soft-copy, copy
  -f FILE, --file=FILE, --makefile=FILE, --sconstruct=FILE
                              Read FILE as the top-level SConstruct file.
  -h, --help                  Print defined help message, or this one.
  -H, --help-options          Print this message and exit.
  -i, --ignore-errors         Ignore errors from build actions.
  -I DIR, --include-dir=DIR   Search DIR for imported Python modules.
  --implicit-cache            Cache implicit dependencies
  --implicit-deps-changed     Ignore cached implicit dependencies.
  --implicit-deps-unchanged   Ignore changes in implicit dependencies.
  --interact, --interactive   Run in interactive mode.
  -j N, --jobs=N              Allow N jobs at once.
  -k, --keep-going            Keep going when a target can't be made.
  --max-drift=N               Set maximum system clock drift to N seconds.
  --md5-chunksize=N           Set chunk-size for MD5 signature computation to
                                N kilobytes.
  -n, --no-exec, --just-print, --dry-run, --recon
                              Don't build; just print commands.
  --no-site-dir               Don't search or use the usual site_scons dir.
  --profile=FILE              Profile SCons and put results in FILE.
  -q, --question              Don't build; exit status says if up to date.
  -Q                          Suppress "Reading/Building" progress messages.
  --random                    Build dependencies in random order.
  -s, --silent, --quiet       Don't print commands.
  --site-dir=DIR              Use DIR instead of the usual site_scons dir.
  --stack-size=N              Set the stack size of the threads used to run
                                jobs to N kilobytes.
  --taskmastertrace=FILE      Trace Node evaluation to FILE.
  --tree=OPTIONS              Print a dependency tree in various formats: all,
                                derived, prune, status.
  -u, --up, --search-up       Search up directory tree for SConstruct,
                                build targets at or below current directory.
  -U                          Search up directory tree for SConstruct,
                                build Default() targets from local SConscript.
  -v, --version               Print the SCons version number and exit.
  --warn=WARNING-SPEC, --warning=WARNING-SPEC
                              Enable or disable warnings.
  -Y REPOSITORY, --repository=REPOSITORY, --srcdir=REPOSITORY
                              Search REPOSITORY for source and target files.

あぁ、ヘルプ見てもどうやってクロスコンパイルするかわからなかった。

sconsを調べてみた

sconsというmake?、autotools?のようなビルドツールを使っているけど使うのは初めてなのでまず、調査から・・・

"SConstruct"というファイルを読み込んでビルドしていくらしい。

ARM Compute LibraryのSConstructは下記の一行が有効な行だった。

sconscriptを読めってか?

SConscript('sconscript', variant_dir='build', duplicate=0)

Yocto Project環境でビルド

sconscriptの下記の部分を修正する。

修正前

if env['arch'] == 'armv7a':
    flags += ['-march=armv7-a','-mthumb','-mfpu=neon']

    if env['os'] in ['linux','bare_metal']:
        prefix = "arm-linux-gnueabihf-"
        flags += ['-mfloat-abi=hard']
    elif env['os'] == 'android':
        prefix = "arm-linux-androideabi-"
        flags += ['-mfloat-abi=softfp']

修正後

if env['arch'] == 'armv7a':
    flags += ['-march=armv7-a','-mthumb','-mfpu=neon']

    if env['os'] in ['linux','bare_metal']:
        prefix = "arm-poky-linux-gnueabi-"
        flags += ['-mfloat-abi=hard']
        flags += ['--sysroot=/opt/poky/2.2.1-zturn.sdsoc/sysroots/cortexa9hf-neon-poky-linux-gnueabi']
    elif env['os'] == 'android':
        prefix = "arm-linux-androideabi-"
        flags += ['-mfloat-abi=softfp']

それでPATHも通してビルドする。

$ export PATH=/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/:${PATH}
% scons debug=1 neon=1 opencl=0 arch=armv7a

どうも最後のldでエラーが出たみたい。

arm-poky-linux-gnueabi-g++ -o build/libarm_compute_core.so -shared build/src/core/AccessWindowAutoPadding.os build/src/core/AccessWindowStatic.os build/src/core/AccessWindowTranspose.os build/src/core/Error.os build/src/core/HOGInfo.os build/src/core/Helpers.os build/src/core/IAccessWindow.os build/src/core/IDistribution.os build/src/core/IDistribution1D.os build/src/core/IKernel.os build/src/core/ITensor.os build/src/core/MultiImageInfo.os build/src/core/PyramidInfo.os build/src/core/TensorInfo.os build/src/core/Utils.os build/src/core/Validate.os build/src/core/CPP/ICPPSimpleKernel.os build/src/core/CPP/kernels/CPPCornerCandidatesKernel.os build/src/core/CPP/kernels/CPPSortEuclideanDistanceKernel.os build/src/runtime/CPP/CPPScheduler.os build/src/core/NEON/kernels/NEAbsoluteDifferenceKernel.os build/src/core/NEON/kernels/NEAccumulateKernel.os build/src/core/NEON/kernels/NEActivationLayerKernel.os build/src/core/NEON/kernels/NEArithmeticAdditionKernel.os build/src/core/NEON/kernels/NEArithmeticSubtractionKernel.os build/src/core/NEON/kernels/NEBitwiseAndKernel.os build/src/core/NEON/kernels/NEBitwiseNotKernel.os build/src/core/NEON/kernels/NEBitwiseOrKernel.os build/src/core/NEON/kernels/NEBitwiseXorKernel.os build/src/core/NEON/kernels/NEBox3x3Kernel.os build/src/core/NEON/kernels/NECannyEdgeKernel.os build/src/core/NEON/kernels/NEChannelCombineKernel.os build/src/core/NEON/kernels/NEChannelExtractKernel.os build/src/core/NEON/kernels/NECol2ImKernel.os build/src/core/NEON/kernels/NEColorConvertKernel.os build/src/core/NEON/kernels/NEConvolutionKernel.os build/src/core/NEON/kernels/NEConvolutionLayerWeightsReshapeKernel.os build/src/core/NEON/kernels/NECumulativeDistributionKernel.os build/src/core/NEON/kernels/NEDepthConvertKernel.os build/src/core/NEON/kernels/NEDerivativeKernel.os build/src/core/NEON/kernels/NEDilateKernel.os build/src/core/NEON/kernels/NEErodeKernel.os build/src/core/NEON/kernels/NEFastCornersKernel.os build/src/core/NEON/kernels/NEFillArrayKernel.os build/src/core/NEON/kernels/NEFillBorderKernel.os build/src/core/NEON/kernels/NEFillInnerBorderKernel.os build/src/core/NEON/kernels/NEGEMMInterleave4x4Kernel.os build/src/core/NEON/kernels/NEGEMMLowpMatrixMultiplyKernel.os build/src/core/NEON/kernels/NEGEMMMatrixAccumulateBiasesKernel.os build/src/core/NEON/kernels/NEGEMMMatrixAdditionKernel.os build/src/core/NEON/kernels/NEGEMMMatrixMultiplyKernel.os build/src/core/NEON/kernels/NEGEMMTranspose1xWKernel.os build/src/core/NEON/kernels/NEGaussian3x3Kernel.os build/src/core/NEON/kernels/NEGaussian5x5Kernel.os build/src/core/NEON/kernels/NEGaussianPyramidKernel.os build/src/core/NEON/kernels/NEHOGDescriptorKernel.os build/src/core/NEON/kernels/NEHOGDetectorKernel.os build/src/core/NEON/kernels/NEHOGNonMaximaSuppressionKernel.os build/src/core/NEON/kernels/NEHarrisCornersKernel.os build/src/core/NEON/kernels/NEHistogramKernel.os build/src/core/NEON/kernels/NEIm2ColKernel.os build/src/core/NEON/kernels/NEIntegralImageKernel.os build/src/core/NEON/kernels/NELKTrackerKernel.os build/src/core/NEON/kernels/NEMagnitudePhaseKernel.os build/src/core/NEON/kernels/NEMeanStdDevKernel.os build/src/core/NEON/kernels/NEMedian3x3Kernel.os build/src/core/NEON/kernels/NEMinMaxLocationKernel.os build/src/core/NEON/kernels/NENonLinearFilterKernel.os build/src/core/NEON/kernels/NENonMaximaSuppression3x3Kernel.os build/src/core/NEON/kernels/NENormalizationLayerKernel.os build/src/core/NEON/kernels/NEPixelWiseMultiplicationKernel.os build/src/core/NEON/kernels/NEPoolingLayerKernel.os build/src/core/NEON/kernels/NERemapKernel.os build/src/core/NEON/kernels/NEScaleKernel.os build/src/core/NEON/kernels/NEScharr3x3Kernel.os build/src/core/NEON/kernels/NESobel3x3Kernel.os build/src/core/NEON/kernels/NESobel5x5Kernel.os build/src/core/NEON/kernels/NESobel7x7Kernel.os build/src/core/NEON/kernels/NESoftmaxLayerKernel.os build/src/core/NEON/kernels/NETableLookupKernel.os build/src/core/NEON/kernels/NEThresholdKernel.os build/src/core/NEON/kernels/NETransposeKernel.os build/src/core/NEON/kernels/NEWarpKernel.os -Lbuild -L. -Lbuild -L.
/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.1/real-ld: cannot find crti.o: No such file or directory
/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.1/real-ld: cannot find crtbeginS.o: No such file or directory
/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.1/real-ld: cannot find -lstdc++
/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.1/real-ld: cannot find -lm
/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.1/real-ld: cannot find -lgcc_s
/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.1/real-ld: cannot find -lc
/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.1/real-ld: cannot find -lgcc_s
/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.1/real-ld: cannot find crtendS.o: No such file or directory
/opt/poky/2.2.1-zturn.sdsoc/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.1/real-ld: cannot find crtn.o: No such file or directory
collect2: error: ld returned 1 exit status
scons: *** [build/libarm_compute_core.so] Error 1
scons: building terminated because of errors.

sconscriptoの次の行の下にLinker Flagを追加する。

    env.Append(CXXFLAGS=flags)

まぁ、こんな風にするんだろうなぁ。

    env.Append(CXXFLAGS=flags)

    # linker flags
    env.Append(LINKFLAGS = [
    '--sysroot=/opt/poky/2.2.1-zturn.sdsoc/sysroots/cortexa9hf-neon-poky-linux-gnueabi'
    ])

これでビルドできた。

$ ls build/
examples                 libarm_compute_core-static.a  neon_scale
libarm_compute-static.a  libarm_compute_core.so        src
libarm_compute.so        neon_convolution              test_helpers

ビルドできたからなんだってんだ?

試すのはまた後日にする。

今は技術書典向けの作業と他におもちゃがあって手がいっぱいなのだ。