Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-11656] Initialize multiple arrays with unsafeUninitializedCapacity #54067

Open
stephentyrone opened this issue Oct 23, 2019 · 5 comments
Open
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation standard library Area: Standard library umbrella

Comments

@stephentyrone
Copy link
Member

Previous ID SR-11656
Radar None
Original Reporter @stephentyrone
Type Bug
Additional Detail from JIRA
Votes 1
Component/s Compiler, Standard Library
Labels Bug, DiagnosticsQoI
Assignee None
Priority Medium

md5: 55a599730b8584891083fa98181cdf75

Issue Description:

Consider a function like vDSP_ctoz that has multiple output buffers. We would like to be able to expose this in Swift with a signature like:

func ctoz<T>(_ data: T) -> (real: [Float], imag: [Float])
where T: AccelerateBuffer, T.Element == DSPComplex {
  var real = [Float](repeating: 0, count: data.count)
  var imag = [Float](repeating: 0, count: data.count)
  implementation(data, real: &real, imag: &imag)
  return (real, imag)
}

Ideally we would use the unsafeUninitializedCapacity inits instead of needing to zero-fill the arrays just to immediately overwrite them. However, this is either impossible or very difficult to do.

Someone might try:

let real = [Float](unsafeUninitializedCapacity: data.count) { r, _ in
  let imag = [Float](unsafeUninitializedCapacity: data.count) { i, _ in
    implementation(data, real: &r, imag: &i)
  }
}
return (real, imag) // use of unresolved identifier imag

Then they would try:

let imag: [Float]
let real = [Float](unsafeUninitializedCapacity: data.count) { r, _ in
  imag = [Float](unsafeUninitializedCapacity: data.count) { i, _ in // cannot assign to value: imag is a let constant
    implementation(data, real: &r, imag: &i)
  }
}
return (real, imag)

If they apply the suggested fix:

var imag: [Float]
let real = [Float](unsafeUninitializedCapacity: data.count) { r, _ in
  imag = [Float](unsafeUninitializedCapacity: data.count) { i, _ in // Variable image captured by a closure before being initialized
    implementation(data, real: &r, imag: &i)
  }
}
return (real, imag)
@stephentyrone
Copy link
Member Author

Also tagging Diagnostics QoI because of the broken fix that gets suggested.

@stephentyrone
Copy link
Member Author

CC @natecook1000 @airspeedswift

@natecook1000
Copy link
Member

They’re almost there — making the first line var imag: [Float] = [] solves the problem, and is what’s implied by the last error. Can the diagnostics jump over that intermediate error and suggest making imag both mutable and initialized?

@stephentyrone
Copy link
Member Author

That's still kinda unsatisfying from a user perspective in that it requires creating a dummy empty array just to discard it, even if the optimizer can actually remove it. We should also see if we can make this a bit nicer.

@stephentyrone
Copy link
Member Author

(Also, unsatisfying in that they can't benefit from let)

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation standard library Area: Standard library umbrella
Projects
None yet
Development

No branches or pull requests

2 participants