Skip to content
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

empty initialized model #107

Closed
proohit opened this issue May 27, 2021 · 4 comments
Closed

empty initialized model #107

proohit opened this issue May 27, 2021 · 4 comments

Comments

@proohit
Copy link

proohit commented May 27, 2021

I want to have a static variable which holds a model, but I want it to be lazy-loaded. This way, I only have to initialize it once and reuse it during runtime. The final model has been serialized in a file from which it can be loaded.

I'm thinking of something like this:

static mut model: LinearRegression<f64, DenseMatrix<f64>> = None;

fn init(model_path: str) {
    unsafe {
        model = {
            let mut buf: Vec<u8> = Vec::new();
            File::open(&model_path)
                .and_then(|mut f| f.read_to_end(&mut buf))
                .expect("Can not load model");
            bincode::deserialize(&buf).expect("Can not deserialize the model")
        }
    }
}

But it is not possible to initialize a LinearRegression<f64, DenseMatrix<f64>> with None. Is there another easy way to initialize a "default" or "empty" model? I thought of a constructor-like API:

LinearRegression::new()

which constructs an empty model without any parameters.

Additional info

I think in python's scikit-learn this can also be achieved with sklearn.linear_model.LinearRegression().

I tried an alternative by wrapping the model type with an Option<> like this:

static mut model: Option<LinearRegression<f64, DenseMatrix<f64>>> = None;

but this brings in other challenges and feels a little hacky.

Thanks in Advance!

@morenol
Copy link
Collaborator

morenol commented May 27, 2021

Have you checked the lazy_static crate? Maybe it works for your use case.

@proohit
Copy link
Author

proohit commented May 27, 2021

I checked out the crate, but I didn't understand which initial value to assign to my static model variable. In the examples, they seemed to always provide an initial value, but mine comes when invoking the ‘init‘ function during runtime. The function get's a path string from outside which may vary from caller to caller.

@morenol
Copy link
Collaborator

morenol commented Jun 1, 2021

Maybe you can try https://docs.rs/once_cell/1.4.0/once_cell/#lazy-initialized-global-data with something like this(?)

fn init(model_path: &str) -> &'static LinearRegression<f64, DenseMatrix<f64>> {
    static MODEL: OnceCell<LinearRegression<f64, DenseMatrix<f64>>> = OnceCell::new();
    MODEL.get_or_init(|| {
            let mut buf: Vec<u8> = Vec::new();
            File::open(&model_path)
                .and_then(|mut f| f.read_to_end(&mut buf))
                .expect("Can not load model");
            bincode::deserialize(&buf).expect("Can not deserialize the model")
    })
 }

I have not confirmed that this works, but that is what it was suggested here rust-lang-nursery/lazy-static.rs#160.

Hope that this helps

@proohit
Copy link
Author

proohit commented Jun 8, 2021

Hi @morenol , thank you a lot. I'm happy to report your suggested solution works as expected :). Though, I can only use the once_cell crate only in nightly (currently 1.54.0) and when adding #![feature(once_cell)] to to the top of my source file. For reference, here's how I implemented it with MODEL being on the top level:

static mut MODEL: OnceCell<LinearRegression<f64, DenseMatrix<f64>>> = OnceCell::new();
pub fn init(model_path: *mut c_char) {
    unsafe {
        let file_name = CStr::from_ptr(model_path).to_str().unwrap();
        MODEL.get_or_init(|| {
            let mut buf: Vec<u8> = Vec::new();
            File::open(&file_name)
                .and_then(|mut f| f.read_to_end(&mut buf))
                .expect("Can not load model");
            bincode::deserialize(&buf).expect("Can not deserialize the model")
        });
    }
}

@morenol morenol closed this as completed May 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants