Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
* Removed Unique Set Size (USS) collection from :class:`~isaaclab.benchmark.recorders.MemoryInfoRecorder`.
``psutil.Process.memory_full_info()`` walks the process page tables on every call, and the recorder ran it
once per second from the :class:`~isaaclab.benchmark.BenchmarkMonitor` thread while the benchmark was being
timed, perturbing the workload being measured. The ``System Memory USS``, ``System Memory USS std``,
``System Memory USS peak`` and ``System Memory USS n`` measurements are no longer emitted. Resident Set Size
and Virtual Memory Size are unchanged and are read from cheap kernel counters.
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,10 @@ def __init__(self):
self._vms_m2 = 0
self._vms_n = 0

# Welford's algorithm stats for USS (Unique Set Size)
self._uss_mean = 0
self._uss_m2 = 0
self._uss_n = 0

# Peak (running max) alongside the Welford mean/std. Initialised to
# 0.0 so emit-before-record returns a meaningful zero.
self._rss_peak = 0.0
self._vms_peak = 0.0
self._uss_peak = 0.0

# Process handle
self._process = psutil.Process(os.getpid())
Expand Down Expand Up @@ -84,20 +78,7 @@ def _get_runtime_info(self) -> None:
self._memory_runtime_info["vms_n"] = self._vms_n
self._memory_runtime_info["vms_peak"] = self._vms_peak

# USS (Unique Set Size) - memory unique to process (not shared)
try:
uss = self._process.memory_full_info().uss
self._uss_mean, self._uss_m2, self._uss_n, uss_std = self._update_welford(
uss, self._uss_mean, self._uss_m2, self._uss_n
)
self._uss_peak = max(self._uss_peak, float(uss))
self._memory_runtime_info["uss_mean"] = self._uss_mean
self._memory_runtime_info["uss_std"] = uss_std
self._memory_runtime_info["uss_n"] = self._uss_n
self._memory_runtime_info["uss_peak"] = self._uss_peak
except (psutil.AccessDenied, AttributeError):
# USS may not be available on all platforms
pass
# USS (Unique Set Size) is deliberately not sampled, it's too expensive.

def update(self) -> None:
self._get_runtime_info()
Expand Down Expand Up @@ -154,31 +135,6 @@ def get_data(self) -> MeasurementData:
SingleMeasurement(name="System Memory VMS n", value=self._memory_runtime_info.get("vms_n", 0), unit=""),
]

# USS (Unique Set Size) - only if available
Comment thread
fatimaanes marked this conversation as resolved.
Resolved
if "uss_mean" in self._memory_runtime_info:
measurements.extend(
[
SingleMeasurement(
name="System Memory USS",
value=self._bytes_to_gb(self._memory_runtime_info.get("uss_mean", 0)),
unit="GB",
),
SingleMeasurement(
name="System Memory USS std",
value=self._bytes_to_gb(self._memory_runtime_info.get("uss_std", 0)),
unit="GB",
),
SingleMeasurement(
name="System Memory USS peak",
value=self._bytes_to_gb(self._memory_runtime_info.get("uss_peak", 0)),
unit="GB",
),
SingleMeasurement(
name="System Memory USS n", value=self._memory_runtime_info.get("uss_n", 0), unit=""
),
]
)

return MeasurementData(
measurements=measurements,
metadata=[
Expand Down
5 changes: 2 additions & 3 deletions source/isaaclab/test/benchmark/test_recorders.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ def test_get_data_measurement_names(self, recorder):
assert "System Memory VMS" in names
assert "System Memory VMS std" in names
assert "System Memory VMS n" in names
# USS measurements may be present depending on platform (mean, std, peak, n)
assert 8 <= len(data.measurements) <= 12
# Exactly 8: RSS and VMS, each with mean, std, peak and n.
assert len(data.measurements) == 8
metadata = {m.name: m.data for m in data.metadata}
assert len(data.metadata) == 1
assert isinstance(metadata["total_ram_gb"], float) and metadata["total_ram_gb"] > 0
Expand All @@ -277,7 +277,6 @@ class _FakeMemInfo:
def __init__(self, rss):
self.rss = rss
self.vms = rss # mirror so VMS also moves
# USS is read via memory_full_info, not memory_info; leave alone.

def _fake_memory_info(self): # noqa: ARG001 — bound method, self is the process
return _FakeMemInfo(next(scripted_iter))
Expand Down
Loading