[Cython] Hello
Hi! I have just built Cython but haven’t used it yet. I want to check I understand what it does whilst examing the sources in the repository. Please let me know if I have it wrong! Given a Python file, Cython parses it, and translates it to the equivalent C, which can then be compiled to binary, thereby bypassing the overhead of interpreting bytecode, but still executing the same accesses to the CPython run time API that the interpreter would. So there may be a small speed improvement, or maybe not (because it misses optimisations the interpreter might be able to spot). The binary will typically be a C extension module that can be loaded and operate the same way as the original Python. Now, Cython is an extension of Python which allows some extra stuff, including type annotations, and other directives related to integration with C. These can be used to facilitate integration with external C libraries directly, and mapping into Python, as if the code were written in C, only we’re using a Python like language representing a subset of C instead of C. Additionally, the compiler recognises the type annotations, and can reduce or eliminate run time type checks, improving performance, or even replacing common constructions in Python which much faster ones that do the same job “closer to the metal”. To make this work, the CPython API itself is represented in a set of *.pxd files found in the repository in Includes/cpython, splitting the logic of the compiler roughly into two parts: the front and back end. The front end groks Python and Cython code whilst the back end generates the actual C. === Just FYI, I’m the developer of a programming language, Felix, which is C++ code generator. You can think of it as a meta-programming language for C++ with a proper type system. Felix binds C/C++ code with statements like: type PyObject = “PyObject*”; fun add: PyObject * PyObject -> PyObject = “Py_AddLong($1)”; and can use the bindings like: var a : PyObject = …. var b: PyObject = ... var sum = add (a,b); so in some ways its doing the same kind of job as Cython, except it isn’t specialised to bind to Python, it can bind to anything written in C or C++. Including the Python API as illustrated. Right now, I’ve writing a program to translate Include/python/*.pxd files to Felix bindings, to save typing everything by hand. Its even possible I can teach my compiler to read *.pxd files directly, which would make Cython a sublanguage of Felix. Felix is very good at defining DSSLs, Domain Specific Sub Languages, the grammar of the language is defined in the standard library. In the process of doing this I may find some issues in Cython which I’ll report. Hope that helps. As I learn more I may be able to contribute to the project directly. One possible future goal is to replace NumPy with something much better. I also have code written in Python that I might translate to C using Cython. It would be kind of interesting to use Cython to generate C, and then create bindings to that C in Felix, so instead of calling the Python C API, we call the Cython generated API instead, allowing people to write libraries for Felix in Cython instead of C or Felix. However that’s a more major integration task. You’d want Cython to generate the Felix bindings, or at least output meta-data that would allow them to be generated easily .. such as .. a *.pxd file !! — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Hello
> On 27 Jan 2020, at 20:23, Greg Ewing wrote: > > On 27/01/20 6:56 pm, John Skaller2 wrote: >> Felix binds C/C++ code with statements like: >> type PyObject = “PyObject*”; >> fun add: PyObject * PyObject -> PyObject = “Py_AddLong($1)”; >> and can use the bindings like: >> >> var a : PyObject = …. >> var b: PyObject = ... >> var sum = add (a,b); > > How does it deal with reference counting and exception handling? The Felix binding generates C. So the answer is, the same way as you would in C. However the above is a low level binding, one to one with C. Higher level stuff is possible. Won’t know until the binding is operational. My script is basically working translating the *.pxd files in Cython. (Just the functions, the rest can be done by hand). Basically I can write, say, a concurrent matrix multiplication routine and map it to Python. Of course you can do that in C as well, but Felix is a very high level language so you can do stuff you wouldn’t bother attempting in low level languages like C and C++. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Hello
Ok, quick pass on Cython reference .. pretty good. Easy to read, good coverage, well written. Beginning to understand the design. Interesting thing is the limitations are the best clue. For example: "The “?” indicates that the value -1 only indicates a possible error. In this case, Cython generates a call to PyErr_Occurred() if the exception value is returned, to make sure it really is an error.” really tells me how Cython generates code to interface C and Python. Thanks. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Hello
What’s a “descr” when its at home? There are some special words in pxd files like “list” which mean PyObject that happens to be a list. Is there a list of these somewhere? — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Hello
> On 28 Jan 2020, at 21:07, Stefan Behnel wrote: > > John Skaller2 schrieb am 28.01.20 um 10:57: >> What’s a “descr” when its at home? > > A descriptor, a special protocol in Python. > > https://docs.python.org/3/howto/descriptor.html Got it, thanks! > >> There are some special words in pxd files like “list” which mean >> PyObject that happens to be a list. Is there a list of these somewhere? > > See Builtin.py. Got it, thanks! Very useful file. I’m curious about this comment in that file: # This conflicts with the C++ bool type, and unfortunately # C++ is too liberal about PyObject* <-> bool conversions, # resulting in unintuitive runtime behavior and segfaults. #("bool","PyBool_Type", []), I can believe it. Bool is a mess in C, twice as bad in C++ .. and exponentially screwed up in Felix :-) The problem is compatibility in bindings.. The thing is I did translate bint in pxd files to Felix bool, which is a bit, embedded in a 64 bit unsigned int .. different to both C and C++ :-) Now you have me worried! Any more detailed explanation of this issue? — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Hello
So I just had a thought, I might try something to enhance the bindings. Not sure if it will work. My system supports subtyping. For bindings and other nominal types you can simple define a subtyping coercion. Now in Python we have subtyping rules like: dictionary -> mapping -> object If I implement that with just static casts for coercions, then say, given a dictionary and a function accepting a mapping argument, you can pass a dictionary or mapping, but not an object. If you want to pass an object you have to explicitly coerce it. The *problem* with this idea I think is that from memory the reference counting rules for PyObject and dictionaries are not the same as for methods on abstractions. Cython must do something like this, right? And get the ref counting right. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Hello
> > For your system, you may need a way of annotating function > declarations with refcounting rules where they differ from > the defaults. Yeah, and i have to encode that to some extent in the type system. However I have two techs to play with: Felix and C++. Both can, for example, do subtyping. In addition, going pxd [Cython] -> C -> Felix allow safely and efficiently extending the “Python C API”. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
[Cython] Status
Ok, I have processed most of the Cython/Include/python/*.pxd files. Seems these were mechanically derived from docs? Because some of the bugs in the docs are also in these files. Not sure what you would like to do so I’ll ask here before doing github issues. 1. Its not all there. I couldn’t find the API for generators for example. If the API is extracted from the docs the script could be run again. 2. pyport is plain wrong. It contains conflicting C typedefs. 3. Some of the files describe extension modules (datetime, array) rather than the core API. 4. ../cython/Cython/Includes/cpython/weakref.pxd:bint PyWeakref_CheckProxy(ob) ob should be PyObject* there’s a couple more (maybe in ref as well). Python keeps changing the API. Its not clear exactly which version is represented. I have the same issue, i have no idea at the moment how to deal with it. = I’m thinking to do some test runs of Cython on some Python code. I’ll be running Cython as a translator directly from the command line. Now when I built Cython before with “make” I saw lots of “python2.7” in the output which is not what I want to process. My Felix test code is executing plain C code bound againt a brew installed Python run time library, the meta data required to link that is this: Name: Pycore Description: Macosx bindings to Python shared run time library core. cflags: -I/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/include/python3.6m includes: '"Python.h"' provides_dlib: -L/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib -lpython3.6m provides_slib: -L/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib -lpython3.6m And I can run the corresponding Python: ~/felix>/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/bin/python3.6m Python 3.6.5 (default, Apr 25 2018, 14:26:36) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> And here is a test program written in Felix that uses the bindings: println$ Py_GetVersion(); Py_Initialize(); var x : PyObject = PyLong_FromLong (42); var y : long = PyLong_AsLong (x); println$ PyLong_Check x; println$ y; println$ (f"%x" header_version); and here’s the output: ~/felix>flx pycheck.flx 3.6.5 (default, Apr 25 2018, 14:26:36) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] true 42 30605f0 Note this code is generating a shared library BUT it is being run by Felix, it is NOT being loaded as a module under Python. I will check that works next. So I’m showing all this because I would now like to run Cython on a little test script using the same run time library as above, and perhaps the same Python interpreter. I have too many Python’s installed all over the place to really know what’s what. So I would appreciate step by step instructions on how to build and use Cython so it uses and generates code binding to the exact same Python/run time as above. I guess I’ll test some kind of hello world program. === I’m expecting that on OSX and Windows, CPython extensions will work, but on Linux they will fail. This is because last time I looked, extensions were built assuming a flat linker namespace with the API provided by the Python executable. Indeed, I’m not sure if you can even get a Python executable on Linux that isn’t statically linked to the run time. However the shared library extensions I generate will always be linked against a shared library. My build tech does not permit flat namespaces for dynamic linkage. I know you CAN get Python run time as a shared library on Debian based systems, but I don’t think you can get a stub Python executable. Its essential that all the global data is held by the library not the executable, otherwise it won’t be shared by libraries that link to it. However stuff may have changed recently. I can of course build Python from source myself and hack it to build correctly, its not that hard, but Felix clients will not be able to do that. This issue will impact Cython uses exactly the same way for the same reason. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
Just FYI, trying to load my extension I get “ModuleNotFound”. A test *.py file in the same directory can be imported. A check on the shared library (dylib on MacOS) shows that the required function is exported. Maybe my layout of the module table is wrong, its hard to say given so much information (sarcasm). The Python function is _fI64918_ptest. The function _fI64918_ptest executes correctly when called from C. If it crashed when called from Python, I wouldn’t be surprised, but the problem is more basic, the extension can’t be loaded. The generated code below compiles fine. The FLX_EXPORT there is the visibility control** static PyMethodDef pycheck_methods [] = { {"ptest", _fI64918_ptest, METH_VARARGS, "/Users/skaller/felix/pycheck.flx: line 98, cols 1 to 61"}, {NULL, NULL, 0, NULL} }; static PyModuleDef pycheck_module = { PyModuleDef_HEAD_INIT, // m_base "pycheck", // m_name "pycheck generated by Felix ", // m_doc -1, // m_size pycheck_methods, // m_methods 0, // m_reload 0, // m_traverse 0, // m_clear 0 // m_free }; extern "C" FLX_EXPORT PyObject *PyInit_pycheck() { return PyModule_Create(&pycheck_module);} ** Python gets the visibilty control wrong for Linux. That’s because Python is built incorrectly on Linux. But I’m running MacOS so it should work, shouldn’t it? — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> On 30 Jan 2020, at 17:20, John Skaller2 wrote: > > Just FYI, trying to load my extension I get “ModuleNotFound”. using Cython I get a different result. ~/felix>cat oldtest.py def testit(): print("Testit”) Note the original name was test.py, changed so it cannot be loaded. Under the original name: ~/felix>python ../cython/cython.py test.py /Users/skaller/cython/Cython/Compiler/Main.py:344: FutureWarning: Cython directive 'language_level' not set, using '3str' for now (Py3). This has changed from earlier releases! File: /Users/skaller/felix/test.py tree = Parsing.p_module(s, pxd, full_module_name) That made a C file. Now to compile it: ~/felix>clang -I /usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/include/python3.6m/ -L /usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib -lpython3.6m -dynamic -shared -o test.dylib test.c ~/felix>ls test.dylib test.dylib ~/felix>mv test.py oldtest.py ~/felix>/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/bin/python3.6m Python 3.6.5 (default, Apr 25 2018, 14:26:36) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import test Traceback (most recent call last): File "", line 1, in ImportError: bad magic number in 'test': b'\x03\xf3\r\n’ Well, this is a better result than from the C generated by Felix. At least the extension module actually got found, even if it failed a consistency check. Any idea what’s happening? [the Cython seems to have been built for 2.7, I don’t know if that makes any difference: it’s run by command “python” which is Python 2.7. But the languagfe of the translator isn’t necessarily related to the target of its output .. there’s no reference for the command line compiler] — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> On 30 Jan 2020, at 18:44, John Skaller2 wrote: > > > >> On 30 Jan 2020, at 17:20, John Skaller2 wrote: >> >> Just FYI, trying to load my extension I get “ModuleNotFound”. > > ~/felix>/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/bin/python3.6m > Python 3.6.5 (default, Apr 25 2018, 14:26:36) > [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin > Type "help", "copyright", "credits" or "license" for more information. >>>> import test > Traceback (most recent call last): > File "", line 1, in > ImportError: bad magic number in 'test': b'\x03\xf3\r\n’ Oh, sorry! This was a *pyc file hanging around. After deleting it Python happily loaded the wrong module because I picked a bad name. So .. /Users/skaller/cython/Cython/Compiler/Main.py:344: FutureWarning: Cython directive 'language_level' not set, using '3str' for now (Py3). This has changed from earlier releases! File: /Users/skaller/felix/oldtest.py tree = Parsing.p_module(s, pxd, full_module_name) ~/felix>clang -I /usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/include/python3.6m/ -L /usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib -lpython3.6m -dynamic -shared -o oldtest.dylib oldtest.c ~/felix>mv oldtest.py oldertest.py ~/felix>/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/bin/python3.6m Python 3.6.5 (default, Apr 25 2018, 14:26:36) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import oldtest Traceback (most recent call last): File "", line 1, in ModuleNotFoundError: No module named 'oldtest' >>> which is the same problem my Felix generated C is giving. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> On 30 Jan 2020, at 18:00, Yury V. Zaytsev wrote: > > On 30. Jan 2020, at 03:52, John Skaller2 wrote: >> >> However the shared library extensions I generate will always be linked >> against a shared library. My build tech does not permit flat namespaces >> for dynamic linkage. I know you CAN get Python run time as a shared >> library on Debian based systems, but I don’t think you can get >> a stub Python executable. Its essential that all the global data is held >> by the library not the executable, otherwise it won’t be shared by >> libraries that link to it. > > Users of MPI libraries have some of the same problems - maybe you could have > a look at the mpi4py - coincidentally it’s also a heavy user of Cython, so a > lot of inspiration can be found in the sources. > > https://mpi4py.readthedocs.io/en/stable/appendix.html#mpi-enabled-python-interpreter Thanks. That “rebuild Python from source” is also my main worry. Luckily, I previously found, as long as you have the runtime, its easy to build a stub like the one shown in the above page. The problem is prebuilt binary extensions don’t work, unless the symbol table of the library is imported into the executable so they can be re-exported into the extensions. Which requires a flat namespace at least for the executable. With my system, the executable is pre-built but it has no external dependencies except C library with dlopen (or Windows equivalent). Even if that used a flat namespace it wouldn’t help, because the shared libs I generate always link to their dependencies with a two level namespace, so the dependence on Python run time cannot re-export the run time library symbols. That, after all, is the whole point of using a two level namespace. Of course, I can also do static links which is intrinsically using a flat namespace. So I could change it to use a flat namespace. But sometimes progress requires avoiding stepping back decades into the medieval world :-) [No relation to Vasily Grigoryevich Zaytsev? Just curious ..] — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
OMG. I don’t believe it. Renaming the binary from *.dylib to *.so fixed it. Both the Cython and Felix shared libraries can be imported and both run. Sorry for the noise. Just didn’t occur to me that Python would want *.so filenames on MacOS. Until I remembered seeing some in Cython build directory .. Here is the Felix program, just for interest, excluding the binding code, note I defined “PyObject” in Felix to be “PyObject*” in C. /// fun ptest(q:PyObject,w:PyObject):PyObject { println$ Py_GetVersion(); Py_Initialize(); var x : PyObject = PyLong_FromLong (42); var y : long = PyLong_AsLong (x); println$ PyLong_Check x; println$ y; println$ (f"%x" header_version); return x; } C_hack::ignore (ptest(Py_None,Py_None)); export python fun ptest of (PyObject * PyObject) as "ptest”; // The ptest fun at the start is an ordinary Felix function that just happens to use the CPython API bindings I just generated to make a function with the type actually required for CPython. The C_hack::ignore (ptest (Py_None, Py_None)); generates a C function call that actually runs it from C. The hack is needed because Felix function are not allowed to have side effects, and, if the result of a function is unused, the function then cannot serve any useful purpose, and is deleted. The “hack” fools the compiler into believing the result of the function is actually used. That call is done as part of the library initialisation. The final line is the interesting one. It generates a wrapper for the function ptest, which is a plain C function AND it tells the compiler, there is a Python function floating about that has to be put into a Python Module table. So the compiler builds a module table, and puts the function in it, and then defines PyInit_modulename() which returns the module table address, and exports it. When imported from Python, the initialisation is not done, but the function can be run from the module dictionary., So this shared library can be used BOTH from C, and from Python. It’s a Felix program AND a Python extenion as well. The idea has been, you can write ultra-high performance code in Felix, and then with some work to make a CPython binding to the operations, you can make the resulting binary library accessible not only to C (and C++), but also to Python, by simply tell the compiler to export functions to python. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> On 31 Jan 2020, at 00:22, Stefan Behnel wrote: > >> Seems these were mechanically derived from docs? > > They were manually copied over time. Ouch. A lot of work. >> 2. pyport is plain wrong. It contains conflicting C typedefs. > > PRs welcome. Is this your prefered method (pull request)? >> 4. ../cython/Cython/Includes/cpython/weakref.pxd:bint >> PyWeakref_CheckProxy(ob) >> >> ob should be PyObject* > > No, the declaration looks correct to me. The input is an object. It does > not seem helpful to me to require users to do a cast. I don’t understand. ob isn’t a type, is it? A type is required. Else where “object” is used as an alias for PyObject*. It also suggests standard ref counting is required whereas plain PyObject* suggests non-standard ref counting. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> On 30 Jan 2020, at 22:23, Greg Ewing wrote: > > On 30/01/20 8:58 pm, John Skaller2 wrote: > >>>> import oldtest > > Traceback (most recent call last): > >File "", line 1, in > > ModuleNotFoundError: No module named 'oldtest' > What happens if you use a .so extension instead of .dylib? It works. Why Python would look for a linux extension only on MacOS I have no idea. A symlink appears to work too. Was tearing hare out for many hours. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> The mystery to me is why MacOSX introduced .dylib instead of > sticking with .so. There were *.so files and hacks to load them. But the structure od dylib is different and uses a slightly different loader, dyld. I guess they wanted to make a distinction. The had some kind of Obj C dynamic plugin things as well. Software history is full of regrets. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> On 31 Jan 2020, at 16:51, Greg Ewing wrote: > > On 31/01/20 9:47 am, John Skaller2 wrote: > >>>> 2. pyport is plain wrong. It contains conflicting C typedefs. >>> >>> PRs welcome. >> Is this your prefered method (pull request)? > > I'm sure PRs are very welcome, but at the least you could > give us some idea of what these conflicting typedefs are! The file is small: cdef extern from "Python.h": ctypedef int int32_t ctypedef int int64_t ctypedef unsigned int uint32_t ctypedef unsigned int uint64_t Obviously this is an incorrect translation of the original source. One of each pair may well be correct. But its impossible both are. Defining a symbol defined in the C99 standard seems like a bad idea. Python’s pyport.h actually says: #include .. #define PY_UINT32_T uint32_t #define PY_UINT64_T uint64_t /* Signed variants of the above */ #define PY_INT32_T int32_t #define PY_INT64_T int64_t … — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
ob should be PyObject* >>> >>> No, the declaration looks correct to me. The input is an object. >> I don’t understand. ob isn’t a type, is it? A type is required. > > It's a (dummy) parameter name. Cython defaults to "object" when a > type isn't specified. > > Looking at the other declarations in that file, it was probably > *meant* to say "object ob", but it's not wrong -- it still works > that way. Ok, but now the syntax is made very context sensitive. To interpret it correctly, you have to know “ob” is not a type. And the Python docs make exactly the same mistake. In C this would not work because there is no default type, so the Python docs are wrong because they’re supposedly documenting C. [The only case it could be correct would be if the symbol were a macro] And my translator script got fooled, because it assumes any single identifier used as a parameter is a type, and if two words are used, the first is a type and the second can be discarded, except in the special case “unsigned int”. Note, I’m just trying to help by bringing up inconsistencies, which are things my simplistic translator script can’t handle. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> On 1 Feb 2020, at 00:36, Greg Ewing wrote: > > On 1/02/20 12:25 am, John Skaller2 wrote: >> cdef extern from "Python.h": >> ctypedef int int32_t >> ctypedef int int64_t >> ctypedef unsigned int uint32_t >> ctypedef unsigned int uint64_t > > These work because Cython doesn't need to know the exact > sizes of these types. All it needs to know is that they're > some kind of integer so that its type checks will pass. > The typedef names end up in the generated C code, and the > C compiler figures out their actual sizes. Ah. I see. That makes sense. So this is some kind of hack way of getting something a bit like Haskell type classes, you’re basically saying int32_t and int64_t are of class “Integer”. This also explains the conflict for me, because Felix is the opposite: it aims to make the types of things more precise (and has actual type classes for generalisation). — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> > Yes, there is -- the default type in C is int. I don’t think that is true in C99 but I’m not sure. Its definitely not allowed in C++. I know because I actually moved the motion on the C++ ISO committee to disallow it :-) In any case its a bad idea in an interface specification even if it’s legal. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
[Cython] Size of output
When I ran Cython on a two line Python function I got this from wc: 4276 13798 161338 oldtest.c It took a while to actually find the implementation of the function. A lot of the emitted code appeared to be run time and compile time support code which wasn’t actually used. Eliminating stuff that isn’t required with dependency tracking is nontrivial, and not much use whereas a single self contained compilable C files is very useful. Is there an option to use an #include for the standard stuff? — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> On 1 Feb 2020, at 09:49, Greg Ewing wrote: > > On 1/02/20 3:03 am, John Skaller2 wrote: >> So this is some kind of hack way >> of getting something a bit like Haskell type classes, >> you’re basically saying int32_t and int64_t are of class “Integer”. > > I suppose you could think of it that way, but it's really > not that formal. > >> This also explains the conflict for me, because Felix is the opposite: >> it aims to make the types of things more precise (and has actual >> type classes for generalisation). > > To define them any more precisely, Cython would need to > know how things vary depending on the platform, which would > mean conditional compilation, etc. It's much easier to leave > all that up to the C compiler and system headers. It also > ensures that there can't be any mismatch between the two. But the all hell breaks loose for pointers. Your hack only works for rvalues. Of course you probably know this doesn’t occur. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Size of output
> >> Is there an option to use an #include for the standard stuff? > > There are upsides and downsides to that as well. Hence an option. But it could be work to implement so I’m just exploring at the moment. > The way > things are, the generated file is self-contained, and can > be shipped without worrying about it becoming disconnected > from a compatible version of the include file. This is > important when details of the support code can change > without notice between Cython releases. Yes, and in this case an include file may actually be better because it will upgrade with Cython. YMMV I guess. But the main reason is to remove a lot of useless clutter. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Size of output
> I agree there's some fat that could be trimmed there, but not sure > it'd be worth the effort. You’re probably right. Its a problem writing a compiler in a language wholy unsuited for the job. Even with a more suitable language, emitting code, in the right order, with just the things actually required, is difficult. I use a multi-pass predictive system and a multi-pass code generator and I find bugs all the time because it isn’t run by actually dependencies but predicted ones. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
[Cython] linkage
OMG. Python is moving backwards. Some people just have no understanding of tech. As of 3.8, extensions must not be dynamically linked to libpython. This doesn’t apply to Windows or MacOS because that’s the only way on those platforms. But Debian/Ubuntu was always wrong and now the error is being made canonical. If anyone here knows a way on Linux to fix this, with some sort of stub loader for example, I’d be interested. All my code is linked with visibility=default, and all dynamic loads use two level namespaces, i.e, the symbol table of a shared library being imported is only visible to the importer. The may be some impact on Cython, since its primary job is building Python extensions. BTW: its all due to a stupid bug in ld which links shared libraries without bothering to check external references are satisfiable. Until load time, maybe.. :-) — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Size of output
> given target. Removing the final 0.5% of code that is "unused in some > cases" is really not something I would want to invest days into, each time > we make a change in Cython. But its not 0.5%. My problem is trying to read the generated code. A possibility might be an option which puts the boilerplate in one file and the variant code in another that then #includes the boilerplate. So the code is the same, but the main file is much easier to inspect to see what got generated. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
> On 1 Feb 2020, at 20:00, Greg Ewing wrote: > > On 1/02/20 3:29 pm, John Skaller2 wrote: >> But the all hell breaks loose for pointers. Your hack only >> works for rvalues. > > Yes, using these it's possible for Cython to accept something > that will later be rejected by the C compiler. It's not perfect, > but it gets the job done most of the time. My concern is that the C compiler wont reject it, the program will corrupt data or crash: int32_t *x=..; *x = 42; int64_t *x=..; *x = 42; The C compiler will overwrite 4 or 8 bytes. Which one matters. In an rvalue context it probably doesn’t matter, in an lvalue context it does. But probably this doesn’t happen in Cython. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Size of output
> On 2 Feb 2020, at 02:23, Stefan Behnel wrote: > > John Skaller2 schrieb am 01.02.20 um 15:32: >> My problem is trying to read the generated code. > > You might be looking for "cython -a". OK. I see these: ~/felix>../cython/cython.py usage: cython.py [-h] [-V] [-l] [-I INCLUDE_PATH] [-o OUTPUT_FILE] [-t] [-f] [-v] [-p] [--cleanup GENERATE_CLEANUP_CODE] [-w WORKING_PATH] [--gdb] [--gdb-outdir GDB_OUTDIR] [-D] [-a] [--annotate-fullc] [--annotate-coverage ANNOTATE_COVERAGE_XML] [--line-directives] [-+] [--embed] [-2] [-3] [--3str] [--lenient] [--capi-reexport-cincludes] [--fast-fail] [-Werror] [-Wextra] [-X NAME=VALUE,...] [-E NAME=VALUE,...] [sources [sources ...]] cython.py: error: cython: Need at least one source file What does -a do? I couldn’t find complete docs on the compiler switches although some are explained in the user guide. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Status
>> >> My concern is that the C compiler wont reject it, the program >> will corrupt data or crash: >> >> int32_t *x=..; *x = 42; >> int64_t *x=..; *x = 42; >> >> The C compiler will overwrite 4 or 8 bytes. Which one matters. > > As stated before, the C compiler will see the correct definition of the > types in the header files. And the generated C code will use the same type > names that the user had in their source code. "int64_t" will not magically > become "int" there. Ah. Ok, I get it now. Thanks. The “int” is just telling Cython the type has the same operations as “int”, i.e. +, - *, / etc. Like I said, a poor mans version of a “type class”. But, the compiler emits the symbols the user wrote when required. — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Size of output
> On 2 Feb 2020, at 03:06, Prakhar Goel wrote: > > Isn't it? > https://cython.readthedocs.io/en/latest/src/tutorial/cython_tutorial.html#primes: > Jump down to the part where it has "annotate=True" and it describes it > in some detail. > > Also this takes all of thirty-seconds to try out and the result is > pretty self explanatory. Ah, I missed that. The options are documented. What’s missing is the heading. The documentation is under “Jupyter Notebook”, whatever that is. I may have skipped reading that since I have no idea what it is. After that there is a heading, Compiler Options, but that actually refers to options set in setup.py rather than command line switches. https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#Cython.Compiler.Options.annotate In any case whilst useful it’s not really what I would have liked to see, which is a file with just the “yellow” code in it, and no boilerplate. Be good to suppress the refnanny stuff too. Is that possible? That seems to be for debugging, yes? — John Skaller skal...@internode.on.net ___ cython-devel mailing list cython-devel@python.org https://mail.python.org/mailman/listinfo/cython-devel