1+
2+ import argparse
3+ import os
4+
5+ import torch
6+ import torch .nn as nn
7+
8+ from torchvision import models , datasets
9+ from torchvision .transforms import ToTensor
10+ from torchinfo import summary
11+
12+ from scalesim import topology_utils
13+
14+
15+ base_dir = '../topologies/custom'
16+
17+
18+ # creates topology file from PyTorch module
19+ def create_conv_topo (model , path = base_dir , filename = '' , input_dim = (2 , 3 , 224 , 224 ), include_lin = False ):
20+ if filename == '' :
21+ filename = model .__class__ .__name__ + '_custom.csv'
22+
23+ topo = topology_utils .topologies ()
24+ prev_arr , curr_arr = [], []
25+ last = 0
26+
27+ model_stats = summary (model , input_size = input_dim , col_names = ('input_size' ,'output_size' ,'num_params' ,'kernel_size' ), verbose = 1 )
28+ idx = 1
29+ for layer in model_stats .summary_list :
30+ if layer .class_name == 'Conv2d' :
31+ if prev_arr :
32+ prev_arr [6 ] = last
33+ topo .topo_arrays .append (prev_arr )
34+ idx += 1
35+ curr_arr .append (layer .class_name + '_{}' .format (idx )) # layer name
36+ curr_arr .append (layer .input_size [2 ]) # IFMAP height
37+ curr_arr .append (layer .input_size [3 ]) # IFMAP width
38+ curr_arr .append (layer .kernel_size [0 ]) # filter height
39+ curr_arr .append (layer .kernel_size [1 ]) # filter width
40+ curr_arr .append (layer .input_size [1 ]) # channels
41+ curr_arr .append (0 ) # output channels (num filters)
42+ curr_arr .append (layer .module .stride [0 ]) # stride
43+ prev_arr = curr_arr
44+ curr_arr = []
45+ elif layer .class_name == 'Linear' and include_lin :
46+ if prev_arr :
47+ prev_arr [6 ] = last
48+ topo .topo_arrays .append (prev_arr )
49+ idx += 1
50+ curr_arr .append (layer .class_name + '_{}' .format (idx )) # layer name
51+ print (layer .input_size )
52+ curr_arr .append (1 ) # IFMAP height
53+ curr_arr .append (1 ) # IFMAP width
54+ curr_arr .append (1 ) # filter height
55+ curr_arr .append (1 ) # filter width
56+ curr_arr .append (layer .input_size [1 ]) # channels
57+ curr_arr .append (0 ) # output channels (num filters)
58+ curr_arr .append (1 ) # stride
59+ prev_arr = curr_arr
60+ curr_arr = []
61+ last = layer .input_size [1 ]
62+ # last layer
63+ if prev_arr :
64+ prev_arr [6 ] = last
65+ topo .topo_arrays .append (prev_arr )
66+
67+ topo .topo_load_flag = True
68+ topo .write_topo_file (path = path , filename = filename )
69+
70+
71+ if __name__ == '__main__' :
72+ parser = argparse .ArgumentParser ()
73+ parser .add_argument ('-m' , metavar = 'PyTorch module name' , type = str ,
74+ default = 'alexnet' ,
75+ help = "Class name of PyTorch module to turn into SCALESim topology"
76+ )
77+ parser .add_argument ('-p' , metavar = 'Path to directory' , type = str ,
78+ default = '../topologies/custom' ,
79+ help = "Directory at which to save the created topology file"
80+ )
81+ parser .add_argument ('-f' , metavar = 'File name' , type = str ,
82+ default = 'alexnet_custom.csv' ,
83+ help = "File name for SCALESim topology"
84+ )
85+ parser .add_argument ('-l' , metavar = 'Include linear layers?' , type = bool ,
86+ default = False ,
87+ help = "Boolean deciding whether or not to include nn.Linear layers in topology"
88+ )
89+
90+
91+ args = parser .parse_args ()
92+ if not os .path .exists (base_dir ):
93+ os .mkdir (base_dir )
94+
95+ model_name = args .m
96+ print (model_name )
97+ print (args .p )
98+ try :
99+ model = getattr (models , model_name )(pretrained = True )
100+ except :
101+ print ('PyTorch module does not exist' )
102+ exit ()
103+
104+ path = args .p
105+ file_name = args .f
106+ include_lin = args .l
107+
108+ create_conv_topo (model , path = path , filename = file_name , include_lin = include_lin )
0 commit comments