Hi,
I'm trying to interface with
PARI (2.11.1) libraries from Python using Cython and came across the
CyPari2 package which looks really convenient, but am having trouble installing it in Docker on the continuumio/anaconda2 image using either
or
RUN pip install cysignals --upgrade
RUN pip install cypari2 --upgrade
In the Dockerfile, I've prebuilt GMP and PARI into the "/app/EXTERNAL_SOFTWARE/local" directory of the image. When using just "RUN pip install cypari2" it gives "Error: No module named cysignals". The meaning of the error from the second option is less clear since pip has already been upgraded (see attachment for full output):
I also tried to interface directly with a few PARI functions directly using Cython with the pari.pxd, pari.pyx and setup.py files below. The pari_test() function works, pari_qfrep0 fails when calling the pari_printf() function, and pari_qfisom() fails when calling qfisom(). Both of these failures give a "bug in PARI/GP (segmentation fault)" to report to PARI, but I wanted to check if this was an issue with the way I'm using Cython to perform the wrapping first.
Any comments to help get these working would be appreciated!
Thanks,
-Jon
============================================
setup.py:
---------
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext = Extension('pari',
sources=['pari.pyx'],
include_dirs = ['/app/EXTERNAL_SOFTWARE/local/include/pari', '/usr/local/include', '.'],
libraries = ['gmp', 'gmpxx', 'pari'],
library_dirs = ['/app/EXTERNAL_SOFTWARE/local/lib', '/usr/local/lib'],
language='c++')
setup(
ext_modules = cythonize([ext])
)
pari.pxd:
---------
## Declare the PARI header files that we're using in pari.pyx
cdef extern from "pari.h":
ctypedef long *GEN
ctypedef unsigned long ulong
cdef GEN gp_read_str(const char *t)
cdef GEN qfisom(GEN G, GEN H, GEN fl, GEN grp)
cdef GEN qfrep0(GEN a, GEN borne, long flag)
cdef void pari_init(size_t pari_size, ulong maxprime)
cdef void pari_printf(const char *fmt, ...)
cdef void pari_flush()
pari.pyx:
---------
## Python function using the C++ function calling the PARI library
def pari_test():
"""
Returns the results of a few PARI routines.
"""
## Initialize the PARI stack with 4MB and all primes up to 2.
pari_init(4000000, 2)
## Create a Pari matrix
PARI_MATRIX = gp_read_str("[1, 0; 0, 1]")
## Print the matrix
pari_printf("%Pd\n", PARI_MATRIX)
pari_flush()
## Compute an isomorphism between two quadratic forms (if one exists)
def pari_qfrep0():
"""
The qfrep0() routine from PARI. This takes a square symmetric integer Gram matrix
and returns the theta series.
"""
## Initialize the PARI stack with 4MB and all primes up to 2.
pari_init(4000000, 2)
## Call the PARI function qfrep0
PARI_MATRIX = gp_read_str("[1, 0; 0, 1]")
PARI_PRECISION = gp_read_str("20")
ans_GEN = qfrep0(PARI_MATRIX, PARI_PRECISION, 0)
## Print the answer
pari_printf("%Pd\n", ans_GEN[0])
pari_flush()
## Compute an isomorphism between two quadratic forms (if one exists)
def pari_qfisom():
"""
The qfisom() routine from PARI. This takes two square symmetric integer matrices and either returns
False or a matrix that gives this automorphism.
"""
## Initialize the PARI stack with 4MB and all primes up to 2.
pari_init(4000000, 2)
## Call the PARI function qfisom
PARI_MATRIX = gp_read_str("[1, 0; 0, 1]")
ans_GEN = qfisom(PARI_MATRIX, PARI_MATRIX, NULL, NULL)
## Print the answer
pari_printf("%Pd\n", ans_GEN)
pari_flush()