Skip to content

Commit 7931030

Browse files
Merge remote-tracking branch 'origin/SEA-234_ubuntu22.04_python3.10_ray2.10' into cal_NAN_prevention
2 parents 7ffcf5b + 617d04f commit 7931030

File tree

5 files changed

+49
-43
lines changed

5 files changed

+49
-43
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -414,4 +414,5 @@ See [LICENSE](LICENSE.md).
414414

415415
## Contact
416416

417-
For technical questions about SCOS Actions, contact Justin Haze, [[email protected]](mailto:[email protected])
417+
For technical questions about SCOS Actions, contact the
418+
[ITS Spectrum Monitoring Team](mailto:[email protected]).

pyproject.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ classifiers = [
4545

4646
dependencies = [
4747
"environs>=9.5.0",
48-
"django>=3.2.18,<4.0",
48+
"django>=4.2,<5.0",
4949
"its_preselector @ git+https://github.com/NTIA/[email protected]",
5050
"msgspec>=0.16.0,<1.0.0",
5151
"numexpr>=2.8.3",
5252
"numpy>=1.22.0",
5353
"psutil>=5.9.4",
5454
"python-dateutil>=2.0",
55-
"ray>=2.6.3,<2.8.0",
55+
"ray>=2.10.0",
5656
"ruamel.yaml>=0.15",
5757
"scipy>=1.8.0",
5858
"sigmf @ git+https://github.com/NTIA/SigMF@multi-recording-archive",
@@ -67,7 +67,7 @@ test = [
6767
dev = [
6868
"hatchling>=1.14.1,<2.0",
6969
"pre-commit>=3.3.1,<4.0",
70-
"ray[default]>=2.4.0",
70+
"ray[default]>=2.10.0",
7171
"scos-actions[test]",
7272
]
7373

scos_actions/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "10.0.2"
1+
__version__ = "11.0.0"

scos_actions/actions/acquire_sea_data_product.py

+41-35
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
FFT_WINDOW = get_fft_window(FFT_WINDOW_TYPE, FFT_SIZE)
114114
FFT_WINDOW_ECF = get_fft_window_correction(FFT_WINDOW, "energy")
115115
IMPEDANCE_OHMS = 50.0
116-
NUM_ACTORS = 3 # Number of ray actors to initialize
116+
NUM_ACTORS = env.int("RAY_WORKERS", default=3) # Number of ray actors to initialize
117117

118118
# Create power detectors
119119
TD_DETECTOR = create_statistical_detector("TdMeanMaxDetector", ["max", "mean"])
@@ -417,14 +417,10 @@ def __init__(self, params: dict, iir_sos: np.ndarray):
417417
self.apd_worker = AmplitudeProbabilityDistribution.remote(
418418
params[APD_BIN_SIZE_DB], params[APD_MIN_BIN_DBM], params[APD_MAX_BIN_DBM]
419419
)
420-
self.workers = [
421-
self.fft_worker,
422-
self.pvt_worker,
423-
self.pfp_worker,
424-
self.apd_worker,
425-
]
420+
426421
del params
427422

423+
@ray.method(num_returns=4)
428424
def run(self, iqdata: np.ndarray) -> list:
429425
"""
430426
Filter the input IQ data and concurrently compute FFT, PVT, PFP, and APD results.
@@ -436,9 +432,11 @@ def run(self, iqdata: np.ndarray) -> list:
436432
# Filter IQ and place it in the object store
437433
iqdata = ray.put(sosfilt(sos=self.iir_sos, x=iqdata))
438434
# Compute PSD, PVT, PFP, and APD concurrently.
439-
# Do not wait until they finish. Yield references to their results.
440-
yield [worker.run.remote(iqdata) for worker in self.workers]
441-
del iqdata
435+
fft_reference = self.fft_worker.run.remote(iqdata)
436+
pvt_reference = self.pvt_worker.run.remote(iqdata)
437+
pfp_reference = self.pfp_worker.run.remote(iqdata)
438+
apd_reference = self.apd_worker.run.remote(iqdata)
439+
return fft_reference, pvt_reference, pfp_reference, apd_reference
442440

443441

444442
class NasctnSeaDataProduct(Action):
@@ -541,7 +539,7 @@ def __call__(self, sensor: Sensor, schedule_entry: dict, task_id: int):
541539
logger.debug(f"Spawned {NUM_ACTORS} supervisor actors in {toc-tic:.2f} s")
542540

543541
# Collect all IQ data and spawn data product computation processes
544-
dp_procs, cpu_speed, reference_points = [], [], []
542+
data_products_refs, cpu_speed, reference_points = [], [], []
545543
capture_tic = perf_counter()
546544

547545
for i, parameters in enumerate(self.iteration_params):
@@ -552,10 +550,10 @@ def __call__(self, sensor: Sensor, schedule_entry: dict, task_id: int):
552550
)
553551
# Start data product processing but do not block next IQ capture
554552
tic = perf_counter()
555-
556-
dp_procs.append(
553+
data_products_refs.append(
557554
iq_processors[i % NUM_ACTORS].run.remote(measurement_result["data"])
558555
)
556+
559557
del measurement_result["data"]
560558
toc = perf_counter()
561559
logger.debug(f"IQ data delivered for processing in {toc-tic:.2f} s")
@@ -585,35 +583,43 @@ def __call__(self, sensor: Sensor, schedule_entry: dict, task_id: int):
585583
[],
586584
)
587585
result_tic = perf_counter()
588-
for channel_data_process in dp_procs:
589-
# Retrieve object references for channel data
590-
channel_data_refs = ray.get(channel_data_process)
586+
channel_count = len(data_products_refs)
587+
logger.debug(f"Have {channel_count} channel results")
588+
for index in range(len(data_products_refs)):
589+
logger.debug(f"Working on channel {index}")
591590
channel_data = []
592-
for i, data_ref in enumerate(channel_data_refs):
593-
# Now block until the data is ready
594-
data = ray.get(data_ref)
595-
if i == 1:
596-
# Power-vs-Time results, a tuple of arrays
597-
data, summaries = data # Split the tuple
598-
max_max_ch_pwrs.append(DATA_TYPE(summaries[0]))
599-
med_mean_ch_pwrs.append(DATA_TYPE(summaries[1]))
600-
mean_ch_pwrs.append(DATA_TYPE(summaries[2]))
601-
median_ch_pwrs.append(DATA_TYPE(summaries[3]))
602-
del summaries
603-
if i == 3: # Separate condition is intentional
604-
# APD result: append instead of extend,
605-
# since the result is a single 1D array
606-
channel_data.append(data)
607-
else:
608-
# For 2D arrays (PSD, PVT, PFP)
609-
channel_data.extend(data)
591+
# Now block until the data is ready
592+
dp_refs_tuple = ray.get(data_products_refs[index])
593+
psd_ref, pvt_ref, pfp_ref, apd_ref = dp_refs_tuple
594+
psd_data = ray.get(psd_ref)
595+
channel_data.extend(psd_data)
596+
597+
pvt_data = ray.get(pvt_ref)
598+
# Power-vs-Time results, a tuple of arrays
599+
data, summaries = pvt_data # Split the tuple
600+
max_max_ch_pwrs.append(DATA_TYPE(summaries[0]))
601+
med_mean_ch_pwrs.append(DATA_TYPE(summaries[1]))
602+
mean_ch_pwrs.append(DATA_TYPE(summaries[2]))
603+
median_ch_pwrs.append(DATA_TYPE(summaries[3]))
604+
channel_data.extend(data)
605+
del summaries
606+
607+
pfp_data = ray.get(pfp_ref)
608+
channel_data.extend(pfp_data)
609+
610+
# APD result: append instead of extend,
611+
# since the result is a single 1D array
612+
apd_data = ray.get(apd_ref)
613+
channel_data.append(apd_data)
614+
610615
toc = perf_counter()
611616
logger.debug(f"Waited {toc-tic} s for channel data")
612617
all_data.extend(NasctnSeaDataProduct.transform_data(channel_data))
618+
613619
for ray_actor in iq_processors:
614620
ray.kill(ray_actor)
615621
result_toc = perf_counter()
616-
del dp_procs, iq_processors, channel_data, channel_data_refs
622+
del iq_processors, channel_data
617623
logger.debug(f"Got all processed data in {result_toc-result_tic:.2f} s")
618624

619625
# Build metadata and convert data to compressed bytes

scos_actions/hardware/utils.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ def get_current_cpu_clock_speed() -> float:
4040
:return:
4141
"""
4242
try:
43-
out = subprocess.run("lscpu | grep 'MHz'", shell=True, capture_output=True)
44-
spd = str(out.stdout).split("\\n")[0].split()[2]
45-
return float(spd)
43+
cpu_freq = psutil.cpu_freq()
44+
return cpu_freq.current
4645
except Exception as e:
4746
logger.error("Unable to retrieve current CPU speed")
4847
raise e

0 commit comments

Comments
 (0)