Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add resources to provenance #3016

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

benjeffery
Copy link
Member

@benjeffery benjeffery commented Oct 9, 2024

Description

Add optional resources to provenances along with a helper method to populate the field. This is intended for long-running processed such as tsinfer, where measuring the resources used across distributed pipelines is awkward and easier to do in the actual process that makes the tree sequence.

PR Checklist:

  • Tests that fully cover new/changed functionality.
  • Documentation including tutorial content if appropriate.
  • Changelogs, if there are API changes.

@benjeffery benjeffery force-pushed the resources-provenance branch 2 times, most recently from 5a313f9 to 6798b1a Compare October 9, 2024 11:08
@benjeffery
Copy link
Member Author

@jeromekelleher I'm not sure how library methods such as simplify that could be run as part of a larger process are going to record their max_mem.

Copy link

codecov bot commented Oct 9, 2024

Codecov Report

Attention: Patch coverage is 78.57143% with 3 lines in your changes missing coverage. Please review.

Project coverage is 89.83%. Comparing base (7320290) to head (06a4132).
Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
python/tskit/provenance.py 78.57% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3016      +/-   ##
==========================================
- Coverage   89.84%   89.83%   -0.01%     
==========================================
  Files          29       29              
  Lines       32093    32111      +18     
  Branches     6230     5758     -472     
==========================================
+ Hits        28833    28847      +14     
- Misses       1859     1861       +2     
- Partials     1401     1403       +2     
Flag Coverage Δ
c-tests 86.69% <ø> (ø)
lwt-tests 80.78% <ø> (ø)
python-c-tests 89.05% <ø> (ø)
python-tests 98.95% <71.42%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
python/tskit/provenance.py 93.75% <78.57%> (-6.25%) ⬇️

... and 3 files with indirect coverage changes

Copy link
Member

@jeromekelleher jeromekelleher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if we want to get into the business of generating this in tskit, although I agree it would be nice to not have to redo it in libraries.

I guess we could require the start_time as a parameter, which would force users to generate a sensible one?

I think this is something that we don't expect to be recorded much, except in cases where there's a lot of resources involved. Msprime, for example, wouldn't bother with this.

@@ -72,6 +80,31 @@ def get_environment(extra_libs=None, include_tskit=True):
return env


def get_resources():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to do this here? I feel like this will get misused pretty badly as people won't realise that time is relative to when tskit got imported. It's only really appropriate in cases where the time is essentially the full life of the interpreter.

"description": "System time used in seconds.",
"type": "number"
},
"max_mem": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this max_memory here, I've commited this in sc2ts and the brevity doesn't really help.

@@ -216,7 +216,8 @@ def pack_arrays(list_of_lists, dtype=np.float64):
"""
Packs the specified list of numeric lists into a flattened numpy array
of the specified dtype with corresponding offsets. See
:ref:`sec_encoding_ragged_columns` for details of this encoding of columns
:ref:`sec_encoding_ragged_columns` for detThis information
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some collatoral damage?

@benjeffery
Copy link
Member Author

Yes, it was only when I went to add it to existing tskit methods I realised this was the wrong approach. I don't think adding it to all tskit methods is useful.

I still think the method is useful though, how about I add the start_time argument and leave it undocumented?

@jeromekelleher
Copy link
Member

Sgtm

@benjeffery benjeffery force-pushed the resources-provenance branch 3 times, most recently from 923b54e to 118e9a0 Compare October 9, 2024 12:44
@benjeffery
Copy link
Member Author

@jeromekelleher Ok! Should be good to go.

Copy link
Member

@jeromekelleher jeromekelleher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spotted a few more things, but LGTM then.

We should get some wider input on this before adding to schema i guess, maybe do a shout out on Slack?

@@ -35,6 +43,9 @@
import tskit.provenance as provenance


_start_time = time.time()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Global value probably doesn't help with testing

assert "max_memory" in resources

def test_used_resources_values(self):
resources = provenance.get_resources(_start_time)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something less fragile would be time.time() - delta, and then test that elapsed time is >= delta.

assert isinstance(resources["user_time"], float)
assert isinstance(resources["sys_time"], float)
assert resources["elapsed_time"] > 0.0001
assert resources["user_time"] > 0.0001
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just do > 0 here, there will surely be cases there this fails in CI or whatever


try:
import resource
except ImportError:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's just that the module doesn't exist on Win right? Otherwise check wouldn't work.

"sys_time": times.system + times.children_system,
}
if resource is not None:
# Don't report max memory on Windows. We could do this using the psutil lib, via
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment isn't accurate for tskit - I don't think we'd want a dependency on psutil.

# psutil.Process(os.getpid()).get_ext_memory_info().peak_wset if demand exists
ret["max_memory"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
if sys.platform != "darwin":
ret["max_memory"] *= 1024 # Linux, freeBSD et al reports in KB, not bytes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be specific it's KiB not KB (10**3)

@benjeffery
Copy link
Member Author

Comments addressed in 06a4132

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants