Skip to content

Restore memory efficiency - #75

Merged
XingerTang merged 1 commit into
AlphaGenes:develfrom
XingerTang:refactor/seg-prob-mem-optional
Aug 7, 2026
Merged

Restore memory efficiency#75
XingerTang merged 1 commit into
AlphaGenes:develfrom
XingerTang:refactor/seg-prob-mem-optional

Conversation

@XingerTang

Copy link
Copy Markdown
Contributor

What changed

  • segregation probability would store in memory only if segregation outpus is required

Why this change

  • To reduce unnecessary memory usage

Notes / Risks

  • Small changes only

@XingerTang
XingerTang changed the base branch from main to devel August 6, 2026 09:25
@XingerTang

Copy link
Copy Markdown
Contributor Author

After the change, the memory usage for the combined mode accuracy test dropped from

Allocation results for tests/accuracy_tests/run_accu_test.py::test_accu[combined] at the high watermark

         📦 Total memory allocated: 158.0MiB
         📏 Total allocations: 11
         📊 Histogram of allocation sizes: |▅▂█ ▂|
         🥇 Biggest allocating functions:
                - _read:/Users/xtang3/anaconda3/envs/phase/lib/python3.11/site-packages/numpy/lib/_npyio_impl.py:1046 -> 96.9MiB
                - _read:/Users/xtang3/anaconda3/envs/phase/lib/python3.11/site-packages/numpy/lib/_npyio_impl.py:1046 -> 61.0MiB
                - decode:<frozen codecs>:322 -> 32.1KiB
                - _read:/Users/xtang3/anaconda3/envs/phase/lib/python3.11/site-packages/numpy/lib/_npyio_impl.py:962 -> 15.6KiB
                - assess_peeling:/Users/xtang3/AlphaImpute2/tests/accuracy_tests/run_accu_test.py:140 -> 15.6KiB

to

Allocation results for tests/accuracy_tests/run_accu_test.py::test_accu[combined] at the high watermark

         📦 Total memory allocated: 79.9MiB
         📏 Total allocations: 10
         📊 Histogram of allocation sizes: |▂▂█ ▅|
         🥇 Biggest allocating functions:
                - _read:/Users/xtang3/anaconda3/envs/phase/lib/python3.11/site-packages/numpy/lib/_npyio_impl.py:1046 -> 49.3MiB
                - _read:/Users/xtang3/anaconda3/envs/phase/lib/python3.11/site-packages/numpy/lib/_npyio_impl.py:1046 -> 30.5MiB
                - decode:<frozen codecs>:322 -> 32.1KiB
                - _read:/Users/xtang3/anaconda3/envs/phase/lib/python3.11/site-packages/numpy/lib/_npyio_impl.py:962 -> 15.6KiB
                - assess_peeling:/Users/xtang3/AlphaImpute2/tests/accuracy_tests/run_accu_test.py:134 -> 15.6KiB

# Sets the founder anterior values and penetrance value for Heuristic peeling.
for ind in pedigree:
ind.setPeelingView()
ind.setPeelingView(bool(args.seg_output))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I personally like to add arg keyword as it makes code clearer to me, but I don't know what's the preferred/popular Python style;) Your call @XingerTang!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The whole args might be unnecessary here. I can make seg_outputa variable that is assigned earlier separately; it would be like:

seg_output = bool(args.seg_output)
for ind in pedigree:
  ind.setPeelingView(seg_output)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree it's not needed. I personally prefer code like ind.setPeelingView(store_out_segregation = bool(args.seg_output)) or ind.setPeelingView(store_out_segregation = seg_output), but that's just my taste. You decide what works best for this codebase!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated the code to the latter way. Python requires all positional arguments to come before any keyword arguments; I usually do not specify the keyword if it can be positional during development to avoid the ordering issue. But this one only has one argument, so it doesn't matter.

@gregorgorjanc gregorgorjanc left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like a simple change! Great.

@XingerTang

Copy link
Copy Markdown
Contributor Author

In 7ac3f4f, the memory is no longer allocated to the segregation prob output vector if that is not required. While the pytest memray benchmark results are promising, the experiment with the real data is not as effective as expected.

