diff --git a/MooreOnlineConf/options/perf_profile.py b/MooreOnlineConf/options/perf_profile.py new file mode 100644 index 0000000000000000000000000000000000000000..a9d3b14b27ac9921607d2199c5116b67c18c3049 --- /dev/null +++ b/MooreOnlineConf/options/perf_profile.py @@ -0,0 +1,20 @@ +############################################################################### +# (c) Copyright 2024 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from Configurables import PerfProfile, HLTControlFlowMgr +HLTControlFlowMgr('HLTControlFlowMgr').PreambleAlgs = HLTControlFlowMgr( + 'HLTControlFlowMgr').PreambleAlgs + [ + PerfProfile( + FIFOPath="perf_control.fifo", + StartFromEventN=1000, + # if we run for 10min: 600s * 70 Evts/s = 42k + StopAtEventN=42000, + ) + ] diff --git a/MooreScripts/job/runHLT2Perf.sh b/MooreScripts/job/runHLT2Perf.sh new file mode 100755 index 0000000000000000000000000000000000000000..fd1d452001944b75f1ea14355b3b9699595b6cb1 --- /dev/null +++ b/MooreScripts/job/runHLT2Perf.sh @@ -0,0 +1,31 @@ +#!/bin/bash +############################################################################### +# (c) Copyright 2024 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +set -euo pipefail +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +source "$DIR/setupTask.sh" + +setup_options_path +settings=$(python -c 'import OnlineEnvBase; print(OnlineEnvBase.HLTType)') +if [ -z "$settings" ]; then + echo "ERROR settings (HLTType) is empty!" + exit 3 +fi +exec_gaudirun \ + $MOOREONLINECONFROOT/options/verbosity.py \ + $MOOREONLINECONFROOT/options/tags-OnlineEnv.py \ + $MOOREONLINECONFROOT/options/hlt2.py \ + $HLT2CONFROOT/options/${settings}.py \ + $MOOREONLINECONFROOT/options/online.py \ + $MOOREONLINECONFROOT/options/perf_profile.py \ + --post-option="from Configurables import HiveDataBrokerSvc, PerfProfile" \ + --post-option="p = PerfProfile()" \ + --post-option="if p not in HiveDataBrokerSvc().DataProducers: HiveDataBrokerSvc().DataProducers.append(p)" \ No newline at end of file diff --git a/MooreScripts/python/MooreScripts/testbench/architecture.py b/MooreScripts/python/MooreScripts/testbench/architecture.py index 22a725e4f73caa89ed47d1e07e43093104fb1652..adde57d0ec46eaa3d2d8c96c3c077c8f8b73e940 100644 --- a/MooreScripts/python/MooreScripts/testbench/architecture.py +++ b/MooreScripts/python/MooreScripts/testbench/architecture.py @@ -114,6 +114,6 @@ def overwrite_dict_value(data: Any, mapping: dict) -> Any: elif isinstance(data, list): return [overwrite_dict_value(item, mapping) for item in data] elif isinstance(data, tuple): - return (overwrite_dict_value(item, mapping) for item in data) + return tuple(overwrite_dict_value(item, mapping) for item in data) else: return data diff --git a/MooreScripts/python/MooreScripts/testbench/emulator.py b/MooreScripts/python/MooreScripts/testbench/emulator.py index c9287beab55d88ca55efa538b00e8590d580e025..e3f8a814a062fc8b6cebb7f71f4a21ae7b2b109a 100644 --- a/MooreScripts/python/MooreScripts/testbench/emulator.py +++ b/MooreScripts/python/MooreScripts/testbench/emulator.py @@ -216,15 +216,22 @@ class Task: self._status_task = None self.process = None self._perf_data = None + self._perf_control = None self.utgid = args["args"][0] for a in args["args"]: if a.startswith("-type="): self.type = a.removeprefix("-type=") - def use_perf(self): + def use_perf(self, control=False): if self.process is not None: raise RuntimeError("use_perf() must be called before load()") self._perf_data = Path(f"{self.utgid}.perf.data").absolute() + if control: + self._perf_control = Path("perf_control.fifo").absolute() + try: + os.mkfifo(self._perf_control) + except FileExistsError: + pass async def __aenter__(self): pass @@ -242,7 +249,7 @@ class Task: if self._perf_data: args["args"][0] = args["executable"] - args["args"] = [ + perf_cmd = [ "perf", "record", f"--output={self._perf_data}", @@ -250,7 +257,10 @@ class Task: "--aio", "--call-graph=dwarf,65528", "--count=100000000", - ] + args["args"] + ] + if self._perf_control: + perf_cmd.append(f"--control=fifo:{self._perf_control}") + args["args"] = perf_cmd + args["args"] args["executable"] = "perf" def exit_callback(p): diff --git a/MooreScripts/python/MooreScripts/testbench/scenarios/default.py b/MooreScripts/python/MooreScripts/testbench/scenarios/default.py index 1416b9a77170ced989956034d0e7251f3fe23f6f..e2667f5fa00d9720888e8195bf0bdca91ba0360e 100644 --- a/MooreScripts/python/MooreScripts/testbench/scenarios/default.py +++ b/MooreScripts/python/MooreScripts/testbench/scenarios/default.py @@ -34,6 +34,10 @@ async def run(tasks: List[emulator.Task], args, extra_argv): "--use-perf", action="store_true", help="perf record the main tasks and create a flamegraph") + parser.add_argument( + "--use-perf-control", + action="store_true", + help="perf record the event loop and create a flamegraph") parser.add_argument( "--wait-after-load", action="store_true", @@ -49,9 +53,9 @@ async def run(tasks: List[emulator.Task], args, extra_argv): raise ValueError("There must be exactly one *Prod task") prod_task = prod_tasks[0] - if extra_args.use_perf: + if extra_args.use_perf or extra_args.use_perf_control: for t in main_tasks: - t.use_perf() + t.use_perf(control=extra_args.use_perf_control) await tasks_load(tasks) # TODO for some reason HLT2 publishes OFFLINE before NOT_READY, but only sometimes @@ -78,7 +82,7 @@ async def run(tasks: List[emulator.Task], args, extra_argv): if args.measure_throughput > 0: # wait a bit for things to settle and measure throughput - await asyncio.sleep(args.measure_throughput / 8) + await asyncio.sleep(args.delay_tp_measurement) await tasks_measure_throughput( tasks, max_duration=args.measure_throughput) else: @@ -101,7 +105,7 @@ async def run(tasks: List[emulator.Task], args, extra_argv): # if there is a writer, wait for the output rate to be 0 if any("Writer" in task.utgid for task in tasks): await tasks_wait_for_output(tasks) - elif "HLT2" in main_tasks[0].utgid: + elif "HLT2" in main_tasks[0].utgid and not args.measure_throughput > 0: log.info(f"Waiting to process all {n_events_produced} events") n_events_processed = sum(await tasks_wait_for_value( main_tasks, diff --git a/MooreScripts/scripts/testbench.py b/MooreScripts/scripts/testbench.py index f16ee43c9373dbe5988a8475d344f43bcfe25653..c42e18c5d94a6a824462b35c9aa4fbd9f7096ee2 100755 --- a/MooreScripts/scripts/testbench.py +++ b/MooreScripts/scripts/testbench.py @@ -112,6 +112,12 @@ parser.add_argument( type=float, help="How long to measure throughput for.", ) +parser.add_argument( + "--delay-tp-measurement", + default=60, + type=float, + help="How long to measure throughput for.", +) parser.add_argument( "--tfdb-nfiles", type=int, @@ -158,8 +164,10 @@ replacements = { arch = architecture.read_xml(args.architecture) if args.write_encoding_keys: - arch = architecture.overwrite_dict_value(arch, - {"WRITE_ENCODING_KEYS": "1"}) + arch = architecture.overwrite_dict_value( + arch, + {"WRITE_ENCODING_KEYS": "1"}, + ) task_instance_args = architecture.instance_args(arch, replacements) emulator.check_for_orphans([a["args"][0] for a in task_instance_args]) diff --git a/MooreScripts/tests/options/HLT2Perf/Arch.xml b/MooreScripts/tests/options/HLT2Perf/Arch.xml new file mode 100644 index 0000000000000000000000000000000000000000..ebeeea451eb4ef6c0af06ad55fc7819f3bc89e7d --- /dev/null +++ b/MooreScripts/tests/options/HLT2Perf/Arch.xml @@ -0,0 +1,66 @@ +<!-- + (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration + + This software is distributed under the terms of the GNU General Public + Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". + + In applying this licence, CERN does not waive the privileges and immunities + granted to it by virtue of its status as an Intergovernmental Organization + or submit itself to any jurisdiction. +--> +<tasks_inventory> + + <task name="MBM" user="${USER}" group="${GROUP}"> + <command>${MOORESCRIPTSROOT}/scripts/runDFTask.sh</command> + <argument name="-type" value="${NAME}" /> + <argument name="-runinfo" value="${RUNINFO}" /> + <argument name="-options" value="${MOORESCRIPTSROOT}/options/HLT2MBM.opts" /> + <argument name="-class" value="Class0" /> + <fmcparam name="utgid" value="${PARTITION}_${NODE}_${NAME}_${INSTANCE}" /> + <fmcparam name="define" value="BINARY_TAG=${BINARY_TAG}" /> + <fmcparam name="define" value="WORKING_DIR=${WORKING_DIR}" /> + <timeout action="Any" value="20" /> + </task> + + <task name="MDFProd" user="${USER}" group="${GROUP}"> + <command>${MOORESCRIPTSROOT}/scripts/runDFTask.sh</command> + <argument name="-type" value="${NAME}" /> + <argument name="-runinfo" value="${RUNINFO}" /> + <argument name="-options" value="${MOORESCRIPTSROOT}/options/HLT2MDFProd.opts" /> + <argument name="-class" value="Class2" /> + <fmcparam name="utgid" value="${PARTITION}_${NODE}_${NAME}_${INSTANCE}" /> + <fmcparam name="define" value="BINARY_TAG=${BINARY_TAG}" /> + <fmcparam name="define" value="WORKING_DIR=${WORKING_DIR}" /> + <fmcparam name="define" value="DATA_DIR=${DATA_DIR}" /> + <timeout action="Any" value="30" /> + </task> + + <task name="HLT2" user="${USER}" group="${GROUP}" instances="1"> + <command>${MOORESCRIPTSROOT}/job/runHLT2Perf.sh</command> + <argument name="-type" value="${NAME}" /> + <argument name="-runinfo" value="${RUNINFO}" /> + <argument name="-class" value="Class1" /> + <argument name="-numthreads" value="20" /> + <fmcparam name="utgid" value="${PARTITION}_${NODE}_${NAME}_${INSTANCE}" /> + <fmcparam name="define" value="BINARY_TAG=${BINARY_TAG}" /> + <fmcparam name="define" value="WORKING_DIR=${WORKING_DIR}" /> + <fmcparam name="define" value="BIND_NUMA=1" /> + <fmcparam name="define" value="WRITE_ENCODING_KEYS=1" /> + <timeout action="Any" value="120" /> + <timeout action="load" value="20" /> + </task> + + <task name="Writer" user="${USER}" group="${GROUP}"> + <command>${MOORESCRIPTSROOT}/scripts/runDFTask.sh</command> + <argument name="-type" value="${NAME}" /> + <argument name="-runinfo" value="${RUNINFO}" /> + <argument name="-options" value="${MOORESCRIPTSROOT}/options/TestWriter.opts" /> + <argument name="-class" value="Class1" /> + <fmcparam name="utgid" value="${PARTITION}_${NODE}_${NAME}_${INSTANCE}" /> + <fmcparam name="define" value="BINARY_TAG=${BINARY_TAG}" /> + <fmcparam name="define" value="WORKING_DIR=${WORKING_DIR}" /> + <timeout action="Any" value="20" /> + <timeout action="load" value="20" /> + </task> + +</tasks_inventory> diff --git a/MooreScripts/tests/options/HLT2Perf/OnlineEnv.opts b/MooreScripts/tests/options/HLT2Perf/OnlineEnv.opts new file mode 100644 index 0000000000000000000000000000000000000000..6dd43d33872f706004c03dd45a9df4d7734fbc30 --- /dev/null +++ b/MooreScripts/tests/options/HLT2Perf/OnlineEnv.opts @@ -0,0 +1,8 @@ +OnlineEnv.PartitionID = 65535; +OnlineEnv.PartitionName = "TESTBEAMGUI"; +OnlineEnv.Activity = "PHYSICS"; +OnlineEnv.OutputLevel = 3; +// +OnlineEnv.Reader_Rescan = 0; +OnlineEnv.Reader_Directories = {"/calib/online/tmpHlt1Dumps/LHCb/0000263844"}; +OnlineEnv.Reader_FilePrefix = "Run_0000263844"; diff --git a/MooreScripts/tests/options/HLT2Perf/OnlineEnvBase.py b/MooreScripts/tests/options/HLT2Perf/OnlineEnvBase.py new file mode 100644 index 0000000000000000000000000000000000000000..04c55cd1cefff2497cfef1bbb02907d0a1be1644 --- /dev/null +++ b/MooreScripts/tests/options/HLT2Perf/OnlineEnvBase.py @@ -0,0 +1,18 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +PartitionID = 65535 +PartitionName = "TESTBEAMGUI" +Activity = "PHYSICS" +HltArchitecture = "dummy" +OnlineVersion = "v0" +MooreVersion = "v0" +MooreOnlineVersion = "v0" +OutputLevel = 3