Ticket #13447: trac_13447-rely_on_singular_refcount.patch
File trac_13447-rely_on_singular_refcount.patch, 17.1 KB (added by , 10 years ago) |
---|
-
sage/libs/singular/function.pxd
# HG changeset patch # User Simon King <simon.king@uni-jena.de> # Date 1347900112 25200 # Node ID eca1b57c72e06d366bcc49dd00ec51a556f3d049 # Parent d3c4342687384e481349a5d3b401636896f5864a #13447: Remove the custom ring refcount, and entirely rely on the refcounter provided by Singular diff --git a/sage/libs/singular/function.pxd b/sage/libs/singular/function.pxd
a b 18 18 from sage.libs.singular.decl cimport leftv, idhdl, syStrategy, matrix, poly, ideal, intvec 19 19 from sage.libs.singular.decl cimport ring as singular_ring 20 20 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular, MPolynomial_libsingular 21 from sage.libs.singular.ring cimport singular_ring_reference, singular_ring_delete 21 22 22 23 cdef poly* access_singular_poly(p) except <poly*> -1 23 24 cdef singular_ring* access_singular_ring(r) except <singular_ring*> -1 -
sage/libs/singular/function.pyx
diff --git a/sage/libs/singular/function.pyx b/sage/libs/singular/function.pyx
a b 146 146 if not self.is_commutative(): 147 147 return "<noncommutative RingWrap>" 148 148 return "<RingWrap>" 149 149 150 150 def __dealloc__(self): 151 if self._ring!=NULL: 152 self._ring.ref -= 1 151 singular_ring_delete(self._ring) 153 152 154 153 def ngens(self): 155 154 """ … … 816 815 """ 817 816 Append the ring ``r`` to the list. 818 817 """ 819 cdef ring *_r = access_singular_ring(r) 820 _r.ref+=1 818 cdef ring *_r = singular_ring_reference(access_singular_ring(r)) 821 819 return self._append(<void *>_r, RING_CMD) 822 820 823 821 cdef leftv *append_matrix(self, mat) except NULL: … … 957 955 958 956 959 957 elif rtyp == RING_CMD or rtyp==QRING_CMD: 960 return new_RingWrap( <ring*> to_convert.data ) 958 # We need to incref the to-be-converted data, 959 # since apparently removing to_convert.data would 960 # decref it. 961 return new_RingWrap( singular_ring_reference(<ring*> to_convert.data) ) 961 962 962 963 elif rtyp == MATRIX_CMD: 963 964 return self.to_sage_matrix(<matrix*> to_convert.data ) … … 1790 1791 #cdef ring*? 1791 1792 cdef inline RingWrap new_RingWrap(ring* r): 1792 1793 cdef RingWrap ring_wrap_result = PY_NEW(RingWrap) 1793 ring_wrap_result._ring = r 1794 ring_wrap_result._ring.ref += 1 1795 1794 ring_wrap_result._ring = singular_ring_reference(r) 1796 1795 return ring_wrap_result -
sage/libs/singular/groebner_strategy.pxd
diff --git a/sage/libs/singular/groebner_strategy.pxd b/sage/libs/singular/groebner_strategy.pxd
a b 15 15 16 16 cdef class NCGroebnerStrategy(SageObject): 17 17 cdef skStrategy *_strat 18 cdef ring *_parent_ring 18 19 cdef NCPolynomialRing_plural _parent 19 20 cdef object _ideal 20 21 -
sage/libs/singular/groebner_strategy.pyx
diff --git a/sage/libs/singular/groebner_strategy.pyx b/sage/libs/singular/groebner_strategy.pyx
a b 339 339 340 340 cdef NCPolynomialRing_plural R = <NCPolynomialRing_plural>L.ring() 341 341 self._parent = R 342 self._parent_ring = singular_ring_reference(R._ring) 342 343 343 344 if not R.term_order().is_global(): 344 345 raise NotImplementedError("The local case is not implemented yet.") … … 394 395 omfree(self._strat.fromQ) 395 396 id_Delete(&self._strat.Shdl, self._parent._ring) 396 397 397 if self._parent ._ring != currRing:398 if self._parent_ring != currRing: 398 399 oldRing = currRing 399 rChangeCurrRing(self._parent ._ring)400 rChangeCurrRing(self._parent_ring) 400 401 delete_skStrategy(self._strat) 401 402 rChangeCurrRing(oldRing) 402 403 else: 403 404 delete_skStrategy(self._strat) 405 singular_ring_delete(self._parent_ring) 404 406 405 407 def _repr_(self): 406 408 """ -
sage/libs/singular/ring.pxd
diff --git a/sage/libs/singular/ring.pxd b/sage/libs/singular/ring.pxd
a b 48 48 # create a new singular ring 49 49 cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL 50 50 51 # referencean existing ring51 # incref an existing ring 52 52 cdef ring *singular_ring_reference(ring *existing_ring) except NULL 53 53 54 54 # carefully delete a ring once its refcount is zero -
sage/libs/singular/ring.pyx
diff --git a/sage/libs/singular/ring.pyx b/sage/libs/singular/ring.pyx
a b 328 328 329 329 330 330 ############################################################################# 331 ring_refcount_dict = {}332 333 331 334 332 cdef class ring_wrapper_Py(object): 335 333 r""" … … 462 460 sage: _ = gc.collect() 463 461 sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular 464 462 sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy 465 sage: from sage.libs.singular.ring import ring_refcount_dict 466 sage: n = len(ring_refcount_dict) 467 sage: prev_rings = set(ring_refcount_dict.keys()) 463 sage: n = len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) 468 464 sage: P = MPolynomialRing_libsingular(GF(541), 2, ('x', 'y'), TermOrder('degrevlex', 2)) 469 sage: ring_ptr = set(ring_refcount_dict.keys()).difference(prev_rings).pop()470 sage: ring_ptr # random output471 The ring pointer 0x7f78a646b8d0472 sage: ring_refcount_dict[ring_ptr]473 4474 465 475 466 sage: strat = GroebnerStrategy(Ideal([P.gen(0) + P.gen(1)])) 476 sage: ring_refcount_dict[ring_ptr]477 6478 467 479 468 sage: del strat 480 sage: _ = gc.collect()481 sage: ring_refcount_dict[ring_ptr]482 4483 484 469 sage: del P 485 470 sage: _ = gc.collect() 486 sage: ring_ptr in ring_refcount_dict487 False471 sage: n == len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) 472 True 488 473 """ 489 474 if existing_ring==NULL: 490 475 raise ValueError('singular_ring_reference(ring*) called with NULL pointer.') … … 524 509 # this function is typically called in __deallocate__, so we can't raise an exception 525 510 import traceback 526 511 traceback.print_stack() 527 528 if not ring_refcount_dict: # arbitrary finalization order when we shut Sage down529 512 return 530 513 531 if doomed.ref > 1: 532 doomed.ref = doomed.ref-1 514 doomed.ref = doomed.ref-1 515 if doomed.ref > 0: 516 return 517 518 if doomed.ref < 0: 519 print "singular_ring_delete(ring*) called with a ring that had no references." 520 import traceback 521 traceback.print_stack() 533 522 return 534 523 535 524 global currRing -
sage/modular/modsym/ambient.py
diff --git a/sage/modular/modsym/ambient.py b/sage/modular/modsym/ambient.py
a b 1341 1341 def boundary_space(self): 1342 1342 r""" 1343 1343 Return the subspace of boundary modular symbols of this modular symbols ambient space. 1344 1344 1345 1345 EXAMPLES:: 1346 1347 sage: ModularSymbols(20,2).boundary_space() 1346 1347 sage: M = ModularSymbols(20, 2) 1348 sage: B = M.boundary_space(); B 1348 1349 Space of Boundary Modular Symbols for Congruence Subgroup Gamma0(20) of weight 2 and over Rational Field 1349 sage: ModularSymbols(20,2).dimension() 1350 sage: M.cusps() 1351 [Infinity, 0, -1/4, 1/5, -1/2, 1/10] 1352 sage: M.dimension() 1350 1353 7 1351 sage: ModularSymbols(20,2).boundary_space().dimension()1354 sage: B.dimension() 1352 1355 6 1356 1353 1357 """ 1354 1358 raise NotImplementedError 1355 1359 -
sage/rings/polynomial/multi_polynomial_libsingular.pyx
diff --git a/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/sage/rings/polynomial/multi_polynomial_libsingular.pyx
a b 392 392 if self._ring != NULL: # the constructor did not raise an exception 393 393 singular_ring_delete(self._ring) 394 394 395 def _get_refcount(self): 396 """ 397 Return the number of references set to this ring. 398 399 NOTE: 400 401 This is mainly for doctesting. 402 403 EXAMPLES:: 404 405 sage: import gc 406 sage: gc.collect() # random 407 sage: R.<x,y,z> = GF(5)[] 408 sage: n = R._get_refcount() 409 sage: p = x*y+z 410 sage: R._get_refcount() == n+1 411 True 412 sage: del p 413 sage: gc.collect() # random 414 sage: R._get_refcount() == n 415 True 416 417 """ 418 if self._ring==NULL: 419 return 0 420 return self._ring.ref 421 395 422 def __copy__(self): 396 423 """ 397 424 Copy ``self``. … … 402 429 403 430 sage: import gc 404 431 sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular 405 sage: from sage.libs.singular.ring import ring_refcount_dict406 432 sage: gc.collect() # random output 407 sage: n = len( ring_refcount_dict)433 sage: n = len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) 408 434 sage: R = MPolynomialRing_libsingular(GF(547), 2, ('x', 'y'), TermOrder('degrevlex', 2)) 409 sage: len( ring_refcount_dict) == n +1435 sage: len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) == n+1 410 436 True 411 437 412 438 sage: Q = copy(R) # indirect doctest … … 417 443 sage: del p 418 444 sage: del q 419 445 sage: gc.collect() # random output 420 sage: len( ring_refcount_dict) == n446 sage: len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) == n 421 447 True 422 448 """ 423 449 return self -
sage/rings/polynomial/plural.pxd
diff --git a/sage/rings/polynomial/plural.pxd b/sage/rings/polynomial/plural.pxd
a b 4 4 from sage.structure.element cimport RingElement, Element 5 5 from sage.structure.parent cimport Parent 6 6 from sage.libs.singular.function cimport RingWrap 7 from sage.libs.singular.ring cimport singular_ring_reference 7 8 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular 8 9 9 10 … … 29 30 30 31 cdef class NCPolynomial_plural(RingElement): 31 32 cdef poly *_poly 33 cdef ring *_parent_ring 32 34 cpdef _repr_short_(self) 33 35 cdef long _hash_c(self) 34 36 cpdef is_constant(self) -
sage/rings/polynomial/plural.pyx
diff --git a/sage/rings/polynomial/plural.pyx b/sage/rings/polynomial/plural.pyx
a b 111 111 from sage.structure.parent_gens cimport ParentWithGens 112 112 113 113 # singular rings 114 from sage.libs.singular.ring cimport singular_ring_new, singular_ring_delete , wrap_ring114 from sage.libs.singular.ring cimport singular_ring_new, singular_ring_delete 115 115 import sage.libs.singular.ring 116 116 117 117 from sage.rings.integer cimport Integer … … 335 335 cdef RingWrap rw = ncalgebra(self._c, self._d, ring = P) 336 336 337 337 # rw._output() 338 self._ring = rw._ring338 self._ring = singular_ring_reference(rw._ring) 339 339 self._ring.ShortOut = 0 340 340 341 341 self.__ngens = n … … 408 408 sage: _ = gc.collect() 409 409 """ 410 410 singular_ring_delete(self._ring) 411 411 412 def _get_refcount(self): 413 """ 414 Return the number of references to the underlying c data of this ring. 415 416 NOTE: 417 418 This is mainly for doctesting. 419 420 EXAMPLES:: 421 422 sage: import gc 423 sage: gc.collect() # random 424 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 425 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 426 sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 427 sage: n = H._get_refcount() 428 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 429 sage: strat = NCGroebnerStrategy(I) 430 431 We have created three elements of `H` and one Groebner strategy. 432 Each create a reference to the underlying c data. Hence, we have:: 433 434 sage: H._get_refcount() == n+4 435 True 436 sage: del strat 437 sage: gc.collect() # random 438 sage: H._get_refcount() == n+3 439 True 440 sage: del I 441 sage: gc.collect() # random 442 sage: H._get_refcount() == n 443 True 444 sage: p = x*y+z 445 sage: H._get_refcount() == n+1 446 True 447 sage: del p 448 sage: gc.collect() # random 449 sage: H._get_refcount() == n 450 True 451 452 """ 453 if self._ring==NULL: 454 return 0 455 return self._ring.ref 456 412 457 def _element_constructor_(self, element): 413 458 """ 414 459 Make sure element is a valid member of self, and return the constructed element. … … 853 898 854 899 from sage.libs.singular.function import singular_function 855 900 ring = singular_function('ring') 856 return ring(L, ring=self) 901 cdef RingWrap W = ring(L, ring=self) 902 # Apparently, the "ring" function does *not* increment the reference 903 # count to the ring. 904 W._ring = singular_ring_reference(W._ring) 905 return W 857 906 858 907 # TODO: Implement this properly! 859 908 # def quotient(self, I): … … 1357 1406 """ 1358 1407 self._poly = NULL 1359 1408 self._parent = <ParentWithBase>parent 1409 self._parent_ring = singular_ring_reference(parent._ring) 1360 1410 1361 1411 def __dealloc__(self): 1362 # TODO: Warn otherwise!1363 # for some mysterious reason, various things may be NULL in some cases1364 if self._parent is not <ParentWithBase>None and (<NCPolynomialRing_plural>self._parent)._ring != NULL and self._poly != NULL:1365 p_Delete(&self._poly, (<NCPolynomialRing_plural>self._parent)._ring)1412 if self._poly != NULL: 1413 if self._parent_ring != NULL: 1414 p_Delete(&self._poly, self._parent_ring) 1415 singular_ring_delete(self._parent_ring) 1366 1416 1367 1417 # def __call__(self, *x, **kwds): # ? 1368 1418 … … 1757 1807 sage: f # indirect doctest 1758 1808 x^3 - x*z*y + z^2 + z 1759 1809 """ 1760 cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring1810 cdef ring *_ring = self._parent_ring 1761 1811 s = singular_polynomial_str(self._poly, _ring) 1762 1812 return s 1763 1813 … … 2677 2727 """ 2678 2728 cdef NCPolynomial_plural p = PY_NEW(NCPolynomial_plural) 2679 2729 p._parent = <ParentWithBase>parent 2730 p._parent_ring = singular_ring_reference(parent._ring) 2680 2731 p._poly = juice 2681 2732 p_Normalize(p._poly, parent._ring) 2682 2733 return p … … 2712 2763 2713 2764 Check that #13145 has been resolved:: 2714 2765 2715 sage: h = hash(R.gen() + 1) # sets currRing 2716 sage: from sage.libs.singular.ring import ring_refcount_dict, currRing_wrapper 2717 sage: curcnt = ring_refcount_dict[currRing_wrapper()] 2718 sage: newR = new_CRing(W, H.base_ring()) 2719 sage: ring_refcount_dict[currRing_wrapper()] - curcnt 2720 1 2766 sage: import gc 2767 sage: gc.collect() # random 2768 sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy 2769 sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 2770 sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 2771 sage: n = H._get_refcount() 2772 sage: I = H.ideal([y^2, x^2, z^2-H.one_element()]) 2773 sage: strat = NCGroebnerStrategy(I) 2774 2775 We have created three elements and one Groebner strategy, and thus have 2776 four additional references to the underlying c data:: 2777 2778 sage: H._get_refcount() == n+4 2779 True 2780 sage: del strat, I 2781 sage: gc.collect() # random 2782 sage: H._get_refcount() == n 2783 True 2784 2721 2785 """ 2722 2786 assert( rw.is_commutative() ) 2723 2787 2724 2788 cdef MPolynomialRing_libsingular self = <MPolynomialRing_libsingular>PY_NEW(MPolynomialRing_libsingular) 2725 2726 self._ring = rw._ring 2727 2728 wrapped_ring = wrap_ring(self._ring) 2729 cur_refcnt = sage.libs.singular.ring.ring_refcount_dict.get(wrapped_ring, 0) 2730 sage.libs.singular.ring.ring_refcount_dict[wrapped_ring] = cur_refcnt + 1 2789 2790 self._ring = singular_ring_reference(rw._ring) 2731 2791 2732 2792 self._ring.ShortOut = 0 2733 2793 … … 2790 2850 assert( not rw.is_commutative() ) 2791 2851 2792 2852 cdef NCPolynomialRing_plural self = <NCPolynomialRing_plural>PY_NEW(NCPolynomialRing_plural) 2793 self._ring = rw._ring 2794 2795 wrapped_ring = wrap_ring(self._ring) 2796 cur_refcnt = sage.libs.singular.ring.ring_refcount_dict.get(wrapped_ring, 0) 2797 sage.libs.singular.ring.ring_refcount_dict[wrapped_ring] = cur_refcnt + 1 2853 self._ring = singular_ring_reference(rw._ring) 2798 2854 2799 2855 self._ring.ShortOut = 0 2800 2856 … … 2908 2964 I = H.ideal([H.gen(i) *H.gen(i) for i in alt_vars]).twostd() 2909 2965 L = H._ringlist() 2910 2966 L[3] = I 2911 W = H._list_to_ring(L)2967 cdef RingWrap W = H._list_to_ring(L) 2912 2968 return new_NRing(W, H.base_ring()) 2913 2969 2914 2970 cdef poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring):