Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
bf16f4b
ajflksjflkjflkajfklajjadsf
s-n-sharma Oct 29, 2025
64fbd2e
finished rudimentary qr solver
s-n-sharma Oct 31, 2025
aa72d75
rayon+openblas
s-n-sharma Nov 4, 2025
e754757
sparseQR
s-n-sharma Nov 6, 2025
e6a74da
decreased time by parallelization and fixing m < n case
s-n-sharma Nov 10, 2025
2b6a65e
removed some unused dependencies
s-n-sharma Nov 10, 2025
c8697d4
improved the building of the sparse matrices, removed dmatrix middleman
s-n-sharma Nov 11, 2025
0402e6b
refactor(solver): remove redundant temp variable for constraint IDs
GottaGetPaid Nov 11, 2025
bed1c7e
perf(solver): reduce usage of parallelism in small tasks
GottaGetPaid Nov 11, 2025
791716a
refactor(solver): remove unused free-var_idx variable
GottaGetPaid Nov 11, 2025
7b62baa
perf(solver): optimize triplet creation to take advantage of sparsity
GottaGetPaid Nov 11, 2025
26af3cb
perf(solver): reduce usage of parallelism in small tasks
GottaGetPaid Nov 12, 2025
140c5fe
Merge pull request #102 from ucb-substrate/sid-branch-2
s-n-sharma Nov 14, 2025
0a7b8cb
perf(solver): removed redundant construction of AT, improved SPQR struct
s-n-sharma Nov 15, 2025
1198a31
feat(solver): added free/determined variables checking
s-n-sharma Nov 15, 2025
1928e0a
Merge branch 'main' into solver-improvements
s-n-sharma Nov 18, 2025
e65b64d
perf(solver): improvements to nullspace computation, made it all sparse
s-n-sharma Nov 24, 2025
6795bda
perf(solver): improvements to nullspace computation, made it all sparse
s-n-sharma Nov 24, 2025
0e5f011
perf(solver): removed addition of zeroed variables to matrix
s-n-sharma Nov 24, 2025
8c95cf6
Merge branch 'main' into solver-improvements
s-n-sharma Nov 24, 2025
3d6d2ca
cleaned up some code
s-n-sharma Nov 25, 2025
62f8ae6
cleaning up
s-n-sharma Nov 27, 2025
1cf0825
cleaning up
s-n-sharma Nov 27, 2025
25c6f64
feat(solver): added rounding
s-n-sharma Nov 27, 2025
0f433e0
feat(solver): improved tests
s-n-sharma Jan 3, 2026
845a68e
feat(solver): numerical stability test
s-n-sharma Jan 4, 2026
4a04462
refactor(solver): removed unneeded stuff in build.rs
s-n-sharma Jan 4, 2026
edd79e0
Merge remote-tracking branch 'origin/main' into solver-improvements
s-n-sharma Jan 4, 2026
215d7ca
refactor(compiler): merging main
s-n-sharma Jan 4, 2026
8d68cca
refactor(solver): GDS in lib.rs for preparation to merge to main
s-n-sharma Jan 4, 2026
b3312d8
feat(solver): added support for windows
s-n-sharma Jan 4, 2026
07bd083
feat(solver): eigen backend
s-n-sharma Jan 9, 2026
88e856b
fix(solver): fixed bug where m or n = 0 in matrix
s-n-sharma Jan 9, 2026
60bcbd1
feat(solver): optimized solver by reducing formation of dense q
s-n-sharma Jan 9, 2026
a8b3e3f
chore: cleaning up after eigen backend
s-n-sharma Jan 9, 2026
d2de2b3
chore(solver): cleanup
s-n-sharma Jan 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion core/compiler/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
build/
build/

7 changes: 6 additions & 1 deletion core/compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ edition = "2024"

[dependencies]
derive-where = { version = "1", features = ["serde"] }
nalgebra = "0.34"
nalgebra = { version = "0.34", features = ["rayon"] }
nalgebra-sparse = "0.11"
klayout-lyp = "0.1.1"
rayon = "1.10"
libc = "0.2"
rand = "0.8.5"
gds21 = "0.2"

anyhow = { workspace = true }
Expand All @@ -32,6 +36,7 @@ const_format = "0.2"

[build-dependencies]
lrpar = { version = "0.13", features = ["serde"] }
cc = "1.2.51"

cfgrammar = { workspace = true }
lrlex = { workspace = true }
20 changes: 20 additions & 0 deletions core/compiler/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,24 @@ fn main() {
.mod_name("cell_l")
.build()
.unwrap();

let mut build = cc::Build::new();

build
.cpp(true) // Use C++ compiler
.std("c++14") // Eigen requires C++14 or newer
.file("src/eigen_qr.cpp") // Path to your C++ file
.flag("-O3");


if std::path::Path::new("/opt/homebrew/include/eigen3").exists() {
build.include("/opt/homebrew/include/eigen3");
} else {
build.include("/usr/local/include/eigen3");
}

build.compile("eigen_qr");

println!("cargo:rerun-if-changed=src/eigen_qr.cpp");
println!("cargo:rerun-if-changed=build.rs");
}
140 changes: 140 additions & 0 deletions core/compiler/src/eigen_qr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include <Eigen/Sparse>
#include <Eigen/SparseQR>
#include <vector>
#include <iostream>

using namespace Eigen;
using namespace std;

