Ask Your Question
1

How to run Cython examples in SageMathCell

asked 2018-09-27 17:20:24 +0100

Matteo gravatar image

updated 2018-10-08 12:42:03 +0100

Hi, this is not a math question, this is a programming question.

I'm trying to run the first example at doc.sagemath.org/html/en/thematic_tutorials/cython_interface by using SageMathCell service (link).

For this, I've created a zip folder that I've stored in the cloud (Google Drive).

When I run the following python script in SageMathCell (I wrote it to test Cython capabilities in SageMath remote server), it seems good, but I can't see the output, that would be "Hello World".

This python script, after execution, ends with "Compiling ./Call_C_code/hello_sage.pyx..." without anyone else output.

Can you help me? Thanks,

import os
import tempfile
import sys
from distutils.dir_util import copy_tree

directory_name = tempfile.mkdtemp()
print(directory_name)
sys.path.append(directory_name)

#https://drive.google.com/open?id=129vvaCzB0M5iuPxdSdNWRG5A2gG0DwEu

import urllib
url = "https://drive.google.com/uc?export=download&id=129vvaCzB0M5iuPxdSdNWRG5A2gG0DwEu"
filename = "/Call_C_code.zip"
urllib.urlretrieve(url, directory_name + filename)

# opening the zip file in READ mode
from zipfile import ZipFile
os.chdir(directory_name)
file_name = "Call_C_code.zip"

with ZipFile(file_name, 'r') as zip:
    # extracting all the files
    print('Extracting all the files now...')
    zip.extractall()
    print('Done!')

print(sys.path)
print(os.getcwd())

for root, dirs, files in os.walk("."):  
    for filename in files:
        print(filename)

#############
%runfile Call_C_code/hello_sage.pyx
my_bridge_function()
edit retag flag offensive close merge delete

Comments

For what it's worth, I don't know why you're doing sys.path.append(directory_name), but you probably needn't do so. What does hello_sage.pyx have in it? You can also use %cython for directly compiling Cython code, but %runfile should effectively do the same if it's passed a path to a .pyx file.

Iguananaut gravatar imageIguananaut ( 2018-10-02 14:47:49 +0100 )edit

Hi @Iguananaut thanks, I use sys.path.append() to be sure the remote python environment can find my files and libraries to be compiled in the temporary folder. Why it is not necessary?

"hello_sage.pyx" is a file containing: """ cdef extern from "hello.c": void hello_world()

def my_bridge_function(): hello_world() # This is the C function from hello.c """ as this link suggests. The path for "hello_sage.pyx", I suppose, is directory_name/Call_C_code, as indicated in "%runfile Call_C_code/hello_sage.pyx" and with the command "os.chdir(directory_name)" I'm sure my working folder is the temporary folder named "directory_name".

What is wrong? Thank you

Matteo gravatar imageMatteo ( 2018-10-03 16:03:40 +0100 )edit

FWIW you should be able to edit your question to add more details like the contents of the file.

I don't know what you mean by "the remote python environment". If you just want to run a single Python module it's not necessary to add its path to sys.path. sys.path only affects where modules are searched for when you use the import statement, wheres %runfile is already giving the path to a module directly.

This is like the difference in a shell when running a command by name like ls, as opposed to its full path /bin/ls. To run /bin/ls you don't need /bin on your PATH environment variable, but if you just run ls you do because the shell needs to know what paths to look in for a program called ls.

Iguananaut gravatar imageIguananaut ( 2018-10-08 11:11:03 +0100 )edit

Hi @Iguananaut thank you for support, I try to describe better what I mean. I use sage only on the Internet using the free service SageMathCell. It is an online sagemath service.

Inside the zip folder "Call_C_code.zip" there are 3 files, one of them (text.txt) is a dummy text file I added for some tests, the other two files are the files of the example here. The two files for Cython test are: "hello_sage.pyx" and "hello_test.c".

Inside "hello_sage.pyx" there is the Cython code, while inside "hello_test.c" there is the C code. The content is, adapted on filenames, the same you find here.

Matteo gravatar imageMatteo ( 2018-10-08 12:29:11 +0100 )edit

Please can you run without problems the script in first post by using SageMathCell or not? I'm testing Cython features of the online service SageMathCell by following the simple example "How to call a C code (or a compiled library) from Sage?".

"hello_sage.pyx":

cdef extern from "Call_C_code/hello_test.c":
    void hello_world()

def my_bridge_function():
    hello_world() # This is the C function from hello_test.c

"hello_test.c":

#include <stdio.h>

void hello_world(){
    printf("Hello World\n");
}

Thanks

Matteo gravatar imageMatteo ( 2018-10-08 12:34:25 +0100 )edit

1 Answer

Sort by ยป oldest newest most voted
3

answered 2018-10-08 15:40:18 +0100

Iguananaut gravatar image

I'll attempt to recreate my original answer here; I'm not sure what happened to the old one. I tried your example code in SageMathCell and it works fine (as I previously suggested however there is no need for modifying sys.path).

The problem seems to have something to do with how SageMathCell handles standard output. I noticed this after trying: print(sys.__stdout__) in SMC, and that returns: <log.StdLog object at 0x7f68d71cbb50>.

I don't know exactly how SMC works, but that seems to indicate that Python's normal stdout is being replaced with some object that logs stdout at the Python level. However, when you compile C code containing printf()s, that outputs at the C level, but I suspect SMC is not capturing that, and is only capturing prints from Python by overriding sys.__stdout__. I would consider this a bug in SMC, as it should be able to capture output to the stdout file descriptor, but it appears it does not.

edit flag offensive delete link more

Comments

Hi @Iguananaut, thank you for testing it! Ok, I will try to contact the SageMathCell service to understand how to solve the problem.

For now I will try to perform some tests with C functions that are independent from the standard C input/output library.

Thanks, I appreciated your help.

Matteo gravatar imageMatteo ( 2018-10-08 17:08:16 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2018-09-27 17:20:24 +0100

Seen: 713 times

Last updated: Oct 08 '18