computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Ping timeout: 256 seconds]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
<Hodgestar>
How was the meeting?
<Hodgestar>
If the data API is specifically only covering the Python API (and not any C API) how relevant is it to HPy?
<steve_s>
I haven't read up on it yet, but @mattip mentioned that numpy will/does have a mode, which implements this and which supports only dtyped without python objects in them
<steve_s>
The idea was that we'll support numpy in this mode only, because it will remove all the issues with how to traverse the memory in tp_traverse if we do not have a context and cannot query the dtype object about the shape of the memory, i.e., find out where are the HPyField in the C struct
<Hodgestar>
Ah, so this would provide a subset of numpy that HPy could support more easily.
<Hodgestar>
mattip: Any idea if the people being funded by AMD would be interested in collaborating on porting that subset of numpy? It would be amazing to have some input / conversations about how things are done by both sides so that HPy doesn't have to rely on continually dodging "mistakes" made in the API design because of other considerations or just by accident.
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
<steve_s>
I plan to write up mode details into some GitHub issue where we can discuss it further. Main thing is that it would not be something like piconumpy, it would be full numpy with the intention to upstream the code, but you would be allowed to use object in arrays only in CPython ABI mode, in universal mode, when you create an array with objects in it, it will raise an error. The parts of numpy that are necessary to support arrays with objects in
<steve_s>
them can keep on using CPython API, they will never be called in universal mode.
<steve_s>
The idea is that this mode should be the preferred numpy mode and there will be more reasons for using it not only HPy
<Hodgestar>
steve_s: Re m_traverse: I think I still don't understand why HPy could not just register a different tp_traverse when it creates a module object (that then calls any tp_traverse passed to HPy)?
<Hodgestar>
mattip: I was think more collaborating (i.e. working together) and not high-level discussions.
<steve_s>
Re m_traverse: the trampoline that is generated for normal tp_traverse does basically this: bounce_to_user_tp_traverse(HPy_AsStruct(object), visit, arg), but for module we need bounce_to_user_tp_traverse(HPyModule_GetState(object), visit, arg). The generated trampoline could check if the object is module or type, but I think m_traverse solution is better.
<ronan>
steve_s: Actually, if we don't implement item traversal, everything should work with the universal ABI. The only issue is that cycles won't be detected, but that's numpy's current status anyway.
<Hodgestar>
steve_s: The trampoline wouldn't necessarily have to check though -- it could just be a different trampoline.
<Hodgestar>
steve_s: Btw, I am not necessarily advocating for a particular solution here, just working through the options to understand them.
<steve_s>
> it could just be a different trampoline
<steve_s>
yes, that's what I suggest. But from the function itself you don't know which one to generate. However, we could just generate both trampolines for every tp_traverse, is that what you mean? Yes that sounds also good, maybe better, just more generated code but that's not a big issue?
<steve_s>
but this struct:
<steve_s>
typedef struct {
<steve_s>
HPySlot_Slot slot; // The slot to fill
<steve_s>
void *cpy_trampoline; // Used by CPython to call impl
<steve_s>
} HPySlot;
<steve_s>
would need one more field for the other trampoline...
<steve_s>
void *impl; // Function pointer to the implementation
<antocuni>
ronan: "if we don't implement item traversal, everything should work". What do you mean? If you don't implement a proper tp_traverse, everything will explode pretty quickly on PyPy because the GC would have only a partial view of the memory
<antocuni>
which means objects which are collected even if they are still alive, and others which are moved but without updating their pointers
<steve_s>
ronan: yes the use case for tp_traverse on HPy is not only cycles detection
<steve_s>
but to also know what objects to clear, right? I.e. the autogenerated tp_clear
<ronan>
antocuni: no, it'll be handled by cpyext through refcounting - just like on upstream numpy + pypy
<antocuni>
ok, then I'm confused and I don't know what we are talking about
<steve_s>
who will decrement the refcount though?
<ronan>
numpy does it already
<steve_s>
where?
<antocuni>
in array_dealloc, I suppose
<ronan>
yes, or array_finalize in hpy-numpy
<steve_s>
right, well, then that sounds good actually. If numpy ignores cycles detection, hpy-numpy may as well and being able to access context in tp_traverse is not an issue at all
<steve_s>
then it is a question if we still do not want to support only the array api standard, because that would save us from all the HPyField stuff like storing/loading unaligned fields, memcpy and all that
<steve_s>
so maybe there are still reasons to support only the array api standard and not dtypes with objects
<antocuni>
well, it is still an issue because if I understand correctly this means that the plan is to implement the object dtype using legacy PyObject
<antocuni>
which prevents to compile in pure universal mode
<antocuni>
but I guess there is still a long way before we can kill the legacy code so maybe it's not an immediate problem
<steve_s>
> which prevents to compile in pure universal mode
<steve_s>
hm, yes :/ but yes, converting that to use HPy fields can be the next step. It is already a massive undertaking so the more we can partition it to smaller self-contained useful steps...
<ronan>
in any case, all the object dtype code will need either to be removed or ported to compile in pure universal mode. tp_traverse is just a small part of it
<antocuni>
anyway, if we can support dtype=object via legacy PyObject* it's still a good thing for now, because it means that we can move forward
<steve_s>
ronan: but I assume you've ported some of the dtype support already? I was thinking if it could stay half way: some parts of the code, irrelevant in the array api standard, can stay in CPython API and you'd convert the handle to PyObject and pass it to that code and be done (for now, for this porting iteration).
<steve_s>
Re universal mode: as long as the code actually doesn't call into CPython API, then PyPy/GraalPyton could still run it in universal mode, right? We'd need to provide the CPython API functions so the linker is happy, but they can be just stubs, or not if there are PyObject* <-> HPy conversion functions on the context doing the right thing they can just work.
<steve_s>
but yes it would not be pure universal binary
<steve_s>
Re: dtype support, what is more of an issue are PyObjects stored in the arrays themselves, right? Those I would not convert to HPyFields and just let them be PyObject and not port all the code that handles them.
computerfarmer has quit [Quit: Konversation terminated!]
computerfarmer has joined #hpy
<ronan>
yes, I have ported quite a lot of the object dtype support, but there are lots of places that can probably only work on CPython, e.g. where I used HPyField_Load(ctx, HPy_NULL, some_field)
<ronan>
The problem for the universal mode is that as soon as you start converting PyObject* to HPyField, you need to convert everything, and you can't run the tests until you do
<ronan>
stopping before that gives a point where PyPy can run all of numpy (with all the object dtype stuff running in cpyext)
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
<antocuni>
ronan: re "you need to convert everything": is this because you cannot mix HPyField and PyObject* in the same struct? Or there is some other hidden problem which prevents fields to be ported one by one?
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Read error: Connection reset by peer]
computerfarmer has joined #hpy
computerfarmer has quit [Quit: Konversation terminated!]
<ronan>
antocuni: it's about the items inside the array, they're stored in a void*, so you need to consistently use either (HPyField *)data_ptr or (PyObject **)data_ptr. In universal mode, you can't mix and match. It's much less of a problem for fields that are directly on the PyArrayObject struct, partly because there are accessor macros and because the compiler can help you.