Skip to content

Commit 8f65d7b

Browse files
committed
Merge branch 'main' into NGC-1264-f-dither-tidy
2 parents 161e4fb + b5bc125 commit 8f65d7b

File tree

13 files changed

+110
-37
lines changed

13 files changed

+110
-37
lines changed

qualification/Jenkinsfile

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,19 +101,39 @@ pipeline {
101101
junit testResults: 'result.xml', skipPublishingChecks: true
102102

103103
// Compress and publish json file so that at least we have that.
104+
// 'includes' specifies which files from the current directory to archive;
105+
// we only want the linked file itself
104106
sh 'xz --keep --force -T 0 report.json'
105-
publishHTML(target: [keepAll: true, reportName: 'Qualification Test Intermediate JSON', reportDir: '', reportFiles: 'report.json.xz'])
107+
publishHTML(target: [
108+
keepAll: true,
109+
reportName: 'Qualification Test Intermediate JSON',
110+
reportDir: '',
111+
reportFiles: 'report.json.xz',
112+
includes: 'report.json.xz'
113+
])
106114

107115
script {
108116
// Generate and publish test report
109117
COMMIT_ID = sh(script: 'qualification/report/generate_pdf.py report.json report.pdf -c', returnStdout: true)
110118
currentBuild.displayName = "#${BUILD_NUMBER} (${COMMIT_ID})"
111119
}
112-
publishHTML(target: [keepAll: true, reportName: 'Qualification Test Report', reportDir: '', reportFiles: 'report.pdf'])
120+
publishHTML(target: [
121+
keepAll: true,
122+
reportName: 'Qualification Test Report',
123+
reportDir: '',
124+
reportFiles: 'report.pdf',
125+
includes: 'report.pdf'
126+
])
113127

114128
// If that worked, we can probably generate and publish a procedure as well
115129
sh 'qualification/report/generate_pdf.py report.json procedure.pdf --generate-procedure-doc'
116-
publishHTML(target: [keepAll: true, reportName: 'Qualification Test Procedure', reportDir: '', reportFiles: 'procedure.pdf'])
130+
publishHTML(target: [
131+
keepAll: true,
132+
reportName: 'Qualification Test Procedure',
133+
reportDir: '',
134+
reportFiles: 'procedure.pdf',
135+
includes: 'procedure.pdf'
136+
])
117137
}
118138
}
119139
}

qualification/cbf.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ class CBFBase:
4848
mode_config: dict # Configuration values used for MeerKAT mode string
4949
uuid: UUID
5050

51-
async def close(self) -> None:
52-
"""Shut down all the connections."""
51+
async def close(self, master_controller_client: aiokatcp.Client | None) -> None:
52+
"""Shut down all the connections and deconfigure the subarray product."""
5353
pass # Derived classes can override
5454

5555

@@ -153,13 +153,15 @@ async def steady_state_timestamp(self, *, max_delay: int = DEFAULT_MAX_DELAY) ->
153153
logger.debug("steady_state_timestamp: %d", timestamp)
154154
return timestamp
155155

156-
async def close(self) -> None:
157-
"""Shut down all the connections."""
156+
async def close(self, master_controller_client: aiokatcp.Client | None) -> None:
157+
"""Shut down all the connections and deconfigure the subarray product."""
158158
clients = self.dsim_clients + [self.product_controller_client]
159159
async with asyncio.TaskGroup() as tg:
160160
for client in clients:
161161
client.close()
162162
tg.create_task(client.wait_closed())
163+
if master_controller_client is not None:
164+
await master_controller_client.request("product-deconfigure", self.name)
163165

