Skip to content

Commit ee9eea1

Browse files
committed
Merge remote branch 'origin/dev' into read-failures
2 parents 740b329 + cfb5a4b commit ee9eea1

470 files changed

Lines changed: 238490 additions & 5810 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.clang-tidy‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ Checks:
1818
- modernize-use-uncaught-exceptions
1919
- readability-braces-around-statements
2020
- -clang-diagnostic-vla-cxx-extension
21+
# Select which of the enabled checks should be reported as errors instead of warnings.
22+
WarningsAsErrors: >-
23+
*,
2124
CheckOptions:
2225
# Naming conventions
2326
readability-identifier-naming.ClassCase: CamelCase

‎.github/workflows/clean-test.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ name: Clean PR checks
2727
description: build/O2/fullCI_slc9
2828
type: boolean
2929
default: true
30+
'check_build/O2/fullCI-slc10-x86':
31+
description: build/O2/fullCI-slc10-x86
32+
type: boolean
33+
default: true
3034
# Off by default, unlike every other check here: the gpu pool is a single
3135
# worker and a gpu-test round is hours, so resetting this is a much bigger
3236
# ask than requeueing one of the twenty-odd slc9/slc10 builders. Tick it

‎.skills/dpl-mcp/SKILL.md‎

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
name: dpl-mcp
3+
description: Inspect a running DPL workflow through the DPL MCP server (Framework/Core/scripts/dpl-mcp-server) — devices and their state, live metrics, logs, signposts, per-mapping memory (smaps), resuming a workflow started with -s. Use when asked to look at, debug or measure a workflow while it runs, locally or on Hyperloop.
4+
---
5+
6+
# DPL MCP server
7+
8+
`Framework/Core/scripts/dpl-mcp-server/dpl_mcp_server.py` is an MCP server
9+
(`FastMCP("DPL Status")`) that talks to the `/status` WebSocket of a running
10+
DPL **driver**. Everything it reports comes from the driver, which already
11+
holds the devices' metrics, logs and pids, so nothing has to be enabled in the
12+
workflow: every driver listens, `-b` or not.
13+
14+
The driver side is `Framework/Core/src/StatusWebSocketHandler.{h,cxx}`; the
15+
header documents the wire protocol. A tool and its driver command are added
16+
together: a command the driver does not know is silently ignored, which the
17+
tool reports as a timeout.
18+
19+
## Setup
20+
21+
Dependencies are `mcp` and `websockets` (`pyproject.toml`, Python ≥ 3.11).
22+
Use a virtualenv next to the script and register the script itself; the server
23+
takes no command-line arguments, workflows are attached at run time with
24+
`connect`:
25+
26+
```sh
27+
cd Framework/Core/scripts/dpl-mcp-server
28+
python3 -m venv .venv && .venv/bin/pip install mcp websockets
29+
claude mcp add dpl -- "$PWD/.venv/bin/python3" "$PWD/dpl_mcp_server.py"
30+
```
31+
32+
Several workflows can be connected at once; each tool takes the `workflow`
33+
name that `connect` returned.
34+
35+
## Attaching to a workflow
36+
37+
- **Local**: `connect(pid=<driver pid>)` or `connect(port=<port>)`.
38+
The driver binds `8080 + pid % 30000` (or `DPL_REMOTE_GUI_PORT`), but moves
39+
to the next free port if that one is taken, so when `pid=` fails take the
40+
port from the driver log: `Driver listening on port: <n>`. The driver pid is
41+
the one without `--id` on its command line.
42+
- **Hyperloop**: `connect_hyperloop(url=https://alimonitor.cern.ch/train-workdir/remote-gui/remote_proxy.html?<token>/<port>)`
43+
for a test that exposes the remote GUI. NOTE: this still targets the old
44+
`ws://localhost:8888` proxy with `HYPERLOOP_TOKEN`; it has to be moved to
45+
the security-proxy before it works again.
46+
47+
## Tools
48+
49+
| Tool | What it does |
50+
|------|--------------|
51+
| `connect`, `connect_hyperloop`, `disconnect`, `list_workflows` | attach / detach workflows |
52+
| `list_devices(workflow)` | name, pid, active, streaming state, device state of every device |
53+
| `list_metrics(workflow, device)` | numeric metrics a device publishes (string/enum ones are left out) |
54+
| `subscribe` / `unsubscribe(workflow, device, metrics)` | the driver pushes a subscribed metric each cycle in which it changed |
55+
| `get_updates(workflow, max_updates)` | drain the buffered metric updates, time-ordered |
56+
| `subscribe_logs` / `unsubscribe_logs(workflow, device)` | stream a device's log lines |
57+
| `get_logs(workflow, max_lines)` | drain the buffered log lines |
58+
| `enable_signpost` / `disable_signpost(workflow, device, streams)` | switch signpost streams on a device (`device=""` for the driver), e.g. `ch.cern.aliceo2.device`, `ch.cern.aliceo2.completion`, `ch.cern.aliceo2.monitoring_service`, `ch.cern.aliceo2.data_processor_context`, `ch.cern.aliceo2.stream_context`; the output arrives in the logs |
59+
| `start_devices(workflow)` | SIGCONT every device of a workflow started with `-s` (stop before device start) |
60+
| `smaps(workflow, device, top)` | memory per mapping, read by the driver from `/proc/<pid>/smaps` (Linux only) |
61+
62+
Updates and logs are buffered by the server between calls and drained by
63+
`get_updates` / `get_logs`, so poll them rather than expecting a push.
64+
65+
## Memory per mapping (`smaps`)
66+
67+
The driver reads `/proc/<pid>/smaps` of the device and returns, per path, kB of
68+
rss, pss, shared/private clean/dirty and swap (unnamed mappings as `[anon]`).
69+
The tool groups them into O2Physics, O2, ROOT, arrow and other libraries,
70+
heap, anon and shm, and lists the `top` paths by PSS.
71+
72+
- Compare **private-dirty**: it is what the device itself costs. PSS splits
73+
shared pages among every process mapping them, so it moves with how many
74+
other jobs on the node use the same libraries.
75+
- It works where an outside reader cannot: Hyperloop tests run as `alitrain`,
76+
and only a process of that user (the driver) may read the devices' smaps.
77+
- Take it while the workflow is processing, to see the working set rather than
78+
what is left after end of stream.
79+
80+
## Typical uses
81+
82+
- Why is a workflow stuck: `list_devices` for the states, then
83+
`subscribe_logs` + `get_logs` on the device whose streaming or device state lags the others
84+
and the `completion` signpost stream to see which inputs a
85+
device is waiting for.
86+
- Throughput or backpressure: `list_metrics`, then `subscribe` to the rate,
87+
size or relayer metrics (e.g. `inputs/relayed/*`, `total_rate_in_mb_s`) and
88+
read `get_updates` over time.
89+
- Where the memory of a device goes: `smaps`.
90+
- Debugging from the start: launch with `-s`, attach, enable signposts /
91+
subscribe to logs, then `start_devices`.