In the early version v0.0.1, the memory usage is:

 Max vmem         = 3.917G
 Max rss          = 2.821G

Before this change (v0.0.4), the memory usage is:

 Max vmem         = 5.503G
 Max rss          = 5.284G

After the commit, without seg_output requested, the memory usage is:

 Max vmem         = 4.792G
 Max rss          = 4.562G

There is a significant decrease after the change, but it is not as much as the difference between v0.0.1 and v0.0.4.

Therefore, in 46d2ca1, I cleared the peeling_view when seg_output is not requested.
This change does not change the memory usage of pytest, but it might be that the data size is not enough, as the code would just make some of the used memory space available for a new memory requirement.

@XingerTang

Copy link
Copy Markdown
Contributor Author

After 46d2ca1, the memory usage dropped to

 Max vmem         = 3.722G
 Max rss          = 3.487G

which the Max vmem is smaller than the v0.0.1 usage. However, the Max rss is still higher.

@XingerTang

Copy link
Copy Markdown
Contributor Author

A possible source of the difference of Max vmem might be led by the full storage of genotype probabilities of all individuals instead of the individuals with progeny, which was introduced in the v0.0.3 to correct the haplotypes when the haplotypes and genotypes do not match.

dc5595f restored the original probability storage pattern without affecting the haplotype and genotype matching.

The memray profile on pytest still stay the same, but the real data result might be different.

@XingerTang XingerTang changed the title Make seg prob stored in memory optional Restore memory efficiency Aug 6, 2026
@XingerTang

XingerTang commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

The memory usage for dc5595f on the same data gives:

 Max vmem         = 2.850G
 Max rss          = 2.615G

which I'm quite happy to see.

diff against output files shows that the outputs after the changes are exactly the same as the outputs before the changes.

@gregorgorjanc

Copy link
Copy Markdown
Member

@XingerTang this is great testing! I assume all accuracy metrics and runtime are unaffected - good to check. I am asking because I see you are not storing or you are clearing some objects, which is what we want so I guess this is all fine and gives you lower memory footprint, but you seem to have to do some extra work with phase_probabilities too (will that change runtime, probably not). Looking at the code it seems that accuracies should not change.

@XingerTang

Copy link
Copy Markdown
Contributor Author

@XingerTang this is great testing! I assume all accuracy metrics and runtime are unaffected - good to check. I am asking because I see you are not storing or you are clearing some objects, which is what we want so I guess this is all fine and gives you lower memory footprint, but you seem to have to do some extra work with phase_probabilities too (will that change runtime, probably not). Looking at the code it seems that accuracies should not change.

All the metrics are the same, and essentially the output files are exactly the same. There are more temporary holders (such as phase_probabilities) instead of big blocks of probabilities, but essentially it does not change anything.

@gregorgorjanc

Copy link
Copy Markdown
Member

All the metrics are the same, and essentially the output files are exactly the same. There are more temporary holders (such as phase_probabilities) instead of big blocks of probabilities, but essentially it does not change anything.

Excellent - all is well then. Well done on cracking this memory issue!

@XingerTang

Copy link
Copy Markdown
Contributor Author

There are some issues with GitHub Action runners: https://www.githubstatus.com/

@XingerTang

Copy link
Copy Markdown
Contributor Author

I think it's okay we ignore the failing tests (all caused by the GitHub runner issue) and merge

Comment thread pyproject.toml
[project]
name = "AlphaImpute2"
version = "0.0.4"
version = "0.0.5"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@XingerTang I suggest we also add maintainers here and later co-authors.

@gregorgorjanc

Copy link
Copy Markdown
Member

I agree - all the failures are due to outage on GitHub side. Add the maintainers and merge;)

@XingerTang
XingerTang force-pushed the refactor/seg-prob-mem-optional branch from 7a0a314 to ae67a85 Compare August 7, 2026 11:30
@XingerTang
XingerTang merged commit a354acf into AlphaGenes:devel Aug 7, 2026
24 checks passed
@XingerTang
XingerTang deleted the refactor/seg-prob-mem-optional branch August 7, 2026 13:28
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