164166
async def dsim_time(self, dsim_idx: int = 0) -> float:
165167
"""Get the current UNIX time, as reported by a dsim.
@@ -271,6 +273,8 @@ async def get_task_details(suffix: str, type: type[_T]) -> dict[str, _T]:
271273
interfaces = await get_task_details_multi(r"interfaces\.([^.]+)\.name", str)
272274
tasks: dict[str, TaskDict] = {}
273275
for task_name, hostname in hosts.items():
276+
if task_name not in git_version_futures:
277+
raise RuntimeError(f"could not get katcp port for {task_name}: possible DNS failure")
274278
task_interfaces = interfaces.get(task_name, {})
275279
tasks[task_name] = {
276280
"host": hostname,
@@ -326,10 +330,8 @@ async def _close_cbf(self) -> None:
326330
if self._cbf is not None:
327331
name = self._cbf.name
328332
logger.info("Tearing down CBF %s.", name)
329-
await self._cbf.close()
333+
await self._cbf.close(self._master_controller_client)
330334
self._cbf = None
331-
if self._master_controller_client is not None:
332-
await self._master_controller_client.request("product-deconfigure", name)
333335

334336
async def _get_master_controller_client(self) -> aiokatcp.Client:
335337
if self._master_controller_client is not None:
@@ -351,8 +353,8 @@ async def get_cbf(self, cbf_config: dict, cbf_mode_config: dict) -> CBFBase:
351353
if self._cbf is not None and self._cbf.config == cbf_config:
352354
return self._cbf
353355

354-
await self._close_cbf()
355356
try:
357+
await self._close_cbf()
356358
master_controller_client = await self._get_master_controller_client()
357359
product_name = self._pytestconfig.getini("product_name")
358360
try:

qualification/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ yarl==1.9.4
398398
# -c qualification/../requirements-dev.txt
399399
# -c qualification/../requirements.txt
400400
# aiohttp
401-
zipp==3.17.0
401+
zipp==3.19.2
402402
# via
403403
# -c qualification/../requirements-dev.txt
404404
# -c qualification/../requirements.txt

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ yarl==1.9.4
425425
# via
426426
# -c requirements.txt
427427
# aiohttp
428-
zipp==3.17.0
428+
zipp==3.19.2
429429
# via
430430
# -c requirements.txt
431431
# importlib-metadata

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,5 +174,5 @@ xarray==2023.12.0
174174
# via katgpucbf (setup.cfg)
175175
yarl==1.9.4
176176
# via aiohttp
177-
zipp==3.17.0
177+
zipp==3.19.2
178178
# via importlib-metadata

scratch/fgpu/benchmarks/compute_bench.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import numpy as np
2222
from katsdpsigproc import accel
2323

24-
from katgpucbf import DIG_SAMPLE_BITS
24+
from katgpucbf import DEFAULT_JONES_PER_BATCH, DIG_SAMPLE_BITS
2525
from katgpucbf.fgpu.compute import ComputeTemplate, NarrowbandConfig
2626
from katgpucbf.fgpu.engine import generate_ddc_weights, generate_pfb_weights
2727
from katgpucbf.fgpu.main import DEFAULT_DDC_TAPS_RATIO
@@ -33,7 +33,7 @@ def main(): # noqa: C901
3333
parser.add_argument("--recv-chunk-samples", type=int, default=32 * 1024 * 1024)
3434
parser.add_argument("--send-chunk-jones", type=int, default=8 * 1024 * 1024)
3535
parser.add_argument("--channels", type=int, default=32768)
36-
parser.add_argument("--spectra-per-heap", type=int, default=256)
36+
parser.add_argument("--jones-per-batch", type=int, default=DEFAULT_JONES_PER_BATCH)
3737
parser.add_argument("--dig-sample-bits", type=int, default=DIG_SAMPLE_BITS)
3838
parser.add_argument("--send-sample-bits", type=int, default=8, choices=[4, 8])
3939
parser.add_argument("--passes", type=int, default=1000)
@@ -57,6 +57,9 @@ def main(): # noqa: C901
5757
parser.error("--sem must divide into --passes")
5858
if args.kernel == "ddc" and not args.narrowband:
5959
parser.error("--kernel=ddc requires --narrowband")
60+
if args.jones_per_batch % args.channels != 0:
61+
parser.error("--jones-per-batch must be a multiple of --channels")
62+
spectra_per_heap = args.jones_per_batch // args.channels
6063

6164
rng = np.random.default_rng(seed=1)
6265
context = accel.create_some_context(device_filter=lambda device: device.is_cuda)
@@ -77,14 +80,14 @@ def main(): # noqa: C901
7780
context, args.taps, args.channels, args.dig_sample_bits, args.send_sample_bits, narrowband=narrowband_config
7881
)
7982
command_queue = context.create_tuning_command_queue()
80-
out_spectra = accel.roundup(args.send_chunk_jones // args.channels, args.spectra_per_heap)
83+
out_spectra = accel.roundup(args.send_chunk_jones // args.channels, spectra_per_heap)
8184
frontend_spectra = min(args.recv_chunk_samples // spectra_samples, out_spectra)
8285
extra_samples = window - spectra_samples
8386
fn = template.instantiate(
8487
command_queue,
8588
samples=args.recv_chunk_samples + extra_samples,
8689
spectra=out_spectra,
87-
spectra_per_heap=args.spectra_per_heap,
90+
spectra_per_heap=spectra_per_heap,
8891
seed=123,
8992
sequence_first=456,
9093
)

scratch/fgpu/compare_fengs.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
#!/usr/bin/env python3
22

3+
################################################################################
4+
# Copyright (c) 2022, 2024, National Research Foundation (SARAO)
5+
#
6+
# Licensed under the BSD 3-Clause License (the "License"); you may not use
7+
# this file except in compliance with the License. You may obtain a copy
8+
# of the License at
9+
#
10+
# https://opensource.org/licenses/BSD-3-Clause
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
################################################################################
18+
319
"""Compare output of two F-engines.
420
521
This can be used to ensure that a change to F-engine code produces
@@ -22,7 +38,7 @@
2238

