zshipko / futhark-bindgen Goto Github PK
View Code? Open in Web Editor NEWA Futhark binding generator for Rust and OCaml
License: ISC License
A Futhark binding generator for Rust and OCaml
License: ISC License
In OCaml, the type of the Cartesian product of two types 'a,'b
is denoted 'a * 'b
.
The *.mli files generated by futhark-bindgen annotates product types as ('a, 'b)
. This is not standard OCaml syntax.
This Futhark file will cause Dune to complain about syntax errors.
entry pair (i : i32) (j : i32) = (i, j)
(And potentially become much more confused because I don't think Dune is really designed to deal with syntax errors in mli files in the build directory - probably the build system is designed under the assumption that syntax checks happen before the mli file is copied from the source directory to build directory. I get very weird errors from Merlin as a result of this)
I am using OCaml to write a wrapper for my Futhark program. OCaml is a garbage collected language, so if I dynamically allocate an array, I don't have to think about deallocating it, the garbage collector does it for me.
Now, say I create a new Futhark context, then allocate an array in OCaml.
let ctx = Context.v
~debug:false ~log:false ~profile:false ~auto_sync:true ()
let pt_cloud= read_pt_cloud file (* pt_cloud_array is a 2D Bigarray.Genarray *)
let z = Array_f64_2d.v ctx pt_cloud
let m = my_futhark_fn ctx z
I assume this Array_f64_2d.v
merely "registers" the array pt_cloud
with the Futhark context and creates some small overhead data structure with pointers to it.
Now I call a Futhark function, get my result.
I am now confused about what to do with the Futhark 2D array z
I constructed on top of my OCaml array. I was thinking that I should call the Futhark function Array_f64_2d.free z
but it's not clear to me how that interacts with OCaml's garbage collection system. When I run the code without calling any free functions, it seems to work, but I'm unclear on whether I'm creating a memory leak by not deallocating the resources. Conversely when I run the code and use the free functions, I hit a bunch of segfaults in my OCaml code and I'm not sure how to get around them. It's occurring to me that these segfaults might be caused by the garbage collector trying to collect memory which has already been deallocated by Futhark.
Do you have any advice on how to proceed here?
Thank you very much!
This is a somewhat minimized version of what appears to be a pretty subtle and tricky bug, it gives a use-after-free error for me on OCaml 5.1.1. If you cannot easily reproduce it then possibly increasing the number of iterations of the main loop will help.
I am using the master branch of Futhark and gcc 11.4, but if you cannot reproduce it please let me know and I will try and give a more robust version of the bug.
The code relies on the ctypes.foreign
library which can be installed with opam install ctypes-foreign
.
The main executable is in test/futhark_test.ml
. It can be executed with dune exec ./test/futhark_test.exe
from the top directory of the project.
@athas If you have any insight into what is happening here, it would be greatly appreciated.
Edit: I asked athas directly on a Futhark discussion group and he said:
It is very strange. I can think of one reason it could happen: just before calling the Futhark entry point, after extracting the pointers from the OCaml-level array objects, the GC runs. At this point, the OCaml arrays are dead, and are garbage collected, and so the C pointers are also freed. But this would imply that using finalizers to wrap C objects in OCaml is very fragile, and must be done very carefully. In particular, the finalizer should be attached to the C pointer. And... maybe you should use a weak reference?
I initially thought this was due to Futhark's lazy semantics, maybe it was freeing the memory before Futhark was finished with the computation, but even if I call Context.sync ctx
after every iteration of the loop, it still segfaults.
However, manually calling Array_f64_2d.free seems to fix the problem so far, so it can be worked around just by manually freeing the memory everywhere.
I am not experienced with compiling OCaml with C dependencies so I had some pretty basic misunderstandings while trying to get this set up. This is basically just a problem with me misunderstanding how dune works in this scenario but other newbies might have the same issue.
The futhark-bindgen help --backend xyz
commands are very helpful, but do you think you could futher clarify (either in the OCaml example section or in the help command itself or both) whether the given flags are supposed to be fed to library_flags
or c_library_flags
?
I initially thought that all the flags given by the --backend xyz
were supposed to be given to library_flags
and had to consult the dune documentation for a while to resolve my misunderstanding.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.