‎CCDB/CMakeLists.txt‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ o2_target_root_dictionary(CCDB
3232
include/CCDB/IdPath.h
3333
include/CCDB/BasicCCDBManager.h
3434
include/CCDB/CCDBTimeStampUtils.h
35-
include/CCDB/CCDBQuery.h
36-
include/CCDB/CCDBDownloader.h)
35+
include/CCDB/CCDBQuery.h)
3736

3837
o2_add_executable(inspectccdbfile
3938
COMPONENT_NAME ccdb

‎CODEOWNERS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
/DataFormats/Detectors/TPC @davidrohr @wiechula @shahor02
4343
/DataFormats/Detectors/TRD @f3sch @bazinski @wille10
4444
/DataFormats/Detectors/Upgrades @mconcas
45+
/DataFormats/Detectors/Upgrades/ALICE3 @mconcas @njacazio @fcolamar @pbutti
4546
/DataFormats/Detectors/Upgrades/ITS3 @fgrosa @arossi81
4647
/DataFormats/Detectors/ZDC @coppedis @cortesep
4748

@@ -63,6 +64,7 @@
6364
/Detectors/FOCAL @maxrauch @iarsene @matthiasrichter
6465
/Detectors/Geometry @sawenzel @shahor02
6566
/Detectors/GlobalTracking @shahor02
67+
/Detectors/GenericTracking @f3sch @mpuccio
6668
/Detectors/GlobalTrackingWorkflow @shahor02
6769
/Detectors/HMPID @gvolpe79
6870
/Detectors/ITSMFT @f3sch @fprino @mcoquet642 @mconcas @shahor02

‎Common/CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
add_subdirectory(Constants)
1313
add_subdirectory(MathUtils)
14+
add_subdirectory(TrackTools)
1415
add_subdirectory(Field)
1516
add_subdirectory(Types)
1617
add_subdirectory(Utils)

‎Common/MathUtils/include/MathUtils/detail/StatAccumulator.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct StatAccumulator {
4242
wsum += w;
4343
n++;
4444
}
45-
double getMean() const { return wsum > 0. ? sum / wsum : 0.; }
45+
double getMean() const { return wsum > 0. ? sum / wsum : double{0}; }
4646

4747
#ifndef GPUCA_GPUCODE_DEVICE
4848
template <typename T = float>

‎Common/MathUtils/include/MathUtils/detail/basicMath.h‎

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,36 @@ GPUdi() T log(T x)
9191
return o2::gpu::GPUCommonMath::Log(x);
9292
};
9393

