Skip to content
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

member functions and memory #133

Open
alexjbest opened this issue Mar 2, 2023 · 0 comments · May be fixed by #134
Open

member functions and memory #133

alexjbest opened this issue Mar 2, 2023 · 0 comments · May be fixed by #134

Comments

@alexjbest
Copy link
Contributor

alexjbest commented Mar 2, 2023

Currently we see the following error in Sage

sage: R.<y> = QQ[]
sage: K = NumberField(y^2-y-1,'a')
sage: A = pari(K).alginit([2,[[],[]],[0,0]])
sage: K(A.algb())
1
sage: K(A.algb())
---------------------------------------------------------------------------
SystemError                               Traceback (most recent call last)
Input In [20], in <cell line: 5>()
      3 A = pari(K).alginit([Integer(2),[[],[]],[Integer(0),Integer(0)]])
      4 K(A.algb())
----> 5 K(A.algb())

File cypari2/auto_gen.pxi:718, in cypari2.gen.Gen_base.algb()

File cypari2/stack.pyx:182, in cypari2.stack.new_gen()

File cypari2/stack.pyx:212, in cypari2.stack.new_gen_noclear()

SystemError: new_gen() argument not on PARI stack, not on PARI heap and not a universal constant

We hypothesised that this is because the member functions are treated differently by pari and gp, in pari.desc the prototype is marked with m to tell gp to copy the return value to the stack. Aurel explained this to me a bit after talking with Bill and I wrote the following patch based on my understanding of the situation but running ./tests/rundoctest.py gives memory leaks, so I guess it's not quite correct, expert advice would be great!

diff --git a/autogen/ret.py b/autogen/ret.py
index 2186297..a004430 100644
--- a/autogen/ret.py
+++ b/autogen/ret.py
@@ -54,6 +54,13 @@ class PariReturnGEN(PariReturn):
         s = "        return new_gen({name})\n"
         return s.format(name=self.name)
 
+class PariReturnmGEN(PariReturn):
+    def ctype(self):
+        return "GEN"
+    def return_code(self):
+        s = "        return copy_gen({name})\n"
+        return s.format(name=self.name)
+
 class PariReturnInt(PariReturn):
     def ctype(self):
         return "int"
@@ -78,7 +85,7 @@ class PariReturnVoid(PariReturn):
 
 pari_ret_types = {
         '':  PariReturnGEN,
-        'm': PariReturnGEN,
+        'm': PariReturnmGEN,
         'i': PariReturnInt,
         'l': PariReturnLong,
         'u': PariReturnULong,
diff --git a/cypari2/gen.pyx b/cypari2/gen.pyx
index 247b1ad..d371931 100644
--- a/cypari2/gen.pyx
+++ b/cypari2/gen.pyx
@@ -72,7 +72,7 @@ from .convert cimport PyObject_AsGEN, gen_to_integer
 from .pari_instance cimport (prec_bits_to_words, prec_words_to_bits,
                              default_bitprec, get_var)
 from .stack cimport (new_gen, new_gens2, new_gen_noclear,
-                     clone_gen, clear_stack, reset_avma,
+                     clone_gen, copy_gen, clear_stack, reset_avma,
                      remove_from_pari_stack, move_gens_to_heap)
 from .closure cimport objtoclosure
 
diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx
index 1366ab4..494bb11 100644
--- a/cypari2/pari_instance.pyx
+++ b/cypari2/pari_instance.pyx
@@ -287,7 +287,7 @@ from .string_utils cimport to_string, to_bytes
 from .paridecl cimport *
 from .paripriv cimport *
 from .gen cimport Gen, objtogen
-from .stack cimport (new_gen, new_gen_noclear, clear_stack,
+from .stack cimport (new_gen, new_gen_noclear, clear_stack, clone_gen, copy_gen,
                      set_pari_stack_size, before_resize, after_resize)
 from .handle_error cimport _pari_init_error_handling
 from .closure cimport _pari_init_closure
diff --git a/cypari2/stack.pxd b/cypari2/stack.pxd
index 00ef3a0..40388fb 100644
--- a/cypari2/stack.pxd
+++ b/cypari2/stack.pxd
@@ -5,6 +5,7 @@ from .gen cimport Gen_base, Gen
 cdef Gen new_gen(GEN x)
 cdef new_gens2(GEN x, GEN y)
 cdef Gen new_gen_noclear(GEN x)
+cdef Gen copy_gen(GEN x)
 cdef Gen clone_gen(GEN x)
 cdef Gen clone_gen_noclear(GEN x)
 
diff --git a/cypari2/stack.pyx b/cypari2/stack.pyx
index 95a7f1b..1370d95 100644
--- a/cypari2/stack.pyx
+++ b/cypari2/stack.pyx
@@ -224,6 +224,12 @@ cdef Gen new_gen_noclear(GEN x):
     return z
 
 
+cdef Gen copy_gen(GEN x):
+    t = Gen_stack_new(x)
+    #remove_from_pari_stack(y)
+    clear_stack()
+    return t
+
 cdef Gen clone_gen(GEN x):
     x = gclone(x)
     clear_stack()

Original issue from code Aurel Page and Eloi Torrents were writing at CIRM

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 a pull request may close this issue.

1 participant