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
Speeding up congruence-related lattice functions #23383
Comments
Changed branch from u/jmantysalo/precompute-intervals to none |
Commit: |
comment:4
I consider Hasse diagrams not as part of the true API, but an implementation detail of posets. So I don't see any problem with changing the output type. Although it is part of the API for Also, it might be faster to have the
There is no need to create the empty object and you save a lot of Python calls by doing the dict comprehension. New commits:
|
comment:5
Replying to @tscrim:
Actually, even faster should be a list of lists, that needs no lookup at all.
True. I was thinking about lists but then somehow ended up to dict in this PoC. And now the most important:
OK. I tested by adding precomputing to |
comment:6
Replying to @jm58660:
Well, there still is a lookup, but now it is (relatively) very fast. +1 for list of lists.
I think it would be best if the numbering was done increasing (as that is assumed to be a linear extension IIRC). |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:8
Here it is. The speedup is quite big:
|
comment:9
If you want even more speed: - v_up = [None] * n
- v_down = [None] * n
- for v in range(n):
- v_up[v] = frozenset(self.depth_first_search(v))
- v_down[v] = frozenset(self.depth_first_search(v, neighbors=self.neighbors_in))
+ v_up = [frozenset(self.depth_first_search(v)) for v in range(n)]
+ v_down = [frozenset(self.depth_first_search(v, neighbors=self.neighbors_in))
+ for v in range(n)]
- self._intervals = [[None] * n for _ in range(n)]
- for u in range(n):
- for v in range(n):
- self._intervals[u][v] = sorted(v_up[u].intersection(v_down[v]))
+ self._intervals = [[sorted(up.intersection(down)) for down in v_down]
+ for up in v_up] I've seen using list comprehension have a significant effect for things like this because of the extra Python overhead. I do not like the documentation of You also should update the ticket description. |
Branch pushed to git repo; I updated commit sha1. New commits:
|
This comment has been minimized.
This comment has been minimized.
comment:11
Replying to @tscrim:
Done that. And yes, it gives some milliseconds: for Much more speedup should be possible with better algorithm: an interval from
I added a note about this to the description. Needs to think for a while. |
Reviewer: Travis Scrimshaw |
comment:12
However, I still would like to see a bit better of documentation for |
comment:13
First, a technical question: A Python function can return an internal function, i.e. this will print "Hello":
Would it be meaningfull to use this feature, and remove Now to the main question. The problem is, IMO, When should this precomputing be called? In I will formulate longer description for |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:15
More comments on this? Specially for this:
|
comment:16
Replying to @jm58660:
Yes, that is correct. We return functions in a number of places within Sage too.
I do not think so by default because of how much memory this would use. Although it could be something we do for small posets (less that 5 vertices?).
That should not be true. Once you delete all references to a poset, it should be freeable as it is a weak reference (otherwise it is a memory leak bug).
Probably in none of these places, but instead we should document it as an alternative method for increasing the speed. |
comment:17
Replying to @tscrim:
If that would be true, then for example this should print the same number again and again:
(Compare this with same except Currently there is no way to for example search for counter-example with random posets to unlimited time. |
comment:18
I know import gc
i = 0
j = 0
for P in Posets(8):
j += 1
if j % 100 == 0:
gc.collect()
print(sage.misc.getusage.get_memory_usage())
if P.is_connected():
i += 1
print(i) IIRC, Python will force a garbage collection to see if it can free up the memory before giving an out-of-memory exception. Although I've never really done anything that would cause that to happen. |
comment:19
Replying to @tscrim: First, thanks for
The problem is propably memory overcommit or usage of every bit of memory. When almost every byte is used, Linux is extremely slow, and so never goes to the limit where Python would give out-of-memory exception. This should be handled in Python level or in OS level. Sage can only add some temporary workarounds. |
comment:20
One last trivial thing: code format |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:22
Replying to @tscrim:
Done that. |
Changed branch from u/jmantysalo/precompute-intervals to |
This patch adds precomputing intervals in the
HasseDiagram
to speed up some congruence-related lattice functions. IfL = Posets.BooleanLattice(7)
, then we haveand after
L._hasse_diagram._precompute_intervals()
OTOH this will eat memory.
Currently this feature is well hidden, only available as a
_
-function of a_
-variable. Later we should think about interface. A global "save-cpu-eat-memory" -switch or "aux functions" to lattices (posets?) or something else?CC: @tscrim @fchapoton
Component: combinatorics
Author: Jori Mäntysalo
Branch/Commit:
6f8c510
Reviewer: Travis Scrimshaw
Issue created by migration from https://trac.sagemath.org/ticket/23383
The text was updated successfully, but these errors were encountered: