Skip to content

Commit cffd0dc

Browse files
richmckeevercopybara-github
authored andcommitted
Enable use of a separately-run gRPC server with xls_delay_model_generation targets.
This makes it easier to plug in different synthesis tools and configs to collect delay model data points. PiperOrigin-RevId: 645459644
1 parent b1f1125 commit cffd0dc

File tree

1 file changed

+49
-27
lines changed

1 file changed

+49
-27
lines changed

xls/tools/run_timing_characterization.py

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@
5050
'Names of ops from samples textproto to generate data points for. If empty,'
5151
' all of them are included. Note that kIdentity is always included',
5252
)
53+
_RPC_PORT = flags.DEFINE_integer(
54+
'rpc_port',
55+
None,
56+
'Endpoint port for a separately running synthesis server. If not provided,'
57+
' yosys_server_main will be started internally.',
58+
)
5359
_MAX_THREADS = flags.DEFINE_integer(
5460
'max_threads',
5561
max(os.cpu_count() // 2, 1),
@@ -110,6 +116,10 @@
110116
'server', None, 'Path for timing characterization server executable'
111117
)
112118

119+
# How long to wait before trying to connect a client to an internally-started
120+
# synthesis server.
121+
_SERVER_STARTUP_WAIT_SECS = 5
122+
113123

114124
class WorkerConfig:
115125
"""Configuration for workers process."""
@@ -204,7 +214,11 @@ def _do_config_task(config: WorkerConfig):
204214
raise app.UsageError('Must provide either --bazel_bin_path or --client.')
205215
config.client_bin = os.path.realpath(_CLIENT.value)
206216

207-
print('server bin path:', config.server_bin)
217+
if _RPC_PORT.value is None:
218+
if not os.path.isfile(config.server_bin):
219+
raise app.UsageError(f'Server tool not found with {config.server_bin}')
220+
print('server bin path:', config.server_bin)
221+
208222
print('client bin path:', config.client_bin)
209223
print(
210224
'output checkpoint path:',
@@ -217,13 +231,14 @@ def _do_config_task(config: WorkerConfig):
217231
if not os.path.isfile(config.sta_bin):
218232
raise app.UsageError(f'STA tool not found with {config.sta_bin}')
219233

220-
if not os.path.isfile(config.server_bin):
221-
raise app.UsageError(f'Server tool not found with {config.server_bin}')
222-
223234
if not os.path.isfile(config.client_bin):
224235
raise app.UsageError(f'Client tool not found with {config.client_bin}')
225236

226-
config.rpc_port = portpicker.pick_unused_port()
237+
config.rpc_port = (
238+
_RPC_PORT.value
239+
if _RPC_PORT.value is not None
240+
else portpicker.pick_unused_port()
241+
)
227242

228243
if config.debug:
229244
config.server_extra_args = ['--save_temps', '--v 1', '--alsologtostderr']
@@ -298,17 +313,8 @@ def _do_config_sky130(config: WorkerConfig):
298313
config.client_args.append('--max_ps=10000')
299314

300315

301-
def _do_worker_task(config: WorkerConfig):
302-
"""Run the worker task."""
303-
logging.info('Running Target : {config.target}')
304-
305-
if config.debug:
306-
logging.info(' OpenROAD dir : %s', config.openroad_path)
307-
logging.info(' Server : %s', config.server_bin)
308-
logging.info(' Client : %s', config.client_bin)
309-
logging.info(' Using Yosys : %s', config.yosys_bin)
310-
logging.info(' Using STA : %s', config.sta_bin)
311-
316+
def _start_server(config: WorkerConfig) -> subprocess.Popen[bytes]:
317+
"""Starts a Yosys synthesis server locally using the given config."""
312318
server = [repr(config.server_bin)]
313319
server.append(f'--yosys_path={config.yosys_bin!r}')
314320
server.append(
@@ -328,6 +334,29 @@ def _do_worker_task(config: WorkerConfig):
328334

329335
server_cmd = ' '.join(server)
330336

337+
# start non-blocking process
338+
server_proc = subprocess.Popen(server_cmd, stdout=subprocess.PIPE, shell=True)
339+
time.sleep(_SERVER_STARTUP_WAIT_SECS)
340+
return server_proc
341+
342+
343+
def _do_worker_task(config: WorkerConfig):
344+
"""Run the worker task."""
345+
logging.info('Running Target : {config.target}')
346+
347+
if config.debug:
348+
logging.info(' Client : %s', config.client_bin)
349+
if _RPC_PORT.value is not None:
350+
logging.info(' External RPC port : %s', config.rpc_port)
351+
else:
352+
logging.info(' OpenROAD dir : %s', config.openroad_path)
353+
logging.info(' Server : %s', config.server_bin)
354+
logging.info(' Using Yosys : %s', config.yosys_bin)
355+
logging.info(' Using STA : %s', config.sta_bin)
356+
357+
start = datetime.datetime.now()
358+
server_proc = None if _RPC_PORT.value is not None else _start_server(config)
359+
331360
client = [repr(config.client_bin)]
332361
if config.client_checkpoint_file:
333362
client.append(f'--checkpoint_path {config.client_checkpoint_file!r}')
@@ -337,21 +366,13 @@ def _do_worker_task(config: WorkerConfig):
337366
client.append(f'--port={config.rpc_port}')
338367

339368
client_cmd = ' '.join(client)
340-
341369
# create a checkpoint file if not already there
342370
if config.client_checkpoint_file and not os.path.isfile(
343371
config.client_checkpoint_file
344372
):
345373
with open(config.client_checkpoint_file, 'w') as f:
346374
f.write('')
347375

348-
start = datetime.datetime.now()
349-
350-
# start non-blocking process
351-
server_proc = subprocess.Popen(server_cmd, stdout=subprocess.PIPE, shell=True)
352-
353-
time.sleep(5)
354-
355376
client_process = subprocess.Popen(
356377
client_cmd, stdout=subprocess.PIPE, shell=True, text=True
357378
)
@@ -364,9 +385,10 @@ def _do_worker_task(config: WorkerConfig):
364385
' Total elapsed time for worker (%s) : %s', config.target, elapsed
365386
)
366387

367-
# clean up
368-
server_proc.kill()
369-
server_proc.communicate()
388+
if server_proc is not None:
389+
# clean up
390+
server_proc.kill()
391+
server_proc.communicate()
370392

371393

372394
def main(_):

0 commit comments

Comments
 (0)