'Metal kernel function not found

I am trying to use Metal Performance Shaders with Core Image.

Unfortunately, the filter code is in Objective C and I am using the bridge to make it work with the Swift project.

My-Project-Bridging-Header.h

#import "MyCustomFilter.h"

MyCustomFilter.h

#import <CoreImage/CoreImage.h>

@interface MyCustomFilter : CIFilter
......
@end

MyCustomFilter.m

#import "MyCustomFilter.h"
#import "MyCustomFilterKernel.h"

.......

MyCustomFilterKernel.h

#import <CoreImage/CoreImage.h>

@interface MyCustomFilterKernel : CIImageProcessorKernel

@end

MyCustomFilterKernel.m

#import "FTWaveformScopeKernel.h"
#import "FTWaveformScopeFilter.h"

#import <Metal/Metal.h>

    ...

+ (void) initialize {
 id<MTLFunction> customFunction = [defaultLibrary newFunctionWithName:@"custom_Function"];
 if (customFunction) {
  NSError* error;
  kCustomComputePipelineState = [kDevice newComputePipelineStateWithFunction: customFunction error:&error];
  if (error) {
    NSLog(@"error loading kernel function (custom_Function): %@", error);
  } 
 } else {
     NSLog(@"kernel function (custom_Function) not found");
 }

CustomFunction.metal

    #include <metal_stdlib>
    using namespace metal;
   
    ......

    kernel void
    custom_Function(texture2d<float, access::sample>        inTexture       [[texture(0)]],
                        texture2d<float, access::write>         outTexture      [[texture(1)]],
                        volatile device atomic_uint*            columnDataRed   [[buffer(0)]],
                        volatile device atomic_uint*            columnDataGreen [[buffer(1)]],
                        volatile device atomic_uint*            columnDataBlue  [[buffer(2)]],
                        sampler                                 wrapSampler     [[sampler(0)]],
                        uint2                                   gid                       
                        [[thread_position_in_grid]])
{

........

}

The error I get is (with the metal view being blank/transparent):

kernel function (custom_Function) not found

I've also done:

enter image description here

I am dealing with Xcode 12.x. The above code compiles and runs.

UPDATE

After that first reply, I followed the new Xcode 12 and later settings: https://developer.apple.com/videos/play/wwdc2020/10021/

  1. Changed CustomFunction.metal in to CustomFunction.ci.metal

  2. Added the first rule: enter image description here

  3. Added the third rule: enter image description here

Now the project does not compile:

LLVM ERROR: Error opening 

    /Users/xxxxxx/Library/Developer/Xcode/DerivedData/xxxxxx-ggaphqixkeecbkewrntvhssdgnac/Build/Intermediates.noindex/xxxxxx.build/Debug-iphoneos/xxxxxx.build/DerivedSources/CustomFunction.ci.air': No such file or directory!
    Command RuleScriptExecution failed with a nonzero exit code


RuleScriptExecution /Users/xxxx/Library/Developer/Xcode/DerivedData/xxxx-ggaphqixkeecbkewrntvhssdgnac/Build/Products/Debug-iphoneos/xxxx\ xxxx.app/CustomFunction.ci.metallib /Users/xxxx/Library/Developer/Xcode/DerivedData/xxxx-xxxx-ggaphqixkeecbkewrntvhssdgnac/Build/Intermediates.noindex/xxxx-xxxx.build/Debug-iphoneos/xxxx-xxxx.build/DerivedSources/CustomFunction.ci.air normal undefined_arch (in target 'xxxx-xxxx' from project 'xxxx-xxxx')
    cd /Users/xxxx/Desktop/xxxx-xxxx\ CustomFunction
    /bin/sh -c xcrun\ metallib\ -cikernel\ \"\$\{INPUT_FILE_PATH\}\"\ -o\ \"\$\{SCRIPT_OUTPUT_FILE_0\}\"'
'

These are the two lines in text:

xcrun metallib -cikernel "${INPUT_FILE_PATH}" -o "${SCRIPT_OUTPUT_FILE_0}"

xcrun metal -c -I $MTL_HEADER_SEARCH_PATHS -fcikernel  "${INPUT_FILE_PATH}" -o "${SCRIPT_OUPUT_FILE_0}"

Since I had to type these looking at a screenshot, maybe I made a mistake interpreting? There is a double space after -fcikernel?



Solution 1:[1]

The Metal toolchain changed in Xcode 12. The above linker flags no longer work since the default toolchain no longer uses the metallib linker.

Please check out David's talk from WWDC 2020 on how to properly set up the build system for compiling custom Core Image kernels.

Solution 2:[2]

There is indeed a typo in your script (missing T in SCRIPT_OUPUT_FILE_0)

I copied your script and got same error. Once typo was corrected, the app built successfully. The corrected script text follows...

xcrun metal -c -I $MTL_HEADER_SEARCH_PATHS -fcikernel "${INPUT_FILE_PATH}" -o "${SCRIPT_OUTPUT_FILE_0}"

xcrun metallib -cikernel "${INPUT_FILE_PATH}" -o "${SCRIPT_OUTPUT_FILE_0}"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Frank Schlegel
Solution 2 gpdawson