OpaquePointer errors with complex functions in Accelerate

Right, and I read your intention to not have this warning...

This would work:

alpha.withUnsafeBufferPointer { alphap in
    a.withUnsafeBytes { ap in
        x.withUnsafeBufferPointer { xp in
            beta.withUnsafeBytes { betap in
                y.withUnsafeBytes { yp in // Haha, immutable!!!
                    cblas_cgemv(
                        CblasRowMajor,
                        CblasNoTrans,
                        m,
                        n,
                        .init(alphap.baseAddress!),
                        .init(ap.baseAddress!),
                        m,
                        .init(xp.baseAddress!),
                        1,
                        .init(betap.baseAddress!),
                        .init(yp.baseAddress!),
                        1
                    )
                }
            }
        }
    }
}

or, if you prefer:

func cblas_cgemv_wrapper(order: CBLAS_ORDER, transpose: CBLAS_TRANSPOSE, m: Int, n: Int, alpha: UnsafeRawPointer, a: UnsafeRawPointer, lda: Int, x: UnsafeRawPointer, incX: Int, beta: UnsafeRawPointer, y: UnsafeRawPointer, incY: Int) {
    cblas_cgemv(
        order,
        transpose,
        m,
        n,
        .init(alpha),
        .init(a),
        lda,
        .init(x),
        incX,
        .init(beta),
        .init(y),
        incY
    )
}

Usage:

cblas_cgemv_wrapper(
    order: CblasRowMajor,
    transpose: CblasNoTrans,
    m: m,
    n: n,
    alpha: alpha,
    a: a,
    lda: m,
    x: x,
    incX: 1,
    beta: beta,
    y: y,
    incY: 1
)

to have a more convenient wrapper.

Answering myself above:

  • withUnsafeBufferPointer & withUnsafeBytes give identical results in this code.
  • withUnsafeBufferPointer (without Mutable) or withUnsafeBytes (without Mutable) wrapped in a OpaquePointer could indeed be used for the output parameter that's supposed to be mutable! Looks like a small hole in the type safety system.