[swift-users] Implicitly capture a mutating self
Richard Wei
rxrwei at gmail.com
Fri Dec 16 14:10:39 CST 2016
`sync` is not escaping. Shadow copy causes the device memory to make a copy, which can’t be a solution either. I’ll file a radar.
> Note that, independently, this part looks fishy:
>
>> try! fill<<<(blockSize, blockCount)>>>[
>> .pointer(to: &self)
>
> UnsafePointers formed by passing an argument inout are not valid after the called function returns, so if this function is forming and returning a pointer, it will likely result in undefined behavior. You should use `withUnsafePointer(&self) { p in ... }` to get a usable pointer.
This part is a semi-"type safe” wrapper to CUDA kernel launcher. The purpose is to make explicit which argument gets passed to the kernel as a pointer; in this case, self is a `DeviceArray`. `.pointer` is a factory method under `KernelArgument`. Since most arguments to the kernel are passed in by pointers, IMO using a bunch of `withUnsafe...` clauses would only make it look unnecessarily clumsy.
-Richard
> On Dec 16, 2016, at 12:41, Joe Groff <jgroff at apple.com> wrote:
>
>
>> On Dec 15, 2016, at 11:46 PM, Richard Wei via swift-users <swift-users at swift.org> wrote:
>>
>> Hi,
>>
>> Swift 3.0.2 seems to have broken my code due to mutating self capture. But I have to pass inout self to the closure. Any workaround?
>>
>> let blockSize = min(512, count)
>> let blockCount = (count+blockSize-1)/blockSize
>> device.sync { // Launch CUDA kernel
>> try! fill<<<(blockSize, blockCount)>>>[
>> .pointer(to: &self), .value(value), .value(Int64(count))
>> ]
>> }
>
> This looks like a compiler bug. Assuming `sync`'s closure is not @escaping, it should be allowed to capture self. If you haven't yet, would you be able to file a bug at bugs.swift.org? Does making a shadow copy work as a workaround, something like:
>
> var tmpSelf = self
> device.sync {... &tmpSelf ...}
> self = tmpSelf
>
> Note that, independently, this part looks fishy:
>
>> try! fill<<<(blockSize, blockCount)>>>[
>> .pointer(to: &self)
>
> UnsafePointers formed by passing an argument inout are not valid after the called function returns, so if this function is forming and returning a pointer, it will likely result in undefined behavior. You should use `withUnsafePointer(&self) { p in ... }` to get a usable pointer.
>
> -Joe
More information about the swift-users
mailing list