metal

Error loading default Metal library for command line Swift tool


The Metal framework function MTLLibrary.makeDefaultLibrary() loads "your app’s default Metal library." However, it doesn't specify where it finds this default library.

When I build an example command line project, like marzvrover/Performing-Calculations-on-a-GPU, Xcode creates the file default.metallib alongside the executable. This file needs to be present or makeDefaultLibrary() fails.

I am trying to build my own project from the command line using swiftc and the Metal command line tools directly. when I build my own project from the command line, I link my compiled shaders together into default.metallib:

$ xcrun -sdk macosx metal -c add.metal -o add.ir
$ xcrun -sdk macosx metal-ar r default.metallib add.ir
$ swiftc -framework Metal -o tool main.swift

Yet, makeDefaultLibrary() is still failing. Why can it be loaded by a program built by Xcode, but not my program compiled "manually"?


Solution

  • The MTLDevice.makeDefaultLibrary(bundle:) function will throw an error which describes the problem. If I switch to this code, I can see the error message:

    do {
        try self.device.makeDefaultLibrary(bundle: Bundle.main)
    } catch {
        print("Unexpected error: \(error)")
    }
    

    If the file is missing, the error is:

    Error Domain=MTLLibraryErrorDomain Code=6 "no default library was found" UserInfo={NSLocalizedDescription=no default library was found}

    However in my case, it was telling me the file is invalid:

    Error Domain=MTLLibraryErrorDomain Code=1 "Invalid library file" UserInfo={NSLocalizedDescription=Invalid library file}

    The problem was because I produced an invalid .metallib file with the metal-ar — which outputs archives, not libraries — instead of metallib. See Building a Shader Library by Precompiling Source File.

     $ xcrun -sdk macosx metal -c add.metal -o add.ir
    +$ xcrun -sdk macosx metallib -o default.metallib add.ir
     $ swiftc -framework Metal -o tool main.swift