User defined. What I typically do is 1) add some sensible defaults to the top of my shader code so that I can use a precompiled library if I choose:
#ifndef THREADS_PER_THREADGROUP
#define THREADS_PER_THREADGROUP (256)
#endif
#ifndef VALUES_PER_THREAD
#define VALUES_PER_THREAD (4)
#endif
and 2) when I want to compile a custom library at compile time, do that via compilation options:
MTLCompileOptions* options = [[MTLCompileOptions alloc] init];
options.preprocessorMacros = @{@"THREADS_PER_THREADGROUP" : @(threadsPerThreadgroup),
@"VALUES_PER_THREAD" : @(valuesPerThread)};
id<MTLLibrary> library = [self.device newLibraryWithSource:sourceString options:options error:&error];
This way, I can have a different, optimized set of parameters if I am on an architecture where 256X4 isn't the fastest...
Thanks for reading!