94-
#ifndef GPUCA_GPUCODE_DEVICE // Double overloads using std namespace not visible on GPU
94+
template <class T>
95+
GPUdi() T exp(T x)
96+
{
97+
return o2::gpu::GPUCommonMath::Exp(x);
98+
};
99+
100+
#if !defined(GPUCA_GPUCODE_DEVICE) || defined(__CUDACC__) || defined(__HIPCC__) // Double specialisations, not for OpenCL and Metal
95101
template <>
96102
GPUhdi() double copysign(double x, double y)
97103
{
98-
return std::copysign(x, y);
104+
return o2::gpu::GPUCommonMath::Copysignd(x, y);
99105
}
100106
template <>
101107
GPUhdi() double sqrt(double x)
102108
{
103-
return std::sqrt(x);
109+
return o2::gpu::GPUCommonMath::Sqrtd(x);
104110
};
111+
template <>
112+
GPUdi() double log(double x)
113+
{
114+
return o2::gpu::GPUCommonMath::Logd(x);
115+
};
116+
template <>
117+
GPUdi() double exp(double x)
118+
{
119+
return o2::gpu::GPUCommonMath::Expd(x);
120+
};
121+
#endif
122+
123+
#ifndef GPUCA_GPUCODE_DEVICE // Double overloads using std namespace not visible on GPU
105124
GPUhdi() double abs(double x)
106125
{
107126
return std::abs(x);
@@ -120,11 +139,6 @@ GPUdi() bool finite(double x)
120139
return std::isfinite(x);
121140
#endif
122141
}
123-
template <>
124-
GPUdi() double log(double x)
125-
{
126-
return std::log(x);
127-
};
128142
#endif
129143

130144
} // namespace detail

‎Common/MathUtils/include/MathUtils/detail/trigonometric.h‎

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ GPUhdi() T to02Pi(T phi)
4848
template <typename T>
4949
GPUhdi() void bringTo02Pi(T& phi)
5050
{
51-
phi = to02Pi<T>(phi);
51+
phi = to02Pi(phi);
5252
}
5353

5454
template <typename T>
@@ -68,7 +68,7 @@ inline T to02PiGen(T phi)
6868
template <typename T>
6969
inline void bringTo02PiGen(T& phi)
7070
{
71-
phi = to02PiGen<T>(phi);
71+
phi = to02PiGen(phi);
7272
}
7373

7474
template <typename T>
@@ -87,7 +87,7 @@ GPUhdi() T toPMPi(T phi)
8787
template <typename T>
8888
GPUhdi() void bringToPMPi(T& phi)
8989
{
90-
phi = toPMPi<T>(phi);
90+
phi = toPMPi(phi);
9191
}
9292

9393
template <typename T>
@@ -107,7 +107,7 @@ inline T toPMPiGen(T phi)
107107
template <typename T>
108108
inline void bringToPMPiGen(T& phi)
109109
{
110-
phi = toPMPiGen<T>(phi);
110+
phi = toPMPiGen(phi);
111111
}
112112

