// device
//
+enum ggml_metal_device_id {
+ GGML_METAL_DEVICE_GENERIC = 0,
+
+ GGML_METAL_DEVICE_M1,
+ GGML_METAL_DEVICE_M1_PRO,
+ GGML_METAL_DEVICE_M1_MAX,
+ GGML_METAL_DEVICE_M1_ULTRA,
+ GGML_METAL_DEVICE_M2,
+ GGML_METAL_DEVICE_M2_PRO,
+ GGML_METAL_DEVICE_M2_MAX,
+ GGML_METAL_DEVICE_M2_ULTRA,
+ GGML_METAL_DEVICE_M3,
+ GGML_METAL_DEVICE_M3_PRO,
+ GGML_METAL_DEVICE_M3_MAX,
+ GGML_METAL_DEVICE_M3_ULTRA,
+ GGML_METAL_DEVICE_M4,
+ GGML_METAL_DEVICE_M4_PRO,
+ GGML_METAL_DEVICE_M4_MAX,
+ GGML_METAL_DEVICE_M5,
+ GGML_METAL_DEVICE_M5_PRO,
+ GGML_METAL_DEVICE_M5_MAX,
+ GGML_METAL_DEVICE_M5_ULTRA,
+};
+
struct ggml_metal_device_props {
int device;
char name[128];
bool supports_gpu_family_apple7;
+ enum ggml_metal_device_id device_id;
+
int op_offload_min_batch_size;
};
free(rsets);
}
+static enum ggml_metal_device_id ggml_metal_device_id_parse(const char * name) {
+ if (!name) {
+ return GGML_METAL_DEVICE_GENERIC;
+ }
+
+ static const char prefix[] = "Apple ";
+ if (strncmp(name, prefix, sizeof(prefix) - 1) != 0) {
+ return GGML_METAL_DEVICE_GENERIC;
+ }
+ const char * suffix = name + sizeof(prefix) - 1;
+
+ static const struct {
+ const char * name;
+ enum ggml_metal_device_id id;
+ } table[] = {
+ {"M1", GGML_METAL_DEVICE_M1},
+ {"M1 Pro", GGML_METAL_DEVICE_M1_PRO},
+ {"M1 Max", GGML_METAL_DEVICE_M1_MAX},
+ {"M1 Ultra", GGML_METAL_DEVICE_M1_ULTRA},
+ {"M2", GGML_METAL_DEVICE_M2},
+ {"M2 Pro", GGML_METAL_DEVICE_M2_PRO},
+ {"M2 Max", GGML_METAL_DEVICE_M2_MAX},
+ {"M2 Ultra", GGML_METAL_DEVICE_M2_ULTRA},
+ {"M3", GGML_METAL_DEVICE_M3},
+ {"M3 Pro", GGML_METAL_DEVICE_M3_PRO},
+ {"M3 Max", GGML_METAL_DEVICE_M3_MAX},
+ {"M3 Ultra", GGML_METAL_DEVICE_M3_ULTRA},
+ {"M4", GGML_METAL_DEVICE_M4},
+ {"M4 Pro", GGML_METAL_DEVICE_M4_PRO},
+ {"M4 Max", GGML_METAL_DEVICE_M4_MAX},
+ {"M5", GGML_METAL_DEVICE_M5},
+ {"M5 Pro", GGML_METAL_DEVICE_M5_PRO},
+ {"M5 Max", GGML_METAL_DEVICE_M5_MAX},
+ {"M5 Ultra", GGML_METAL_DEVICE_M5_ULTRA},
+ };
+
+ for (size_t i = 0; i < sizeof(table)/sizeof(table[0]); ++i) {
+ if (strcmp(suffix, table[i].name) == 0) {
+ return table[i].id;
+ }
+ }
+ return GGML_METAL_DEVICE_GENERIC;
+}
+
ggml_metal_device_t ggml_metal_device_init(int device) {
ggml_metal_device_t dev = calloc(1, sizeof(struct ggml_metal_device));
dev->props.supports_gpu_family_apple7 = [dev->mtl_device supportsFamily:MTLGPUFamilyApple7];
+ dev->props.device_id = ggml_metal_device_id_parse([[dev->mtl_device name] UTF8String]);
+
dev->props.op_offload_min_batch_size = getenv("GGML_OP_OFFLOAD_MIN_BATCH") ? atoi(getenv("GGML_OP_OFFLOAD_MIN_BATCH")) : 32;
dev->props.max_buffer_size = dev->mtl_device.maxBufferLength;