#17435: Cythonise path algebra elements
-------------------------------------+-------------------------------------
       Reporter:  SimonKing          |        Owner:
           Type:  enhancement        |       Status:  needs_review
       Priority:  major              |    Milestone:  sage-6.8
      Component:  algebra            |   Resolution:
       Keywords:  path algebra       |    Merged in:
  elements, days64.5, days65         |    Reviewers:
        Authors:  Simon King         |  Work issues:
Report Upstream:  N/A                |       Commit:
         Branch:                     |  8d5d84687d0b60db3890a1f00b6b8acac3fc2c67
  public/17435/cythonise_path_algebra_elements|     Stopgaps:
   Dependencies:  #16453 #17526      |
-------------------------------------+-------------------------------------

Comment (by SimonKing):

 Replying to [comment:123 jdemeyer]:
 > In short, I would prefer to revert all changes to bitset/biseq.

 I didn't revert all changes, but most of them. Also I changed the signal
 handling according to your advices.

 These changes did hardly change the timings for the few examples that I
 did. As mentioned in comment:136, profiling indicated that I should use
 more care for deallocation resp. for the freelist. I did as follows:

 1. The freelist (which serves for lazy allocation/deallocation of terms)
 now is not a linked list of terms, but a static array. That allowed to
 simplify term_free and term_create_... functions.

 2. I increased the size of the freelist from 1000 to 5000. Hopefully
 acceptable.

 3. Examples show that it is unlikely that the freelist is empty, it is
 unlikely that we are dealing with paths of length zero, and it is likely
 that monomials have more than one reference. I used Cython's likely(...)
 and unlikely(...) accordingly, which seemed to have an effect.

 __Results__

 - Doctests pass.

 - It still seems that functions are interruptible.

 - I tested that
   {{{
 sage: P =
 
DiGraph({Integer(1):{Integer(1):['x','y','z']}}).path_semigroup().algebra(GF(Integer(25),'t'))
 sage: P.inject_variables()
 Defining e_1, x, y, z
 sage: while 1:
 ....:     p = x^4+x*y*x*z+2*z^2*x*y
 ....:     q = p^7
 ....:     print get_memory_usage()
   }}}
   does not leak memory.

 - Timing now is as follows:
   {{{
 sage: %timeit p = x^4+x*y*x*z+2*z^2*x*y
 The slowest run took 4.13 times longer than the fastest. This could mean
 that an intermediate result is being cached
 100000 loops, best of 3: 17.9 µs per loop
 sage: p = x^4+x*y*x*z+2*z^2*x*y
 sage: %timeit q = p^7
 1000 loops, best of 3: 954 µs per loop
   }}}
   That is no change in the "small" example and a visible improvement in
 the second example.
 - Profiling yields
   {{{
 sage: %crun for n in xrange(1000): q = (x^4+x*y*x*z+2*z^2*x*y)^7
 PROFILE: interrupts/evictions/bytes = 103/1/28248
 Using local file /home/king/Sage/git/sage/local/bin/python.
 Using local file /home/king/.sage/temp/linux-
 va3e.site/14199/tmp_FhpNzY.perf.
 Total: 103 samples
        0   0.0%   0.0%       91  88.3% PyEval_EvalCode
        1   1.0%   1.0%       91  88.3% PyEval_EvalCodeEx
        1   1.0%   1.9%       91  88.3% PyEval_EvalFrameEx
        0   0.0%   1.9%       91  88.3% PyObject_Call
        0   0.0%   1.9%       91  88.3% PyRun_FileExFlags
        0   0.0%   1.9%       91  88.3% PyRun_SimpleFileExFlags
        0   0.0%   1.9%       91  88.3% PyRun_StringFlags
        0   0.0%   1.9%       91  88.3% Py_Main
        0   0.0%   1.9%       91  88.3% __libc_start_main
        0   0.0%   1.9%       91  88.3% _start
        0   0.0%   1.9%       91  88.3% call_function (inline)
        0   0.0%   1.9%       91  88.3% exec_statement (inline)
        0   0.0%   1.9%       91  88.3% ext_do_call (inline)
        0   0.0%   1.9%       91  88.3% fast_function (inline)
        0   0.0%   1.9%       91  88.3% function_call
        0   0.0%   1.9%       91  88.3% run_mod (inline)
        0   0.0%   1.9%       81  78.6% PyNumber_Multiply
        0   0.0%   1.9%       81  78.6% PyNumber_Power
        0   0.0%   1.9%       81  78.6%
 __pyx_f_4sage_9structure_7element_generic_power_c
        0   0.0%   1.9%       81  78.6%
 __pyx_pf_4sage_9structure_7element_11RingElement_10__mul__ (inline)
        0   0.0%   1.9%       81  78.6%
 __pyx_pf_4sage_9structure_7element_11RingElement_16__pow__ (inline)
        0   0.0%   1.9%       81  78.6%
 __pyx_pw_4sage_9structure_7element_11RingElement_11__mul__
        0   0.0%   1.9%       81  78.6%
 __pyx_pw_4sage_9structure_7element_11RingElement_17__pow__
        0   0.0%   1.9%       81  78.6% binary_op1 (inline)
        0   0.0%   1.9%       81  78.6% ternary_op (inline)
        0   0.0%   1.9%       80  77.7%
 __pyx_f_4sage_7quivers_16algebra_elements_18PathAlgebraElement__mul_
        2   1.9%   3.9%       79  76.7%
 __pyx_f_4sage_7quivers_16algebra_elements_poly_iadd_lmul.isra.60.constprop.73
        2   1.9%   5.8%       36  35.0%
 __pyx_f_4sage_7quivers_16algebra_elements_mon_mul_path
        2   1.9%   7.8%       27  26.2%
 __pyx_f_4sage_7quivers_16algebra_elements_term_create_keep_mon (inline)
        2   1.9%   9.7%       24  23.3%
 __pyx_f_4sage_15data_structures_25bounded_integer_sequences_biseq_init_concat
        1   1.0%  10.7%       24  23.3%
 __pyx_f_4sage_7quivers_16algebra_elements_mon_free (inline)
        1   1.0%  11.7%       23  22.3%
 __pyx_f_4sage_7quivers_16algebra_elements_mon_free.part.15
       20  19.4%  31.1%       20  19.4% _int_free
        3   2.9%  34.0%       16  15.5%
 __pyx_f_4sage_15data_structures_25bounded_integer_sequences_biseq_init
       10   9.7%  43.7%       12  11.7% __calloc
        0   0.0%  43.7%       12  11.7%
 __pyx_f_4sage_15data_structures_25bounded_integer_sequences_bitset_init
 (inline)
        0   0.0%  43.7%       12  11.7%
 __pyx_f_4sage_3ext_6memory_check_calloc (inline)
        0   0.0%  43.7%       12  11.7% sage_calloc (inline)
        0   0.0%  43.7%       11  10.7%
 __pyx_f_4sage_3ext_6memory_check_malloc (inline)
        0   0.0%  43.7%       11  10.7% sage_malloc (inline)
       10   9.7%  53.4%       10   9.7% _int_malloc
        2   1.9%  55.3%        9   8.7% __GI___libc_malloc
        0   0.0%  55.3%        8   7.8% PyDict_SetItem
        0   0.0%  55.3%        8   7.8%
 __pyx_f_4sage_7quivers_16algebra_elements_homog_poly_free
        0   0.0%  55.3%        8   7.8%
 __pyx_f_4sage_7quivers_16algebra_elements_poly_dealloc (inline)
        0   0.0%  55.3%        8   7.8%
 __pyx_f_4sage_7quivers_16algebra_elements_poly_free (inline)
        8   7.8%  63.1%        8   7.8%
 __pyx_f_4sage_7quivers_16algebra_elements_term_free (inline)
        0   0.0%  63.1%        8   7.8%
 __pyx_pf_4sage_7quivers_16algebra_elements_18PathAlgebraElement_2__dealloc__
 (inline)
        0   0.0%  63.1%        8   7.8%
 __pyx_pw_4sage_7quivers_16algebra_elements_18PathAlgebraElement_3__dealloc__
 (inline)
        0   0.0%  63.1%        8   7.8%
 __pyx_tp_dealloc_4sage_7quivers_16algebra_elements_PathAlgebraElement
        0   0.0%  63.1%        8   7.8% dict_set_item_by_hash_or_entry
 (inline)
        0   0.0%  63.1%        8   7.8% insertdict (inline)
        0   0.0%  63.1%        8   7.8% insertdict_by_entry
        1   1.0%  64.1%        5   4.9% PyObject_IsTrue
        0   0.0%  64.1%        5   4.9% __Pyx_PyObject_IsTrue (inline)
        2   1.9%  66.0%        5   4.9%
 __pyx_f_4sage_7quivers_16algebra_elements_negdegrevlex
        4   3.9%  69.9%        4   3.9%
 
__pyx_pf_4sage_5rings_12finite_rings_14element_givaro_25FiniteField_givaroElement_8__nonzero__
 (inline)
        0   0.0%  69.9%        4   3.9%
 
__pyx_pw_4sage_5rings_12finite_rings_14element_givaro_25FiniteField_givaroElement_9__nonzero__
        3   2.9%  72.8%        3   2.9% __GI___sigsetjmp
        3   2.9%  75.7%        3   2.9%
 __pyx_f_4sage_9structure_7element_have_same_parent_c
        3   2.9%  78.6%        3   2.9% _init@4f78
        3   2.9%  81.6%        3   2.9% _sig_on_prejmp (inline)
        2   1.9%  83.5%        3   2.9% sig_block (inline)
        0   0.0%  83.5%        2   1.9% __Pyx_GetException
        1   1.0%  84.5%        2   1.9%
 
__pyx_f_4sage_5rings_12finite_rings_14element_givaro_25FiniteField_givaroElement__mul_
        2   1.9%  86.4%        2   1.9% mpn_ior_n
        0   0.0%  86.4%        1   1.0% 0x0000000004ac78f7
        0   0.0%  86.4%        1   1.0% 0x0000000004b0b55f
        0   0.0%  86.4%        1   1.0% 0x00007f5bb6e0988f
        0   0.0%  86.4%        1   1.0% 0x00007f5bb6e09ebf
        1   1.0%  87.4%        1   1.0% PyObject_GC_UnTrack
        0   0.0%  87.4%        1   1.0% PyObject_RichCompare
        0   0.0%  87.4%        1   1.0% _PyObject_GC_Track
        1   1.0%  88.3%        1   1.0% __GI___libc_free
        0   0.0%  88.3%        1   1.0%
 __Pyx_Generator_CheckRunning.isra.10.part.11
        0   0.0%  88.3%        1   1.0% __Pyx_PyObject_Call (inline)
        0   0.0%  88.3%        1   1.0%
 __Pyx_mul_mp_bitcnt_t_checking_overflow (inline)
        1   1.0%  89.3%        1   1.0%
 __Pyx_mul_unsigned_long_checking_overflow (inline)
        1   1.0%  90.3%        1   1.0% __gmpn_cmp (inline)
        1   1.0%  91.3%        1   1.0% __gmpn_lshift
        0   0.0%  91.3%        1   1.0%
 __pyx_f_4sage_15data_structures_25bounded_integer_sequences_biseq_init_slice
        1   1.0%  92.2%        1   1.0%
 __pyx_f_4sage_15data_structures_25bounded_integer_sequences_bitset_lshift
 (inline)
        1   1.0%  93.2%        1   1.0%
 
__pyx_f_4sage_5rings_12finite_rings_14element_givaro_make_FiniteField_givaroElement
        1   1.0%  94.2%        1   1.0%
 __pyx_f_4sage_7quivers_16algebra_elements_18PathAlgebraElement__cmp_
        1   1.0%  95.1%        1   1.0%
 __pyx_f_4sage_7quivers_16algebra_elements_18PathAlgebraElement__new_
        0   0.0%  95.1%        1   1.0%
 __pyx_f_4sage_9structure_11coerce_maps_24DefaultConvertMap_unique__call_
        0   0.0%  95.1%        1   1.0%
 __pyx_f_4sage_9structure_14coerce_actions_16LeftModuleAction__call_
        0   0.0%  95.1%        1   1.0%
 __pyx_f_4sage_9structure_6coerce_24CoercionModel_cache_maps_bin_op
        0   0.0%  95.1%        1   1.0%
 __pyx_f_4sage_9structure_7element_7Element__richcmp
        0   0.0%  95.1%        1   1.0%
 __pyx_f_4sage_9structure_7element_7Element__richcmp_
        0   0.0%  95.1%        1   1.0%
 __pyx_pf_4sage_9structure_7element_7Element_62__richcmp__ (inline)
        0   0.0%  95.1%        1   1.0%
 __pyx_pw_4sage_9structure_7element_7Element_63__richcmp__
        0   0.0%  95.1%        1   1.0%
 __pyx_tp_dealloc_4sage_7quivers_16algebra_elements___pyx_scope_struct____iter__
        0   0.0%  95.1%        1   1.0% __setfpucw
        1   1.0%  96.1%        1   1.0% _init@4ab8
        1   1.0%  97.1%        1   1.0% _sig_on_postjmp
        1   1.0%  98.1%        1   1.0% _sig_on_postjmp (inline)
        0   0.0%  98.1%        1   1.0% free_check
        0   0.0%  98.1%        1   1.0% ln1
        1   1.0%  99.0%        1   1.0% sig_unblock
        1   1.0% 100.0%        1   1.0% sig_unblock (inline)
   }}}

 The difference in the profiling between biseq_init_concat and mon_mul_path
 indicates how much time is spent for memory allocation of `path_mon_t*`.
 It makes me think if I should perhaps replace the usage of `path_mon_t*`
 by arrays of length one.

 That would be similar to what is done for biseq_t and seemed to yield an
 improvement. I couldn't do the same trick for terms, because I have linked
 lists of terms. But for monomials it would perhaps make sense.

 If someone likes to finish reviewing: Go ahead! If changing the monomials
 has a good effect, then I can still open a new ticket, or post it here if
 the review isn't finished yet.

--
Ticket URL: <http://trac.sagemath.org/ticket/17435#comment:138>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/d/optout.

Reply via email to