maxwelllink.sockets.aggregated_susceptibility module

Aggregated SocketHub for Meep MXLSocketSusceptibility connections.

Same Meep-facing MXLINIT protocol as susceptibility.py, but the timestep traffic is fanned out through a small number of aggregate bridges instead of one socket per driver:

Meep ranks ==MXLINIT/AGGSTEP==> _AggregatedSusceptibilitySocketHubServer
    ==AGGHELLO/AGGINIT==> mxl_bridge nodes ==UNIX==> many local drivers

The user-facing AggregatedSusceptibilitySocketHub subclasses SusceptibilitySocketHub (same proxy surface, different downstream transport) and adds the bridge manifest and launch-command helpers. The two hub-specific hard parts live here and only here: the global timestep barrier, which lets several socket susceptibilities per Meep rank advance in Meep’s serial update_P order, and the deferred bridge manifest, which is finalized only once Meep announces how many socket molecules exist.

Server-side step-method call hierarchy (one Meep AGGSTEP frame in):

_serve_step_frame                      block-path eligible?
├── no:  _handle_step -> _run_susceptibility_step
│            └── _run_global_susceptibility_step   (cross-rank barrier)
│                    ├── runner, plan built: _run_merged_block_step
│                    │        └── _block_step_round / _collect_block_group
│                    └── runner, dict path:  _run_merged_susceptibility_step
│                             └── AggregatedSocketHub.step_barrier
└── yes: _run_block_step -> _run_global_susceptibility_step  (same barrier)

Both _run_merged_* runners retry through the shared _MeepRankServerMixin._step_with_rebind skeleton.

class maxwelllink.sockets.aggregated_susceptibility.AggregatedSusceptibilitySocketHub[source]

Bases: SusceptibilitySocketHub

Process-backed aggregate hub for Meep MXLSocketSusceptibility.

Same user-facing surface as SusceptibilitySocketHub (endpoint fields, rank_stats, lorentzian_conversion, stop); the downstream transport runs through aggregate bridges instead of direct driver sockets, and this subclass adds the bridge manifest plus the bridge/driver launch-command helpers.

Parameters:
  • host (str or None, optional) – Interface to bind the upstream TCP server to. None, "", "0.0.0.0", or "::" bind all interfaces; peers connect back over 127.0.0.1.

  • port (int or None, default: 31415) – TCP port for the upstream server. None falls back to 31415 and 0 selects an ephemeral port.

  • timeout (float, default: 60000.0) – Operation timeout (seconds) for binding and stepping.

  • latency (float, default: 0.05) – Polling interval (seconds) for the bind/step loops.

  • num_bridges (int, default: 10) – Initial number of aggregate bridge groups.

  • unix_prefix (str, default: "mxl_bridge_") – Prefix used to generate aggregate bridge group ids.

  • bridge_manifest (str, default: "mxl_bridge_manifest.json") – Path the bridge manifest is written to after startup.

  • init_grace_seconds (float, default: 0.5) – Grace period (seconds) for collecting the first burst of rank INITs when the expected molecule total is not announced up front.

  • unixsocket (str or None, optional) – Reserved for API symmetry; must be falsy (TCP upstream only).

Raises:
  • ValueError – If unixsocket is provided.

  • RuntimeError – If the child hub process fails to start.

__init__(host=None, port=31415, timeout=60000.0, latency=0.05, num_bridges=10, unix_prefix='mxl_bridge_', bridge_manifest='mxl_bridge_manifest.json', init_grace_seconds=0.5, unixsocket=None)[source]

Initialize the proxy-side state shared by every process-backed hub.

Concrete hubs validate their own arguments, call this, set any extra attributes, and then call _start_server_process(). Pre-setting the lifecycle attributes here keeps stop() and __del__ safe even when a subclass __init__ fails before the child is launched.

Parameters:
  • timeout (float) – Socket timeout (seconds) passed to the child server.

  • latency (float) – Polling interval (seconds) passed to the child server.

  • host (str | None)

  • port (int | None)

  • num_bridges (int)

  • unix_prefix (str)

  • bridge_manifest (str)

  • init_grace_seconds (float)

  • unixsocket (str | None)

bridge_command(idx, *, info=None)[source]

Build the shell command that launches one aggregate bridge node.

Parameters:
  • idx (int) – Zero-based bridge index within the manifest.

  • info (str or None, optional) – Manifest path to reference. Defaults to self.bridge_manifest.

Return type:

str

property bridge_info: dict

A copy of the manifest reported by the child hub (may be empty).

property bridge_specs: list[dict]

A copy of the manifest’s bridges list (empty when unavailable).

driver_command_template(*, omega_au, mu0_au, orientation)[source]

Build the shell template that launches one SHO driver against a socket.

Returns a /bin/bash -c ... command with a {unixsocket} placeholder. The wrapper waits for the UNIX socket to appear, jitters its start, and restarts the driver until it exits cleanly or the timeout (clamped to [30, 600] seconds) elapses.

Parameters:
  • omega_au (float)

  • mu0_au (float)

  • orientation (int)

Return type:

str

init_remote_bridges(susceptibility=None, *, molecules_per_bridge, unix_prefix='bridge_', save_file='aggregation.json')[source]

Configure delayed bridge partitioning for MXLSocketSusceptibility.

Meep generates the actual socket molecule ids later, during its first polarization update, so this method only records the bridge policy (and forwards it to the child hub). The child writes the final manifest to save_file once MXLINIT reports expected_total_molecules; any stale save_file is removed up front on the MPI master.

Parameters:
  • susceptibility (object, optional) – Accepted and ignored, for API symmetry with AggregatedSocketHub.init_remote_bridges().

  • molecules_per_bridge (int) – Target number of socket molecules per aggregate bridge.

  • unix_prefix (str, default: "bridge_") – Prefix used to generate downstream UNIX-socket names.

  • save_file (str or path-like, default: "aggregation.json") – Path the finalized bridge manifest will be written to.

Returns:

Always empty; the concrete bridge specs are only known later and are written to save_file by the child hub.

Return type:

list[RemoteBridgeSpec]

Raises:

ValueError – If molecules_per_bridge is not a positive integer.

lorentzian_conversion(frequency, sigma, resolution, *, gamma=0.0, dimensions=1, time_units_fs=0.1, mu0_au=187.0819866, orientation=0)

Convert a Meep Lorentzian susceptibility to SHO driver parameters.

The numerical mapping is lorentzian_to_sho_parameters(); this template adds the launch command from _driver_command_for() (targeting this hub’s transport), prints a short report on the MPI master, and merges any _conversion_extras() into the result.

Returns:

{"rescaling_factor", "driver_command", ...extras} where rescaling_factor is the symmetric bright-state coupling scale to pass to mp.MXLSocketSusceptibility(rescaling_factor=...).

Return type:

dict

Raises:

ValueError – If any argument is outside its documented valid range.

Parameters:
  • frequency (float)

  • sigma (float)

  • resolution (float)

  • gamma (float)

  • dimensions (int)

  • time_units_fs (float)

  • mu0_au (float)

  • orientation (int)

property rank_stats: dict[int, dict]

Latest per-Meep-rank statistics from the running server.

Returns:

Mapping from rank to its stats row (molecule_count, steps, requests, peer, …). Empty on non-master ranks.

Return type:

dict[int, dict]

stop()

Stop the hub and tear down the child server process.

Idempotent and safe on non-master ranks. Signals the child via the stop event, joins it, and falls back to terminate() if it does not exit; a final stats drain captures any closing counters.

Return type:

None

write_bridge_manifest(path)[source]

Write the current bridge manifest to path and return it.

Parameters:

path (str)

Return type:

dict