UnsafeMutablePointer Swift 3 conversion


(Patrice Kouame) #1

Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice


(Jacob Bandes-Storch) #2

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I
think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity:
MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass
elements in the buffer, not the size of each element. Using `bindMemory(to:
ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the
size of each element.

More info at
https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some
compiler (playground) crashes, but it does seem to work most of the time.
Although I only have 1 buffer :slight_smile:
https://github.com/jtbandes/Metalbrot.playground

Jacob

···

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users < swift-users@swift.org> wrote:

Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and
Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest
UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their
sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to
the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the
correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(
constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to:
ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by:
1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> =
shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity:
MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }

        //Advance and cast to ObjectData

// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by:
1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by:
1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<
>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size +
mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender)
{ i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/
60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/
60.0)
            }
        }

        ptr = ptr.advanced(by: objectsToRender)

        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary.
Here’s a clip of the stack trace.

0 swift 0x000000010714a99d
PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous
namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous
namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&,
swift::Expr*) + 273
7 swift 0x00000001047624e7
swift::ASTVisitor<(anonymous namespace)::RValueEmitter,
swift::Lowering::RValue, void, void, void, void, void,
swift::Lowering::SGFContext>::visit(swift::Expr*,
swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::
SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*)
+ 195
9 swift 0x000000010474fbc3 swift::Lowering::
SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned
int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction,
void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019
swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void,
void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::
SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775
swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*
)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322
swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous
namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e
swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*)
+ 30
17 swift 0x0000000104709093
swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*,
unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::
constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*,
llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&,
swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&,
swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5
swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*,
swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Patrice Kouame) #3

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

···

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Gerard Iglesias) #4

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

···

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Patrice Kouame) #5

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

···

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Gerard Iglesias) #6

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

···

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Jacob Bandes-Storch) #7

Yikes! That's unsafe! When using withMemoryRebound, I think you're only
supposed to use the argument $0 inside the block. Saving it and using it
after withMemoryRebound is probably undefined behavior. But maybe you can
move your ".pointee = x" into a separate function rather than using a
closure?

···

On Sat, Sep 3, 2016 at 1:12 PM, Patrice Kouame via swift-users < swift-users@swift.org> wrote:

Finally Success! I’m seeing my pretty little 3D twirling Metal Renderer
cubes again… Here’s how

Snippet of old sample code which no longer compiles in Xcode 8 beta 6
with stricter Swift3 unsafe type casting restrictions
(in MetalView.swift from # Adopting Metal II: Designing and Implementing
a Real-World Metal Renderer)

let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.
contents())
let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
mainPtr.pointee = mainPassFrameData
var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))

My conversion attempt that crashes Swift 3 Xcode 8 beta 6 (see RADAR 28150447
- Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE)

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to:
ShadowPass.self, capacity: MemoryLayout<shadowPassData>.size)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by:
1).withMemoryRebound(to: MainPass.self, capacity: 1) {
$0.pointee = mainPassFrameData
}
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by:
1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<
ObjectData >.size) {$0}

Latest conversion that make Xcode and Swift 3 smile again...

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to:
ShadowPass.self, capacity: shadowPassData.count)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by:
1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}
        mainPtr.pointee = mainPassFrameData
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by:
1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {$0}

Yes… Xcode/Swift3 SIL generation definitely did NOT like my "$0.pointee =
mainPassFrameData" statement.
Apparently, reassigning the pointee within the closure makes Swift gag out
of disgust. Sorry ;-(
That’s what I get for trying to be fancy…
And fixed my “capacity” issues thanks to some previous posters.

Hope this helps anyone trying to get the Metal projects to compile again.

At least I got a Radar out of this :wink: Compilers should never burn and
crash out like this...

Regards to all, Patrice

On Sep 3, 2016, at 1:22 PM, Patrice Kouame via swift-users < > swift-users@swift.org> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book
back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I
recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> =
withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity:
objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is
incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to
UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to
mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is
always a little bit tricky - the proposed Xcode fixes should always be
reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users < > swift-users@swift.org> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the
other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com> a écrit :

Indeed. There is a difference between stride and size, but I interpreted
capacity incorrectly for my purposes. It should indicate the number of <T>
elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I
filed this Apple radar against Developer Tools.

28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler
and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users < > swift-users@swift.org> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes
it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users < > swift-users@swift.org> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in
my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to:
ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to
MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> =
shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1)
{
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of
renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by:
1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
}

There are surely ways to refactor and simplify this, but I’m trying to
retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the
project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not
sure where to file this bug : Swift or Apple radar against Xcode or both? I
now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a
lot of churning for very little gain. Don’t you think? The easier, but
“unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety
features. Guess we can’t have our cake and eat it too, especially when
interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I
think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self,
capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass
elements in the buffer, not the size of each element. Using `bindMemory(to:
ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the
size of each element.

More info at https://developer.apple.com/reference/swift/
unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some
compiler (playground) crashes, but it does seem to work most of the time.
Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/
Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users < > swift-users@swift.org> wrote:

Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and
Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest
UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their
sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to
the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the
correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPas
>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to:
ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to
MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by:
1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> =
shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity:
MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }

        //Advance and cast to ObjectData

// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by:
1))
        var ptr : UnsafeMutablePointer<ObjectData> =
mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity:
MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size +
mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender)
{ i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/
60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/
60.0)
            }
        }

        ptr = ptr.advanced(by: objectsToRender)

        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if
necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d
PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous
namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous
namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1
prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7
swift::ASTVisitor<(anonymous namespace)::RValueEmitter,
swift::Lowering::RValue, void, void, void, void, void,
swift::Lowering::SGFContext>::visit(swift::Expr*,
swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313
swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*,
swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3
swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*,
unsigned int) + 195
10 swift 0x00000001047077bd
swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void,
void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019
swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void,
void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba
swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775
swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*
)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322
swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous
namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e
swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*)
+ 30
17 swift 0x0000000104709093
swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*,
unsigned int) + 1795
18 swift 0x000000010470ad4d
swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&,
swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf
performCompile(swift::CompilerInstance&, swift::CompilerInvocation&,
llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5
swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*,
swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Patrice Kouame) #8

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

···

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Patrice Kouame) #9

Finally Success! I’m seeing my pretty little 3D twirling Metal Renderer cubes again… Here’s how

Snippet of old sample code which no longer compiles in Xcode 8 beta 6 with stricter Swift3 unsafe type casting restrictions
(in MetalView.swift from # Adopting Metal II: Designing and Implementing a Real-World Metal Renderer)

  let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
  let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
  mainPtr.pointee = mainPassFrameData
  var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))

My conversion attempt that crashes Swift 3 Xcode 8 beta 6 (see RADAR 28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE)

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<shadowPassData>.size)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
    $0.pointee = mainPassFrameData
  }
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout< ObjectData >.size) {$0}

Latest conversion that make Xcode and Swift 3 smile again...

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}
        mainPtr.pointee = mainPassFrameData
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {$0}

Yes… Xcode/Swift3 SIL generation definitely did NOT like my "$0.pointee = mainPassFrameData" statement.
Apparently, reassigning the pointee within the closure makes Swift gag out of disgust. Sorry ;-(
That’s what I get for trying to be fancy…
And fixed my “capacity” issues thanks to some previous posters.

Hope this helps anyone trying to get the Metal projects to compile again.

At least I got a Radar out of this :wink: Compilers should never burn and crash out like this...

Regards to all, Patrice

···

On Sep 3, 2016, at 1:22 PM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Patrice Kouame) #10

Not sure what you mean?
The positional arg $0 is never used outside the closure whatever the version...
No attempt is ever made to save and reuse after withMemoryRebound?
Why would I use a separate function?

Are we looking at the same code? :nerd_face:

rédigé sur mon iPhone.

···

On Sep 3, 2016, at 4:16 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Yikes! That's unsafe! When using withMemoryRebound, I think you're only supposed to use the argument $0 inside the block. Saving it and using it after withMemoryRebound is probably undefined behavior. But maybe you can move your ".pointee = x" into a separate function rather than using a closure?

On Sat, Sep 3, 2016 at 1:12 PM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:
Finally Success! I’m seeing my pretty little 3D twirling Metal Renderer cubes again… Here’s how

Snippet of old sample code which no longer compiles in Xcode 8 beta 6 with stricter Swift3 unsafe type casting restrictions
(in MetalView.swift from # Adopting Metal II: Designing and Implementing a Real-World Metal Renderer)

  let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
  let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
  mainPtr.pointee = mainPassFrameData
  var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))

My conversion attempt that crashes Swift 3 Xcode 8 beta 6 (see RADAR 28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE)

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<shadowPassData>.size)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
    $0.pointee = mainPassFrameData
  }
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout< ObjectData >.size) {$0}

Latest conversion that make Xcode and Swift 3 smile again...

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}
        mainPtr.pointee = mainPassFrameData
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {$0}

Yes… Xcode/Swift3 SIL generation definitely did NOT like my "$0.pointee = mainPassFrameData" statement.
Apparently, reassigning the pointee within the closure makes Swift gag out of disgust. Sorry ;-(
That’s what I get for trying to be fancy…
And fixed my “capacity” issues thanks to some previous posters.

Hope this helps anyone trying to get the Metal projects to compile again.

At least I got a Radar out of this :wink: Compilers should never burn and crash out like this...

Regards to all, Patrice

On Sep 3, 2016, at 1:22 PM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Jacob Bandes-Storch) #11

I was referring to this:

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced
(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}
        mainPtr.pointee = mainPassFrameData

The result of $0 is being returned from the block and used later.

cc'ing Andrew Trick on this conversation because his input would be quite
useful :slight_smile:

Jacob

···

On Sat, Sep 3, 2016 at 2:03 PM, Patrice Kouame <pkouame@me.com> wrote:

Not sure what you mean?
The positional arg $0 is never used outside the closure whatever the
version...
No attempt is ever made to save and reuse after withMemoryRebound?
Why would I use a separate function?

Are we looking at the same code? :nerd_face:

rédigé sur mon iPhone.

On Sep 3, 2016, at 4:16 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

Yikes! That's unsafe! When using withMemoryRebound, I think you're only
supposed to use the argument $0 inside the block. Saving it and using it
after withMemoryRebound is probably undefined behavior. But maybe you can
move your ".pointee = x" into a separate function rather than using a
closure?

On Sat, Sep 3, 2016 at 1:12 PM, Patrice Kouame via swift-users < > swift-users@swift.org> wrote:

Finally Success! I’m seeing my pretty little 3D twirling Metal Renderer
cubes again… Here’s how

Snippet of old sample code which no longer compiles in Xcode 8 beta 6
with stricter Swift3 unsafe type casting restrictions
(in MetalView.swift from # Adopting Metal II: Designing and Implementing
a Real-World Metal Renderer)

let shadowPtr = UnsafeMutablePointer<ShadowPas
>(constantBufferForFrame.contents())
let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
mainPtr.pointee = mainPassFrameData
var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))

My conversion attempt that crashes Swift 3 Xcode 8 beta 6 (see RADAR 28150447
- Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE)

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to:
ShadowPass.self, capacity: MemoryLayout<shadowPassData>.size)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by:
1).withMemoryRebound(to: MainPass.self, capacity: 1) {
$0.pointee = mainPassFrameData
}
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by:
1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout< Object
Data >.size) {$0}

Latest conversion that make Xcode and Swift 3 smile again...

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to:
ShadowPass.self, capacity: shadowPassData.count)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by:
1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}
        mainPtr.pointee = mainPassFrameData
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by:
1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {$0}

Yes… Xcode/Swift3 SIL generation definitely did NOT like my "$0.pointee =
mainPassFrameData" statement.
Apparently, reassigning the pointee within the closure makes Swift gag
out of disgust. Sorry ;-(
That’s what I get for trying to be fancy…
And fixed my “capacity” issues thanks to some previous posters.

Hope this helps anyone trying to get the Metal projects to compile again.

At least I got a Radar out of this :wink: Compilers should never burn and
crash out like this...

Regards to all, Patrice

On Sep 3, 2016, at 1:22 PM, Patrice Kouame via swift-users < >> swift-users@swift.org> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book
back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I
recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> =
withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity:
objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is
incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to
UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to
mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is
always a little bit tricky - the proposed Xcode fixes should always be
reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users < >> swift-users@swift.org> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the
other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com> a écrit :

Indeed. There is a difference between stride and size, but I interpreted
capacity incorrectly for my purposes. It should indicate the number of <T>
elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So
I filed this Apple radar against Developer Tools.

28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler
and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users < >> swift-users@swift.org> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes
it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users < >> swift-users@swift.org> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements
in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to:
ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to
MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> =
shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity:
1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of
renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> =
mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity:
objectsToRender) {_ in
}

There are surely ways to refactor and simplify this, but I’m trying to
retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting
the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m
not sure where to file this bug : Swift or Apple radar against Xcode or
both? I now Xcode 8 is beta but…it’s been doing this for quite a while
now...

In both our “close to the metal” (no pun intended) cases, it seems like a
lot of churning for very little gain. Don’t you think? The easier, but
“unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety
features. Guess we can’t have our cake and eat it too, especially when
interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com> >> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I
think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self,
capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass
elements in the buffer, not the size of each element. Using `bindMemory(to:
ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the
size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer
/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some
compiler (playground) crashes, but it does seem to work most of the time.
Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Me
talbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users < >> swift-users@swift.org> wrote:

Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and
Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest
UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their
sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer
to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the
correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPas
>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to:
ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to
MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by:
1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> =
shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self,
capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }

        //Advance and cast to ObjectData

// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by:
1))
        var ptr : UnsafeMutablePointer<ObjectData> =
mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self,
capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size +
shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size +
mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations:
objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/
60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/
60.0)
            }
        }

        ptr = ptr.advanced(by: objectsToRender)

        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if
necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d
PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous
namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous
namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1
prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7
swift::ASTVisitor<(anonymous namespace)::RValueEmitter,
swift::Lowering::RValue, void, void, void, void, void,
swift::Lowering::SGFContext>::visit(swift::Expr*,
swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313
swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*,
swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3
swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*,
unsigned int) + 195
10 swift 0x00000001047077bd
swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void,
void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019
swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void,
void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba
swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775
swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*
)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322
swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous
namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e
swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*)
+ 30
17 swift 0x0000000104709093
swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*,
unsigned int) + 1795
18 swift 0x000000010470ad4d
swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&,
swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf
performCompile(swift::CompilerInstance&, swift::CompilerInvocation&,
llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5
swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*,
swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Patrice Kouame) #12

Ok, I see.

But withMemoryRebound requires a return value. Don’t think there’s any way around that…compiler error
And mainPtr (now typed correctly/safely) needs to access the appropriate data structure mainPassFrameData.
Hence the external mainPtr.pointee assignment (since I can’t do so safely within the closure -> Swift compiler crashes)

Gerard Iglesias crafted another version of this snippet of code using assumingMemoryBound but also assigns pointee externally.
So did the original sample code.

Haven’t we achieved the goal of “safely" re-typing raw memory on the fly? To "help the compiler help us" so to speak…
What do you believe is so “unsafe" about the external pointee assignment? Since the compiler won’t let us do so anymore
If the types aren’t all correctly aligned.

Curious to see what Andrew Trick has to say about all of this. Good idea to cc: him

In the meantime, both versions seem to work. Plus am learning a lot about typed versus untyped memory access in Swift...

Best - Patrice

···

On Sep 3, 2016, at 9:27 PM, Jacob Bandes-Storch via swift-users <swift-users@swift.org> wrote:

I was referring to this:

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}
        mainPtr.pointee = mainPassFrameData

The result of $0 is being returned from the block and used later.

cc'ing Andrew Trick on this conversation because his input would be quite useful :slight_smile:

Jacob

On Sat, Sep 3, 2016 at 2:03 PM, Patrice Kouame <pkouame@me.com> wrote:

Not sure what you mean?
The positional arg $0 is never used outside the closure whatever the version...
No attempt is ever made to save and reuse after withMemoryRebound?
Why would I use a separate function?

Are we looking at the same code? :nerd_face:

rédigé sur mon iPhone.

On Sep 3, 2016, at 4:16 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Yikes! That's unsafe! When using withMemoryRebound, I think you're only supposed to use the argument $0 inside the block. Saving it and using it after withMemoryRebound is probably undefined behavior. But maybe you can move your ".pointee = x" into a separate function rather than using a closure?

On Sat, Sep 3, 2016 at 1:12 PM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:
Finally Success! I’m seeing my pretty little 3D twirling Metal Renderer cubes again… Here’s how

Snippet of old sample code which no longer compiles in Xcode 8 beta 6 with stricter Swift3 unsafe type casting restrictions
(in MetalView.swift from # Adopting Metal II: Designing and Implementing a Real-World Metal Renderer)

  let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
  let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
  mainPtr.pointee = mainPassFrameData
  var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))

My conversion attempt that crashes Swift 3 Xcode 8 beta 6 (see RADAR 28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE)

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<shadowPassData>.size)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
    $0.pointee = mainPassFrameData
  }
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout< ObjectData >.size) {$0}

Latest conversion that make Xcode and Swift 3 smile again...

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {$0}
        mainPtr.pointee = mainPassFrameData
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {$0}

Yes… Xcode/Swift3 SIL generation definitely did NOT like my "$0.pointee = mainPassFrameData" statement.
Apparently, reassigning the pointee within the closure makes Swift gag out of disgust. Sorry ;-(
That’s what I get for trying to be fancy…
And fixed my “capacity” issues thanks to some previous posters.

Hope this helps anyone trying to get the Metal projects to compile again.

At least I got a Radar out of this :wink: Compilers should never burn and crash out like this...

Regards to all, Patrice

On Sep 3, 2016, at 1:22 PM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Gerard Iglesias) #13

This is my funny version… I succeeded and I didn’t come back to find an other way…

// Grab a pointer to the constant buffer's data store
// Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
// We need to make a copy of these so the block captures the correct data
    
//let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
let shadowPtr = constantBufferForFrame.contents().assumingMemoryBound(to: ShadowPass.self)
shadowPtr.pointee = shadowPassData[0]
    
//More Swift specific stuff - advance pointer and cast to MainPass
    
//let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
let mainPtr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size).assumingMemoryBound(to: MainPass.self)
mainPtr.pointee = mainPassFrameData
    
//Advance and cast to ObjectData

//var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
var ptr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size + MemoryLayout<MainPass>.size).assumingMemoryBound(to: ObjectData.self)

···

On 3 Sep 2016, at 19:22, Patrice Kouame <pkouame@me.com> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Patrice Kouame) #14

Cool. Another approach. Never thought of using assumingMemoryBound.
Need to read up on that. I wonder how both versions compare from a safety/security/performance stand point.

Behold the spinning cubes… :wink:

P

···

On Sep 3, 2016, at 9:03 PM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

This is my funny version… I succeeded and I didn’t come back to find an other way…

// Grab a pointer to the constant buffer's data store
// Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
// We need to make a copy of these so the block captures the correct data
    
//let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
let shadowPtr = constantBufferForFrame.contents().assumingMemoryBound(to: ShadowPass.self)
shadowPtr.pointee = shadowPassData[0]
    
//More Swift specific stuff - advance pointer and cast to MainPass
    
//let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
let mainPtr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size).assumingMemoryBound(to: MainPass.self)
mainPtr.pointee = mainPassFrameData
    
//Advance and cast to ObjectData

//var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
var ptr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size + MemoryLayout<MainPass>.size).assumingMemoryBound(to: ObjectData.self)

On 3 Sep 2016, at 19:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Andrew Trick) #15

This is my funny version… I succeeded and I didn’t come back to find an other way…

// Grab a pointer to the constant buffer's data store
// Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
// We need to make a copy of these so the block captures the correct data
    
//let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
let shadowPtr = constantBufferForFrame.contents().assumingMemoryBound(to: ShadowPass.self)
shadowPtr.pointee = shadowPassData[0]
    
//More Swift specific stuff - advance pointer and cast to MainPass
    
//let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
let mainPtr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size).assumingMemoryBound(to: MainPass.self)
mainPtr.pointee = mainPassFrameData
    
//Advance and cast to ObjectData

//var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
var ptr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size + MemoryLayout<MainPass>.size).assumingMemoryBound(to: ObjectData.self)

Gerard,

I like your code. A couple of things to consider:

1. If the memory has never been bound to a type (i.e. it's straight from MTLBuffer.newBuffer), then rather than “assuming” memory is bound to these types, you should just bind it here (substitute all your assumingMemoryBound(to: _) with bindMemory(to: _, capacity: 1). Think of it as two-phase initialization of the memory. First declare the memory's type (e.g. some structure that holds a bunch of floats), then write individual float values into the memory.

2. If you want the compiler to compute byte offsets for you like the original code, then can be done as follows:

  let mainPtr = UnsafeMutableRawPointer(shadowPtr + 1).bindMemory(
  mainPtr.pointee = mainPassFrameData
  ...

However, your approach of computing byte offsets is more explicit.

My migration guide landed on swift.org today! I think it will be a big help.
https://swift.org/migration-guide/se-0107-migrate.html

-Andy

···

On Sep 3, 2016, at 6:03 PM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

    to: MainPass.self, capacity: 1)

On 3 Sep 2016, at 19:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Jacob Bandes-Storch) #16

My migration guide landed on swift.org today! I think it will be a big
help.
https://swift.org/migration-guide/se-0107-migrate.html

-Andy

Thanks Andy, this is great!

I hope that over time, even more accessible material is added for
newcomers. I still feel I would have a hard time answering the question of
what bindMemory "does", if someone asked me. My impression is that all
these methods are really just hints to the compiler about which kinds of
transformations/optimizations are allowed and which are not — making it
aware of aliasing.

The example below (from your proposal) is a good, practical showcase of
what might go wrong with aliasing. But what *should* this look like when
using the new API / how do the changes help prevent these problems? The
example shows only the "old version".

// --- old version ---func testUndefinedExecution() {
  let pA = UnsafeMutablePointer<A>.allocate(capacity: 1)
  pA[0] = A(value:42)
  if pA[0].value != 42 {
    // Code path should never execute...
    releaseDemons()
  }
  // This compiler may inline this, and hoist the store above the
  // previous check.
  unforeseenCode(pA)
}
func releaseDemons() {
  // Something that should never be executed...
}
func assignB(_ pB: UnsafeMutablePointer<B>) {
  pB[0] = B(value:13)
}
func unforeseenCode(_ pA: UnsafeMutablePointer<A>) {
  // At some arbitrary point in the future, the same memory is
  // innocuously assigned to B.
  assignB(UnsafeMutablePointer(pA))
}


(Gerard Iglesias) #17

Andrew,

Thank you for the compliment :wink:

And thank you for the 2 advices

And the question about use of size or stride ? I understand that the underlaying float data are aligned in this specific case, but I wonder in fact if the shader compiler align memory the same way the swift compiler do, I suppose yes unless it would be a nightmare, but murphy’s principle says me … take care :wink:

Thanks in advance

Gerard

···

On 8 Sep 2016, at 07:21, Andrew Trick <atrick@apple.com> wrote:

On Sep 3, 2016, at 6:03 PM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

This is my funny version… I succeeded and I didn’t come back to find an other way…

// Grab a pointer to the constant buffer's data store
// Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
// We need to make a copy of these so the block captures the correct data
    
//let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
let shadowPtr = constantBufferForFrame.contents().assumingMemoryBound(to: ShadowPass.self)
shadowPtr.pointee = shadowPassData[0]
    
//More Swift specific stuff - advance pointer and cast to MainPass
    
//let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
let mainPtr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size).assumingMemoryBound(to: MainPass.self)
mainPtr.pointee = mainPassFrameData
    
//Advance and cast to ObjectData

//var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
var ptr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size + MemoryLayout<MainPass>.size).assumingMemoryBound(to: ObjectData.self)

Gerard,

I like your code. A couple of things to consider:

1. If the memory has never been bound to a type (i.e. it's straight from MTLBuffer.newBuffer), then rather than “assuming” memory is bound to these types, you should just bind it here (substitute all your assumingMemoryBound(to: _) with bindMemory(to: _, capacity: 1). Think of it as two-phase initialization of the memory. First declare the memory's type (e.g. some structure that holds a bunch of floats), then write individual float values into the memory.

2. If you want the compiler to compute byte offsets for you like the original code, then can be done as follows:

  let mainPtr = UnsafeMutableRawPointer(shadowPtr + 1).bindMemory(
    to: MainPass.self, capacity: 1)
  mainPtr.pointee = mainPassFrameData
  ...

However, your approach of computing byte offsets is more explicit.

My migration guide landed on swift.org <http://swift.org/> today! I think it will be a big help.
https://swift.org/migration-guide/se-0107-migrate.html

-Andy

On 3 Sep 2016, at 19:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Andrew Trick) #18

Andrew,

Thank you for the compliment :wink:

And thank you for the 2 advices

And the question about use of size or stride ? I understand that the underlaying float data are aligned in this specific case, but I wonder in fact if the shader compiler align memory the same way the swift compiler do, I suppose yes unless it would be a nightmare, but murphy’s principle says me … take care :wink:

Always use stride for contiguous in-memory values.

-Andy

···

On Sep 8, 2016, at 4:04 AM, Gerard Iglesias <gerard_iglesias@me.com> wrote:

Thanks in advance

Gerard

On 8 Sep 2016, at 07:21, Andrew Trick <atrick@apple.com <mailto:atrick@apple.com>> wrote:

On Sep 3, 2016, at 6:03 PM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

This is my funny version… I succeeded and I didn’t come back to find an other way…

// Grab a pointer to the constant buffer's data store
// Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
// We need to make a copy of these so the block captures the correct data
    
//let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
let shadowPtr = constantBufferForFrame.contents().assumingMemoryBound(to: ShadowPass.self)
shadowPtr.pointee = shadowPassData[0]
    
//More Swift specific stuff - advance pointer and cast to MainPass
    
//let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
let mainPtr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size).assumingMemoryBound(to: MainPass.self)
mainPtr.pointee = mainPassFrameData
    
//Advance and cast to ObjectData

//var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
var ptr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size + MemoryLayout<MainPass>.size).assumingMemoryBound(to: ObjectData.self)

Gerard,

I like your code. A couple of things to consider:

1. If the memory has never been bound to a type (i.e. it's straight from MTLBuffer.newBuffer), then rather than “assuming” memory is bound to these types, you should just bind it here (substitute all your assumingMemoryBound(to: _) with bindMemory(to: _, capacity: 1). Think of it as two-phase initialization of the memory. First declare the memory's type (e.g. some structure that holds a bunch of floats), then write individual float values into the memory.

2. If you want the compiler to compute byte offsets for you like the original code, then can be done as follows:

  let mainPtr = UnsafeMutableRawPointer(shadowPtr + 1).bindMemory(
    to: MainPass.self, capacity: 1)
  mainPtr.pointee = mainPassFrameData
  ...

However, your approach of computing byte offsets is more explicit.

My migration guide landed on swift.org <http://swift.org/> today! I think it will be a big help.
https://swift.org/migration-guide/se-0107-migrate.html

-Andy

On 3 Sep 2016, at 19:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com <mailto:pkouame@me.com>> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Patrice Kouame) #19

Andy - yes thanks for the guidance and great job on your guide.
There's a lot to absorb there. I think the metal samples are another great use case for your new apis. I have a small side project in mind to
analyze its impact on performance, comparing the swift 3 compliant "safe" implementation versus straight objective-c.

P.

···

On Sep 8, 2016, at 1:35 PM, Andrew Trick via swift-users <swift-users@swift.org> wrote:

On Sep 8, 2016, at 4:04 AM, Gerard Iglesias <gerard_iglesias@me.com> wrote:

Andrew,

Thank you for the compliment :wink:

And thank you for the 2 advices

And the question about use of size or stride ? I understand that the underlaying float data are aligned in this specific case, but I wonder in fact if the shader compiler align memory the same way the swift compiler do, I suppose yes unless it would be a nightmare, but murphy’s principle says me … take care :wink:

Always use stride for contiguous in-memory values.

-Andy

Thanks in advance

Gerard

On 8 Sep 2016, at 07:21, Andrew Trick <atrick@apple.com> wrote:

On Sep 3, 2016, at 6:03 PM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

This is my funny version… I succeeded and I didn’t come back to find an other way…

// Grab a pointer to the constant buffer's data store
// Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
// We need to make a copy of these so the block captures the correct data
    
//let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
let shadowPtr = constantBufferForFrame.contents().assumingMemoryBound(to: ShadowPass.self)
shadowPtr.pointee = shadowPassData[0]
    
//More Swift specific stuff - advance pointer and cast to MainPass
    
//let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
let mainPtr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size).assumingMemoryBound(to: MainPass.self)
mainPtr.pointee = mainPassFrameData
    
//Advance and cast to ObjectData

//var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
var ptr = constantBufferForFrame.contents().advanced(by: MemoryLayout<ShadowPass>.size + MemoryLayout<MainPass>.size).assumingMemoryBound(to: ObjectData.self)

Gerard,

I like your code. A couple of things to consider:

1. If the memory has never been bound to a type (i.e. it's straight from MTLBuffer.newBuffer), then rather than “assuming” memory is bound to these types, you should just bind it here (substitute all your assumingMemoryBound(to: _) with bindMemory(to: _, capacity: 1). Think of it as two-phase initialization of the memory. First declare the memory's type (e.g. some structure that holds a bunch of floats), then write individual float values into the memory.

2. If you want the compiler to compute byte offsets for you like the original code, then can be done as follows:

  let mainPtr = UnsafeMutableRawPointer(shadowPtr + 1).bindMemory(
    to: MainPass.self, capacity: 1)
  mainPtr.pointee = mainPassFrameData
  ...

However, your approach of computing byte offsets is more explicit.

My migration guide landed on swift.org today! I think it will be a big help.
https://swift.org/migration-guide/se-0107-migrate.html

-Andy

On 3 Sep 2016, at 19:22, Patrice Kouame <pkouame@me.com> wrote:

Gerard-

Excellent! Looking forward to seeing your fix (hoping you get your book back soon :wink: )

I think Xcode/Swift gags on the last ptr advance to objectData. I recently tried another variant using withUnsafeMutablePointer like this:

        var ptr : UnsafeMutablePointer<ObjectData> = withUnsafeMutablePointer(to: &mainPtr) {
            $0.withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {
                $0.pointee = renderables[0].objectData
            }
        }

..but still crashes with no hints.

My bug report also mentions that the Xcode migration/conversion tool is incomplete.
It handles the “simpler" UnsafeMutableRawPointer<X> to UnsafeMutablePonter<Y> with bindMemory cases correctly (one still has to mind the capacity value though)
In all fairness, migrating/converting automagically in these cases is always a little bit tricky - the proposed Xcode fixes should always be reviewed by a human...

Patrice

On Sep 3, 2016, at 1:05 PM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

Ok

For the record I succeeded this transformation phase last week

I remember the tedious stuff to advance pointer from one struct to the other kind of struct... it worked

But I don't have my MacBook with me, only the phone, the six :slight_smile:

Gérard

Le 3 sept. 2016 à 18:22, Patrice Kouame <pkouame@me.com> a écrit :

Indeed. There is a difference between stride and size, but I interpreted capacity incorrectly for my purposes. It should indicate the number of <T> elements (not their size - right?) and the snippets below should work.

Still, compiler crashes and Xcode IDE is left in inconsistent state. So I filed this Apple radar against Developer Tools.

  28150447 - Swift 3 UnsafeMutablePointer conversion crashes the compiler and IDE
Should I file a Swift bug too? Would that be helpful?

Regards, Patrice

On Sep 3, 2016, at 11:39 AM, Gerard Iglesias via swift-users <swift-users@swift.org> wrote:

Hello,

I think that it is more secure to use stride in place of size, sometimes it is not the same value.

I use it in my own use of raw bindings

Regards

Gérard

Le 3 sept. 2016 à 10:03, Patrice Kouame via swift-users <swift-users@swift.org> a écrit :

Hi Jacob -

I think you’re right. “capacity” should be the count of type T elements in my buffer. So in my case that line should read

        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: shadowPassData.count)

The withMemoryRebound calls need similar adjustments. The pointer to MainPass is actually a single structure to it should be safe to do this

        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: 1) {
            $0.pointee = mainPassFrameData
        }

Whereas the unsafe pointer to <ObjectData> is actually a buffer of renderable objects, so this should work:

        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: objectsToRender) {_ in
  }

There are surely ways to refactor and simplify this, but I’m trying to retain as much of the original sample code approach as possible.

However, the compiler still segs badly.
Xcode also borks an internal error often. Only cleaning or restarting the project can clear up that state.
Compilers (or Playgrounds for that matter) should never crash, and I’m not sure where to file this bug : Swift or Apple radar against Xcode or both? I now Xcode 8 is beta but…it’s been doing this for quite a while now...

In both our “close to the metal” (no pun intended) cases, it seems like a lot of churning for very little gain. Don’t you think? The easier, but “unsafe” casting afforded previously did the trick with the normal caveats.
Don’t get me wrong, I love Swift and “get" all the neat type safety features. Guess we can’t have our cake and eat it too, especially when interfacing with “unsafe” C APIs.

Anyway, back to rtfm … maybe some of the Swift Gods can chime in? :wink:

I must be doing something stupid...Patrice

On Sep 3, 2016, at 2:32 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Hi Patrice,
I don't have a solution for you, but I just wanted to point out what I think may be an error with your use of the new UnsafeRawPointer APIs:

constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)

I believe the `capacity` should actually be the number of ShadowPass elements in the buffer, not the size of each element. Using `bindMemory(to: ShadowPass.self` already implies that MemoryLayout<ShadowPass>.size is the size of each element.

More info at https://developer.apple.com/reference/swift/unsaferawpointer/2428875-bindmemory

I just updated a small Metal project of mine to Swift 3. I ran into some compiler (playground) crashes, but it does seem to work most of the time. Although I only have 1 buffer :slight_smile: https://github.com/jtbandes/Metalbrot.playground

Jacob

On Fri, Sep 2, 2016 at 11:00 AM, Patrice Kouame via swift-users <swift-users@swift.org> wrote:
Hi all -

I’m converting Apple’s Swift Sample "Adopting Metal II: Designing and Implementing a Real-World Metal Renderer” in Xcode 8 beta6 to the latest UnsafeMutablePointer API for untyped memory access.
Changes are necessary in MetalView.swift (Apple hasn’t updated their sample code for the latest beta yet…)
The Swift Compiler crashes (Segmentation Fault: 11) on the attempt:

        // Grab a pointer to the constant buffer's data store
        // Since we are using Swift, it is easier to cast the pointer to the ShadowPass type to fill the constant buffer
        // We need to make a copy of these so the block captures the correct data

// let shadowPtr = UnsafeMutablePointer<ShadowPass>(constantBufferForFrame.contents())
        let shadowPtr = constantBufferForFrame.contents().bindMemory(to: ShadowPass.self, capacity: MemoryLayout<ShadowPass>.size)
        shadowPtr.pointee = shadowPassData[0]

        //More Swift specific stuff - advance pointer and cast to MainPass

// let mainPtr = UnsafeMutablePointer<MainPass>(shadowPtr.advanced(by: 1))
// mainPtr.pointee = mainPassFrameData
        let mainPtr : UnsafeMutablePointer<MainPass> = shadowPtr.advanced(by: 1).withMemoryRebound(to: MainPass.self, capacity: MemoryLayout<MainPass>.size) {
            $0.pointee = mainPassFrameData
        }
        
        //Advance and cast to ObjectData
        
// var ptr = UnsafeMutablePointer<ObjectData>(mainPtr.advanced(by: 1))
        var ptr : UnsafeMutablePointer<ObjectData> = mainPtr.advanced(by: 1).withMemoryRebound(to: ObjectData.self, capacity: MemoryLayout<ObjectData>.size) {_ in
        }

        let shadowOffset = 0
        let mainPassOffset = MemoryLayout<ShadowPass>.size + shadowOffset
        let objectDataOffset = MemoryLayout<MainPass>.size + mainPassOffset

        // Update position of all the objects
        if multithreadedUpdate {
            DispatchQueue.concurrentPerform(iterations: objectsToRender) { i in
                let thisPtr = ptr.advanced(by: i)
                _ = self.renderables[i].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        else {
            for index in 0..<objectsToRender {
                ptr = renderables[index].UpdateData(ptr, deltaTime: 1.0/60.0)
            }
        }
        
        ptr = ptr.advanced(by: objectsToRender)
        
        _ = groundPlane!.UpdateData(ptr, deltaTime: 1.0/60.0)

Any help is appreciated. I have the latest Xcode log handy if necessary. Here’s a clip of the stack trace.

0 swift 0x000000010714a99d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x000000010714a3e6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fff91461bba _sigtramp + 26
3 libsystem_platform.dylib 000000000000000000 _sigtramp + 1857676384
4 swift 0x00000001047207b3 (anonymous namespace)::SILGenApply::visitExpr(swift::Expr*) + 51
5 swift 0x0000000104723ace (anonymous namespace)::SILGenApply::visitApplyExpr(swift::ApplyExpr*) + 5182
6 swift 0x0000000104711cc1 prepareApplyExpr(swift::Lowering::SILGenFunction&, swift::Expr*) + 273
7 swift 0x00000001047624e7 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 103
8 swift 0x0000000104762313 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 195
9 swift 0x000000010474fbc3 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 195
10 swift 0x00000001047077bd swift::ASTVisitor<swift::Lowering::SILGenFunction, void, void, void, void, void, void>::visit(swift::Decl*) + 125
11 swift 0x00000001047c0019 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4169
12 swift 0x00000001047809ba swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 314
13 swift 0x00000001046fd775 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1877
14 swift 0x00000001046fc322 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 626
15 swift 0x00000001047c7007 (anonymous namespace)::SILGenType::emitType() + 1271
16 swift 0x00000001047c6a9e swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 30
17 swift 0x0000000104709093 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1795
18 swift 0x000000010470ad4d swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1629
19 swift 0x00000001045621bf performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 19487
20 swift 0x000000010455b2c5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
21 swift 0x000000010451888d main + 8685
22 libdyld.dylib 0x00007fff91255255 start + 1

Patrice

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users