无法使用Swift在Metal中加载默认库

时间:2017-04-12 12:02:22

标签: swift initialization shader metal

对于我的项目(编译为框架),我有一个文件kernel void add(device float *lhs [[buffer(0)]], device float *rhs [[buffer(1)]], device float *result [[buffer(2)]], uint id [[ thread_position_in_grid ]]) { result[id] = lhs[id] + rhs[id]; }

@available(OSX 10.11, *)
public class MTLContext {
    var device: MTLDevice!
    var commandQueue:MTLCommandQueue!
    var library:MTLLibrary!
    var commandBuffer:MTLCommandBuffer
    var commandEncoder:MTLComputeCommandEncoder

    init() {
        if let defaultDevice = MTLCreateSystemDefaultDevice() {
            device = defaultDevice
            print("device created")
        } else {
            print("Metal is not supported")
        }

        commandQueue = device.makeCommandQueue()

        library = device.newDefaultLibrary()
        if let defaultLibrary = device.newDefaultLibrary() {
            library = defaultLibrary
        } else {
            print("could not load default library")
        }

        commandBuffer = commandQueue.makeCommandBuffer()
        commandEncoder = commandBuffer.makeComputeCommandEncoder()
    }

    deinit {
        commandEncoder.endEncoding()
    }
}

以及以下Swift代码:

MTLContext

当我尝试在单元测试中创建could not load default library的实例时,会创建设备,但无法创建默认库(" default.metallib")。我已经检查过编译的框架在Resources中有一个newDefaultLibrary(这是kernel给出的最常见原因)。

不幸的是,我还没有找到任何在Metal Shader文件中创建计算Error is: "weblogic.application.ModuleException: java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger" weblogic.application.ModuleException: java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger at weblogic.application.internal.ExtensibleModuleWrapper.prepare(ExtensibleModuleWrapper.java:114) at weblogic.application.internal.flow.ModuleListenerInvoker.prepare(ModuleListenerInvoker.java:100) at weblogic.application.internal.flow.ModuleStateDriver$1.next(ModuleStateDriver.java:192) at weblogic.application.internal.flow.ModuleStateDriver$1.next(ModuleStateDriver.java:187) at weblogic.application.utils.StateMachineDriver$ParallelChange.run(StateMachineDriver.java:83) Truncated. see log file for complete stacktrace Caused By: java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericClassLoader.java:1026) at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoader.java:987) at weblogic.utils.classloaders.ChangeAwareClassLoader.findClass(ChangeAwareClassLoader.java:83) at weblogic.utils.classloaders.GenericClassLoader.doFindClass(GenericClassLoader.java:608) at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:540) Truncated. see log file for complete stacktrace weblogic.application.ModuleException: java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger at weblogic.application.internal.ExtensibleModuleWrapper.prepare(ExtensibleModuleWrapper.java:114) at weblogic.application.internal.flow.ModuleListenerInvoker.prepare(ModuleListenerInvoker.java:100) at weblogic.application.internal.flow.ModuleStateDriver$1.next(ModuleStateDriver.java:192) at weblogic.application.internal.flow.ModuleStateDriver$1.next(ModuleStateDriver.java:187) at weblogic.application.utils.StateMachineDriver$ParallelChange.run(StateMachineDriver.java:83) Truncated. see log file for complete stacktrace Caused By: java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericClassLoader.java:1026) at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoader.java:987) at weblogic.utils.classloaders.ChangeAwareClassLoader.findClass(ChangeAwareClassLoader.java:83) at weblogic.utils.classloaders.GenericClassLoader.doFindClass(GenericClassLoader.java:608) at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:540) Truncated. see log file for complete stacktrace 的工作示例(有一些使用性能着色器的示例,但它们没有需要在着色器文件中创建内核。)

任何建议都将不胜感激!

1 个答案:

答案 0 :(得分:5)

newDefaultLibrary()从当前运行的应用程序的 main 包中加载。它不会搜索任何嵌入式框架或其他库的位置。

如果要使用编译为嵌入式框架的metallib,最简单的方法是获取对其包含Bundle的引用,并要求该包的默认库:

let frameworkBundle = Bundle(for: SomeClassFromMyShaderFramework.self)
guard let defaultLibrary = try? device.makeDefaultLibrary(bundle: frameworkBundle) else {
    fatalError("Could not load default library from specified bundle")
}

这确实要求在包含着色器的框架中至少有一个公开可见的类,但这可以像为了进行bundle查找而严格声明一个空类一样简单:

public class SomeClassFromMyShaderFramework {}