Ticket #13400: trac_13400_cache_small_rings.patch

File trac_13400_cache_small_rings.patch, 4.4 KB (added by SimonKing, 7 years ago)

Prevent small finite rings from being garbage collected

  • sage/categories/covariant_functorial_construction.py

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1346013741 -7200
    # Node ID e122550648872290ee7ff51dbbeb2e726cfbd9cb
    # Parent  a4f96312df70992d0e7979afd92c77f5bbb0b55a
    imported patch trac_13400_cache_small_rings.patch
    
    diff --git a/sage/categories/covariant_functorial_construction.py b/sage/categories/covariant_functorial_construction.py
    a b  
    356356        """
    357357        return Category.join([getattr(cat, cls._functor_category)(*args) for cat in category._super_categories])
    358358
    359     def is_subcategory(self, C):
    360         """
    361         .. todo:: doctests + explain why this method is needed
    362         """
    363         if C is self:
    364             return True
    365         return any(X.is_subcategory(C) for X in self._super_categories)
    366 
    367359    def __init__(self, category, *args):
    368360        """
    369361        TESTS::
  • sage/categories/homset.py

    diff --git a/sage/categories/homset.py b/sage/categories/homset.py
    a b  
    1919    True
    2020
    2121Nonetheless, garbage collection occurs when the original references are
    22 overwritten::
     22overwritten. Note that finite fields of order at most 500 are permantently
     23cached, by :trac:`13400`, so that we have to use bigger fields in this example::
    2324
    24     sage: for p in prime_range(200):
     25    sage: for p in prime_range(500,1000):
    2526    ...     K = GF(p)
    2627    ...     H = Hom(ZZ, K)
    2728    ...
    2829    sage: import gc
    2930    sage: _ = gc.collect()
    3031    sage: from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn as FF
    31     sage: L = [x for x in gc.get_objects() if isinstance(x, FF)]
     32    sage: L = [x for x in gc.get_objects() if isinstance(x, FF) and x.order()>500]
    3233    sage: len(L)
    33     2
     34    1
    3435    sage: L
    35     [Finite Field of size 2, Finite Field of size 199]
     36    [Finite Field of size 997]
    3637
    3738AUTHORS:
    3839
     
    115116    Here, we test against a memory leak that has been fixed at :trac:`11521` by
    116117    using a weak cache::
    117118
    118         sage: for p in prime_range(10^5):
     119        sage: for p in prime_range(500,10^5):
    119120        ...    K = GF(p)
    120121        ...    a = K(0)
    121122        sage: import gc
    122123        sage: gc.collect()       # random
    123124        624
    124125        sage: from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn as FF
    125         sage: L = [x for x in gc.get_objects() if isinstance(x, FF)]
    126         sage: len(L), L[0], L[len(L)-1]
    127         (2, Finite Field of size 2, Finite Field of size 99991)
     126        sage: L = [x for x in gc.get_objects() if isinstance(x, FF) and x.order()>500]
     127        sage: L
     128        [Finite Field of size 99991]
    128129
    129130    To illustrate the choice of the category, we consider the
    130131    following parents as running examples::
  • sage/rings/finite_rings/constructor.py

    diff --git a/sage/rings/finite_rings/constructor.py b/sage/rings/finite_rings/constructor.py
    a b  
    172172
    173173from sage.structure.factory import UniqueFactory
    174174
     175strong_references = [] # if the elements of a finite field are cached,
     176                       # the field itself will be strongly cached, too
     177
    175178class FiniteFieldFactory(UniqueFactory):
    176179    """
    177180    Return the globally unique finite field of given order with
     
    458461                    else:
    459462                        from finite_field_ext_pari import FiniteField_ext_pari
    460463                        K = FiniteField_ext_pari(order, name, modulus, **kwds)
    461 
     464        if elem_cache:
     465            strong_references.append(K)
    462466        return K
    463467
    464468    def other_keys(self, key, K):
  • sage/rings/finite_rings/integer_mod_ring.py

    diff --git a/sage/rings/finite_rings/integer_mod_ring.py b/sage/rings/finite_rings/integer_mod_ring.py
    a b  
    177177default_category = JoinCategory((CommutativeRings(), FiniteEnumeratedSets()))
    178178ZZ = integer_ring.IntegerRing()
    179179
     180strong_references = [] # If the elements are cached, then the ring itself, too.
     181
    180182class IntegerModRing_generic(quotient_ring.QuotientRing_generic):
    181183    """
    182184    The ring of integers modulo N, with N composite.
     
    333335        if cache is None:
    334336            cache = order < 500
    335337        if cache:
     338            strong_references.append(self)
    336339            self._precompute_table()
    337340        self._zero_element = integer_mod.IntegerMod(self, 0)
    338341        self._one_element = integer_mod.IntegerMod(self, 1)