2339
import katgpucbf.recv
2440
import katgpucbf.xbgpu.recv
25-
from katgpucbf import COMPLEX, N_POLS
41+
from katgpucbf import COMPLEX, DEFAULT_JONES_PER_BATCH, N_POLS
2642

2743

2844
def parse_args() -> argparse.Namespace:
@@ -31,21 +47,25 @@ def parse_args() -> argparse.Namespace:
3147
parser.add_argument("--interface", type=get_interface_address, help="Interface on which to listen")
3248
parser.add_argument("--ibv", action="store_true", help="Use ibverbs")
3349
parser.add_argument("--array-size", type=int, required=True)
34-
parser.add_argument("--channels-per-stream", type=int, required=True)
35-
parser.add_argument("--spectra-per-heap", type=int, default=256)
50+
parser.add_argument("--channels", type=int, required=True)
51+
parser.add_argument("--channels-per-substream", type=int, required=True)
52+
parser.add_argument("--jones-per-batch", type=int, default=DEFAULT_JONES_PER_BATCH)
3653
parser.add_argument("--samples-between-spectra", type=int, required=True)
37-
parser.add_argument("--heaps-per-fengine-per-chunk", type=int, default=16)
54+
parser.add_argument("--heaps-per-fengine-per-chunk", type=int, default=32)
3855
args = parser.parse_args()
56+
if args.jones_per_batch % args.channels != 0:
57+
parser.error("--jones-per-batch must be a multiple of --channels")
3958
return args
4059

4160

4261
async def main() -> None:
4362
args = parse_args()
63+
spectra_per_heap = args.jones_per_batch // args.channels
4464
layout = katgpucbf.xbgpu.recv.Layout(
4565
n_ants=args.array_size,
46-
n_channels_per_stream=args.channels_per_stream,
47-
n_spectra_per_heap=args.spectra_per_heap,
48-
timestamp_step=args.samples_between_spectra * args.spectra_per_heap,
66+
n_channels_per_substream=args.channels_per_substream,
67+
n_spectra_per_heap=spectra_per_heap,
68+
timestamp_step=args.samples_between_spectra * spectra_per_heap,
4969
sample_bits=8,
5070
heaps_per_fengine_per_chunk=args.heaps_per_fengine_per_chunk,
5171
)
@@ -56,14 +76,14 @@ async def main() -> None:
5676
shape = (
5777
layout.heaps_per_fengine_per_chunk,
5878
layout.n_ants,
59-
layout.n_channels_per_stream,
79+
layout.n_channels_per_substream,
6080
layout.n_spectra_per_heap,
6181
N_POLS,
6282
COMPLEX,
6383
)
6484
data = np.ones(shape, np.int8)
6585
present = np.zeros(shape[:2], np.uint8)
66-
chunk = katgpucbf.recv.Chunk(data=data, present=present, stream=stream)
86+
chunk = katgpucbf.recv.Chunk(data=data, present=present, sink=stream)
6787
chunk.recycle()
6888

6989
srcs = [(ep.host, ep.port) for ep in args.src]

scratch/xbgpu/benchmarks/beamform_bench.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,36 @@
2020

2121
import katsdpsigproc.accel
2222

23+
from katgpucbf import DEFAULT_JONES_PER_BATCH
2324
from katgpucbf.xbgpu.beamform import BeamformTemplate
2425

2526

2627
def main():
2728
parser = argparse.ArgumentParser()
2829
parser.add_argument("--array-size", type=int, default=80, help="Antennas in the array [%(default)s]")
30+
parser.add_argument(
31+
"--channels", type=int, default=1024, help="Total number of channels in the stream [%(default)s]"
32+
)
2933
parser.add_argument(
3034
"--channels-per-substream", type=int, default=16, help="Channels processed by one engine [%(default)s]"
3135
)
32-
parser.add_argument("--spectra-per-heap", type=int, default=256, help="Spectra in each batch [%(default)s]")
36+
parser.add_argument(
37+
"--jones-per-batch",
38+
type=int,
39+
default=DEFAULT_JONES_PER_BATCH,
40+
help="Number of antenna-channelised-voltage Jones vectors in each F-engine batch [%(default)s]",
41+
)
3342
parser.add_argument("--heaps-per-fengine-per-chunk", type=int, default=32, help="Batches per chunk [%(default)s]")
3443
parser.add_argument("--beams", type=int, default=4, help="Number of dual-pol beams [%(default)s]")
3544
parser.add_argument("--passes", type=int, default=10000, help="Number of times to repeat the test [%(default)s]")
3645
args = parser.parse_args()
46+
if args.jones_per_batch % args.channels != 0:
47+
parser.error("--jones-per-batch must be a multiple of --channels")
48+
spectra_per_heap = args.jones_per_batch // args.channels
3749

