77
88import hashlib
99import inspect
10- import json
1110import logging
1211import shutil
1312import subprocess
2322from QEfficient .base .pytorch_transforms import PytorchTransform
2423from QEfficient .compile .qnn_compiler import compile as qnn_compile
2524from QEfficient .generation .cloud_infer import QAICInferenceSession
26- from QEfficient .utils import constants , dump_qconfig
25+ from QEfficient .utils import constants , create_json , dump_qconfig , generate_mdp_partition_config , load_json
2726from QEfficient .utils .cache import QEFF_HOME , to_hashable
2827
2928logger = logging .getLogger (__name__ )
@@ -269,17 +268,17 @@ def _compile(
269268 specializations = specializations ,
270269 custom_io = custom_io ,
271270 device_group = list (range (mdp_ts_num_devices )),
272- num_cores = compiler_options .get ("aic_num_cores" , 16 ),
273- mxfp6 = compiler_options .get ("mxfp6_matmul" , False ),
271+ num_cores = compiler_options .get ("aic_num_cores" , constants . DEFAULT_AIC_NUM_CORES ),
272+ mxfp6 = compiler_options .get ("mxfp6_matmul" , constants . DEFAULT_AIC_MXPF6_MATMUL ),
274273 mxint8 = mxint8_kv_cache ,
275274 qnn_config = qnn_config ,
276275 )
277276
278277 return self .qpc_path
279278
280279 command = constants .COMPILER + [f"-m={ onnx_path } " ]
281- if mdp_ts_json_path := compiler_options . pop ( "mdp_ts_json_path" , None ):
282- mdp_ts_num_devices = None
280+
281+ if mdp_ts_json_path := compiler_options . pop ( "mdp_load_partition_config" , None ):
283282 command .append (f"-mdp-load-partition-config={ mdp_ts_json_path } " )
284283
285284 for key , value in compiler_options .items ():
@@ -289,6 +288,17 @@ def _compile(
289288 command .append (option )
290289 continue
291290 command .append (f"{ option } ={ value } " )
291+
292+ # Create a dummy mdp_ts_json if mdp-load-partition-config not provided and num_devices > 1
293+ if mdp_ts_json_path is not None :
294+ mdp_ts_json = load_json (str (mdp_ts_json_path ))
295+ elif mdp_ts_num_devices > 1 :
296+ mdp_ts_json = generate_mdp_partition_config (
297+ mdp_ts_num_devices , compiler_options .get ("aic_num_cores" , constants .DEFAULT_AIC_NUM_CORES )
298+ )
299+ else :
300+ mdp_ts_json = None
301+
292302 compile_hash = hashlib .sha256 (to_hashable (command ))
293303
294304 if specializations is not None :
@@ -299,30 +309,37 @@ def _compile(
299309
300310 if num_speculative_tokens :
301311 compile_hash .update (to_hashable ({"num_speculative_tokens" : num_speculative_tokens }))
302- # Hash num_devices too, since default value would always be 1.
303- compile_hash .update (to_hashable (mdp_ts_num_devices ))
312+
313+ # Hash the MDP partition config and the number of devices.
314+ compile_hash .update (to_hashable (mdp_ts_json ))
315+ compile_hash .update (to_hashable ({"mdp_ts_num_devices" : mdp_ts_num_devices }))
304316
305317 # Check if already compiled
306318 compile_hash = compile_hash .hexdigest ()[:16 ]
307319 compile_dir = qpc_path .with_name (qpc_path .name + "-" + compile_hash )
308320 qpc_path = compile_dir / "qpc"
309321 qpc_path .mkdir (parents = True , exist_ok = True )
322+
310323 if qpc_path .is_dir ():
311324 if (qpc_path / "programqpc.bin" ).is_file ():
312325 self .qpc_path = qpc_path
313326 return qpc_path
314327 # Probably compilation failure last time, delete directory to start over
315328 shutil .rmtree (qpc_path )
316329
330+ # write the MDP partition config file if not provided
331+ if mdp_ts_json is not None :
332+ mdp_ts_json_path = compile_dir / f"mdp_ts_{ mdp_ts_num_devices } .json"
333+ create_json (str (mdp_ts_json_path ), mdp_ts_json )
334+ command .append (f"-mdp-load-partition-config={ mdp_ts_json_path } " )
335+
317336 # Write specializations.json file
318337 if specializations is not None :
319338 specializations_json = compile_dir / "specializations.json"
320- with open (specializations_json , "w" ) as fp :
321- json .dump (
322- {"specializations" : [{k : str (v ) for k , v in spec .items ()} for spec in specializations ]},
323- fp ,
324- indent = 4 ,
325- )
339+ specializations_data = {
340+ "specializations" : [{k : str (v ) for k , v in spec .items ()} for spec in specializations ]
341+ }
342+ create_json (str (specializations_json ), specializations_data )
326343 command .append (f"-network-specialization-config={ specializations_json } " )
327344
328345 # Write custom_io.yaml file
@@ -333,26 +350,6 @@ def _compile(
333350 fp .write (f" - IOName: { io_name } \n Precision: { dtype } \n \n " )
334351 command .append (f"-custom-IO-list-file={ custom_io_yaml } " )
335352
336- # Write mdp_config.json file
337- if not mdp_ts_json_path and mdp_ts_num_devices > 1 :
338- num_cores = compiler_options .get ("aic_num_cores" , 16 )
339- mdp_ts_json = compile_dir / f"mdp_ts_{ mdp_ts_num_devices } .json"
340- with open (mdp_ts_json , "w" ) as fp :
341- json .dump (
342- {
343- "connections" : [{"devices" : list (range (mdp_ts_num_devices )), "type" : "p2p" }],
344- "partitions" : [
345- {
346- "name" : "Partition0" ,
347- "devices" : [{"deviceId" : d , "numCores" : num_cores } for d in range (mdp_ts_num_devices )],
348- }
349- ],
350- },
351- fp ,
352- indent = 4 ,
353- )
354- command .append (f"-mdp-load-partition-config={ mdp_ts_json } " )
355-
356353 command .append (f"-aic-binary-dir={ qpc_path } " )
357354 logger .info (f"Running compiler: { ' ' .join (command )} " )
358355 try :
0 commit comments