arraysswiftstruct

ContiguousArray to UnsafePointer conversion cannot be done


I am trying to call cblas functions from a user defined Matrix type, which uses an array to hold matrix elements. A very simplified form of the code is here:

struct BoxArr{
    var y: Array<Double>
    init( y: Array<Double> ){
        self.y = y
    }
}

var a = BoxArr( y: [1.0, 2.0, 3.0] )
let s = cblas_dasum( Int32(a.y.count), a.y, 1 )
print(s)

The above code works with no problem, producing the correct sum of 6.0. Note that the function cblas_dasum receives three arguments, which are (1) the number of elements in the array, (2) the pointer to the array holding the numbers, and (3) stride. I am having a type conversion problem with the second argument. If I change the type of the struct member y from Array to ContiguousArray as I did in the following:

struct BoxContArr{
    var y: ContiguousArray<Double>
    init( y: ContiguousArray<Double> ){
        self.y = y
    }
}

var a = BoxContArr( y: [1.0, 2.0, 3.0] )
let s = cblas_dasum( Int32(a.y.count), a.y, 1 )
print(s)

I receive the following error:

Cannot convert value of type 'ContiguousArray<Double>' to expected argument type 'UnsafePointer<Double>?'

In the former case, the second argument a.y's type Array<Double> was implicitly converted to UnsafePointer<Double> but in the latter case ContiguousArray<Double> was not converted to UnsafePointer<Double>. I wonder why this is happening and how to fix it. I prefer using ContiguousArray for possibly better performance. I made shallow copies of the arrays in the constructor but this is not changing the outcome (In the extended implementation, a deep copy is done.)


Solution

  • The pointer needs to be to the first element of the buffer:

        var a = BoxContArr( y: [1.0, 2.0, 3.0] )
        a.y.withUnsafeBufferPointer { ptr in
            let s = cblas_dasum( Int32(a.y.count), ptr.baseAddress, 1 )
            print(s) // 6.0
        }