Open stacksmith opened 5 years ago
Hey @stacksmith, sorry for the slow replies I've been putting all time into work recently. The days need extra hours.
Luckily these two are easy to explain. In reverse order
Gpu-arrays are not designed to stay in sync. they are just meant to be an array on the gpu. c-arrays are the local analog and are meant to have a layout that makes it easy to transfer data (relatively) efficiently between them.
Is a symptom of how slime/slync etc work. When you compile top level forms in slime it runs them on a different thread than the thread the repl is running on. This then causes an error usually we start cepl from the repl and that means that is the thread the GL context is bound to. I've looked into using multiple contexts on the threads in question but whilst it would help for some GL objects, not all of them are available on all contexts (VAOs are a good example).
The way I usually handle it on small sessions is to (defvar something nil) and then have a 'reset' method that is called on start and then I can call on demand whilst I'm experiementing. For larger projects I'm likely to have some more interesting lifetime requirements anyway and so I'm less likely to just have misc gpu-arrays in top level vars.
It's a bit of a pain in the ass though. You can start swank using communication-mode nil which means no multi-threading at all. With everything on the same thread i think what you are trying will work but that has it's own disadvantages as you could imagine.
Thanks. I am still confused about 2. So I cannot use 'with-gpu-array-as-c-array' to mutate the GPU array? I thought that's exactly what it's for...
@stacksmith You are totally right. Sorry for misreading. Here is my test I think is equivilent
(defun test1 ()
(let ((garray (make-gpu-array '(0.0 1.0 2.0) :element-type :float)))
(print (pull-g garray))
(with-gpu-array-as-c-array (qqq garray)
(setf (aref-c qqq 0) 999))
(print (pull-g garray))))
I get an error saying
The value
999
is not of type
SINGLE-FLOAT
when I change it to 999f0 I get
TESTS> (test1)
(0.0 1.0 2.0)
(999.0 1.0 2.0)
(999.0 1.0 2.0)
I then wondered if my test was too different and compiled these:
(defvar garray nil)
(defun test1 ()
(setf garray (make-gpu-array '(0.0 1.0 2.0)
:element-type :float)))
and then ran this
TESTS> (test1)
#<GPU-ARRAY :element-type :FLOAT :dimensions (3) :backed-by :BUFFER>
TESTS> garray
#<GPU-ARRAY :element-type :FLOAT :dimensions (3) :backed-by :BUFFER>
TESTS> (pull-g garray)
(0.0 1.0 2.0)
TESTS> (with-gpu-array-as-c-array (qqq garray) (setf (aref-c qqq 0) 999))
; Evaluation aborted on #<TYPE-ERROR expected-type: SINGLE-FLOAT datum: 999>.
TESTS> (with-gpu-array-as-c-array (qqq garray) (setf (aref-c qqq 0) 999f0))
999.0
TESTS> (pull-g garray)
(999.0 1.0 2.0)
I'm not sure what to try next to replicate the issue
1: immediate commands containing MAKE-GPU-ARRAY crash on compile inside an Emacs file (C-C), but work fine in REPL.
It seems there is no way to compile immediate-mode GPU allocations.
2: GPU arrays lose sync with underlying C arrays
I though pull-g only goes one level and pulls GPU arrays into C arrays? Here we wind up with a Lisp list...