I am trying to perform an LU-factorization in Kotlin/Native by using a LAPACK c-function. However, I don’t know how to read back the values to Kotlin that is modified by the c-function. dgetrf_
modifies the data that pivots
points to. How do I get an IntArray
in Kotlin with the values referenced by pivots
?
fun luPivots(matrix : DoubleArray) : IntArray {
val dim = sqrt(matrix.size.toDouble()).toInt()
var cDim: CValuesRef<__CLPK_integerVar> = cValuesOf(dim)
var inMatrix: CValuesRef<__CLPK_doublerealVar> = matrix.toCValues()
var pivots: CValuesRef<__CLPK_integerVar> = Array(matrix.size) { 0 }.toIntArray().toCValues()
var info: CValuesRef<__CLPK_integerVar> = cValuesOf(0)
// Taken from iOS platform.Accelerate
dgetrf_(cDim, cDim, inMatrix, cDim, pivots, info)
return ???
}
It seems that toCValues()
and cValuesOf()
creates a temporary copy of the data in memory (There is a hint here). Hence, if the data should be modified and read back it is necessary to manually allocate the memory, perform the operation, read it back and then free the memory. The function above was part of the inverse
function I am writing. Can anyone confirm that the way I write below is best practice or are there improvements?
fun inverse(matrix : DoubleArray) : DoubleArray {
val dim = sqrt(matrix.size.toDouble()).toInt()
val inMatrixPtr = nativeHeap.allocArray<__CLPK_doublerealVar>(matrix.size)
matrix.forEachIndexed { i, v -> inMatrixPtr[i] = v}
val pivotsPtr = nativeHeap.allocArray<__CLPK_integerVar>(dim)
dgetrf_(cValuesOf(dim), cValuesOf(dim), inMatrixPtr, cValuesOf(dim), pivotsPtr, cValuesOf(0))
val workLength = dim * dim
val workspacePtr = nativeHeap.allocArray<__CLPK_doublerealVar>(workLength)
dgetri_(cValuesOf(dim), inMatrixPtr, cValuesOf(dim), pivotsPtr, workspacePtr, cValuesOf(workLength), cValuesOf(0))
nativeHeap.free(pivotsPtr)
nativeHeap.free(workspacePtr)
val outMatrix: DoubleArray =
memScoped {
val ptr: CPointer<DoubleVarOf<__CLPK_doublereal>> = inMatrixPtr.getPointer(memScope)
(0 until matrix.size).map { ptr[it] }.toDoubleArray()
}
nativeHeap.free(inMatrixPtr)
return outMatrix
}