Operator overloading with generics

That's not how generics work. When compiling QRDecompose<M: MatrixProtocol>, the compiler only knows that M conforms to MatrixProtocol, so the generic implementation is used. If you want to get runtime dispatch based on the scalar type, another option is to create a protocol to bind the scalar type, and add the implementation hooks as protocol requirements:

// warning: I'm coding this in the forums text editor, so no guarantees =)
protocol MatrixScalar: BinaryFloatingPoint {
  static func gemm(_ m1: Matrix<Self>, _ m2: Matrix<Self>) -> Matrix<Self>
}

extension Float: MatrixScalar {
  static func gemm(_ m1: Matrix<Float>, _ m2: Matrix<Float>) -> Matrix<Float> {
    cblas_sgemm( ... ) // use this instead of vDSP_mmul
  }
}

extension Double: MatrixScalar {
  static func gemm(_ m1: Matrix<Double>, _ m2: Matrix<Double>) -> Matrix<Double> {
    cblas_dgemm( ... ) // use this instead of vDSP_mmulD
  }
}

public struct Matrix<Scalar: MatrixScalar> {
  // ...
  static func *(_ m1: Matrix, _ m2: Matrix) -> Matrix {
    Scalar.gemm(m1, m2)
  }
}
2 Likes