-
Notifications
You must be signed in to change notification settings - Fork 20
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
Placement of if
clauses
#1
Comments
That's a very good point! I could definitely save many keystrokes if I thought of it earlier :) There might be a few places where separate docstring is useful, especially when only partial functionality is supported in TensorFlow. But overall just checking the clause at the beginning will definitely make things much cleaner. I think an even better way to organize the project would be to have separate "implementation" modules, e.g.
And then selectively import them from the root |
If you want separate docstrings (that possibly list the constraints to be aware of depending on the backend), then probably the current pattern is the way to go.
Sure, that would be cleaner, but if you spread things over multiple files like this, it may be harder to keep their interfaces in sync. Whenever you extend/change the interface, you need to touch three files instead of one then. It would limit the case distinction to your global import os
mode = os.environ.get('TENSORFUSE_MODE', 'cgt')
del os
if mode == "theano":
import * from .theano_backend
elif mode == "cgt":
import * from .cgt_backend
elif mode in "tensorflow", "tf":
import * from .tensorflow_backend
else:
raise ImportError("Unsupported TENSORFUSE_MODE") (That's against PEP8, but there are ways around it.) |
Right. I think I'm fine with maintaining multiple files, since most of the code is just reimporting (especially for theano), and most of the file content will focus on bridging the few incompatibilities. Things get a little tricky when multiple backends share the same / similar bridging, like Just wondering, if you do the |
Hmm, no. Another advantage of providing the submodules would be allowing users to do: import tensorfuse.cgt_backend as theano
T = theano.tensor But still, if you want to be able to document each and every wrapper function, the current layout is suited better, otherwise you'd end up triplicating the docstrings. |
I do like the flexibility of importing custom backend. The replication of docstrings might not be that bad, since methods that need documentation will most likely have different specifications depending on the chosen backend. For example, for |
It might be good to highlight those in a common docstring, though, so as a user you know what to expect in the different backends when using |
Nice idea! I'm not so sure about the current implementation pattern, though. Take
tensor.nnet
:In the very beginning, you already check which backend was selected, so there's no way out. So instead of checking for the backend again and again, you could just do:
Similarly, if you have to wrap something (instead of just providing some existing function under a new name), you could place the
def
s in the initialif
clauses.I understand that most functions won't be called a lot anyway as they're just building the graph (so performance is not an issue), but it seems weird to replicate the clauses everywhere.
Are there other reasons for the current pattern? For example, do you plan to add your own docstring for each function? Do you want to fix the interface of the wrapper functions (e.g.,
relu
is just a subset of Theano'srelu
now)?The text was updated successfully, but these errors were encountered: