文書の過去の版を表示しています。
目次
Installation on MacOS 12.3.1 Monterey in Dec. 2023
- Linuxにインストール際は以下のパッケージあたりが必要であるが、macOS の brew では開発用パッケージ (*-devel (RedHat Enterprise Linux 系)、 *-dev (Debian / Ubuntu 系)) がなく、本体のパッケージに同梱されているようだ。
- zstd
- libzstd-devel
- bzip2-devel
- python3-devel
- cmake
- これらのパッケージは AlmaLinux にインストールしたときに必要だったもの。参考: Installation on shoa-a/shoa-b in Oct. 2023
- 例えば、AlmaLinux で言うところの libzstd-devel というパッケージは zstd パッケージでよいらしい。 ( https://groups.google.com/g/sbcl-help-archive/c/6BJkp0sFn7U )
- とりあえず、以下のコマンドを実行して、NestDAQ のインストールを開始した。
$ brew install zstd bzip2 python cmake root
$ python3 --version Python 3.11.6 $ cmake --version cmake version 3.28.1 $ bzip2 --version bzip2, a block-sorting file compressor. Version 1.0.8, 13-Jul-2019. ... $ zstd --version *** Zstandard CLI (64-bit) v1.5.5, by Yann Collet *** $ root --version ROOT Version: 6.30/02
$ sysctl -n hw.ncpu 8
NestDAQ 本体のインストール
- 2023年12月31日(金)現在、NestDAQのインストール方法に関するドキュメントはいくつかある。本家の GitHub のリポジトリの以下のインストール方法が公式と思われるが、CMAKE_PREFIX_PATHの指定が不要なところもあり、新しめのインストール方法のメモを見るのが良さそう。
- インストールメモの原典は e50server01 のインストールログが存在している。このメモから多くのメモが派生した。
- このページは、RCNPの計算機クラスター saho-a/saho-b へのインストールメモ(Installation on shoa-a/shoa-b in Oct. 2023)をベースにした。
- SELinux は大抵問題を引き起こすので、切っておきたいが、macOS ではそういうのはない?
- さらに、一般に、DAQの開発段階では firewall は切っておきたいところ。動作テスト段階では切っておくのが良い。
redis のインストール
- git でソースをダウンロードしてコンパイル
$ mkdir -p $HOME/nestdaq/src $ cd $HOME/nestdaq/src $ git clone https://github.com/redis/redis.git $ cd redis $ git checkout -b 6.0.16 6.0.16 $ time make -j20 PREFIX=$HOME/nestdaq ... real 0m29.140s user 1m4.825s sys 0m14.634s $ make PREFIX=$HOME/nestdaq install
- 設定ファイルを $HOME/nestdaq/etc にコピー
$ mkdir $HOME/nestdaq/etc $ cp $HOME/nestdaq/src/redis/redis.conf $HOME/nestdaq/etc/
- daemon mode をオンにする。
$ emacs -nw $HOME/nestdaq/etc/redis.conf daemonize no | | | V V V #daemonize no daemonize yes
RedisTimeSeries をインストール
$ cd $HOME/nestdaq/src $ git clone --recursive https://github.com/RedisTimeSeries/RedisTimeSeries.git $ cd RedisTimeSeries $ git checkout -b v1.4.9 v1.4.9 $ time make ... real 0m7.395s user 0m17.047s sys 0m9.026s $ mkdir $HOME/nestdaq/lib $ cp $HOME/nestdaq/src/RedisTimeSeries/bin/macos-x64-release/redistimeseries.so $HOME/nestdaq/lib/
- まず、以下のエラーのエラーが出た。
$ time make deps/readies/mk/main:6: *** GNU Make version is too old. Aborting.. Stop $ which make /usr/bin/make $ make --version GNU Make 3.81 ...
which コマンドを打つと、/usr/bin/make を参照しているようなので、\$HOME/.bashrc に以下の行を追記した。
export PATH="/usr/local/opt/make/libexec/gnubin:$PATH"
を.bashrc に追記した。
$ source $HOME/.bashrc $ make --version GNU Make 4.4.1 ...
- make 時に -j2 オプションを指定すると、以下のエラーとなる。
$ time make -j2 make[1]: warning: -j0 forced in submake: resetting jobserver mode. Submodule path 'deps/RedisModulesSDK': checked out 'c0740b8209abae38775adc6f3fefe05a520be55b' Submodule path 'deps/readies': checked out '32e37e68f6ffa66f5a6e41cb37794147e84c38cb' ../deps/readies/mk/main:67: /Users/kobayash/nestdaq/src/RedisTimeSeries/deps/readies/mk/cfg: No such file or directory make[1]: *** No rule to make target '/Users/kobayash/nestdaq/src/RedisTimeSeries/deps/readies/mk/cfg'. Stop. make: *** [Makefile:31: build] Error 2 real 0m6.484s user 0m3.370s sys 0m1.615s
Boot をインストール
- Boost をダウンロードしてきてmake
$ cd $HOME/nestdaq/src $ git clone https://github.com/boostorg/boost.git $ cd boost $ git checkout -b boost-1.80.0 boost-1.80.0 $ time git submodule update --init --recursive ... real 6m55.410s user 2m27.709s sys 1m32.061s $ time ./bootstrap.sh ... real 1m0.161s user 0m52.336s sys 0m5.457s $ time ./b2 install \ link=static,shared \ threading=single,multi \ cxxstd=17 \ variant=release,debug \ --layout=tagged \ -j6 \ --prefix=$HOME/nestdaq ... - zlib : yes [5] - bzip2 : yes [5] - lzma : yes [5] - zstd : yes [5] ... ...updated 21568 targets... real 27m49.572s user 90m49.187s sys 15m12.590s
ZeroMQをインストール
- ZeroMQ を持ってきてコンパイル
$ cd $HOME/nestdaq/src $ git clone https://github.com/zeromq/libzmq.git $ cd libzmq $ mkdir build $ cmake \ -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq \ -DCMAKE_CXX_STANDARD=17 \ -B ./build \ -S . $ cd build $ time make -j6 ... real 0m50.005s user 3m48.128s sys 0m34.792s $ make install
fmtlib をインストール
$ cd $HOME/nestdaq/src $ git clone https://github.com/fmtlib/fmt.git $ cd fmt $ mkdir build $ cmake \ -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq \ -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ -DCMAKE_CXX_STANDARD=17 \ -B build \ -S . $ cd build $ time make -j6 ... real 1m37.986s user 7m5.120s sys 0m12.524s $ make install
FairLogger をインストール
$ cd $HOME/nestdaq/src $ git clone https://github.com/FairRootGroup/FairLogger.git $ cd FairLogger $ mkdir build $ cmake \ -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq \ -DCMAKE_CXX_STANDARD=17 \ -DUSE_EXTERNAL_FMT=OFF \ -B build \ -S . $ cd build $ time make -j6 ... real 0m23.984s user 1m6.988s sys 0m2.763s $ make install
FairMQ をインストール
$ cd $HOME/nestdaq/src $ git clone https://github.com/FairRootGroup/FairMQ.git $ cd FairMQ $ git checkout -b v1.4.55 v1.4.55 $ mkdir build $ cmake \ -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq \ -DCMAKE_CXX_STANDARD=17 \ -DCMAKE_PREFIX_PATH="$HOME/nestdaq" \ -B build \ -S . $ cd build $ time make -j6 ... real 3m41.908s user 15m46.357s sys 0m43.298s $ make install
hiredis のインストール
$ cd $HOME/nestdaq/src $ git clone https://github.com/redis/hiredis.git $ cd hiredis $ time make PREFIX=$HOME/nestdaq install ... real 0m2.954s user 0m2.283s sys 0m0.428s
redis-plus-plus のインストール
$ cd $HOME/nestdaq/src $ git clone https://github.com/sewenew/redis-plus-plus.git $ cd redis-plus-plus $ mkdir build $ cmake \ -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_PREFIX_PATH=$HOME/nestdaq \ -DREDIS_PLUS_PLUS_CXX_STANDARD=17 \ -DREDIS_PLUS_PLUS_BUILD_TEST=OFF \ -B ./build \ -S . $ cd build $ time make -j6 install ... real 0m18.499s user 1m27.838s sys 0m5.375s
nestdaq のインストール
$ cd $HOME/nestdaq/src $ git clone https://github.com/spadi-alliance/nestdaq.git $ cd nestdaq $ mkdir build $ cmake \ -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq \ -DCMAKE_PREFIX_PATH=$HOME/nestdaq \ -B ./build \ -S . $ cd build $ time make -j6 install ...
redisinsight のインストール
- 最近は登録をしないとバイナリをダウンロードできないらしい。本家ページ https://redis.com/redis-enterprise/redis-insight/#insight-form で RedisInsight-mac-x64.dmg をダウンロード。
- 以下のウィンドウで Redisinsight をスライドさせてインストール。
スクリプトなどの設定
- run ディレクトリ作成
$ mkdir $HOME/run
- 初期設定ファイル nestdaq.sh を /home/nestdaq/run に作成
$ cd $HOME/run $ emacs nestdaq.sh
中身は以下。
#!/bin/bash export NESTDAQ=$HOME/nestdaq export PATH=$NESTDAQ/bin:$PATH
さらに、$HOME/.bashrc に以下の行を追記。
# For NestDAQ 2023.12.31 source $HOME/run/nestdaq.sh
- redis の立ち上げのためのファイル作成
$ cd $HOME/run $ emacs init.sh
中身は以下。
#!/bin/bash redis-server $NESTDAQ/etc/redis.conf --loadmodule $NESTDAQ/lib/redistimeseries.so #RIHOST=0.0.0.0 redisinsight-linux64 & #daq-webctl >& $NESTDAQ/log/daq-webctl.log & daq-webctl >& /dev/null &
- init.sh に実行権限を付与
$ chmod +x ./init.sh
- NestDAQ起動のためのスクリプトをコピー
$ cd $HOME/run $ cp $HOME/nestdaq/scripts/*.sh ./
NestDAQ 本体付属のサンプルを動かしてみる
- run ディレクトリに移動
cd $HOME/run
- .bashrcをソースし、init.sh を実行する。
$ source $HOME/.bashrc $ ./init.sh
もし間違って ./init.sh を複数回実行した場合、redis と daq-webctl のプロセスを殺す。プロセスの殺し方は色々あるが、
$ killall redis-server $ killall daq-webctl
とすれば、全部殺せる。このようなスクリプトを用意しておいても良いかも。または、init.sh を編集し、すでにプロセスが立ち上がっていたら新たに立ち上げないとか、既存のプロセスを殺してから立ち上げるとか、賢い感じに編集しても良い。
- これで Firefox などのブラウザを立ち上げ、http://localhost:8080/にアクセス
- web ブラウザ上で、 任意の Run Number を入力。初回起動時は最新のランナンバーがないと言われるが、それが正しい。
- tmux を立ち上げ、ウィンドウを分割。Ctl-b “ で上下方向分割、Ctl-b % で左右方向分割。ウィンドウ間の移動は Ctl-b o。emacs のショートカットに近いものに設定しても良い。
- tmux 上で画面を 4 分割くらいにして、以下のスクリプトを実行。
--------------------------------------- $ ./topology-1-1.sh ... --------------------------------------- $ ./start_device.sh Sampler --enable-uds false ... --------------------------------------- $ ./start_device.sh Sink --enable-uds false ... ---------------------------------------
- この状態で、DAQ Controller から、Initialize, Reset Task, Run とボタンを押すと、DAQがスタートする。
- DAQをストップする場合は、 Stop ボタンを押す。
nestdaq-user-impl のインストール
- まず、ROOTがインストールされている必要がある。インストールされていなければ、HomeBrew でインストールする。以下のコマンドを端末で打てば良い。
$ brew install root
- 試しにroot を実行。
$ root root ------------------------------------------------------------------ | Welcome to ROOT 6.30/02 https://root.cern | | ... | ------------------------------------------------------------------ root [0] TF1 * f = new TF1("f","sin(x)",0,10) (TF1 *) 0x7fbee9856540 root [1] f->Draw() Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1 <sin カーブが書かれる。> root [2] .q
- nestdaq-user-impl をコンパイル。
$ cd $HOME/nestdaq/src $ git clone https://github.com/spadi-alliance/nestdaq-user-impl.git $ cd nestdaq-user-impl $ mkdir build $ locate vdtMath.h /usr/local/Cellar/root/6.30.02_1/include/root/vdt/vdtMath.h $ cmake \ -DVDT_INCLUDE_DIR=/usr/local/Cellar/root/6.30.02_1/include/root \ -DVDT_LIBRARY=/usr/local/Cellar/root/6.30.02_1/lib/root \ -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq \ -DCMAKE_PREFIX_PATH=$HOME/nestdaq \ -B ./build \ -S . $ cd build $ time make -j6 install ...
ただし、これをすると /home/nestdaq/nestdaq/bin 内の nestdaq のインストール時に作られた実行形式ファイル Sampler や Sink が上書きされる。nestdaq の 実行形式ファイルと nestdaq-user-impl の実行形式ファイルを別々に扱うには、インストール場所を変えるなどの対策が必要 (-DCMAKE_INSTALL_PREFIX を変えるとか)。また、途中でvdtMath.h というファイルを locate コマンドで探し来てきている。このvdtMath.h があるディレクトリを cmake コマンド実行時のオプションとして与えないと、Troubleshooting にあるように、エラーとなる。ちなみに、locate コマンドのデータベースのアップデートは $ sudo /usr/libexec/locate.updatedbというコマンドを実行する。
nestdaq-user-impl (TFBFilePlayer - fltcoin - tfdump) の実行
- 五十嵐さんの以下のドキュメントを参考に、Data Replayer を動かしてみる。
$ cd $HOME/run $ wget http://www-online.kek.jp/~igarashi/nestdaq/run000408_00_stf.dat.gz $ wget http://www-online.kek.jp/~igarashi/nestdaq/run000410.dat.gz $ wget http://www-online.kek.jp/~igarashi/nestdaq/topo_player.sh $ gunzip run000408_00_stf.dat.gz $ gunzip run000410.dat.gz $ ls ... run000408_00_stf.dat run000410.dat ...
- redis-server と daq-webctl が立ち上がっているか ps コマンドで確認。立ち上がっていなかったら、init.sh を実行。
$ ps aux | grep redis $ ps aux | grep daq-webctl $ ./init.sh
- 五十嵐さんの topo_player.sh を実行。
$ chmod +x topo_plauer.sh $ ./topo_player.sh
- /hoem/nestdaq/run ディレクトリで tmux を立ち上げ、4分割 (Ctrl-b % と Ctrl-b ” を使う。パネル移動は Ctrl-b o。)し、FairMQ デバイスを立ち上げる。
<パネル 1> $ ./start_device.sh TFBFilePlayer --in-file run000410.dat <パネル 2> $ ./start_device.sh fltcoin <パネル 3> $ ./start_device.sh tfdump
- web ブラウザを立ち上げ、 http://localhost:8080 にアクセスしする。
- RUN number の New value: に任意の数字を入力し、 [ Send ] ボタンを押す。
- [Init Device and Connection] > [ Init Task ] > [ Run ] ボタンを順次押すと、実行される。
- DAQ のストップは [ Stop ] ボタンを押す。DAQ を終了する場合は、さらに [ Reset Task ], [ Reset Device ] を押す。
- FairMQデバイスも終了する場合は [ End ] ボタンを押す。
SlowDash のインストール
SlowDash テスト動作時のエラー
- \$ slowdash –port=18881 実行時のエラー
kobayash$ slowdash --port=18881 Traceback (most recent call last): File "/Users/kobayash/Dropbox/works/SlowDash/SlowDash-230501/system/server/slowdash.py", line 5, in <module> import sys, os, io, time, glob, json, yaml, logging, importlib ModuleNotFoundError: No module named 'yaml'
- pip コマンドで pyyaml をインストールすれば良い。
$ pip install pyyaml
- 最初、間違って pip install yaml とすると以下のメッセージが出た。
$ pip install yaml ERROR: Could not find a version that satisfies the requirement yaml (from versions: none) ERROR: No matching distribution found for yaml [notice] A new release of pip is available: 23.3.1 -> 23.3.2 [notice] To update, run: python3.11 -m pip install --upgrade pip
- \$ python3.11 -m pip install –ipgrade pip としてから、 \$ pip install pyyaml とした。
$ python3.11 -m pip install --upgrade pip Requirement already satisfied: pip in /usr/local/lib/python3.11/site-packages (23.3.1) Collecting pip Downloading pip-23.3.2-py3-none-any.whl.metadata (3.5 kB) Downloading pip-23.3.2-py3-none-any.whl (2.1 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 17.6 MB/s eta 0:00:00 Installing collected packages: pip Attempting uninstall: pip Found existing installation: pip 23.3.1 Uninstalling pip-23.3.1: Successfully uninstalled pip-23.3.1 Successfully installed pip-23.3.2 $ pip install pyyaml Collecting pyyaml Downloading PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl.metadata (2.1 kB) Downloading PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl (187 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 187.9/187.9 kB 3.8 MB/s eta 0:00:00 Installing collected packages: pyyaml Successfully installed pyyaml-6.0.1
SlowDash で Scalerから Redis に投げたヒストグラムなどを表示する
- SlowDash の Project 用のディレクトリを作成
$ mkdir $HOME/nestdaq/src/SlowDash-231226/Projects/Test_Redis_Histo $ cd $HOME/nestdaq/src/SlowDash-230608/Projects/Test_Redis_Histo
- SlowDash の SlowdashProject.yaml ファイルを作成
slowdash_project: name: RedisTest title: Redis Test, Simple version data_source: type: Redis parameters: url: redis://localhost:6379/ time_series: {db: 1} object: { db: 3 }
- ここに移動し、試しに起動。ただ、起動前に python の redis パッケージが必要だった。
$ pip install redis $ slowdash --port=18881
- python の redis モジュールがない時のエラーメッセージは以下。
* $ slowdash --port=18881 24-01-07 01:46:50 ERROR: unable to load datasource module: datasource_Redis: [Errno 2] No such file or directory: '/Users/kobayash/Dropbox/works/SlowDash/SlowDash-230501/system/plugin/datasource_Redis.py' 24-01-07 01:46:50 ERROR: Traceback (most recent call last): File "/Users/kobayash/Dropbox/works/SlowDash/SlowDash-230501/system/server/datasource.py", line 308, in load module = importlib.machinery.SourceFileLoader(modulename, filepath).load_module() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "<frozen importlib._bootstrap_external>", line 605, in _check_name_wrapper <省略> FileNotFoundError: [Errno 2] No such file or directory: '/Users/kobayash/Dropbox/works/SlowDash/SlowDash-230501/system/plugin/datasource_Redis.py' 24-01-07 01:46:50 ERROR: Unable to load data source: Redis listening at port 18881 ^CTerminated
- web ブラウザで http://localhost:18881 にアクセス。
Troubleshooting
- nestdaq 本体の cmake 時のエラー
$ cmake \ > -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq \ > -DCMAKE_PREFIX_PATH=$HOME/nestdaq \ > -B ./build \ > -S . -- The CXX compiler identification is AppleClang 13.1.6.13160021 -- The C compiler identification is AppleClang 13.1.6.13160021 -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- PROJECT_NAME: nestdaq c++ compiler ID is AppleClang turn on colored error message of Clang CMake Error at CMakeLists.txt:14 (add_compiler_options): Unknown CMake command "add_compiler_options". -- Configuring incomplete, errors occurred!
原因は CMakeLists.txt のタイポ。
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") message("turnn on colored error message of GNU") add_compile_options(-fdiagnostics-color=always) elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") message("turn on colored error message of Clang") add_compiler_options(-fcolor-diagnostics) endif()
で、 add_compiler_options(-fcolor-diagnostics) は add_compile_options(-fcolor-diagnostics) にすべし。
- nestdaq make 時のエラー
$ make [ 3%] Building CXX object plugins/CMakeFiles/FairMQPlugin_daq_service.dir/DaqServicePlugin.cxx.o In file included from /Users/kobayash/nestdaq/src/nestdaq/plugins/DaqServicePlugin.cxx:14: In file included from /Users/kobayash/nestdaq/include/boost/property_tree/json_parser.hpp:16: In file included from /Users/kobayash/nestdaq/include/boost/property_tree/json_parser/detail/read.hpp:13: /Users/kobayash/nestdaq/include/boost/property_tree/json_parser/detail/parser.hpp:29:43: warning: declaration shadows a field of 'source<Encoding, Iterator, Sentinel>' [-Wshadow] void set_input(const std::string& filename, const Range& r) ^ /Users/kobayash/nestdaq/include/boost/property_tree/json_parser/detail/parser.hpp:105:21: note: previous declaration is here std::string filename; ^ In file included from /Users/kobayash/nestdaq/src/nestdaq/plugins/DaqServicePlugin.cxx:23: In file included from /Users/kobayash/nestdaq/src/nestdaq/plugins/TopologyConfig.h:16: In file included from /Users/kobayash/nestdaq/src/nestdaq/plugins/DaqServicePlugin.h:22: In file included from /Users/kobayash/nestdaq/include/boost/asio.hpp:130: In file included from /Users/kobayash/nestdaq/include/boost/asio/ip/basic_resolver.hpp:30: In file included from /Users/kobayash/nestdaq/include/boost/asio/ip/basic_resolver_query.hpp:21: < Omitted > /Users/kobayash/nestdaq/src/nestdaq/plugins/DaqServicePlugin.cxx:706:83: warning: unused parameter 'ec' [-Wunused-parameter] fTimer->Start(fContext, fTtlUpdateInterval * 1000, [this](const auto& ec) { ^ /Users/kobayash/nestdaq/src/nestdaq/plugins/DaqServicePlugin.cxx:960:20: error: use of undeclared identifier 'program_invocation_name' fProcessName = program_invocation_name; ^ In file included from /Users/kobayash/nestdaq/src/nestdaq/plugins/DaqServicePlugin.cxx:23: In file included from /Users/kobayash/nestdaq/src/nestdaq/plugins/TopologyConfig.h:16: /Users/kobayash/nestdaq/src/nestdaq/plugins/DaqServicePlugin.h:125:10: warning: private field 'fStepByStep' is not used [-Wunused-private-field] bool fStepByStep{false}; ^ 5 warnings and 1 error generated. make[2]: *** [plugins/CMakeFiles/FairMQPlugin_daq_service.dir/build.make:76: plugins/CMakeFiles/FairMQPlugin_daq_service.dir/DaqServicePlugin.cxx.o] Error 1 make[1]: *** [CMakeFiles/Makefile2:195: plugins/CMakeFiles/FairMQPlugin_daq_service.dir/all] Error 2 make: *** [Makefile:136: all] Error 2
macOSでは、program_invocation_name は使えないらしい。plugins/DaqServicePlugin.cxx において以下の変更をする。
< 30 - 32 行目> // valid if _GNU_SOURCE is defined //extern char *program_invocation_name; //extern char *program_invocation_short_name; //extern char *__progname; // same as program_invocation_short_name
の 最後の行のコメントアウトを外す。
extern char *__progname; // same as program_invocation_short_name
さらに、960行目
fProcessName = program_invocation_name;
を
//fProcessName = program_invocation_name; fProcessName = __progname;
に変更。これでmake し直すと、ここのerror はなくなる。ちなみに、このコードは Ubuntu MATE 22.04.3 LTS でもコンパイルが通る。Ubuntu 22.04.3.LTS (gcc version 11.4.0) で STFBFilePlayer.cxx 内に以下のコードを書いて実行すると
// valid if _GNU_SOURCE is defined //extern char *program_invocation_name; //extern char *program_invocation_short_name; extern char *__progname; // same as program_invocation_short_name < Omitted > LOG(debug) << " __progname : " << __progname; LOG(debug) << " program_invocation_name : " << program_invocation_name; LOG(debug) << " program_invocation_short_name : " << program_invocation_short_name;
以下の結果になる。
[11:43:20][DEBUG] __progname : STFBFilePlayer [11:43:20][DEBUG] program_invocation_name : /home/nestdaq/nestdaq/bin/STFBFilePlayer [11:43:20][DEBUG] program_invocation_short_name : STFBFilePlayer
ちなみに、 Ubuntu MATE 22.04.3 では extern char *program_invocation_name; と extern char *program_invocation_short_name; の行がコメントアウトしていても問題ない。他の場所で定義されている模様。
- nestdaq make 時のエラー。
[ 6%] Building CXX object plugins/CMakeFiles/FairMQPlugin_daq_service.dir/TimeUtil.cxx.o /Users/kobayash/nestdaq/src/nestdaq/plugins/TimeUtil.cxx:25:12: error: no matching constructor for initialization of 'const std::pair<std::chrono::nanoseconds, std::chrono::system_clock::time_point>' (aka 'const pair<duration<long long, ratio<1LL, 1000000000LL>>, time_point<std::chrono::system_clock>>') return {uptimeNsec, (s + std::chrono::duration_cast<std::chrono::nanoseconds>(uptimeNsec))}; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__utility/pair.h:171:5: note: candidate constructor template not viable: no known conversion from 'time_point<[...], duration<[...], ratio<[...], __static_lcm<ratio<1, 1000000>::den, ratio<1, 1000000000>::den>::value aka 1000000000>>>' to 'const time_point<[...], duration<[...], ratio<[...], 1000000>>>' for 2nd argument pair(_T1 const& __t1, _T2 const& __t2) < Omitted >
このエラーは macOS の std::chrono::system_clock::duration の時間の単位が Linux でコンパイルした時と違うことに起因するエラー。具体的には、nestdaq/plugins/TimeUtil.cxx の以下のコードでエラーが起きている。
auto daq::service::update_date(const std::chrono::system_clock::time_point &s, const std::chrono::steady_clock::time_point &t) -> const std::pair<std::chrono::nanoseconds, std::chrono::system_clock::time_point> { auto uptimeNsec = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - t); return {uptimeNsec, (s + std::chrono::duration_cast<std::chrono::nanoseconds>(uptimeNsec))}; }
Linuxでは std::chrono::system_clock::duration はナノ秒単位 (std::chrono::system_clock::duration = std::chrono::nanoseconds) であり、masOS では std::chrono::system_clock::duration はマイクロ秒単位 (std::chrono::system_clock::duration = std::chrono::microseconds) で与えられる。戻り値のペアの2番目の要素 (s + std::chrono::duration_cast<std::chrono::nanoseconds>(uptimeNsec)) は std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> という time_point 型になっているが、戻り値は std::chrono::system_clock::time_point 型、別表記で std::chrono::time_point<std::chrono::system_clock, std::chrono::system_clock::duration> または std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>である必要があるため、不整合が起きている。そのため、解としては、
return {uptimeNsec, (s + std::chrono::duration_cast<std::chrono::nanoseconds>(uptimeNsec))};
の部分を
return {uptimeNsec, (s + std::chrono::duration_cast<std::chrono::system_clock::duration>(uptimeNsec))};
とするか、
return {uptimeNsec, (s + std::chrono::duration_cast<std::chrono::microseconds>(uptimeNsec))};
とするか、
return {uptimeNsec, std::chrono::time_point_cast <std::chrono::system_clock::duration> (s + uptimeNsec)};
とするか、
return {uptimeNsec, std::chrono::time_point_cast <std::chrono::microseconds> (s + uptimeNsec)};
とすれば良い。一番素直なのは、return {uptimeNsec, (s + std::chrono::duration_cast<std::chrono::nanoseconds>(uptimeNsec))};だと思うので、これに変更したい。ちなみに、std::chrono::system_clock::duration などの型の実体を確認するサンプルコードは NestDAQ C++ techniques を参照。
- make 時のエラー
[ 23%] Building CXX object plugins/CMakeFiles/FairMQPlugin_metrics.dir/MetricsPlugin.cxx.o /Users/kobayash/nestdaq/src/nestdaq/plugins/MetricsPlugin.cxx:172:30: error: no matching conversion for functional-style cast from 'std::chrono::nanoseconds' (aka 'duration<long long, ratio<1LL, 1000000000LL>>') to 'std::chrono::time_point<std::chrono::system_clock>' fCreatedTimeSystem = std::chrono::time_point<std::chrono::system_clock>(dur); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/chrono:1357:28: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'std::chrono::nanoseconds' (aka 'duration<long long, ratio<1LL, 1000000000LL>>') to 'const std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long long, std::ratio<1, 1000000>>>' for 1st argument class _LIBCPP_TEMPLATE_VIS time_point ^ < Omitted >
これは、TimeUtil.cxx のコンパイル時のエラーと同じ。std::chrono::system_clock::duration の型の不整合が原因。Linux でコンパイルは通るのに、macOSでコンパイルが通らないのは、std::chrono::system_clock::duration の型が Linux と macOSで違うため。エラーとなっているのは、nestdaq/plugins/MetricsPlugin.cxx の以下のコード
if (PropertyExists("created-time")) { auto t = GetProperty<int64_t>("created-time"); std::chrono::nanoseconds dur(t); fCreatedTimeSystem = std::chrono::time_point<std::chrono::system_clock>(dur); } else { fCreatedTimeSystem = std::chrono::system_clock::now(); } fCreatedTime = std::chrono::steady_clock::now();
の fCreatedTimeSystem = std::chrono::time_point<std::chrono::system_clock>(dur); の部分。 macOS の場合、system_clock の time_point はマイクロ秒で定義されるため、ナノ秒単位の dur からマイクロ秒の time_point に変換できない。そのため、dur をまずマイクロ秒に変換し、そのあと time_point に変換する必要がある。ちなみに、Linux では、system_clock::time_point はナノ秒単位で定義されるため、ナノ秒単位の経過時間 duration を直接 time_point に変換できる。というわけで、この行は以下のようにすれば、少なくともコンパイルは通る。
fCreatedTimeSystem = std::chrono::time_point<std::chrono::system_clock>(std::chrono::duration_cast<std::chrono::system_clock::duration>(dur));
ただ、そうすると、std::chrono::system_clock::time_point fCreatedTimeSystem に保持される値が macOS の場合、マイクロ秒単位かつマイクロ秒の精度となり、Linux の場合ナノ秒単位かつナノ秒の精度となる。つまり macOS と Linux で保持される値が異なることになる。もし macOS と Linux で経過時間を測定するときにナノ秒精度を保ちたい場合、コードを書き換える必要がある。具体的には軒並み以下のような変換をする必要がある。
std::chrono::system_clock::time_point --> std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> std::chrono::steady_clock::time_point --> std::chrono::time_point<std::chrono::steady_clock, std::chrono::nanoseconds>
これにより、time_point の精度はナノ秒になるが、一方で、macOS で std::chrono::system_clock::now() を使うとマイクロ秒単位の時刻を得ることになる。system_clockをナノ秒単位で得るにはどうすれば良いのだろう?std::chrono::high_resolution_clock::now() を使えば得られるが、それも手か?どのような実装が良いかどうかは高橋さんに聞いてみる必要がありそう。ちなみに、上記修正ののち、nestdaq本体付属の Sampler とSinkを走らせて、Redis に書き込まれた、metrics:last-update-nsをみると、以下のようになる。
127.0.0.1:6379[1]> hgetall metrics:last-update-ns 1) "Sampler-0" 2) "1706852752997102000" 3) "Sink-0" 4) "1706852752862944000"
ns に変換しているが、そもそも、macOS で std::chrono::system_clock::now()で時間情報を取ってきている限り、マイクロ秒精度で時間が与えられるので、これをナノ秒に変換すると、必ず最後が時間のカウントの数字の最後が 000 になる。
- make 時のリンクエラー
[ 6%] Linking CXX shared library libFairMQPlugin_daq_service.dylib Undefined symbols for architecture x86_64: "fair::mq::JSONParser(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from: daq::service::TopologyConfig::InitializeDefaultChannelProperties() in TopologyConfig.cxx.o "fair::mq::ProgOptions::SetProperties(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::any, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, boost::any> > > const&)", referenced from: fair::mq::PluginServices::SetProperties(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::any, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, boost::any> > > const&) in TopologyConfig.cxx.o "fair::mq::ProgOptions::DeleteProperty(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from: fair::mq::PluginServices::DeleteProperty(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in TopologyConfig.cxx.o "fair::mq::GetStateName(fair::mq::State)", referenced from: daq::service::Plugin::ResetTtl() in DaqServicePlugin.cxx.o daq::service::Plugin::Plugin(std::__1::basic_string_view<char, std::__1::char_traits<char> >, fair::mq::tools::Version const&, std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::basic_string_view<char, std::__1::char_traits<char> >, fair::mq::PluginServices*)::$_1::operator()(fair::mq::State) const in DaqServicePlugin.cxx.o "fair::mq::StateMachine::SubscribeToStateChange(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::function<void (fair::mq::State)>)", referenced from: fair::mq::Device::SubscribeToStateChange(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::function<void (fair::mq::State)>) in DaqServicePlugin.cxx.o "fair::mq::StateMachine::UnsubscribeFromStateChange(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from: < Omitted >
動的ライブラリ libFairMQPlugin_daq_service.dylib を作るときに、FairMQ や Boost のライブラリがリンクされず、このエラーが出る。具体的なリンクの状況を見るため make VERBOSE=1 としてコマンドを実行すると、以下のようになっている。
[ 3%] Linking CXX shared library libFairMQPlugin_daq_service.dylib cd /Users/kobayash/nestdaq/src/nestdaq/build/plugins && /usr/local/Cellar/cmake/3.28.1/bin/cmake -E cmake_link_script CMakeFiles/FairMQPlugin_daq_service.dir/link.txt --verbose=1 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -Wall -Wextra -Wshadow -Wfloat-equal -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -dynamiclib -Wl,-headerpad_max_install_names -o libFairMQPlugin_daq_service.dylib -install_name @rpath/libFairMQPlugin_daq_service.dylib CMakeFiles/FairMQPlugin_daq_service.dir/DaqServicePlugin.cxx.o CMakeFiles/FairMQPlugin_daq_service.dir/Timer.cxx.o CMakeFiles/FairMQPlugin_daq_service.dir/TopologyConfig.cxx.o CMakeFiles/FairMQPlugin_daq_service.dir/TimeUtil.cxx.o CMakeFiles/FairMQPlugin_daq_service.dir/tools.cxx.o -Wl,-rpath,/Users/kobayash/nestdaq/lib /Users/kobayash/nestdaq/lib/libhiredis.dylib /Users/kobayash/nestdaq/lib/libredis++.dylib Undefined symbols for architecture x86_64: "fair::mq::JSONParser(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from: daq::service::TopologyConfig::InitializeDefaultChannelProperties() in TopologyConfig.cxx.o < Omitted >
確かに、FairMQ や Boost のライブラリがリンカーの引数になく、リンクされていないことがわかる。ただ、Linux (Ubuntu 22.04.3 LTS) 上で make VERBOSE=1 とすると
[ 20%] Linking CXX shared library libFairMQPlugin_daq_service.so cd /home/nestdaq/nestdaq/src/nestdaq/build/plugins && /usr/bin/cmake -E cmake_link_script CMakeFiles/FairMQPlugin_daq_service.dir/link.txt --verbose=1 /usr/bin/c++ -fPIC -Wall -Wextra -Wshadow -Wfloat-equal -Wl,--enable-new-dtags -shared -Wl,-soname,libFairMQPlugin_daq_service.so -o libFairMQPlugin_daq_service.so CMakeFiles/FairMQPlugin_daq_service.dir/DaqServicePlugin.cxx.o CMakeFiles/FairMQPlugin_daq_service.dir/Timer.cxx.o CMakeFiles/FairMQPlugin_daq_service.dir/TopologyConfig.cxx.o CMakeFiles/FairMQPlugin_daq_service.dir/TimeUtil.cxx.o CMakeFiles/FairMQPlugin_daq_service.dir/tools.cxx.o -Wl,-rpath,/home/nestdaq/nestdaq/lib::::::::::::::: /home/nestdaq/nestdaq/lib/libhiredis.so /home/nestdaq/nestdaq/lib/libredis++.so make[2]: Leaving directory '/home/nestdaq/nestdaq/src/nestdaq/build'
となり、やはり FairMQ や Boost のライブラリがリンクされていない。実際、生成された libFairMQPlugin_daq_service.so ライブラリがリンクしているライブラリを ldd コマンドで確認すると、
$ ldd plugins/libFairMQPlugin_daq_service.so linux-vdso.so.1 (0x00007fffb4fd6000) libhiredis.so.1.2.1-dev => /home/nestdaq/nestdaq/lib/libhiredis.so.1.2.1-dev (0x00007f6c1594c000) libredis++.so.1 => /home/nestdaq/nestdaq/lib/libredis++.so.1 (0x00007f6c158b7000) libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f6c15678000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f6c15658000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6c1542f000) /lib64/ld-linux-x86-64.so.2 (0x00007f6c15c43000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6c15346000)
となり、リンクされていない。そういうものなんだろうか?高橋さんに聞いてみる。とにかく、解決方法としては、nestdaq/plugins/CMakeLists.txt を編集し、FariMQ, FairLogger, Boost のライブラリをリンクすれば良い。具体的には、各プラグインに対して、以下のように target_lini_directories を追加し、target_link_libraries に FariMQ, FairLogger, Boost のライブラリを追加する。
set(PLUGIN FairMQPlugin_metrics) < Omitted > target_link_directories(${PLUGIN} PRIVATE ${Boost_LIBRARY_DIRS}; ${FairMQ_LIBDIR}; ${FairLogger_LIBDIR}; ) target_link_libraries(${PLUGIN} ${CMAKE_THREAD_LIBS_INIT}; ${Boost_LIBRARIES}; FairMQ;FairMQTools;FairMQStateMachine;FairLogger; ${HIREDIS_LIB}; ${REDIS_PLUS_PLUS_LIB}; )
- nestdaq 実行時のエラー: [ERROR] Uncaught exception reached the top of main: An error occurred while instantiating plugin metrics: stoull: no conversion
$ ./start_device.sh Sampler BINDIR = /Users/kobayash/nestdaq/bin PLUGIN_LIBDIR = /Users/kobayash/nestdaq/lib PLUGIN_SEARCH_PATH = -S '</Users/kobayash/nestdaq/lib' DAQSERVICE_PLUGIN = -P daq_service METRICS_PLUGIN = -P metrics CONFIG_PLUGIN = -P parameter_config DAQSERVICE_URI = --registry-uri tcp://127.0.0.1:6379/0 METRICS_URI = --metrics-uri tcp://127.0.0.1:6379/1 CONFIG_URI = --parameter-config-uri tcp://127.0.0.1:6379/2 [16:49:54][INFO] ______ _ _______ _________ / ____/___ _(_)_______ |/ /_ __ \ version 1.4.55 / /_ / __ `/ / ___/__ /|_/ /_ / / / build RelWithDebInfo / __/ / /_/ / / / _ / / / / /_/ / https://github.com/FairRootGroup/FairMQ /_/ \__,_/_/_/ /_/ /_/ \___\_\ LGPL-3.0 © 2012-2022 GSI [16:49:54][STATE] Starting FairMQ state machine --> IDLE [16:49:54][DEBUG] Sampler : AmQ Emulator [16:49:54][DEBUG] PID: 13159 [16:49:54][DEBUG] Loaded plugin: 'daq_service', version '0.0.0', maintainer 'DAQService <maintainer@daq.service.net>', homepage 'https://github.com/spadi-alliance/nestdaq' [16:49:54][DEBUG] daq::service::Plugin() hello [16:49:54][DEBUG] cwd = /Users/kobayash/run [16:49:54][DEBUG] process : 13159 Sampler [16:49:54][DEBUG] daq::service::Plugin uuid = 60efe965-b24b-44d5-8424-df46fb3fc26c [16:49:54][DEBUG] find my ip address by network-interface [16:49:54][DEBUG] Detected network interface name for the default route: en0 [16:49:54][DEBUG] use default route NIC = en0 [16:49:54][DEBUG] ip = 192.168.0.7 [16:49:54][DEBUG] service name is empty. use process name (filename of executable) as service name [16:49:54][DEBUG] nic = en0, ip = 192.168.0.7 [16:49:54][DEBUG] nic = lo0, ip = 127.0.0.1 [16:49:54][INFO] daq::service::Plugin succeeded in TakeDeviceControl() [16:49:54][DEBUG] registry URI = tcp://127.0.0.1:6379/0 [16:49:54][DEBUG] got lock: 60efe965-b24b-44d5-8424-df46fb3fc26c [16:49:54][DEBUG] 'id' (instance id) is empty. calculate service-instance-index [16:49:54][DEBUG] number of expired uuids 0 [16:49:54][DEBUG] service instance-index: 0 for uuid = 60efe965-b24b-44d5-8424-df46fb3fc26c [16:49:54][DEBUG] unlock: 60efe965-b24b-44d5-8424-df46fb3fc26c [16:49:54][DEBUG] mq device id = Sampler-0, service = Sampler, hostname = kobamac01-2.local ip(from_hostname) = 127.0.0.1, 192.168.0.7 [16:49:54][DEBUG] (Register) id = Sampler-0, service = Sampler [16:49:54][DEBUG] precense (key) = daq_service:Sampler:Sampler-0:presence, presence (ttl) = 5 [16:49:54][DEBUG] thread start [16:49:54][DEBUG] timer start 3000 msec [16:49:54][DEBUG] daq::service::Plugin hset daq_service:Sampler:Sampler-0:health kobamac01-2.local 192.168.0.7 [16:49:54][DEBUG] daq::service::Plugin hset daq_service:Sampler:Sampler-0:option [16:49:54][DEBUG] daq::service::TopologyConfig top prefix = daq_service service = Sampler id = Sampler-0 separator = : max ttl = 5 [16:49:54][WARN] daq::service::Plugin SubscribeToDeviceStateChange() [16:49:54][DEBUG] daq::service::Plugin() done [16:49:54][DEBUG] daq::service::Plugin RunStartupSequence() [16:49:54][DEBUG] startup state = idle idle [16:49:54][DEBUG] create a sbuscriber. [16:49:54][DEBUG] Loaded plugin: 'metrics', version '0.0.0', maintainer 'Metrics <maintainer@daq.service.net>', homepage 'https://github.com/spadi-alliance/nestdaq' [16:49:54][DEBUG] daq::service::MetricsPlugin() hello metrics [16:49:54][DEBUG] daq::service::MetricsPlugin n cpu cores (logical) = 8 [16:49:54][DEBUG] Unloaded plugin: 'metrics', version '0.0.0', maintainer 'Metrics <maintainer@daq.service.net>', homepage 'https://github.com/spadi-alliance/nestdaq' [16:49:54][DEBUG] Shutting down Plugin Manager [16:49:54][WARN] daq::service::Plugin UnsubscribeFromDeviceStateChange() [16:49:54][DEBUG] daq::service::TopologyConfig Reset [16:49:54][DEBUG] daq::service::Plugin Unregister [16:49:54][DEBUG] redis : 3 deleted [16:49:54][DEBUG] delete redis hash. key = daq_service:service-instance-index:Sampler, field = 0 [16:49:54][DEBUG] ~daq::service::Plugin() bye [16:49:54][DEBUG] Unloaded plugin: 'daq_service', version '0.0.0', maintainer 'DAQService <maintainer@daq.service.net>', homepage 'https://github.com/spadi-alliance/nestdaq' [16:49:54][DEBUG] Shutting down Plugin Services [16:49:54][DEBUG] Shutting down device [16:49:54][STATE] Exiting FairMQ state machine [16:49:54][ERROR] Uncaught exception reached the top of main: An error occurred while instantiating plugin metrics: stoull: no conversion
stoull のエラーとなっているが、これは、nestdat/plugins/MetricsPlugins.cxx の MetricsPlugin::ReadProcSelfStat() 内の ret.utime = std::stoull(v[Utime]); でエラーが生じている。以下、問題となっているコードの抜粋。
//_____________________________________________________________________________ daq::service::ProcSelfStat_t daq::service::MetricsPlugin::ReadProcSelfStat() { if (!fProcSelfStatFile.is_open()) { fProcSelfStatFile.open("/proc/self/stat"); } std::string s; std::vector<std::string> v; std::getline(fProcSelfStatFile, s); // clear iostate flag and seek to the beginning of the file fProcSelfStatFile.clear(); fProcSelfStatFile.seekg(0); boost::split(v, s, boost::is_space()); //, boost::token_compress_on); ... ProcSelfStat_t ret; ret.utime = std::stoull(v[Utime]); ret.stime = std::stoull(v[Stime]); ret.vsize = std::stoull(v[Vsize]); ret.rss = std::stoull(v[Rss]); return ret; } //_____________________________________________________________________________ daq::service::ProcStat_t daq::service::MetricsPlugin::ReadProcStat() { //LOG(debug) << MyClass << " " << __FUNCTION__; if (!fProcStatFile.is_open()) { fProcStatFile.open("/proc/stat"); } std::string s; while (std::getline(fProcStatFile, s)) { if (s.find("cpu ")==0) { break; } } // clear iostate flag and seek to the beginning of the file fProcStatFile.clear(); fProcStatFile.seekg(0); std::vector<std::string> v; boost::trim_if(s, boost::is_space()); boost::split(v, s, boost::is_space(), boost::token_compress_on); ... ProcStat_t ret; ret.user = std::stoull(v[User]); ret.nice = std::stoull(v[Nice]); ret.system = std::stoull(v[System]); ret.idle = std::stoull(v[Idle]); return ret; }
ちなみに、原因の特定方法は、std::cout をいたるところに書いて、処理がどこまで進んでいるかを調べた。もっと良いデバッグ方法はあるのだろうか?このエラーであるが、大元の原因は、macOS では /proc/self/stat がないことが原因。そのため、macOS 用にコードを追加して、プリプロセッサーで以下のように条件分岐させた。
#ifdef __APPLE__ #include <mach/mach.h> daq::service::ProcSelfStat_t daq::service::MetricsPlugin::ReadProcSelfStat() ... daq::service::ProcStat_t daq::service::MetricsPlugin::ReadProcStat() ... #else // #ifdef __APPLE__ daq::service::ProcSelfStat_t daq::service::MetricsPlugin::ReadProcSelfStat() ... daq::service::ProcStat_t daq::service::MetricsPlugin::ReadProcStat() ... #endif // #ifdef __APPLE__
- nestdaq 本体付属の Sampler を start_device.sh で立ち上げ、 DAQ Controller 上 Init Device and Connection ボタンを押した時のエラー。
$ ./start_device.sh Sampler ... [13:42:40][DEBUG] Created socket Sampler-0.data[0].push [13:42:40][ERROR] Failed binding socket Sampler-0.data[0].push, address: ipc://@/tmp/nestdaq//Sampler/Sampler-0/data[0], reason: No such file or directory [13:42:40][ERROR] failed to attach channel data[0] (bind) [13:42:40][ERROR] 1 of the binding channels could not initialize. Initial configuration incomplete. [13:42:40][DEBUG] Exception caught in ProcessWork(), going to Error state [13:42:40][INFO] daq::service::Plugin state : ERROR [13:42:40][ERROR] daq::service::Plugin::SubscribeToDaqCommand: error in consume(): Controlled device transitioned to error state. ... [13:42:40][DEBUG] Unloaded plugin: 'metrics', version '0.0.0', maintainer 'Metrics <maintainer@daq.service.net>', homepage 'https://github.com/spadi-alliance/nestdaq' [13:42:40][DEBUG] Shutting down Plugin Services [13:42:40][DEBUG] Shutting down device Sampler-0 [13:42:40][STATE] Exiting FairMQ state machine [13:42:40][DEBUG] Destroying ZeroMQ transport... [13:42:40][ERROR] Uncaught exception reached the top of main: 1 of the binding channels could not initialmetrics -P parameter_config --registry- ize. Initial configuration incomplete.
Unix domain socket を使っていることによるエラーのように見える (ちなみに、このエラーになると、Sampler が落ち、daq-webctl もハングるようだ。killall daq-webctl コマンドでプロセスを殺す必要がありそう)。サーバーマシン一台で FairMQ デバイスを動かす場合、プロセス間通信として、デフォルトで Unix domain socket を使うことになった。ただ、macOS だと Unix domain socket を使うのに Linux と同じようには行かないようだ。そこで、 UNIX domain socket を使わず、ethernet ネットでデータを飛ばすことにする。これはオプションで切り替えできて、–enable-udsとすればよい。該当のコードは、nestdaq/plugins/DaqServicePlugin.cxx の定義部の
static constexpr std::string_view EnableUds{"enable-uds"};
と auto PluginProgramOptions() → fair::mq::Plugin::ProgOptions の
(EnableUds.data(), bpo::value<std::string>()->default_value("true"), "Use Unix Domain Socket for the local IPC if available (bool)")
に相当する。これより、start_device.sh Sampler とするときに、 以下のように enable-uds false というオプションを与えれば良い。
$ ./start_device.sh Sampler --enable-uds false
- nestdaq-user-impl の cmake 時に以下のエラーとなる。
$ cmake -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq -DCMAKE_PREFIX_PATH=$HOME/nestdaq -B ./build -S . -- PROJECT_NAME: nestdaq c++ compiler ID is AppleClang turn on colored error message of Clang CMAKE_CXX_FLAGS: -Wall -Wextra -Wshadow -Wfloat-equal -O3 CMAKE_CXX_FLAGS_DEBUG: -g CMAKE_CXX_FLAGS_RELWITHDEBINFO: -O2 -g -DNDEBUG CMAKE_CXX_FLAGS_RELEASE: -Ofast -DNDEBUG -march=native CMAKE_CXX_FLAGS_MINSIZEREL: -Os -DNDEBUG CMAKE_BUILD_TYPE: CMAKE_INSTALL_PREFIX: /Users/kobayash/nestdaq CMAKE_INSTALL_INCLUDEDIR: include CMAKE_INSTALL_LIBDIR: lib CMAKE_INSTALL_BINDIR: bin CMAKE_INSTALL_DATADIR: share -- Performing Test CMAKE_HAVE_LIBC_PTHREAD -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success -- Found Threads: TRUE CMAKE_EXE_LINKER_FLAGS: CMAKE_SHARED_LINKER_FLAGS: -- FairMQ found -- FairMQ_VERSION: 1.4.55 -- FairMQ_GIT_VERSION: 1.4.55 -- FairMQ_PACKAGE_DEPENDENCIES: Boost;FairLogger;Threads -- FairMQ_PACKAGE_COMPONENTS: -- FairMQ_PREFIX: /Users/kobayash/nestdaq -- FairMQ_BINDIR: /Users/kobayash/nestdaq/bin -- FairMQ_INCDIR: /Users/kobayash/nestdaq/include -- FairMQ_LIBDIR: /Users/kobayash/nestdaq/lib -- FairMQ_DATADIR: /Users/kobayash/nestdaq/share/fairmq -- FairMQ_CMAKEMODDIR: /Users/kobayash/nestdaq/share/fairmq/cmake -- FairMQ_BUILD_TYPE: RelWithDebInfo -- FairMQ_CXX_FLAGS: -fdiagnostics-color=always;-O2;-g;-Wshadow;-Wall;-Wextra;-Wpedantic;-DNDEBUG dep: Boost FairMQ_Boost_version: 1.66 FairMQ_Boost_COMPONENTS: container;program_options;filesystem;date_time;regex -- Found Boost: /Users/kobayash/nestdaq/lib/cmake/Boost-1.80.0/BoostConfig.cmake (found suitable version "1.80.0", minimum required is "1.66") found components: container program_options filesystem date_time regex iostreams thread dep: FairLogger FairMQ_FairLogger_VERSION: 1.6.0 dep: Threads FairMQ_Threads_VERSION: -- Boost_INCLUDE_DIRS: /Users/kobayash/nestdaq/include -- Boost_LIBRARY_DIRS: /Users/kobayash/nestdaq/lib -- Boost_LIBRARIES: Boost::container;Boost::program_options;Boost::filesystem;Boost::date_time;Boost::regex;Boost::iostreams;Boost::thread -- FairLogger_INCDIR: /Users/kobayash/nestdaq/include;/Users/kobayash/nestdaq/include/fairlogger/bundled -- fmt_INCDIR: /Users/kobayash/nestdaq/include/fairlogger/bundled -- Found nlohmann_json: /usr/local/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake (found suitable version "3.11.3", minimum required is "3.11.3") CMake Error at /usr/local/Cellar/cmake/3.28.1/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message): Could NOT find a (missing: VDT_INCLUDE_DIR VDT_LIBRARY) Call Stack (most recent call first): /usr/local/Cellar/cmake/3.28.1/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:600 (_FPHSA_FAILURE_MESSAGE) /usr/local/Cellar/root/6.30.02/share/root/cmake/modules/FindVdt.cmake:63 (find_package_handle_standard_args) /usr/local/Cellar/cmake/3.28.1/share/cmake/Modules/CMakeFindDependencyMacro.cmake:76 (find_package) /usr/local/share/root/cmake/ROOTConfig.cmake:132 (find_dependency) CMakeLists.txt:136 (find_package) -- Configuring incomplete, errors occurred!
よくわからないが、VDT_INCLUDE_DIR を設定するところでエラーになっているようで、cmake コマンド実行時に VDT_INCLUDE_DIR の値をオプションで与えると、エラーにならない。macOS の locate コマンドなどで、 vdtMath.h ファイルがどこにあるかを調べ、その情報を元に、cmake コマンドの引数にそのパスを与えれば良い。
$ localte vdtMath.h /usr/local/Cellar/root/6.30.02_1/include/root/vdt/vdtMath.h $ cmake -DVDT_INCLUDE_DIR=/usr/local/Cellar/root/6.30.02_1/include/root -DVDT_LIBRARY=/usr/local/Cellar/root/6.30.02_1/lib/root -DCMAKE_INSTALL_PREFIX=$HOME/nestdaq -DCMAKE_PREFIX_PATH=$HOME/nestdaq -B ./build -S .
これで cmake が通る。
- nestdaq-user-impl の make 時のエラー。
$ make -j6 ... [ 26%] Building CXX object utility/CMakeFiles/Utility.dir/TaskProcessorMT.cxx.o In file included from /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/program_options.cxx:7: /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/program_options.h:15:28: error: no template named 'unordered_map' in namespace 'std' const std::unordered_map<std::string, T> &defaultValues) ~~~~~^ /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/program_options.h:28:28: error: no template named 'unordered_map' in namespace 'std' const std::unordered_map<std::string, T> &defaultValues, const T &t) ~~~~~^ 2 errors generated. ... [ 28%] Building CXX object utility/CMakeFiles/Utility.dir/Reporter.cxx.o In file included from /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/FileUtil.cxx:18: /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/program_options.h:15:28: error: no template named 'unordered_map' in namespace 'std' const std::unordered_map<std::string, T> &defaultValues) ~~~~~^ /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/program_options.h:28:28: error: no template named 'unordered_map' in namespace 'std' const std::unordered_map<std::string, T> &defaultValues, const T &t) ~~~~~^ /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/FileUtil.cxx:83:5: error: no matching function for call to 'add_option' add_option(a, opt::Path, bpo::value<std::string>(), d(opt::Path), v); ^~~~~~~~~~ /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/FileUtil.cxx:84:5: error: no matching function for call to 'add_option' add_option(a, opt::Prefix, bpo::value<std::string>(), d(opt::Prefix), v); ... [ 30%] Linking CXX executable emulator In file included from /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/program_options.cxx:7: /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/program_options.h:15:28: error: no template named 'unordered_map' in namespace 'std' const std::unordered_map<std::string, T> &defaultValues) ~~~~~^ /Users/kobayash/nestdaq/src/nestdaq-user-impl/utility/program_options.h:28:28: error: no template named 'unordered_map' in namespace 'std' const std::unordered_map<std::string, T> &defaultValues, const T &t) ~~~~~^ 2 errors generated. <code>unordered_map がインクルードされていない。nestdaq-user-impl/utility/program_options.hに unordered_map をインクルードすべし。<code>
- nestdaq-user-impl make 時のライブラリインクルードエラー
[ 56%] Linking CXX executable TFBFilePlayer ld: library not found for -lstdc++fs ld: library not found for -lstdc++fs clang: clang: error: error: linker command failed with exit code 1 (use -v to see invocation) linker command failed with exit code 1 (use -v to see invocation)
これは、nestdaq-user-impl/CMakeLists.txt の 以下の部分で、stdc++fs; の部分を # でコメントアウトすれば良い。
target_link_libraries(${EXEC} PUBLIC ${Boost_LIBRARIES}; # ${fmt_LIB}; ${ROOT_LIBRARIES}; ${HIREDIS_LIB}; ${REDIS_PLUS_PLUS_LIB}; ${UHBOOK_LIB}; FairMQ; FairMQStateMachine; FairLogger; Utility; stdc++fs; <-- ここをコメントアウト AmQTdcModule; )
macOS12.3.1 ではリンクしないでもコンパイルは通った。
- nestdaq-user-impl Scaler 実行時のエラー。Run ボタンを押した後、落ちる。
./start_device.sh --enable-uds false [19:27:08][STATE] READY ---> RUNNING [19:27:08][INFO] daq::service::Plugin state : RUNNING [19:27:08][DEBUG] daq::service::Plugin run number (from redis) = 3 [19:27:08][DEBUG] daq::service::MetricsPlugin state change: RUNNING [19:27:08][INFO] fair::mq::Device running... [19:27:08][DEBUG] RUN number = 3 new file opened : scr/run000003.dat hist.GetNBins() = 64 i = 1 , hist.GetBinContent(i) 0 ... i = 64 , hist.GetBinContent(i) 0 hist.GetNBins() = 64 i = 1 , hist.GetBinContent(i) 0 i = 2 , hist.GetBinContent(i) 0 ... i = 64 , hist.GetBinContent(i) 0 Scaler(36842,0x115635600) malloc: Incorrect checksum for freed object 0x7fd764304ab0: probably modified after being freed. Corrupt value: 0x0 Scaler(36842,0x115635600) malloc: *** set a breakpoint in malloc_error_break to debug ./start_device.sh: line 53: 36842 Abort trap: 6 /Users/kobayash/nestdaq/bin/Scaler --enable-uds false -S '</Users/kobayash/nestdaq/lib' -P daq_service -P metrics -P parameter_config --registry-uri tcp://127.0.0.1:6379/0 --metrics-uri tcp://127.0.0.1:6379/1 --parameter-config-uri tcp://127.0.0.1:6379/2 --scaler-uri tcp://127.0.0.1:6379/3 --severity debug4 $
uhbook が 0 始まりでフィルするようになっていたが、Scaler.cxx では 1始まりだったため、エラーになったようだ。 uhbook をアップデートしたら、直った。
- nestdaq-user-impl FileSink のエラー。ラン番号が既にあるものだと、FileSinkが落ちる。
./start_device.sh FileSink --enable-uds false ... [19:39:57][STATE] READY ---> RUNNING [19:39:57][INFO] daq::service::Plugin state : RUNNING [19:39:57][DEBUG] daq::service::Plugin run number (from redis) = 5 [19:39:57][DEBUG] daq::service::MetricsPlugin state change: RUNNING [19:39:57][INFO] fair::mq::Device running... [19:39:57][INFO] 367:PreRun [19:39:57][DEBUG] RUN number = 5 The file is not opened because the file already exists. data/run000005.dat [19:39:57][DEBUG] FileSink::Header.magic : 4918288444365686336 [19:39:57][DEBUG] FileSink::Header.size : 304 [19:39:57][DEBUG] FileSink::Header.fairMQDeviceType : 99 [19:39:57][DEBUG] FileSink::Header.runNumber : 5 [19:39:57][DEBUG] FileSink::Header.startUnixtime : 1706870397 [19:39:57][DEBUG] FileSink::Header.stopUnixtime : 0 [19:39:57][DEBUG] FileSink::Header.comments : FileSinkHeader.h test *** Break *** segmentation violation [/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info) [<unknown binary>] (no debug info) [/Users/kobayash/nestdaq/bin/FileSink] nestdaq::FileSink::PreRun() (no debug info) [/Users/kobayash/nestdaq/lib/libFairMQ.1.4.55.dylib] fair::mq::Device::RunWrapper() /Users/kobayash/nestdaq/src/FairMQ/fairmq/Device.cxx:470 [/Users/kobayash/nestdaq/lib/libFairMQ.1.4.55.dylib] std::__1::__function::__func<fair::mq::Device::Device(fair::mq::ProgOptions*, fair::mq::tools::Version)::$_1, std::__1::allocato r<fair::mq::Device::Device(fair::mq::ProgOptions*, fair::mq::tools::Version)::$_1>, void (fair::mq::State)>::operator()(fair::mq::State&&) /Applications/Xcode.app/Contents/Developer /Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__functional/function.h:352
ラン番号を使っていないもので走らせるべし。