* Disabling the OCaml garbage collector @ 2007-11-27 16:28 Raj Bandyopadhyay 2007-11-27 16:41 ` [Caml-list] " Basile STARYNKEVITCH 2007-11-27 17:05 ` [Caml-list] Python and Caml (was: Disabling the OCaml garbage collector) Thomas Fischbacher 0 siblings, 2 replies; 15+ messages in thread From: Raj Bandyopadhyay @ 2007-11-27 16:28 UTC (permalink / raw) To: caml-list Dear all I am writing a foreign function interface between OCaml and another language (Python) which works via C. Since I have some memory issues currently, I would like to be able to disable the OCaml Garbage collector before jumping into C/Python, and re-enable it when I return to OCaml. I am using the OCaml/C interface and the macros that it provides to manage values (CAMLlocal and CAMLparam), but I would like to be able to disable the GC entirely for short periods. What facilities does OCaml provide to disable/enable the garbage collector? I looked at the GC module and didn't see anything obvious. It's fine if it is something at the C level rather than the OCaml level. Thanks for your help! Raj ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-27 16:28 Disabling the OCaml garbage collector Raj Bandyopadhyay @ 2007-11-27 16:41 ` Basile STARYNKEVITCH 2007-11-28 18:05 ` Raj 2007-11-27 17:05 ` [Caml-list] Python and Caml (was: Disabling the OCaml garbage collector) Thomas Fischbacher 1 sibling, 1 reply; 15+ messages in thread From: Basile STARYNKEVITCH @ 2007-11-27 16:41 UTC (permalink / raw) To: Raj Bandyopadhyay; +Cc: caml-list Raj Bandyopadhyay wrote: > Dear all > > I am writing a foreign function interface between OCaml and another > language (Python) which works via C. Since I have some memory issues > currently, I would like to be able to disable the OCaml Garbage > collector before jumping into C/Python, and re-enable it when I return > to OCaml. I am not convinced it is possible or makes sense. More precisely, your foreign -coded in C, called by Ocaml code- function probably allocates some result, and this allocation can trigger the Ocaml garbage collector In addition, AFAIK, the Ocaml minor garbage collector is only running when called, either implicitly from some allocation routines, or explicitly. So if you don't allocate things either directly or indirectly (e.g. by calling some callback coded in Ocaml) the Ocaml GC is not running. > > I am using the OCaml/C interface and the macros that it provides to > manage values (CAMLlocal and CAMLparam), but I would like to be able to > disable the GC entirely for short periods. You definitely may need to hack the C code inside byterun/minor_gc.c (for example), but I don't understand what you want exactly. However, I do know that mixing GCs, like Ocaml & Python, is a nightmare. Did you consider having two separate Unix processes, one for the Ocaml code and one for the Python code, and having them communicate thru standard stuff like pipes, memory mapped files, ... -- Basile STARYNKEVITCH http://starynkevitch.net/Basile/ email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359 8, rue de la Faiencerie, 92340 Bourg La Reine, France *** opinions {are only mines, sont seulement les miennes} *** ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-27 16:41 ` [Caml-list] " Basile STARYNKEVITCH @ 2007-11-28 18:05 ` Raj 2007-11-28 18:15 ` Alain Frisch ` (3 more replies) 0 siblings, 4 replies; 15+ messages in thread From: Raj @ 2007-11-28 18:05 UTC (permalink / raw) To: caml-list The issue for me is that I need to be able to modify mutable objects in OCaml (eg. array-modification in-place) from both OCaml and C/Python. However, the OCaml GC moves things around while the execution is in C/Python and this crashes my program. The Python GC is very simple, based on reference counts, hence (I think) it suffices just to make sure that any object has a refcount > 0 to keep the Python GC off. Well, I decided to go ahead and hack some C code to build a custom OCaml compiler. These are the steps I followed: 1) Add the following declarations to stdlib/gc.ml and stdlib/gc.mli external disable: unit -> unit = "caml_gc_disable" external enable: unit -> unit = "caml_gc_enable" 2) Modify byterun/gc_ctrl.c and implement the C functions. For example, int gc_enabled = 1; //global variable CAMLprim value caml_gc_enable(){ CAMLparam0(); gc_enabled = 1; CAMLreturn(Val_unit); } 3) Modify the "main loop" in gc_ctrl.c as CAMLprim value caml_gc_compaction(value v) { if(gc_enabled) { Assert (v == Val_unit); caml_empty_minor_heap (); caml_finish_major_cycle (); caml_finish_major_cycle (); caml_compact_heap (); caml_final_do_calls (); } return Val_unit; } However, when I compile this code with 'make world' I get the following error while linking: boot/ocamlrun boot/ocamlc -nostdlib -I boot -linkall -o ocaml.tmp toplevel/toplevellib.cma toplevel/topstart.cmo Error while linking boot/stdlib.cma(Gc): The external function `caml_gc_enable' is not available make: *** [ocaml] Error 2 Any ideas what I am missing? Thanks! Raj > > You definitely may need to hack the C code inside byterun/minor_gc.c > (for example), but I don't understand what you want exactly. > > However, I do know that mixing GCs, like Ocaml & Python, is a nightmare. > Did you consider having two separate Unix processes, one for the Ocaml > code and one for the Python code, and having them communicate thru > standard stuff like pipes, memory mapped files, ... > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-28 18:05 ` Raj @ 2007-11-28 18:15 ` Alain Frisch 2007-11-28 18:31 ` Thomas Fischbacher 2007-11-28 18:25 ` Thomas Fischbacher ` (2 subsequent siblings) 3 siblings, 1 reply; 15+ messages in thread From: Alain Frisch @ 2007-11-28 18:15 UTC (permalink / raw) To: Raj; +Cc: Caml mailing list Raj wrote: > The issue for me is that I need to be able to modify mutable objects in > OCaml (eg. array-modification in-place) from both OCaml and C/Python. > However, the OCaml GC moves things around while the execution is in > C/Python and this crashes my program. Are you sure? The OCaml GC is triggered only when Caml memory blocks are allocated (from Caml or C code) or when you call it explicitly. -- Alain ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-28 18:15 ` Alain Frisch @ 2007-11-28 18:31 ` Thomas Fischbacher 2007-11-28 19:30 ` Raj 0 siblings, 1 reply; 15+ messages in thread From: Thomas Fischbacher @ 2007-11-28 18:31 UTC (permalink / raw) To: Alain Frisch; +Cc: Raj, Caml mailing list Alain Frisch wrote: >> The issue for me is that I need to be able to modify mutable objects >> in OCaml (eg. array-modification in-place) from both OCaml and >> C/Python. However, the OCaml GC moves things around while the >> execution is in C/Python and this crashes my program. > > Are you sure? > > The OCaml GC is triggered only when Caml memory blocks are allocated > (from Caml or C code) or when you call it explicitly. Most likely, he calls back into another OCaml function from Python which does some memory allocation... In real applications, this situation is practically impossible to avoid. -- best regards, Thomas Fischbacher tf@functionality.de ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-28 18:31 ` Thomas Fischbacher @ 2007-11-28 19:30 ` Raj 0 siblings, 0 replies; 15+ messages in thread From: Raj @ 2007-11-28 19:30 UTC (permalink / raw) To: Caml mailing list You are absolutely right, Thomas. Internally, my program goes back and forth between Python and OCaml via C, and there can be chains of calls e.g. OCaml -> Python -> OCaml ->... and so on. If I'm passing a reference to a mutable object (e.g. an Array) around these call-chains, I need to make sure the GC doesn't move it around unexpectedly. Thank you for the suggestions, folks. I'll follow them up and see how they work. Regards Raj Thomas Fischbacher wrote: > > Most likely, he calls back into another OCaml function from Python which > does some memory allocation... In real applications, this situation is > practically impossible to avoid. > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-28 18:05 ` Raj 2007-11-28 18:15 ` Alain Frisch @ 2007-11-28 18:25 ` Thomas Fischbacher 2007-11-28 18:32 ` Xavier Leroy 2007-11-29 8:54 ` Frédéric van der Plancke 3 siblings, 0 replies; 15+ messages in thread From: Thomas Fischbacher @ 2007-11-28 18:25 UTC (permalink / raw) To: Raj; +Cc: caml-list Raj, > The issue for me is that I need to be able to modify mutable objects in > OCaml (eg. array-modification in-place) from both OCaml and C/Python. > However, the OCaml GC moves things around while the execution is in > C/Python and this crashes my program. You strongly should consider malloc()ing data and providing caml functions to read and write entries from a C array. In case the data chunk you want to modify from both caml and C holds non-integer ml values, things become a bit more complicated. Then, you have to register_global_root() these extra pointers into the ML heap. Unregistering of global roots then has to be done in the finalizer of the ML container value that retains a C pointer to malloc()d space. There, you free() this as well. Beware the dreaded global root reference loop though! -- best regards, Thomas Fischbacher tf@functionality.de ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-28 18:05 ` Raj 2007-11-28 18:15 ` Alain Frisch 2007-11-28 18:25 ` Thomas Fischbacher @ 2007-11-28 18:32 ` Xavier Leroy 2007-11-28 19:33 ` Raj 2007-11-29 8:54 ` Frédéric van der Plancke 3 siblings, 1 reply; 15+ messages in thread From: Xavier Leroy @ 2007-11-28 18:32 UTC (permalink / raw) To: Raj; +Cc: caml-list > Well, I decided to go ahead and hack some C code to build a custom OCaml > compiler. These are the steps I followed: [...] > However, when I compile this code with 'make world' I get the following > error while linking: That's a classic bootstrapping issue, and "make bootstrap; make all" might solve it. But you are on the wrong tracks anyway. What your C code does is disable the compactor, which runs from time to time to eliminate fragmentation in the major heap by moving objects around. You can disable it by using Gc.set with the "max_overhead" field set to a suitably high value, as documented in the Gc module. There is no need to hack the run-time system. However, what you will never be able to disable is the minor collector, which moves blocks from the minor heap to the major heap. The reason it cannot be disabled is that the minor heap is of fixed size, so if it gets full and the minor GC isn't executed to empty it, your program cannot proceed. You see, the Caml garbage collector is like a god from ancient mythology: mighty, but very irritable. If you mess with it, it'll make you suffer in surprising ways. The solution to your problem is to play nice with the Caml GC: on the C/Python side, handle Caml "values" through an indirection via a malloc-ed block, and register the Caml value contained within this block with the Caml GC using register_global_roots(), as Thomas Fischbacher outlined. Members of this list can probably point you to some existing C/Caml bindings that does just this and that you could use as inspiration. Hope this helps, - Xavier Leroy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-28 18:32 ` Xavier Leroy @ 2007-11-28 19:33 ` Raj 2007-11-28 20:00 ` Thomas Fischbacher 0 siblings, 1 reply; 15+ messages in thread From: Raj @ 2007-11-28 19:33 UTC (permalink / raw) To: Xavier Leroy; +Cc: caml-list Thank you for the advice, Xavier. I would highly appreciate any pointers to existing code that does the 'register_global_roots()' thing. Examples would definitely help me code it correctly. Regards Raj Xavier Leroy wrote: > > > The solution to your problem is to play nice with the Caml GC: on the > C/Python side, handle Caml "values" through an indirection via a > malloc-ed block, and register the Caml value contained within this > block with the Caml GC using register_global_roots(), as Thomas > Fischbacher outlined. Members of this list can probably point you to > some existing C/Caml bindings that does just this and that you could > use as inspiration. > > Hope this helps, > > - Xavier Leroy > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-28 19:33 ` Raj @ 2007-11-28 20:00 ` Thomas Fischbacher 2007-12-04 20:14 ` Raj Bandyopadhyay 0 siblings, 1 reply; 15+ messages in thread From: Thomas Fischbacher @ 2007-11-28 20:00 UTC (permalink / raw) To: Raj; +Cc: Xavier Leroy, caml-list Raj, > I would highly appreciate any pointers to existing code that does the > 'register_global_roots()' thing. Examples would definitely help me code > it correctly. I would suggest you download the nsim sources from: http://nmag.soton.ac.uk/nmag/current/download/nmag-0.1-core.tar.gz and study the nsim/mpi_petsc/petsc.ml and petsc_stubs.c files. (Actually, the code quality of these functions varies a bit. Most of the module is reasonably good style, but not everything.) Basically, this is an OCaml interface to the PETSc "parallel sparse linear algebra" library. (It also assimilated Xavier's old MPI interface for OCaml. Had to do that, sorry.) Of particular interest should be the function with_petsc_vector_as_bigarray, which will take an opaque petsc vector and a function that takes a double-float bigarray and calls that function from C in such a way that it can address the Petsc vector as if it were a bigarray. Also, you might be interested in the "sundials" module, which interfaces the CVODE time integrator from libsundials to OCaml. -- best regards, Thomas Fischbacher tf@functionality.de ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-28 20:00 ` Thomas Fischbacher @ 2007-12-04 20:14 ` Raj Bandyopadhyay 2007-12-05 4:07 ` Jon Harrop 0 siblings, 1 reply; 15+ messages in thread From: Raj Bandyopadhyay @ 2007-12-04 20:14 UTC (permalink / raw) To: caml-list Dear all, As a followup to this discussion, I have been trying to understand the OCaml/C interface better. Here's a very small program that I've been trying to get to work. It's a mutually recursive function, one part in C and the other in OCaml. (* (* Implement this in C *) let factC g n = if n=0 then [] else ("C",n)::(g (n-1));; *) external factC: (int ->(string * int) list) -> int -> ((string * int) list)= "caml_factC" let factO g n = if n=0 then [] else ("OCaml",n)::(g (n-1));; let rec fact n = factO (factC fact) n;; fact 12000;; The C function corresponding to factC is quite short, however the program crashes for values of n > about 11,000. I have tried inserting the code to register global roots (currently commented out), however, that makes no difference to the point of crash. I was just wondering if there is some really obvious step that I am missing, or using the wrong allocation function in Caml or something like that. Any suggestions would be welcome. I apologize in advice for inflicting code on you all, but I am out of ideas right now :( /* let factC g n = if n=0 then [] else ("C",n)::(g (n-1)) */ value caml_factC(value g,value n){ CAMLparam2(g,n); CAMLlocal3(e,l,new_l); //C value for n int locn = Int_val(n); //2 cases if (locn <= 0){ CAMLreturn(Val_int(0)); //empty list } else { e = alloc_tuple(2); //allocate a new list element ("C",n) Store_field(e,0,copy_string("C")); Store_field(e,1,n); //callback the closure g if(Tag_val(g) == Closure_tag) { //PROGRAM CRASHES HERE for large n and never returns from callback l = callback(g,Val_int(locn-1)); } else { exit(1); } //cons this tuple to the list obtained by callback new_l = alloc(2,0); //structured list value, tag is 0 Store_field(new_l,0,e); Store_field(new_l,1,l); //now we should register e,l and new_l with the GC //The program crashes at the same point (n>11000) regdless of whether the following //code is commented out or not. /* Vstore *roots = (Vstore *)caml_stat_alloc(sizeof (Vstore)); roots->v1 = e; roots->v2 = l; roots->v3 = new_l; caml_register_global_root(&roots->v1); caml_register_global_root(&roots->v2); caml_register_global_root(&roots->v3); CAMLreturn(roots->v3); //newly constructed list */ CAMLreturn(new_l); //newly constructed list } } Thanks! Raj ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-12-04 20:14 ` Raj Bandyopadhyay @ 2007-12-05 4:07 ` Jon Harrop 0 siblings, 0 replies; 15+ messages in thread From: Jon Harrop @ 2007-12-05 4:07 UTC (permalink / raw) To: caml-list On Tuesday 04 December 2007 20:14, Raj Bandyopadhyay wrote: > Dear all, > > As a followup to this discussion, I have been trying to understand > the OCaml/C interface better. Here's a very small program that I've > been trying to get to work. It's a mutually recursive function, one > part in C and the other in OCaml. > > (* (* Implement this in C *) > let factC g n = if n=0 then [] else ("C",n)::(g (n-1));; > *) > > external factC: (int ->(string * int) list) -> int -> ((string * int) > list)= "caml_factC" > let factO g n = if n=0 then [] else ("OCaml",n)::(g (n-1));; Could it just be segfaulting because you've overflowed the stack? Try tail recursive functions, e.g. CPS. I would love to see this working because I never managed to get this kind of stuff to work before. -- Dr Jon D Harrop, Flying Frog Consultancy Ltd. http://www.ffconsultancy.com/products/?e ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Disabling the OCaml garbage collector 2007-11-28 18:05 ` Raj ` (2 preceding siblings ...) 2007-11-28 18:32 ` Xavier Leroy @ 2007-11-29 8:54 ` Frédéric van der Plancke 3 siblings, 0 replies; 15+ messages in thread From: Frédéric van der Plancke @ 2007-11-29 8:54 UTC (permalink / raw) To: rajb, caml-list Raj wrote: > The Python GC is very simple, based on reference counts, hence (I > think) it suffices just to make sure that any object has a refcount > > 0 to keep the Python GC off. No, besides doing basic refcounting, the Python GC is also able to collect cycles despite of refcount > 0. I don't know the details you better ask the Python list. Frédéric ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Python and Caml (was: Disabling the OCaml garbage collector) 2007-11-27 16:28 Disabling the OCaml garbage collector Raj Bandyopadhyay 2007-11-27 16:41 ` [Caml-list] " Basile STARYNKEVITCH @ 2007-11-27 17:05 ` Thomas Fischbacher 2011-08-04 13:10 ` [Caml-list] Python and Caml Stéphane Glondu 1 sibling, 1 reply; 15+ messages in thread From: Thomas Fischbacher @ 2007-11-27 17:05 UTC (permalink / raw) To: Raj Bandyopadhyay; +Cc: caml-list Raj Bandyopadhyay wrote: > I am writing a foreign function interface between OCaml and another > language (Python) which works via C. Acknowledging that there is a number of people interested in interfacing python and caml, I just put up a website from which our bugfixed and extended variant of Art Yerkes' "pycaml" module can be downloaded: http://nmag.soton.ac.uk/tf/pycaml.html (Note ad Debian developers: this fixes some major memory management bugs that can cause crashes in the original pycaml module which is in Debian, so, ideally, our variant should eventually supersede the code that is at present in that Debian package. Interface-wise, our module provides more than the original one, but I think I also had to remove two or three very obscure functions.) -- best regards, Thomas Fischbacher tf@functionality.de ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Caml-list] Python and Caml 2007-11-27 17:05 ` [Caml-list] Python and Caml (was: Disabling the OCaml garbage collector) Thomas Fischbacher @ 2011-08-04 13:10 ` Stéphane Glondu 0 siblings, 0 replies; 15+ messages in thread From: Stéphane Glondu @ 2011-08-04 13:10 UTC (permalink / raw) To: Thomas Fischbacher Cc: Raj Bandyopadhyay, caml-list, arty, Debian Ocaml Maint ML Le 27/11/2007 18:05, Thomas Fischbacher a écrit : > http://nmag.soton.ac.uk/tf/pycaml.html This link is broken. > (Note ad Debian developers: this fixes some major memory management bugs > that can cause crashes in the original pycaml module which is in Debian, > so, ideally, our variant should eventually supersede the code that is at > present in that Debian package. Interface-wise, our module provides more > than the original one, but I think I also had to remove two or three > very obscure functions.) If you still think that, you should file a bugreport [1] against the pycaml package... or at least notify the Debian OCaml Maintainers list (in CC)... Given the patches applied to the Debian packages that merely adapt it to newer Python versions, the absence of new upstream release for 6 years now, the absence of Art Yerkes in this thread (by the way, I put him in CC of this mail), I consider this project "dead" upstream. It would be nice if someone could take over upstream maintenance, and at least incorporate our patches [2] (or any other variant) for wider distribution. As far as Debian is concerned, only coccinelle [3] depends on pycaml. [1] http://www.debian.org/Bugs/Reporting [2] http://patch-tracker.debian.org/package/pycaml [3] http://coccinelle.lip6.fr/ Cheers, -- Stéphane ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2011-08-04 13:10 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-11-27 16:28 Disabling the OCaml garbage collector Raj Bandyopadhyay 2007-11-27 16:41 ` [Caml-list] " Basile STARYNKEVITCH 2007-11-28 18:05 ` Raj 2007-11-28 18:15 ` Alain Frisch 2007-11-28 18:31 ` Thomas Fischbacher 2007-11-28 19:30 ` Raj 2007-11-28 18:25 ` Thomas Fischbacher 2007-11-28 18:32 ` Xavier Leroy 2007-11-28 19:33 ` Raj 2007-11-28 20:00 ` Thomas Fischbacher 2007-12-04 20:14 ` Raj Bandyopadhyay 2007-12-05 4:07 ` Jon Harrop 2007-11-29 8:54 ` Frédéric van der Plancke 2007-11-27 17:05 ` [Caml-list] Python and Caml (was: Disabling the OCaml garbage collector) Thomas Fischbacher 2011-08-04 13:10 ` [Caml-list] Python and Caml Stéphane Glondu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox