Skip to content

Commit

Permalink
Merge branch 'tickets/DM-33837'
Browse files Browse the repository at this point in the history
  • Loading branch information
kfindeisen committed Feb 28, 2022
2 parents 17962e7 + 54cd42a commit a2309f1
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
34 changes: 30 additions & 4 deletions python/lsst/verify/tasks/commonMetrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ def getInputMetadataKeys(cls, config):
The key for when the target method started (`str`).
``"EndTime"``
The key for when the target method ended (`str`).
``"StartTimestamp"``
The key for an ISO 8601-compliant text string where the target
method started (`str`).
``"EndTimestamp"``
The key for an ISO 8601-compliant text string where the target
method ended (`str`).
"""
keyBase = config.target
return {"StartTime": keyBase + "StartCpuTime",
Expand Down Expand Up @@ -212,9 +218,19 @@ def getInputMetadataKeys(cls, config):
``"EndMemory"``
The key for the memory usage at the end of the method (`str`).
``"MetadataVersion"``
The key for the task-level metadata version.
"""
keyBase = config.target
return {"EndMemory": keyBase + "EndMaxResidentSetSize"}
# Parse keyBase to get just the task prefix, if any; needed to
# guarantee that returned keys all point to unique entries.
# The following line returns a "."-terminated string if keyBase has a
# task prefix, and "" otherwise.
taskPrefix = "".join(keyBase.rpartition(".")[0:2])

return {"EndMemory": keyBase + "EndMaxResidentSetSize",
"MetadataVersion": taskPrefix + "__version__",
}

def makeMeasurement(self, memory):
"""Compute a maximum resident set size measurement from metadata
Expand All @@ -228,6 +244,9 @@ def makeMeasurement(self, memory):
``"EndMemory"``
The memory usage at the end of the method (`int` or `None`).
``"MetadataVersion"``
The version of the task metadata in which the value was stored
(`int` or `None`). `None` is assumed to be version 0.
Returns
-------
Expand All @@ -242,33 +261,40 @@ def makeMeasurement(self, memory):
if memory["EndMemory"] is not None:
try:
maxMemory = int(memory["EndMemory"])
version = memory["MetadataVersion"] \
if memory["MetadataVersion"] else 0
except (ValueError, TypeError) as e:
raise MetricComputationError("Invalid metadata") from e
else:
meas = Measurement(self.config.metricName,
self._addUnits(maxMemory))
self._addUnits(maxMemory, version))
meas.notes['estimator'] = 'utils.timer.timeMethod'
return meas
else:
self.log.info("Nothing to do: no memory information for %s found.",
self.config.target)
return None

def _addUnits(self, memory):
def _addUnits(self, memory, version):
"""Represent memory usage in correct units.
Parameters
----------
memory : `int`
The memory usage as returned by `resource.getrusage`, in
platform-dependent units.
version : `int`
The metadata version. If ``0``, ``memory`` is in platform-dependent
units. If ``1`` or greater, ``memory`` is in bytes.
Returns
-------
memory : `astropy.units.Quantity`
The memory usage in absolute units.
"""
if sys.platform.startswith('darwin'):
if version >= 1:
return memory * u.byte
elif sys.platform.startswith('darwin'):
# MacOS uses bytes
return memory * u.byte
elif sys.platform.startswith('sunos') \
Expand Down
25 changes: 25 additions & 0 deletions tests/test_commonMetrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,31 @@ def testBadlyTypedKeys(self):
with self.assertRaises(MetricComputationError):
task.run(metadata)

def testOldMetadata(self):
"""Test compatibility with version 0 metadata
This can't actually test differences in unit handling between version 0
and version 1, but at least verifies that the code didn't choke on
old-style metadata.
"""
newMetadata = self.scienceTask.getFullMetadata()
oldMetadata = newMetadata.copy()
for key in newMetadata.names(topLevelOnly=False):
if "__version__" in key:
oldMetadata.remove(key)

result = self.task.run(oldMetadata)
lsst.pipe.base.testUtils.assertValidOutput(self.task, result)
meas = result.measurement

self.assertIsInstance(meas, Measurement)
self.assertEqual(meas.metric_name, self.metric)

# Since new style is always bytes, old-style will be less or equal
newResult = self.task.run(newMetadata)
self.assertGreater(meas.quantity, 0.0 * u.byte)
self.assertLessEqual(meas.quantity, newResult.measurement.quantity)

def testDeprecated(self):
with warnings.catch_warnings(record=True):
self.config.metric = "verify.DummyMemory"
Expand Down

0 comments on commit a2309f1

Please sign in to comment.