struct EigenQR {
SparseQR<SparseMatrix<double>, COLAMDOrdering<int>> qr_a;
SparseQR<SparseMatrix<double>, COLAMDOrdering<int>> qr_at;

int m;
int n;

EigenQR(int num_rows, int num_cols) : m(num_rows), n(num_cols) {}
};

extern "C" {
void* eigen_create(int m, int n) {
return new EigenQR(m, n);
}

void* eigen_free(void* ptr) {
if (ptr) {
delete (EigenQR*) ptr;
}
}

int eigen_compute_qr(void* ptr, int* rows, int* cols, double* vals, int nnz) {
EigenQR* qr = (EigenQR*) ptr;

std::vector<Triplet<double>> triplets(nnz);

for (int i = 0; i < nnz; i++) {
triplets[i] = Triplet<double>(rows[i], cols[i], vals[i]);
}

SparseMatrix<double> A(qr->m, qr->n);
A.setFromTriplets(triplets.begin(), triplets.end());
A.makeCompressed();

qr->qr_a.compute(A);
if (qr->qr_a.info() != Eigen::Success) {
return 0;
}
qr->qr_at.compute(A.transpose());
if (qr->qr_at.info() != Eigen::Success) {
return 0;
}
return 1;
}

int eigen_get_rank(void* ptr) {
if (ptr) {
EigenQR* qr = (EigenQR*) ptr;
return qr->qr_a.rank();
}
return 0;
}

void eigen_get_q_dense(void* ptr, double* output, int mode) {
EigenQR* qr = (EigenQR*) ptr;
auto& qr_mat = (mode == 0) ? qr->qr_a : qr->qr_at;
int size = (mode == 0) ? qr->m : qr-> n;

MatrixXd I = MatrixXd::Identity(size, size);
MatrixXd Q_dense = qr_mat.matrixQ() * I;

Map<MatrixXd> ret(output, size, size);
ret = Q_dense;
}

void eigen_get_r_dense(void* ptr, double* output, int mode) {
EigenQR* qr = (EigenQR*) ptr;
auto& qr_mat = (mode == 0) ? qr->qr_a : qr->qr_at;
int r_rows = (mode == 0) ? qr->m : qr->n;
int r_cols = (mode == 0) ? qr->n : qr->m;

Map<MatrixXd> ret(output, r_rows, r_cols);
ret.setZero();

MatrixXd R_dense = MatrixXd(qr_mat.matrixR());
int h = std::min((int) R_dense.rows(), r_rows);
int w = std::min((int) R_dense.cols(), r_cols);
ret.block(0, 0, h, w) = R_dense.block(0, 0, h, w);
}

void eigen_get_permutation(void* ptr, int* output, int mode) {
EigenQR* qr = (EigenQR*) ptr;
auto& qr_mat = (mode == 0) ? qr->qr_a : qr->qr_at;
int size = (mode == 0) ? qr->n : qr->m;

auto& p = qr_mat.colsPermutation();
for (int i = 0; i < size; i++) {
output[i] = p.indices()(i);
}
}

//gives the summed absolute value of each null space basis vector along an index
void eigen_get_free_indices(void* ptr, double* output) {
EigenQR* qr = (EigenQR*) ptr;

Map<VectorXd> ret(output, qr->n);
ret.setZero();

if (qr->n - qr->qr_a.rank() <= 0) {
return;
}

VectorXd temp = VectorXd::Zero(qr->n);

for (int i = qr->qr_a.rank(); i < qr->n; i++) {
temp.setZero();
temp(i) = 1.0;

VectorXd col = qr->qr_at.matrixQ() * temp;
ret = ret + col.cwiseAbs();
}
}

void eigen_apply_q(void* ptr, double* input, double* output, int mode_mat_factor, int mode_transpose) {
EigenQR* qr = (EigenQR*) ptr;
auto& qr_mat = (mode_mat_factor == 0) ? qr->qr_a : qr->qr_at;
int size = (mode_mat_factor == 0) ? qr->m : qr->n;

Map<VectorXd> in_vec(input, size);
Map<VectorXd> out_vec(output, size);

VectorXd temp;

if (mode_transpose == 0) {
temp = qr_mat.matrixQ().transpose() * in_vec;
} else {
temp = qr_mat.matrixQ() * in_vec;
}

out_vec = temp;
}
}
7 changes: 6 additions & 1 deletion core/compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ pub mod gds;
pub mod layer;
pub mod parse;
pub mod solver;
//pub mod spqr;
pub mod spqr_eigen;

#[cfg(test)]
mod tests {

use gds21::GdsUnits;
use std::path::PathBuf;

use crate::{
Expand All @@ -19,7 +22,7 @@ mod tests {
use approx::assert_relative_eq;
use const_format::concatcp;

use crate::compile::{compile, CellArg, CompileInput};
use crate::compile::{CellArg, CompileInput, compile};
const EPSILON: f64 = 1e-10;

const EXAMPLES_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../examples");
Expand Down Expand Up @@ -439,6 +442,7 @@ mod tests {
cells
.to_gds(
GdsMap::from_lyp(SKY130_LYP).expect("failed to create GDS map"),
GdsUnits::new(1e-3, 1e-9),
work_dir.join("layout.gds"),
)
.expect("Failed to write to GDS");
Expand Down Expand Up @@ -681,6 +685,7 @@ mod tests {
cells
.to_gds(
GdsMap::from_lyp(SKY130_LYP).expect("failed to create GDS map"),
GdsUnits::new(1e-3, 1e-9),
work_dir.join("layout.gds"),
)
.expect("Failed to write to GDS");
Expand Down
Loading