Execute an replication callback `__data_parallel_replicate__` on each module created by original replication. The callback will be invoked with arguments `__data_parallel_replicate__(ctx, copy_id)` Note that, as all modules are isomorphism, we assign each sub-module with a context
(modules)
| 25 | |
| 26 | |
| 27 | def execute_replication_callbacks(modules): |
| 28 | """ |
| 29 | Execute an replication callback `__data_parallel_replicate__` on each module created by original replication. |
| 30 | |
| 31 | The callback will be invoked with arguments `__data_parallel_replicate__(ctx, copy_id)` |
| 32 | |
| 33 | Note that, as all modules are isomorphism, we assign each sub-module with a context |
| 34 | (shared among multiple copies of this module on different devices). |
| 35 | Through this context, different copies can share some information. |
| 36 | |
| 37 | We guarantee that the callback on the master copy (the first copy) will be called ahead of calling the callback |
| 38 | of any slave copies. |
| 39 | """ |
| 40 | master_copy = modules[0] |
| 41 | nr_modules = len(list(master_copy.modules())) |
| 42 | ctxs = [CallbackContext() for _ in range(nr_modules)] |
| 43 | |
| 44 | for i, module in enumerate(modules): |
| 45 | for j, m in enumerate(module.modules()): |
| 46 | if hasattr(m, "__data_parallel_replicate__"): |
| 47 | m.__data_parallel_replicate__(ctxs[j], i) |
| 48 | |
| 49 | |
| 50 | class DataParallelWithCallback(DataParallel): |
no test coverage detected