I have done searches on the repo and looked through all of conv.jl within NNLib.jl. I can only find a method that takes 2 positional arguments and the rest named arguments. If you except the defaults for all of the named arguments you can call this as conv(x, w). But, the one and only function called conv returns conv(x, w, cdims) where cdims is calculated based on the named arguments to conv().
Somewhere the 3 argument method has to exist. Searches on both the Flux.jl repo and NNLib.jl repo did not reveal it. It has to exist somewhere.
I am trying to learn from the Flux implementation as I have had considerable difficulty writing my own code for convolutional layers using unrolling.
I hate code like that. Layers of layers of indirection. Impossible to see the names of the functions. Impossible even to see the body of the function, although this one just supplies some parameters to the primary conv function.
Is it really necessary to have this macro generated code? Would it be so hard to explicitly code the required methods? Text editors are efficient. Then, others could interpret what the code does.
Why is this so Julian? It’s worse than the c++ standard template library.
I’m not familiar with the source file, either, and only had a quick look for this thread. But maybe you can try a debugger to step into various function definitions to locate the source lines.
When this code was originally written, Julia was a less mature language and NNlib had more, idiosyncratic backends. My understanding is that the code generation and multiple levels of indirection was a way around both of those challenges.
These days, overuse of @eval is not Julian and there are only two CPU implementations left for conv (direct and im2col). Ideally someone could help simplify the template routines in conv.jl. It’s unlikely to happen without a volunteer, unfortunately.
I think the goal of the macro was to avoid dynamic dispatch by instantiating all the needed methods. Sometimes concision collides with clarity and maintainability.
An alternative would have been to create functions that provided the appropriate signature for each method and in each function body prepare the input parameters needed and call the generic code.