55import torch
66
77from dist_ir .ir import FunctionMaker , Topology , get_uniform_topology , Value
8- from dist_ir .ir .type import Int32 , Float32 , Tensor , abstract_values
9- from dist_ir .executor import CostModel , Simulator , infer_types
8+ from dist_ir .ir .type import Int32 , Float16 , Float32 , Tensor , abstract_values
9+ from dist_ir .executor import (
10+ CostModel ,
11+ Simulator ,
12+ ConcreteValue ,
13+ infer_types ,
14+ sequentially_execute ,
15+ )
1016from dist_ir .transforms import mlp_dhp_transform
1117from .parser import Parser
1218import dist_ir .backend .torch as torch_backend
@@ -39,42 +45,40 @@ def get_typed_input_values(inputs, batch_size, input_dim, output_dim):
3945 return tuple (typed_inputs )
4046
4147
42- def get_input_data (batch_size , dim , num_layers ):
43- x = np .random .normal (size = (batch_size , dim ))
44- z = np .random .normal (size = (batch_size , dim ))
45- n = batch_size
46- weights = [np .random .normal (size = (dim , dim ))]
47- for i in range (1 , num_layers - 1 ):
48- weights .append (np .random .normal (size = (dim , dim )))
49- weights .append (np .random .normal (size = (dim , dim )))
48+ def get_input_data (inputs , batch_size , input_dim , output_dim , device , dtype ):
49+ input_data = []
50+ x = np .random .normal (0 , 0.02 , size = (batch_size , input_dim ))
51+ z = np .random .normal (0 , 0.02 , size = (batch_size , output_dim ))
52+ n = np .int64 (batch_size )
53+ weights = [np .random .normal (0 , 0.02 , size = inp .type .shape ) for inp in inputs [3 :]]
5054 input_data = [x , z , n ] + weights
51- input_data = [
52- v . astype ( np . float32 ) if i != 2 else v for i , v in enumerate ( input_data )
53- ]
55+ input_data = [v . astype ( dtype ) if i != 2 else v for i , v in enumerate ( input_data )]
56+ input_data = [ ConcreteValue ( v , device ) for v in input_data ]
57+ assert len ( input_data ) == len ( inputs )
5458 return input_data
5559
5660
57- def mlp (input_dim , hidden_dim , output_dim , num_hidden_layers , device ):
61+ def mlp (input_dim , hidden_dim , output_dim , num_hidden_layers , device , dtype ):
5862 function = FunctionMaker (name = "mlp" )
5963 x = function .add_input_value (
6064 "x" ,
61- Tensor (dtype = Float32 (), shape = None , device = device ),
65+ Tensor (dtype = dtype (), shape = None , device = device ),
6266 )
6367 z = function .add_input_value (
6468 "z" ,
65- Tensor (dtype = Float32 (), shape = None , device = device ),
69+ Tensor (dtype = dtype (), shape = None , device = device ),
6670 )
6771 n = function .add_input_value ("n" , Int32 (device = device ))
6872 weights = []
6973 for i in range (num_hidden_layers - 1 ):
7074 w = function .add_input_value (
7175 f"w{ chr (ord ('A' )+ i )} " ,
72- Tensor (dtype = Float32 (), shape = (input_dim , hidden_dim ), device = device ),
76+ Tensor (dtype = dtype (), shape = (input_dim , hidden_dim ), device = device ),
7377 )
7478 weights .append (w )
7579 w = function .add_input_value (
7680 f"w{ chr (ord ('A' )+ i + 1 )} " ,
77- Tensor (dtype = Float32 (), shape = (hidden_dim , output_dim ), device = device ),
81+ Tensor (dtype = dtype (), shape = (hidden_dim , output_dim ), device = device ),
7882 )
7983 weights .append (w )
8084
@@ -107,24 +111,24 @@ def mlp(input_dim, hidden_dim, output_dim, num_hidden_layers, device):
107111
108112
109113def mlp_inference (
110- batch_size , input_dim , hidden_dim , output_dim , num_hidden_layers , device
114+ batch_size , input_dim , hidden_dim , output_dim , num_hidden_layers , device , dtype
111115):
112116 function = FunctionMaker (name = "mlp" )
113117 weights = []
114118 for i in range (num_hidden_layers - 1 ):
115119 w = function .add_input_value (
116120 f"w{ chr (ord ('A' )+ i )} " ,
117- Tensor (dtype = Float32 (), shape = (input_dim , hidden_dim ), device = device ),
121+ Tensor (dtype = dtype (), shape = (input_dim , hidden_dim ), device = device ),
118122 )
119123 weights .append (w )
120124 w = function .add_input_value (
121125 f"w{ chr (ord ('A' )+ i + 1 )} " ,
122- Tensor (dtype = Float32 (), shape = (hidden_dim , output_dim ), device = device ),
126+ Tensor (dtype = dtype (), shape = (hidden_dim , output_dim ), device = device ),
123127 )
124128 weights .append (w )
125129 x = function .add_input_value (
126130 "x" ,
127- Tensor (dtype = Float32 (), shape = (batch_size , input_dim ), device = device ),
131+ Tensor (dtype = dtype (), shape = (batch_size , input_dim ), device = device ),
128132 )
129133
130134 a = x
@@ -136,7 +140,7 @@ def mlp_inference(
136140
137141
138142def mlp_inference_dp (
139- batch_size , input_dim , hidden_dim , output_dim , num_hidden_layers , devices
143+ batch_size , input_dim , hidden_dim , output_dim , num_hidden_layers , devices , dtype
140144):
141145 num_devices = len (devices )
142146 assert batch_size % num_devices == 0
@@ -147,16 +151,16 @@ def mlp_inference_dp(
147151 for i in range (num_hidden_layers - 1 ):
148152 weights [i , d ] = function .add_input_value (
149153 f"w{ chr (ord ('A' )+ i )} _{ d .device_id } " ,
150- Tensor (dtype = Float32 (), shape = (input_dim , hidden_dim ), device = d ),
154+ Tensor (dtype = dtype (), shape = (input_dim , hidden_dim ), device = d ),
151155 )
152156 weights [num_hidden_layers - 1 , d ] = function .add_input_value (
153157 f"w{ chr (ord ('A' )+ i + 1 )} _{ d .device_id } " ,
154- Tensor (dtype = Float32 (), shape = (hidden_dim , output_dim ), device = d ),
158+ Tensor (dtype = dtype (), shape = (hidden_dim , output_dim ), device = d ),
155159 )
156160 x [d ] = function .add_input_value (
157161 f"x_{ d .device_id } " ,
158162 Tensor (
159- dtype = Float32 (), shape = (batch_size // num_devices , input_dim ), device = d
163+ dtype = dtype (), shape = (batch_size // num_devices , input_dim ), device = d
160164 ),
161165 )
162166
@@ -274,20 +278,38 @@ def simulate(function, input_types, topology, allreduce_parameters=None):
274278 return simulation
275279
276280
277- def run_pytorch (function , input_data , world_size , use_gpu = True ):
281+ def run_pytorch (function , input_data , world_size , use_gpu = torch .cuda .is_available ()):
282+ # TODO: Move this to a utils file
283+ def _resolve_dtype (dtype ):
284+ if dtype == np .int32 :
285+ return torch .int32
286+ elif dtype == np .int64 :
287+ return torch .int64
288+ elif dtype == np .float16 :
289+ return torch .float16
290+ elif dtype == np .float32 :
291+ return torch .float32
292+ else :
293+ raise NotImplementedError (dtype )
294+
278295 if use_gpu and world_size > torch .cuda .device_count ():
279296 raise ValueError (
280297 f"Specified world size is { world_size } , but only "
281298 f"{ torch .cuda .device_count ()} GPUs available"
282299 )
300+ pytorch_input_data = [
301+ torch .tensor (x .val , dtype = _resolve_dtype (x .val .dtype ))
302+ if isinstance (x .val , np .ndarray )
303+ else torch .tensor (x .val , dtype = torch .int32 )
304+ for x in input_data
305+ ]
283306 input_types = abstract_values (
284307 input_data ,
285308 tuple (
286309 Tensor if isinstance (input_data [i ].val , np .ndarray ) else Int32
287310 for i in range (len (input_data ))
288311 ),
289312 )
290- pytorch_input_data = [torch .tensor (x .val , dtype = torch .float32 ) for x in input_data ]
291313 per_rank_outputs , runtimes = torch_backend .run_pytorch (
292314 function ,
293315 pytorch_input_data ,
@@ -302,6 +324,7 @@ def run_pytorch(function, input_data, world_size, use_gpu=True):
302324def run_mlp (
303325 phase ,
304326 backend ,
327+ dtype ,
305328 use_gpu ,
306329 batch_size ,
307330 input_dim ,
@@ -319,6 +342,8 @@ def run_mlp(
319342 trace_file ,
320343 verbose = False ,
321344):
345+ dist_ir_dtype = Float32 if dtype == "fp32" else Float16
346+ numpy_dtype = np .float32 if dtype == "fp32" else np .float16
322347 world_size = dp_degree * hp_degree * pp_degree
323348 topology = get_uniform_topology (
324349 world_size ,
@@ -335,6 +360,7 @@ def run_mlp(
335360 output_dim ,
336361 num_hidden_layers ,
337362 topology .devices [0 ],
363+ dist_ir_dtype ,
338364 )
339365 elif phase == "inference" :
340366 fn = mlp_inference (
@@ -343,13 +369,24 @@ def run_mlp(
343369 output_dim ,
344370 num_hidden_layers ,
345371 topology .devices [0 ],
372+ dist_ir_dtype ,
346373 )
347374
348375 if verbose :
349376 parameter_count , model_size , parameter_count_str , model_size_str = get_stats (fn )
350377 print ("Parameter count:" , parameter_count_str )
351378 print ("Model size:" , model_size_str )
352379
380+ if backend == "pytorch" :
381+ input_data = get_input_data (
382+ fn .inputs ,
383+ batch_size ,
384+ input_dim ,
385+ output_dim ,
386+ topology .devices [0 ],
387+ numpy_dtype ,
388+ )
389+
353390 if world_size > 1 :
354391 init_fn , transformed_fn = mlp_dhp_transform (
355392 fn ,
@@ -365,13 +402,17 @@ def run_mlp(
365402 init_fn = infer_types (init_fn , typed_inputs )
366403 transformed_fn = infer_types (transformed_fn , init_fn .outputs )
367404 input_types = tuple (output .type for output in init_fn .outputs )
405+ if backend == "pytorch" :
406+ transformed_input_data = sequentially_execute (init_fn , input_data )
368407 else :
369408 typed_inputs = get_typed_input_values (
370409 fn .inputs , batch_size , input_dim , output_dim
371410 )
372411 fn = infer_types (fn , typed_inputs )
373412 transformed_fn = fn
374413 input_types = tuple (inp .type for inp in fn .inputs )
414+ if backend == "pytorch" :
415+ transformed_input_data = input_data
375416 transformed_fn = add_optimizer_ops (transformed_fn )
376417 if backend == "simulate" :
377418 simulation = simulate (transformed_fn , input_types , topology )
@@ -381,19 +422,14 @@ def run_mlp(
381422 simulation .dump_chrome_trace (trace_file )
382423 return simulation
383424 elif backend == "pytorch" :
384- input_data = [
385- ConcreteValue (
386- np .random .normal (size = typ .size ).astype (np .float32 ), device = typ .device
387- )
388- for typ in input_types
389- ]
390- return run_pytorch (fn , input_data , world_size , use_gpu )
425+ return run_pytorch (transformed_fn , transformed_input_data , world_size , use_gpu )
391426
392427
393428def main (args ):
394429 run_mlp (
395430 args .phase ,
396431 args .backend ,
432+ args .dtype ,
397433 args .use_gpu ,
398434 args .batch_size ,
399435 args .input_dim ,
0 commit comments