You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Accelerate框架SparseMultiply随机触发EXC_BAD_ACCESS崩溃问题排查

Accelerate框架SparseMultiply随机异常问题排查

问题描述

使用Apple Accelerate框架的Sparse Solvers组件调用SparseMultiply计算SparseMatrix_Double与DenseVector_Double的乘积时,出现随机异常:有时运行正常,有时触发EXC_BAD_ACCESS崩溃,有时返回错误结果。已开启地址 sanitizer及方案设置中“Diagnostics”标签页的各类内存检测选项,但均未检测到问题。

示例代码

func matrixProductExperiment() {
    // Given sparse matrix A, and dense vector X, calculate product of dense vector Y, i.e., y = Ax:
    //
    //              A                X    =      Y
    //   ( 10.0  1.0      2.5 )  ( 2.20 ) = ( 32.025 )
    //   (  1.0 12.0 -0.3 1.1 )  ( 2.85 ) = ( 38.720 )
    //   (      -0.3  9.5     )  ( 2.79 ) = ( 25.650 )
    //   (  2.5  1.1      6.0 )  ( 2.87 ) = ( 25.855 )

    // We use a format known as Compressed Sparse Column (CSC) to store the data. Further,
    // as the matrix is symmetric, we only need to store half the data. The CSC format
    // stores the matrix as a series of column vectors where only the non-zero entries are
    // specified, stored as the pair of (row index, value), although in separate arrays:

    let rowCount: Int32     = 4
    let columnCount: Int32  = 4
    var matrixValues        = [ 10.0, 1.0, 2.5, 12.0, -0.3, 1.1, 9.5, 6.0 ]
    var rowIndices: [Int32] = [    0,   1,   3,    1,    2,   3,   2,   3 ]
    var columnStarts        = [    0,              3,              6,   7 ]

    // vector X

    var xValues = [ 2.20, 2.85, 2.79, 2.87 ]

    // In this library, this raw information is all wrapper into a flexible data type
    // that allows for more complex use cases in other situations.

    rowIndices.withUnsafeMutableBufferPointer { rowIndicesPointer in
        columnStarts.withUnsafeMutableBufferPointer { columnStartsPointer in
            matrixValues.withUnsafeMutableBufferPointer { valuesPointer in
                xValues.withUnsafeMutableBufferPointer { xPointer in
                    let a = SparseMatrix_Double(
                        // Structure of the matrix, without any values
                        structure: SparseMatrixStructure(
                            rowCount:     rowCount,
                            columnCount:  columnCount,
                            columnStarts: columnStartsPointer.baseAddress!,
                            rowIndices:   rowIndicesPointer.baseAddress!,
                            // Matrix meta-data
                            attributes: SparseAttributes_t(
                                transpose: false,
                                triangle: SparseLowerTriangle,
                                kind: SparseSymmetric,
                                _reserved: 0,
                                _allocatedBySparse: false
                            ),
                            blockSize: 1),
                        // Numerical values of the matrix
                        data: valuesPointer.baseAddress!
                    )

                    let x = DenseVector_Double(count: columnCount, data: xPointer.baseAddress!)

                    let y = [Double](unsafeUninitializedCapacity: Int(rowCount)) { resultBuffer, count in
                        let y = DenseVector_Double(count: rowCount, data: resultBuffer.baseAddress!)
                        SparseMultiply(a, x, y)
                        count = Int(rowCount)
                    }

                    print(y) // [32.025, 38.72, 25.65, 25.855] – Correct
                }
            }
        }
    }
}

问题根源与修复

核心原因:CSC格式的columnStarts数组不符合规范

Accelerate的Sparse Solvers对压缩稀疏列(CSC)格式的columnStarts数组有强制要求:

  • 数组长度必须等于矩阵列数 + 1
  • 最后一个元素必须等于矩阵的非零元素总数

你的代码中:

  • 矩阵列数为4,columnStarts仅包含4个元素(缺少1个)
  • 非零元素总数是8,但columnStarts最后一个元素是7,而非8

这种不完整的数组会导致SparseMultiply在遍历矩阵时出现内存越界访问。由于内存越界的行为具有随机性——有时刚好访问到进程地址空间内的合法内存(表现为运行正常或返回错误结果),有时访问到非法内存(触发EXC_BAD_ACCESS崩溃),内存检测工具无法精准捕获这类“合法但错误”的内存访问。

修复步骤

  1. 修正columnStarts数组,补充最后一个元素为非零元素总数:
var columnStarts = [0, 3, 6, 7, 8]
  1. 验证矩阵属性参数:确认SparseAttributes_t中SparseSymmetric和SparseLowerTriangle的设置与实际矩阵结构匹配,确保仅存储了下三角部分的非零元素,避免因矩阵结构描述错误导致的计算异常。

内容的提问来源于stack exchange,提问作者Rob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 23:17:52