我使用的是a SparseMatrix_Double
和a DenseVector_Double
中的SparseMultiply
,使用的是Accelerate框架的Sparse Solvers,它随机崩溃:
有时,它有效.有时,它会崩溃EXC_BAD_ACCESS
.有时,它会返回错误的结果.
我try 在方案设置的"诊断"选项卡上打开各种"address sanitizer"和/或各种内存判断选项,但它们没有报告任何问题.
这是怎么回事?
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
}
}
}
}
}