-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve memory management #6
Comments
For example, the following C code would crash at a certain point: #include <julia.h>
const int N = 1000000;
int main() {
jl_init();
jl_value_t *int1d = jl_apply_array_type((jl_value_t *)jl_float64_type, 1);
jl_array_t *arr = jl_alloc_array_1d(int1d, N);
for (int i = 0; i < N; i++) {
jl_arrayset(arr, jl_box_float64(i), i);
}
jl_function_t *sqrt = jl_get_function(jl_base_module, "sqrt");
for (int i = 0; i < N; i++) {
printf("%.6f\n", jl_unbox_float64(jl_call1(sqrt, jl_arrayref(arr, i))));
}
jl_atexit_hook(0);
return 0;
} And so will the equivalent import {Julia, JuliaArray} from 'jlbun';
Julia.init();
const N = 1000000;
const a = JuliaArray.init(Julia.Float64, N);
for (let i = 0; i < N; i++) {
a.set(i, i);
}
for (let i = 0; i < N; i++) {
console.log(Julia.Base.sqrt(a.get(i)).value);
}
Julia.close(); This is due to Julia's GC. If we totally disable GC by To solve this issue properly, we need to mark the necessary variables as rooted to keep them alive, just like |
Reference use jlrs::prelude::*;
fn main() {
// Initializing Julia is unsafe because it can race with another crate that does
// the same.
let mut julia = unsafe { RuntimeBuilder::new().start().unwrap() };
let mut frame = StackFrame::new();
let mut julia = julia.instance(&mut frame);
let res = julia
.scope(|mut frame| {
let mut array = TypedArray::<f64>::new(frame.as_extended_target(), 1_000_000).unwrap();
unsafe {
let mut acc = array.bits_data_mut()?;
for i in 0..1_000_000 {
acc.set(i, i as f64);
}
let sqrt = Module::base(&frame).function(&mut frame, "sqrt")?;
for i in 0..1_000_000 {
let raw = acc.get_value(&frame, i).unwrap().unwrap().unwrap().value();
let new = sqrt.call1(&mut frame, raw).unwrap().unbox::<f64>().unwrap();
println!("{}", new);
}
}
Ok(())
})
.unwrap();
} |
Reference C code that does not crash: #include <julia.h>
const int N = 1000000;
int main() {
jl_init();
jl_value_t *int1d = jl_apply_array_type((jl_value_t *)jl_float64_type, 1);
jl_array_t *arr = jl_alloc_array_1d(int1d, N);
for (int i = 0; i < N; i++) {
jl_arrayset(arr, jl_box_float64(i), i);
}
jl_function_t *sqrt = jl_get_function(jl_base_module, "sqrt");
JL_GC_PUSH2(&arr, &sqrt);
for (int i = 0; i < N; i++) {
jl_value_t *val = jl_arrayref(arr, i);
jl_value_t *sval = jl_call1(sqrt, val);
printf("%.6f\n", jl_unbox_float64(sval));
}
JL_GC_POP();
jl_atexit_hook(0);
return 0;
} |
Reference import {Julia, JuliaArray} from 'jlbun';
Julia.init();
const N = 1000000;
const a = JuliaArray.init(Julia.Float64, N);
Julia.setGlobal("a", a); // Avoid `a` from being GC-ed.
for (let i = 0; i < N; i++) {
a.set(i, i);
}
for (let i = 0; i < N; i++) {
console.log(Julia.Base.sqrt(a.get(i)).value);
}
Julia.close(); |
Currently, there is no special handling of memory management. jlrs has set an outstanding example, and we can learn from it.
The text was updated successfully, but these errors were encountered: