Refactor CEPL's gpu struct support
We have some issues with the current approach. The lisp version isnt very lispy and the c/gpu versions don't support layout and require the creation of intermediate wrappers for basic interaction.
I think I want to do the following:
- move to using proper lisp structs on the lisp side.
- have a
with-c-elementorwith-c-structmacro for interacting with the elements from c-arrays. This will let us specify the layout too so we dont have to have runtime checking on the wrapper object
We will also be able to pass regular lisp arrays of the structs to the constructors & push-g and be able to trivially get the correct type and dimensions. This will be a massive improvement over the approach we have now.
older related issues
https://github.com/cbaggers/cepl/issues/177
We need the layout support before this can progress
Layout support working. We are not going to support multiple layouts per struct type, so if you want one with same slots and different layout then that will need to be a separate type.
We still want to do roughly what we planned above however. It should be noted that we will have to use classes as structs cant be redefined. Hmm but doesnt defstruct-g have a static option? If not then add it
What a palaver
Ok so each option kind of sucks:
with our wip refactor we have proper lisp types we can use but we pay for the conversions, which if the elements are structs containing arrays can be expensive. Now this could be fine for push-g/pull-g but is pretty bad for map.
The current approach is nice in that we pay a low cost for getting a handle, but we have a bunch of issues.
- make-* causes leaks (can be mitigated by using gc for those entries)
- conversion costs are paid on every access
- the lisp representation of the data is just nested lists...which is nasty
the refactor could benefit from with-g-struct which lets you access a foreign element in the way we do now, however then we need to tell with-g-struct the type so we are less dynamic that we are currently...is that true? well.. now at least we dont have to track the element type so strictly... dont we? .. hmm.
one possibility is to have map-c take a pattern and, before iterating, fetch the accessors.
There is also the question of array or c-array when accessing a slot
Ok, more tests done
The new major issue is with aref-c. If it returns a lisp struct then the following doesnt work:
(setf (g-pnt-pos (aref-c foo 0)) bar)
as you just modify the new struct. This means we would need to make aref-c return a reference instead of a lisp struct...and then we are back in the original damn situation we were before.
We could have a two wrapper types, one which has the pointer and the second which inherits from the first but doesnt use the pointer... Nope, then you need multiple versions of the accessor functions.
I think the answer is that this experiment has hit a dead end. We need to stick with roughly what we have already and see how we can make it better.
To take back to master
- storing struct definitions is nice
- through-c could be good for avoiding consing
- need to type all of the map-c functions where possible
- row-major-aref-c should be added
- row-major-aref-c (or equivalent) can be used in all cases where you dont need the indices as a list
- in across-c make the list first and then mutate it
- map-c and friends should pull the first element and then mutate it for each iteration
- lets see if we can ditch the constructor and use some other function/macro to pour the data into an element of a c-array