113113
#if defined(__OPENCL__) || defined(__METAL__) // TODO: get rid of that stupid workaround for OpenCL template address spaces
@@ -275,12 +275,11 @@ GPUhdi() constexpr T fastATan2(T y, T x)
275275
// Average inaccuracy: 0.00048
276276
// Max inaccuracy: 0.00084
277277
// Speed: 6.2 times faster than atan2f()
278-
constexpr T Pi = 3.1415926535897932384626433832795;
279-
280278
auto atan = [](T a) -> T {
281279
// returns the arctan for the angular range [-Pi/4, Pi/4]
282280
// the polynomial coefficients are taken from:
283281
// https://stackoverflow.com/questions/42537957/fast-accurate-atan-arctan-approximation-algorithm
282+
constexpr T Pi = 3.1415926535897932384626433832795;
284283
constexpr T A = 0.0776509570923569;
285284
constexpr T B = -0.287434475393028;
286285
constexpr T C = ((Pi / 4) - A - B);
@@ -290,6 +289,7 @@ GPUhdi() constexpr T fastATan2(T y, T x)
290289

291290
auto atan2P = [atan](T yy, T xx) -> T {
292291
// fast atan2(yy,xx) for the angular range [0,+Pi]
292+
constexpr T Pi = 3.1415926535897932384626433832795;
293293
constexpr T Pi025 = 1 * Pi / 4;
294294
constexpr T Pi075 = 3 * Pi / 4;
295295
const T x1 = xx + yy; // point p1 (x1,y1) = (xx,yy) - Pi/4
@@ -299,7 +299,7 @@ GPUhdi() constexpr T fastATan2(T y, T x)
299299
if (xx < 0) { // p1 is in the range [Pi/4, 3*Pi/4]
300300
phi0 = Pi075;
301301
tan = y1 > T(0) ? -x1 / y1 : T(0); // yy is always >=0, hence y1>=0
302-
} else { // p1 is in the range [-Pi/4, Pi/4]
302+
} else { // p1 is in the range [-Pi/4, Pi/4]
303303
phi0 = Pi025;
304304
tan = x1 > T(0) ? y1 / x1 : T(0);
305305
}
@@ -376,41 +376,41 @@ GPUdi() double pi()
376376
return o2::constants::math::PI;
377377
}
378378

379-
#ifndef GPUCA_GPUCODE_DEVICE
379+
#if !defined(GPUCA_GPUCODE_DEVICE) || defined(__CUDACC__) || defined(__HIPCC__) // Double specialisations, not for OpenCL and Metal
380380
template <>
381381
GPUdi() double tan(double x)
382382
{
383-
return std::tan(x);
383+
return o2::gpu::GPUCommonMath::Tand(x);
384384
};
385385
template <>
386386
GPUdi() double sin(double x)
387387
{
388-
return std::sin(x);
388+
return o2::gpu::GPUCommonMath::Sind(x);
389389
};
390390
template <>
391391
GPUdi() double atan2(double y, double x)
392392
{
393-
return std::atan2(y, x);
393+
return o2::gpu::GPUCommonMath::ATan2d(y, x);
394394
};
395395
template <>
396396
GPUdi() double atan(double x)
397397
{
398-
return std::atan(x);
398+
return o2::gpu::GPUCommonMath::ATand(x);
399399
};
400400
template <>
401401
GPUdi() double asin(double x)
402402
{
403-
return std::asin(x);
403+
return o2::gpu::GPUCommonMath::ASind(x);
404404
};
405405
template <>
406406
GPUdi() double acos(double x)
407407
{
408-
return std::acos(x);
408+
return o2::gpu::GPUCommonMath::ACosd(x);
409409
};
410410
template <>
411411
GPUdi() double cos(double x)
412412
{
413-
return std::cos(x);
413+
return o2::gpu::GPUCommonMath::Cosd(x);
414414
};
415415
#endif
416416

‎Common/SimConfig/include/SimConfig/G4Params.h‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "CommonUtils/ConfigurableParam.h"
1616
#include "CommonUtils/ConfigurableParamHelper.h"
17+
#include "SimulationDataFormat/MonopoleParticles.h"
1718

1819
namespace o2
1920
{
@@ -80,6 +81,22 @@ struct G4Params : public o2::conf::ConfigurableParamHelper<G4Params> {
8081
bool g4scoring = false;
8182
bool g4fluenceweight = false;
8283

84+
// Enable magnetic-monopole ionisation as defined in Detectors/gconfig/O2MonopolePhysics.
85+
// The G4mplIonisation process (Ahlen stopping power) is attached to
86+
// the O2 monopole particles (PDG +-4110000 / +-4120000) on top of the chosen
87+
// reference physics list. Off by default
88+
bool monopole = false;
89+
// Monopole magnetic charge in units of the Dirac charge g_D = eplus/(2*alpha)
90+
// (~68.5 eplus). 1.0 corresponds to a single classic Dirac monopole.
91+
// The monopole is transported with the full dual Lorentz force
92+
// F = g*(B - v x E/c^2). The electric part acts inside the TPC field cage,
93+
// the only volume with an electric field, and its magnitude is the TPC's own
94+
// TPCGEMParam.ElectricField[0]
95+
float monopoleMagneticCharge = 1.f;
96+
// Monopole mass in GeV, preliminarly applied to all the monopoles species
97+
// To-do: allow different monopoles masses in the same run
98+
float monopoleMass = static_cast<float>(o2::sim::MonopoleMassDefaultGeV);
99+
83100
// Fast simulation. Empty fastSimModels (the default) disables the feature
84101
// entirely; see Detectors/gconfig/include/SimSetup/G4FastSimulation.h.
85102
std::string fastSimModels = ""; // comma-separated model names to activate

0 commit comments

Comments
 (0)