perforatedai.clean_perforatedai
1# Copyright (c) 2025 Perforated AI 2from perforatedai import globals_perforatedai as GPA 3 4import copy 5 6import torch.nn as nn 7import torch 8import pdb 9 10from threading import Thread 11 12doing_threading = False 13 14# This is one implimentation of the forward function of PAI modules that 15# has an option to use python threading 16class PAIModulePyThread(nn.Module): 17 def __init__(self, original_module): 18 """Initialize a threaded inference wrapper from an existing PAI module. 19 20 Parameters 21 ---------- 22 original_module : nn.Module 23 Existing PAI module that provides layers, processors, and buffers. 24 """ 25 super(PAIModulePyThread, self).__init__() 26 self.layer_array = original_module.layer_array 27 self.processor_array = original_module.processor_array 28 # Remove the unused first index (skip_weights[0] is never used) 29 if hasattr(original_module, 'skip_weights') and len(original_module.skip_weights) > 1: 30 self.skip_weights = original_module.skip_weights[1:] 31 elif hasattr(original_module, 'skip_weights') and len(original_module.skip_weights) == 1: 32 # Only one element, don't create skip_weights 33 pass 34 self.register_buffer("node_index", original_module.node_index.clone().detach()) 35 self.register_buffer("num_cycles", original_module.num_cycles) 36 self.register_buffer("view_tuple", original_module.view_tuple) 37 38 def process_and_forward(self, *args2, **kwargs2): 39 """Run one dendrite layer forward pass and store its output. 40 41 Parameters 42 ---------- 43 *args2 : tuple 44 Positional values where the first two entries are layer index and 45 shared output buffer. 46 **kwargs2 : dict 47 Keyword arguments forwarded to the wrapped layer. 48 49 Returns 50 ------- 51 None 52 This function does not return a value. 53 """ 54 c = args2[0] 55 dendrite_outs = args2[1] 56 args2 = args2[2:] 57 if self.processor_array[c] != None: 58 args2, kwargs2 = self.processor_array[c].pre(*args2, **kwargs2) 59 out_values = self.layer_array[c](*args2, **kwargs2) 60 if self.processor_array[c] != None: 61 out = self.processor_array[c].post(out_values) 62 else: 63 out = out_values 64 dendrite_outs[c] = out 65 66 def process_and_pre(self, *args, **kwargs): 67 """Run the final layer pre-pass used before skip accumulation. 68 69 Parameters 70 ---------- 71 *args : tuple 72 Positional values where the first entry is the shared output 73 buffer and the remaining values are layer inputs. 74 **kwargs : dict 75 Keyword arguments forwarded to the wrapped layer. 76 77 Returns 78 ------- 79 None 80 This function does not return a value. 81 """ 82 dendrite_outs = args[0] 83 args = args[1:] 84 out = self.layer_array[-1].forward(*args, **kwargs) 85 if not self.processor_array[-1] is None: 86 out = self.processor_array[-1].pre(out) 87 dendrite_outs[len(self.layer_array) - 1] = out 88 89 def forward(self, *args, **kwargs): 90 """Compute module output with optional threaded dendrite evaluation. 91 92 Parameters 93 ---------- 94 *args : tuple 95 Positional arguments passed into each wrapped layer. 96 **kwargs : dict 97 Keyword arguments passed into each wrapped layer. 98 99 Returns 100 ------- 101 Any 102 Final module output after skip connections and post-processing. 103 """ 104 # this is currently false anyway, just remove the doing multi idea 105 doing_multi = doing_threading 106 dendrite_outs = [None] * len(self.layer_array) 107 threads = {} 108 for c in range(0, len(self.layer_array) - 1): 109 args2, kwargs2 = args, kwargs 110 if doing_multi: 111 threads[c] = Thread( 112 target=self.process_and_forward, 113 args=(c, dendrite_outs, *args), 114 kwargs=kwargs, 115 ) 116 else: 117 self.process_and_forward(c, dendrite_outs, *args2, **kwargs2) 118 if doing_multi: 119 threads[len(self.layer_array) - 1] = Thread( 120 target=self.process_and_pre, args=(dendrite_outs, *args), kwargs=kwargs 121 ) 122 else: 123 self.process_and_pre(dendrite_outs, *args, **kwargs) 124 if doing_multi: 125 for i in range(len(dendrite_outs)): 126 threads[i].start() 127 for i in range(len(dendrite_outs)): 128 threads[i].join() 129 for out_index in range(0, len(self.layer_array)): 130 current_out = dendrite_outs[out_index] 131 if len(self.layer_array) > 1 and hasattr(self, 'skip_weights'): 132 for in_index in range(0, out_index): 133 # Use out_index - 1 because skip_weights[0] was removed 134 skip_weight = self.skip_weights[out_index - 1][in_index, :] 135 # Use cached Python tuple instead of .tolist() during forward 136 skip_weight = skip_weight.view(self.view_tuple.tolist()) 137 current_out = current_out + ( 138 skip_weight.to(current_out.device) 139 * dendrite_outs[in_index] 140 ) 141 if out_index < len(self.layer_array) - 1: 142 current_out = GPA.pc.get_pai_forward_function()(current_out) 143 dendrite_outs[out_index] = current_out 144 if not self.processor_array[-1] is None: 145 current_out = self.processor_array[-1].post(current_out) 146 return current_out 147 148 149def get_pretrained_pai_attr(pretrained_dendrite, member): 150 """Safely get an attribute from a possibly missing module. 151 152 Parameters 153 ---------- 154 pretrained_dendrite : nn.Module or None 155 Source module that may be ``None``. 156 member : str 157 Attribute name to retrieve. 158 159 Returns 160 ------- 161 Any 162 Requested attribute value, or ``None`` if source module is ``None``. 163 """ 164 if pretrained_dendrite is None: 165 return None 166 else: 167 return getattr(pretrained_dendrite, member) 168 169 170def get_pretrained_pai_var(pretrained_dendrite, submodule_id): 171 """Safely get a named child module from a possibly missing module. 172 173 Parameters 174 ---------- 175 pretrained_dendrite : nn.Module or None 176 Source module that may be ``None``. 177 submodule_id : str 178 Submodule identifier passed to ``get_submodule``. 179 180 Returns 181 ------- 182 nn.Module or None 183 Retrieved submodule, or ``None`` when source module is ``None``. 184 """ 185 if pretrained_dendrite is None: 186 return None 187 else: 188 return pretrained_dendrite.get_submodule(submodule_id) 189 190ModuleType = PAIModulePyThread 191doing_threading = False 192 193def make_module(module): 194 """Create the configured wrapper module type for a module. 195 196 Parameters 197 ---------- 198 module : nn.Module 199 Module to wrap. 200 201 Returns 202 ------- 203 nn.Module 204 Wrapped module instance. 205 """ 206 return ModuleType(module) 207 208# This Refreshes a PAI network with the PyThread Module 209def refresh_pai(net, depth, name_so_far, converted_list): 210 """Recursively replace PAILayer instances with threaded inference wrappers. 211 212 Parameters 213 ---------- 214 net : nn.Module 215 Module tree to update. 216 depth : int 217 Current recursion depth. 218 name_so_far : str 219 Dotted/indexed path to the current module. 220 converted_list : list 221 Mutable list of module names already visited. 222 223 Returns 224 ------- 225 nn.Module 226 Updated module tree. 227 """ 228 if GPA.pc.get_extra_verbose(): 229 print("CL calling convert on %s depth %d" % (net, depth)) 230 print( 231 "CL calling convert on %s: %s, depth %d" 232 % (name_so_far, type(net).__name__, depth) 233 ) 234 if type(net) is ModuleType: 235 if GPA.pc.get_extra_verbose(): 236 print( 237 "this is only being called because something in your model is pointed to twice by two different variables. Highest thing on the list is one of the duplicates" 238 ) 239 return net 240 all_members = net.__dir__() 241 if ( 242 issubclass(type(net), nn.Sequential) 243 or issubclass(type(net), nn.ModuleList) 244 or issubclass(type(net), list) 245 ): 246 for submodule_id, layer in net.named_children(): 247 if net != net.get_submodule(submodule_id): 248 converted_list += [name_so_far + "[" + str(submodule_id) + "]"] 249 setattr( 250 net, 251 submodule_id, 252 refresh_pai( 253 net.get_submodule(submodule_id), 254 depth + 1, 255 name_so_far + "[" + str(submodule_id) + "]", 256 converted_list, 257 ), 258 ) 259 if type(net.get_submodule(submodule_id)).__name__ == "PAILayer": 260 setattr( 261 net, 262 submodule_id, 263 make_module(get_pretrained_pai_var(net, submodule_id)), 264 ) 265 elif type(net) in GPA.pc.get_modules_to_track(): 266 return net 267 else: 268 for member in all_members: 269 if isinstance(getattr(type(net), member, None), property): 270 continue 271 try: 272 getattr(net, member, None) 273 except: 274 continue 275 sub_name = name_so_far + "." + member 276 277 if member == "device" or member == "dtype": 278 continue 279 if sub_name in GPA.pc.get_module_names_to_not_save(): 280 continue 281 if name_so_far == "": 282 if ( 283 sub_name in GPA.pc.get_module_names_to_not_save() 284 or sub_name in converted_list 285 ): 286 if GPA.pc.get_extra_verbose(): 287 print("Skipping %s during save" % sub_name) 288 continue 289 290 if ( 291 issubclass(type(getattr(net, member, None)), nn.Module) 292 or member == "layer_array" 293 ): 294 converted_list += [sub_name] 295 if net != getattr(net, member): 296 setattr( 297 net, 298 member, 299 refresh_pai( 300 getattr(net, member), depth + 1, sub_name, converted_list 301 ), 302 ) 303 if type(getattr(net, member, None)).__name__ == "PAILayer": 304 setattr(net, member, make_module(get_pretrained_pai_attr(net, member))) 305 if type(net).__name__ == "PAILayer": 306 net = make_module(net) 307 return net 308 309def refresh_net(pretrained_dendrite): 310 """Refresh a network by converting eligible modules to threaded wrappers. 311 312 Parameters 313 ---------- 314 pretrained_dendrite : nn.Module 315 Network or module tree to refresh. 316 317 Returns 318 ------- 319 nn.Module 320 Refreshed network. 321 """ 322 323 net = refresh_pai(pretrained_dendrite, 0, "", []) 324 return net
17class PAIModulePyThread(nn.Module): 18 def __init__(self, original_module): 19 """Initialize a threaded inference wrapper from an existing PAI module. 20 21 Parameters 22 ---------- 23 original_module : nn.Module 24 Existing PAI module that provides layers, processors, and buffers. 25 """ 26 super(PAIModulePyThread, self).__init__() 27 self.layer_array = original_module.layer_array 28 self.processor_array = original_module.processor_array 29 # Remove the unused first index (skip_weights[0] is never used) 30 if hasattr(original_module, 'skip_weights') and len(original_module.skip_weights) > 1: 31 self.skip_weights = original_module.skip_weights[1:] 32 elif hasattr(original_module, 'skip_weights') and len(original_module.skip_weights) == 1: 33 # Only one element, don't create skip_weights 34 pass 35 self.register_buffer("node_index", original_module.node_index.clone().detach()) 36 self.register_buffer("num_cycles", original_module.num_cycles) 37 self.register_buffer("view_tuple", original_module.view_tuple) 38 39 def process_and_forward(self, *args2, **kwargs2): 40 """Run one dendrite layer forward pass and store its output. 41 42 Parameters 43 ---------- 44 *args2 : tuple 45 Positional values where the first two entries are layer index and 46 shared output buffer. 47 **kwargs2 : dict 48 Keyword arguments forwarded to the wrapped layer. 49 50 Returns 51 ------- 52 None 53 This function does not return a value. 54 """ 55 c = args2[0] 56 dendrite_outs = args2[1] 57 args2 = args2[2:] 58 if self.processor_array[c] != None: 59 args2, kwargs2 = self.processor_array[c].pre(*args2, **kwargs2) 60 out_values = self.layer_array[c](*args2, **kwargs2) 61 if self.processor_array[c] != None: 62 out = self.processor_array[c].post(out_values) 63 else: 64 out = out_values 65 dendrite_outs[c] = out 66 67 def process_and_pre(self, *args, **kwargs): 68 """Run the final layer pre-pass used before skip accumulation. 69 70 Parameters 71 ---------- 72 *args : tuple 73 Positional values where the first entry is the shared output 74 buffer and the remaining values are layer inputs. 75 **kwargs : dict 76 Keyword arguments forwarded to the wrapped layer. 77 78 Returns 79 ------- 80 None 81 This function does not return a value. 82 """ 83 dendrite_outs = args[0] 84 args = args[1:] 85 out = self.layer_array[-1].forward(*args, **kwargs) 86 if not self.processor_array[-1] is None: 87 out = self.processor_array[-1].pre(out) 88 dendrite_outs[len(self.layer_array) - 1] = out 89 90 def forward(self, *args, **kwargs): 91 """Compute module output with optional threaded dendrite evaluation. 92 93 Parameters 94 ---------- 95 *args : tuple 96 Positional arguments passed into each wrapped layer. 97 **kwargs : dict 98 Keyword arguments passed into each wrapped layer. 99 100 Returns 101 ------- 102 Any 103 Final module output after skip connections and post-processing. 104 """ 105 # this is currently false anyway, just remove the doing multi idea 106 doing_multi = doing_threading 107 dendrite_outs = [None] * len(self.layer_array) 108 threads = {} 109 for c in range(0, len(self.layer_array) - 1): 110 args2, kwargs2 = args, kwargs 111 if doing_multi: 112 threads[c] = Thread( 113 target=self.process_and_forward, 114 args=(c, dendrite_outs, *args), 115 kwargs=kwargs, 116 ) 117 else: 118 self.process_and_forward(c, dendrite_outs, *args2, **kwargs2) 119 if doing_multi: 120 threads[len(self.layer_array) - 1] = Thread( 121 target=self.process_and_pre, args=(dendrite_outs, *args), kwargs=kwargs 122 ) 123 else: 124 self.process_and_pre(dendrite_outs, *args, **kwargs) 125 if doing_multi: 126 for i in range(len(dendrite_outs)): 127 threads[i].start() 128 for i in range(len(dendrite_outs)): 129 threads[i].join() 130 for out_index in range(0, len(self.layer_array)): 131 current_out = dendrite_outs[out_index] 132 if len(self.layer_array) > 1 and hasattr(self, 'skip_weights'): 133 for in_index in range(0, out_index): 134 # Use out_index - 1 because skip_weights[0] was removed 135 skip_weight = self.skip_weights[out_index - 1][in_index, :] 136 # Use cached Python tuple instead of .tolist() during forward 137 skip_weight = skip_weight.view(self.view_tuple.tolist()) 138 current_out = current_out + ( 139 skip_weight.to(current_out.device) 140 * dendrite_outs[in_index] 141 ) 142 if out_index < len(self.layer_array) - 1: 143 current_out = GPA.pc.get_pai_forward_function()(current_out) 144 dendrite_outs[out_index] = current_out 145 if not self.processor_array[-1] is None: 146 current_out = self.processor_array[-1].post(current_out) 147 return current_out
Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing them to be nested in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self) -> None:
super().__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
Submodules assigned in this way will be registered, and will also have their
parameters converted when you call to(), etc.
As per the example above, an __init__() call to the parent class
must be made before assignment on the child.
:ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool
18 def __init__(self, original_module): 19 """Initialize a threaded inference wrapper from an existing PAI module. 20 21 Parameters 22 ---------- 23 original_module : nn.Module 24 Existing PAI module that provides layers, processors, and buffers. 25 """ 26 super(PAIModulePyThread, self).__init__() 27 self.layer_array = original_module.layer_array 28 self.processor_array = original_module.processor_array 29 # Remove the unused first index (skip_weights[0] is never used) 30 if hasattr(original_module, 'skip_weights') and len(original_module.skip_weights) > 1: 31 self.skip_weights = original_module.skip_weights[1:] 32 elif hasattr(original_module, 'skip_weights') and len(original_module.skip_weights) == 1: 33 # Only one element, don't create skip_weights 34 pass 35 self.register_buffer("node_index", original_module.node_index.clone().detach()) 36 self.register_buffer("num_cycles", original_module.num_cycles) 37 self.register_buffer("view_tuple", original_module.view_tuple)
Initialize a threaded inference wrapper from an existing PAI module.
Parameters
- original_module (nn.Module): Existing PAI module that provides layers, processors, and buffers.
39 def process_and_forward(self, *args2, **kwargs2): 40 """Run one dendrite layer forward pass and store its output. 41 42 Parameters 43 ---------- 44 *args2 : tuple 45 Positional values where the first two entries are layer index and 46 shared output buffer. 47 **kwargs2 : dict 48 Keyword arguments forwarded to the wrapped layer. 49 50 Returns 51 ------- 52 None 53 This function does not return a value. 54 """ 55 c = args2[0] 56 dendrite_outs = args2[1] 57 args2 = args2[2:] 58 if self.processor_array[c] != None: 59 args2, kwargs2 = self.processor_array[c].pre(*args2, **kwargs2) 60 out_values = self.layer_array[c](*args2, **kwargs2) 61 if self.processor_array[c] != None: 62 out = self.processor_array[c].post(out_values) 63 else: 64 out = out_values 65 dendrite_outs[c] = out
Run one dendrite layer forward pass and store its output.
Parameters
- *args2 (tuple): Positional values where the first two entries are layer index and shared output buffer.
- **kwargs2 (dict): Keyword arguments forwarded to the wrapped layer.
Returns
- None: This function does not return a value.
67 def process_and_pre(self, *args, **kwargs): 68 """Run the final layer pre-pass used before skip accumulation. 69 70 Parameters 71 ---------- 72 *args : tuple 73 Positional values where the first entry is the shared output 74 buffer and the remaining values are layer inputs. 75 **kwargs : dict 76 Keyword arguments forwarded to the wrapped layer. 77 78 Returns 79 ------- 80 None 81 This function does not return a value. 82 """ 83 dendrite_outs = args[0] 84 args = args[1:] 85 out = self.layer_array[-1].forward(*args, **kwargs) 86 if not self.processor_array[-1] is None: 87 out = self.processor_array[-1].pre(out) 88 dendrite_outs[len(self.layer_array) - 1] = out
Run the final layer pre-pass used before skip accumulation.
Parameters
- *args (tuple): Positional values where the first entry is the shared output buffer and the remaining values are layer inputs.
- **kwargs (dict): Keyword arguments forwarded to the wrapped layer.
Returns
- None: This function does not return a value.
90 def forward(self, *args, **kwargs): 91 """Compute module output with optional threaded dendrite evaluation. 92 93 Parameters 94 ---------- 95 *args : tuple 96 Positional arguments passed into each wrapped layer. 97 **kwargs : dict 98 Keyword arguments passed into each wrapped layer. 99 100 Returns 101 ------- 102 Any 103 Final module output after skip connections and post-processing. 104 """ 105 # this is currently false anyway, just remove the doing multi idea 106 doing_multi = doing_threading 107 dendrite_outs = [None] * len(self.layer_array) 108 threads = {} 109 for c in range(0, len(self.layer_array) - 1): 110 args2, kwargs2 = args, kwargs 111 if doing_multi: 112 threads[c] = Thread( 113 target=self.process_and_forward, 114 args=(c, dendrite_outs, *args), 115 kwargs=kwargs, 116 ) 117 else: 118 self.process_and_forward(c, dendrite_outs, *args2, **kwargs2) 119 if doing_multi: 120 threads[len(self.layer_array) - 1] = Thread( 121 target=self.process_and_pre, args=(dendrite_outs, *args), kwargs=kwargs 122 ) 123 else: 124 self.process_and_pre(dendrite_outs, *args, **kwargs) 125 if doing_multi: 126 for i in range(len(dendrite_outs)): 127 threads[i].start() 128 for i in range(len(dendrite_outs)): 129 threads[i].join() 130 for out_index in range(0, len(self.layer_array)): 131 current_out = dendrite_outs[out_index] 132 if len(self.layer_array) > 1 and hasattr(self, 'skip_weights'): 133 for in_index in range(0, out_index): 134 # Use out_index - 1 because skip_weights[0] was removed 135 skip_weight = self.skip_weights[out_index - 1][in_index, :] 136 # Use cached Python tuple instead of .tolist() during forward 137 skip_weight = skip_weight.view(self.view_tuple.tolist()) 138 current_out = current_out + ( 139 skip_weight.to(current_out.device) 140 * dendrite_outs[in_index] 141 ) 142 if out_index < len(self.layer_array) - 1: 143 current_out = GPA.pc.get_pai_forward_function()(current_out) 144 dendrite_outs[out_index] = current_out 145 if not self.processor_array[-1] is None: 146 current_out = self.processor_array[-1].post(current_out) 147 return current_out
Compute module output with optional threaded dendrite evaluation.
Parameters
- *args (tuple): Positional arguments passed into each wrapped layer.
- **kwargs (dict): Keyword arguments passed into each wrapped layer.
Returns
- Any: Final module output after skip connections and post-processing.
150def get_pretrained_pai_attr(pretrained_dendrite, member): 151 """Safely get an attribute from a possibly missing module. 152 153 Parameters 154 ---------- 155 pretrained_dendrite : nn.Module or None 156 Source module that may be ``None``. 157 member : str 158 Attribute name to retrieve. 159 160 Returns 161 ------- 162 Any 163 Requested attribute value, or ``None`` if source module is ``None``. 164 """ 165 if pretrained_dendrite is None: 166 return None 167 else: 168 return getattr(pretrained_dendrite, member)
Safely get an attribute from a possibly missing module.
Parameters
- pretrained_dendrite (nn.Module or None):
Source module that may be
None. - member (str): Attribute name to retrieve.
Returns
- Any: Requested attribute value, or
Noneif source module isNone.
171def get_pretrained_pai_var(pretrained_dendrite, submodule_id): 172 """Safely get a named child module from a possibly missing module. 173 174 Parameters 175 ---------- 176 pretrained_dendrite : nn.Module or None 177 Source module that may be ``None``. 178 submodule_id : str 179 Submodule identifier passed to ``get_submodule``. 180 181 Returns 182 ------- 183 nn.Module or None 184 Retrieved submodule, or ``None`` when source module is ``None``. 185 """ 186 if pretrained_dendrite is None: 187 return None 188 else: 189 return pretrained_dendrite.get_submodule(submodule_id)
Safely get a named child module from a possibly missing module.
Parameters
- pretrained_dendrite (nn.Module or None):
Source module that may be
None. - submodule_id (str):
Submodule identifier passed to
get_submodule.
Returns
- nn.Module or None: Retrieved submodule, or
Nonewhen source module isNone.
194def make_module(module): 195 """Create the configured wrapper module type for a module. 196 197 Parameters 198 ---------- 199 module : nn.Module 200 Module to wrap. 201 202 Returns 203 ------- 204 nn.Module 205 Wrapped module instance. 206 """ 207 return ModuleType(module)
Create the configured wrapper module type for a module.
Parameters
- module (nn.Module): Module to wrap.
Returns
- nn.Module: Wrapped module instance.
210def refresh_pai(net, depth, name_so_far, converted_list): 211 """Recursively replace PAILayer instances with threaded inference wrappers. 212 213 Parameters 214 ---------- 215 net : nn.Module 216 Module tree to update. 217 depth : int 218 Current recursion depth. 219 name_so_far : str 220 Dotted/indexed path to the current module. 221 converted_list : list 222 Mutable list of module names already visited. 223 224 Returns 225 ------- 226 nn.Module 227 Updated module tree. 228 """ 229 if GPA.pc.get_extra_verbose(): 230 print("CL calling convert on %s depth %d" % (net, depth)) 231 print( 232 "CL calling convert on %s: %s, depth %d" 233 % (name_so_far, type(net).__name__, depth) 234 ) 235 if type(net) is ModuleType: 236 if GPA.pc.get_extra_verbose(): 237 print( 238 "this is only being called because something in your model is pointed to twice by two different variables. Highest thing on the list is one of the duplicates" 239 ) 240 return net 241 all_members = net.__dir__() 242 if ( 243 issubclass(type(net), nn.Sequential) 244 or issubclass(type(net), nn.ModuleList) 245 or issubclass(type(net), list) 246 ): 247 for submodule_id, layer in net.named_children(): 248 if net != net.get_submodule(submodule_id): 249 converted_list += [name_so_far + "[" + str(submodule_id) + "]"] 250 setattr( 251 net, 252 submodule_id, 253 refresh_pai( 254 net.get_submodule(submodule_id), 255 depth + 1, 256 name_so_far + "[" + str(submodule_id) + "]", 257 converted_list, 258 ), 259 ) 260 if type(net.get_submodule(submodule_id)).__name__ == "PAILayer": 261 setattr( 262 net, 263 submodule_id, 264 make_module(get_pretrained_pai_var(net, submodule_id)), 265 ) 266 elif type(net) in GPA.pc.get_modules_to_track(): 267 return net 268 else: 269 for member in all_members: 270 if isinstance(getattr(type(net), member, None), property): 271 continue 272 try: 273 getattr(net, member, None) 274 except: 275 continue 276 sub_name = name_so_far + "." + member 277 278 if member == "device" or member == "dtype": 279 continue 280 if sub_name in GPA.pc.get_module_names_to_not_save(): 281 continue 282 if name_so_far == "": 283 if ( 284 sub_name in GPA.pc.get_module_names_to_not_save() 285 or sub_name in converted_list 286 ): 287 if GPA.pc.get_extra_verbose(): 288 print("Skipping %s during save" % sub_name) 289 continue 290 291 if ( 292 issubclass(type(getattr(net, member, None)), nn.Module) 293 or member == "layer_array" 294 ): 295 converted_list += [sub_name] 296 if net != getattr(net, member): 297 setattr( 298 net, 299 member, 300 refresh_pai( 301 getattr(net, member), depth + 1, sub_name, converted_list 302 ), 303 ) 304 if type(getattr(net, member, None)).__name__ == "PAILayer": 305 setattr(net, member, make_module(get_pretrained_pai_attr(net, member))) 306 if type(net).__name__ == "PAILayer": 307 net = make_module(net) 308 return net
Recursively replace PAILayer instances with threaded inference wrappers.
Parameters
- net (nn.Module): Module tree to update.
- depth (int): Current recursion depth.
- name_so_far (str): Dotted/indexed path to the current module.
- converted_list (list): Mutable list of module names already visited.
Returns
- nn.Module: Updated module tree.
310def refresh_net(pretrained_dendrite): 311 """Refresh a network by converting eligible modules to threaded wrappers. 312 313 Parameters 314 ---------- 315 pretrained_dendrite : nn.Module 316 Network or module tree to refresh. 317 318 Returns 319 ------- 320 nn.Module 321 Refreshed network. 322 """ 323 324 net = refresh_pai(pretrained_dendrite, 0, "", []) 325 return net
Refresh a network by converting eligible modules to threaded wrappers.
Parameters
- pretrained_dendrite (nn.Module): Network or module tree to refresh.
Returns
- nn.Module: Refreshed network.