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

Config Derive: Generic Types? #1754

Open
jclmnop opened this issue May 11, 2024 · 2 comments
Open

Config Derive: Generic Types? #1754

jclmnop opened this issue May 11, 2024 · 2 comments

Comments

@jclmnop
Copy link

jclmnop commented May 11, 2024

Feature description

Currently, we can't use generic type parameters on a struct if we want to derive Config for it.

It would be nice if we could. Or, if it's not possible, perhaps a panic! in the derive macro implementation explaining that.

Feature motivation

I was trying to create a loss function that wraps an existing loss function and adds weights to false positives or false negatives for specific targets. It's just meant to use the wrapped loss function and then adjust the losses according to weights depending on whether they're false negatives or false positives.

To do this I created traits for the wrapped loss functions + their configs, and then used a generic type with a trait bound.

#[derive(Config, Debug)]
pub struct WeightedLossConfig<B: Backend, L: WrappedLossConfig<B>> {
    wrapped_loss_fn_config: L,
    #[config(default = "None")]
    false_positive_weights: Option<Vec<f32>>,
    #[config(default = "None")]
    false_negative_weights: Option<Vec<f32>>,
}

This of course doesn't compile because the derive implementation for Config discards all generics.

It's possible I'm just not really doing things the "right" way. I'm also only really planning on using this with CrossEntropyLoss anyway so a concrete implementation without traits will be fine for now.

(Optional) Suggest a Solution

After forking the repo and trying to implement this myself I ran in to issues with the internal burn::serde::Deserialize derive macros inside the Config derive macro, so now I'm assuming there might be a reason this hasn't been implemented before.

If that's the case, maybe just panic in the derive macro when the struct has generic parameters, explaining why they can't be used. Would stop people like me from trying to implement it themselves.

@nathanielsimard
Copy link
Member

Configs are pretty much raw data that can be serialized and deserialized with proper defaults. I'm not sure there are blockers making it impossible to support generics, but I think using an enum in this setting may be simpler. Anyways, I'm happy to review any PR you do in this direction; simply improving the error message can be beneficial to many!

@jclmnop
Copy link
Author

jclmnop commented May 16, 2024

Configs are pretty much raw data that can be serialized and deserialized with proper defaults. I'm not sure there are blockers making it impossible to support generics, but I think using an enum in this setting may be simpler. Anyways, I'm happy to review any PR you do in this direction; simply improving the error message can be beneficial to many!

Yeah when I briefly looked over the serde stuff it didn't seem to be impossible, but might not worth the hassle1. In the end, for my specific use case, I just ended up removing generics from the config struct and instead used generics with trait bounds on methods implemented for that config struct and its module.

I'll have more free time early next month, so will probably open a PR to improve error messages related to generics at the very least, and maybe implement generics for #[derive(Config)] after that if it doesn't prove to be too difficult.

One would assume that it shouldn't be too difficult to implement for generics that already implement Config but we'll see.

Footnotes

  1. Could be argued that anything which makes it easier for people to develop their own "extension" crates is worth it, but I really haven't been using burn for long enough to say whether this is one of those features.

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