Registers and returns a python operator. `f` and `grad_f` can be one of the following: - a function with signature (inputs, outputs), where inputs and outputs are a list of CPUTensor objects. This function will be called from C++ everytime th
(
self,
f,
grad_f=None,
python_func_type=None,
pass_workspace=False,
grad_output_indices=None,
grad_input_indices=None
)
| 2294 | ))) |
| 2295 | |
| 2296 | def Python( |
| 2297 | self, |
| 2298 | f, |
| 2299 | grad_f=None, |
| 2300 | python_func_type=None, |
| 2301 | pass_workspace=False, |
| 2302 | grad_output_indices=None, |
| 2303 | grad_input_indices=None |
| 2304 | ): |
| 2305 | """ |
| 2306 | Registers and returns a python operator. |
| 2307 | |
| 2308 | `f` and `grad_f` can be one of the following: |
| 2309 | - a function with signature (inputs, outputs), where inputs and |
| 2310 | outputs are a list of CPUTensor objects. This function will be |
| 2311 | called from C++ everytime the operator is executed. |
| 2312 | - a tuple (func, args, kwargs), here `func` is a callable, args is |
| 2313 | an argument list, and kwargs is a dict list. The call: |
| 2314 | f = func(*args, kwargs) |
| 2315 | will be performed locally at node initialization time, on all of |
| 2316 | the nodes of the job, returning `f`, a callable that will be used |
| 2317 | as the python operator function to be called during Net execution. |
| 2318 | This is to be used when using python operator in a distributed |
| 2319 | context, and allows to create and keep local python state across |
| 2320 | calls to the operator. |
| 2321 | |
| 2322 | `python_func_type` is a type of an object that constructed as |
| 2323 | python_func_type(f) and provides an implementation to forward and |
| 2324 | backward functions. Its useful in such a case where users needs |
| 2325 | a statefull PythonOp (ex: use autograd for computing grad_f). |
| 2326 | |
| 2327 | If `pass_workspace` is True, the signature is changed to |
| 2328 | (inputs, outputs, workspace) where `workspace` is the workspace the op |
| 2329 | is going to run on. This is potentially dangerous (as the op can |
| 2330 | manipulate the workspace directly), use on your own risk. |
| 2331 | |
| 2332 | If a gradient function is specified (`grad_f`), by default its inputs |
| 2333 | will be: (1) all inputs to `f`, (2) followed by all outputs of `f`, (3) |
| 2334 | and then all gradient outputs of `f`. The outputs of `grad_f` will be |
| 2335 | (by default) all gradient inputs to `f`. If a subset of the gradient |
| 2336 | outputs or gradient inputs is desired instead, then the subsets can be |
| 2337 | specified by providing `grad_output_indices` and/or `grad_input_indices` |
| 2338 | which identify the indices of `f`'s inputs and outputs which have |
| 2339 | gradients. |
| 2340 | """ |
| 2341 | assert(IsOperator('Python')) |
| 2342 | |
| 2343 | def make_builder(t): |
| 2344 | if not isinstance(t, tuple): |
| 2345 | return '' |
| 2346 | assert len(t) == 3, 'Expected builder tuple (func, args, kwargs)' |
| 2347 | func, args, kwargs = t |
| 2348 | normalized = (func, tuple(args), dict(kwargs)) |
| 2349 | return pickle.dumps(normalized) |
| 2350 | |
| 2351 | f_builder = make_builder(f) |
| 2352 | grad_f_builder = make_builder(grad_f) |
| 2353 |