Coverage for klayout_pex/fastercap/fastercap_runner.py: 70%
57 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-17 17:24 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-17 17:24 +0000
1#
2# --------------------------------------------------------------------------------
3# SPDX-FileCopyrightText: 2024 Martin Jan Köhler and Harald Pretl
4# Johannes Kepler University, Institute for Integrated Circuits.
5#
6# This file is part of KPEX
7# (see https://github.com/martinjankoehler/klayout-pex).
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21# SPDX-License-Identifier: GPL-3.0-or-later
22# --------------------------------------------------------------------------------
23#
24import re
25import subprocess
26import time
27from typing import *
29from ..log import (
30 info,
31 # warning,
32 rule,
33 subproc,
34)
35from ..common.capacitance_matrix import CapacitanceMatrix
38def run_fastercap(exe_path: str,
39 lst_file_path: str,
40 log_path: str,
41 tolerance: float,
42 d_coeff: float,
43 mesh_refinement_value: float,
44 ooc_condition: Optional[int],
45 auto_preconditioner: bool,
46 galerkin_scheme: bool,
47 jacobi_preconditioner: bool):
48 args = [
49 exe_path,
50 '-b', # console mode, without GUI
51 '-i', # Dump detailed time and memory information
52 '-v', # Verbose output
53 f"-a{tolerance}", # stop when relative error lower than threshold
54 f"-d{d_coeff}", # Direct potential interaction coefficient to mesh refinement ratio
55 f"-m{mesh_refinement_value}", # Mesh relative refinement value
56 ]
58 if ooc_condition is not None:
59 args += [f"-f{ooc_condition}"]
61 if auto_preconditioner:
62 args += ['-ap']
64 if galerkin_scheme:
65 args += ['-g']
67 if jacobi_preconditioner:
68 args += ['-pj']
70 args += [
71 lst_file_path
72 ]
73 info(f"Calling FasterCap")
74 subproc(f"{' '.join(args)}, output file: {log_path}")
76 rule('FasterCap Output')
77 start = time.time()
79 proc = subprocess.Popen(args,
80 stdin=subprocess.DEVNULL,
81 stdout=subprocess.PIPE,
82 stderr=subprocess.STDOUT,
83 universal_newlines=True,
84 text=True)
85 with open(log_path, 'w') as f:
86 while True:
87 line = proc.stdout.readline()
88 if not line:
89 break
90 subproc(line[:-1]) # remove newline
91 f.writelines([line])
92 proc.wait()
94 duration = time.time() - start
96 rule()
98 if proc.returncode == 0:
99 info(f"FasterCap succeeded after {'%.4g' % duration}s")
100 else:
101 raise Exception(f"FasterCap failed with status code {proc.returncode} after {'%.4g' % duration}s, "
102 f"see log file: {log_path}")
105def fastercap_parse_capacitance_matrix(log_path: str) -> CapacitanceMatrix:
106 with open(log_path, 'r') as f:
107 rlines = f.readlines()
108 rlines.reverse()
110 # multiple iterations possible, find the last matrix
111 for idx, line in enumerate(rlines):
112 if line.strip() == "Capacitance matrix is:":
113 m = re.match(r'^Dimension (\d+) x (\d+)$', rlines[idx-1])
114 if not m:
115 raise Exception(f"Could not parse capacitor matrix dimensions")
116 dim = int(m.group(1))
117 conductor_names: List[str] = []
118 rows: List[List[float]] = []
119 for i in reversed(range(idx-1-dim, idx-1)):
120 line = rlines[i].strip()
121 cells = [cell.strip() for cell in line.split(' ')]
122 cells = list(filter(lambda c: len(c) >= 1, cells))
123 conductor_names.append(cells[0])
124 row = [float(cell)/1e6 for cell in cells[1:]]
125 rows.append(row)
126 cm = CapacitanceMatrix(conductor_names=conductor_names, rows=rows)
127 return cm
129 raise Exception(f"Could not extract capacitance matrix from FasterCap log file {log_path}")