opt: transpose(inv) -> inv(transpose)

This transformation canonicalizes sandbox linalg ops so that the various
cholesky-related transformations are not confused by a transpose.
opt: solve(chol) -> solve(triangular, chol)

Cholesky outputs a triangular matrix, so if a general solve is applied to
a cholesky output, then transform it into a triangular solve.
enh: infer_shapes for MatrixInverse
fix: local_log_add dont crash on >2 args
enh: tag_solve_triangular transpose case
enh: faster CGer
check if the node has an owner before accessing owner op
Initial test file
Add CPU/GPU check
Questions remaining: here the import relation is really strange, so i use a new import here.
new test_ifelse() function
Remove Unused line
fix crash, check first if the var is in variable_shape
Remove unused lines
Remove previous wrong lines
Initial version of optimization
Removed debug prints
- remove a variable that's not used anymore
- remove unnecessary comments
Add CPU/GPU check, and cg mark for different men info set
adding infer_shape test for MatrixInverse Op
testing Solve perform method with specific cases for lower and upper traingular matrices