3850
ctx = katsdpsigproc.accel.create_some_context()
3951
command_queue = ctx.create_command_queue()
40-
template = BeamformTemplate(ctx, [0, 1] * args.beams, n_spectra_per_batch=args.spectra_per_heap)
52+
template = BeamformTemplate(ctx, [0, 1] * args.beams, n_spectra_per_batch=spectra_per_heap)
4153
fn = template.instantiate(
4254
command_queue,
4355
n_batches=args.heaps_per_fengine_per_chunk,
@@ -66,7 +78,7 @@ def main():
6678
voltages = (
6779
args.array_size
6880
* args.channels_per_substream
69-
* args.spectra_per_heap
81+
* spectra_per_heap
7082
* args.heaps_per_fengine_per_chunk
7183
* args.passes
7284
)

scratch/xbgpu/benchmarks/correlate_bench.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,35 @@
2020

2121
import katsdpsigproc.accel
2222

23+
from katgpucbf import DEFAULT_JONES_PER_BATCH
2324
from katgpucbf.xbgpu.correlation import CorrelationTemplate
2425

2526

2627
def main():
2728
parser = argparse.ArgumentParser()
2829
parser.add_argument("--array-size", type=int, default=80, help="Antennas in the array [%(default)s]")
30+
parser.add_argument(
31+
"--channels", type=int, default=1024, help="Total number of channels in the stream [%(default)s]"
32+
)
2933
parser.add_argument(
3034
"--channels-per-substream", type=int, default=16, help="Channels processed by one engine [%(default)s]"
3135
)
32-
parser.add_argument("--spectra-per-heap", type=int, default=256, help="Spectra in each batch [%(default)s]")
36+
parser.add_argument(
37+
"--jones-per-batch",
38+
type=int,
39+
default=DEFAULT_JONES_PER_BATCH,
40+
help="Number of antenna-channelised-voltage Jones vectors in each F-engine batch [%(default)s]",
41+
)
3342
parser.add_argument("--heaps-per-fengine-per-chunk", type=int, default=32, help="Frames per chunk [%(default)s]")
3443
parser.add_argument("--passes", type=int, default=10000, help="Number of times to repeat the test [%(default)s]")
3544
args = parser.parse_args()
45+
if args.jones_per_batch % args.channels != 0:
46+
parser.error("--jones-per-batch must be a multiple of --channels")
47+
spectra_per_heap = args.jones_per_batch // args.channels
3648

3749
ctx = katsdpsigproc.accel.create_some_context()
3850
command_queue = ctx.create_command_queue()
39-
template = CorrelationTemplate(ctx, args.array_size, args.channels_per_substream, args.spectra_per_heap, 8)
51+
template = CorrelationTemplate(ctx, args.array_size, args.channels_per_substream, spectra_per_heap, 8)
4052
fn = template.instantiate(command_queue, args.heaps_per_fengine_per_chunk)
4153

4254
fn.ensure_all_bound()
@@ -54,7 +66,7 @@ def main():
5466
voltages = (
5567
args.array_size
5668
* args.channels_per_substream
57-
* args.spectra_per_heap
69+
* spectra_per_heap
5870
* args.heaps_per_fengine_per_chunk
5971
* args.passes
6072
)

src/katgpucbf/fsim/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def parse_args(arglist: Sequence[str] | None = None) -> argparse.Namespace:
7373
"--array-size", type=int, default=80, help="Number of antennas in the simulated array [%(default)s]"
7474
)
7575
parser.add_argument(
76-
"--channels", type=int, default=32768, help="Total number of channels in the simulated array [%(default)s]"
76+
"--channels", type=int, default=32768, help="Total number of channels in the simulated stream [%(default)s]"
7777
)
7878
parser.add_argument(
7979
"--channels-per-substream", type=int, default=512, help="Number of channels sent by this fsim [%(default)s]"

0 commit comments

Comments
 (0)