@@ -404,6 +404,64 @@ bool ggml_numa_apply_kernel_force_strategy(ggml_numa_kernel_query_result_t * res
404404 } \
405405} while(0)
406406
407+ /**
408+ * NUMA_REGISTER_SYMLINK_KERNEL - Macro to register one operation as a symlink to another
409+ *
410+ * This macro allows one operation to use another operation's kernel implementation.
411+ * Perfect for cases like CONT → CPY where operations have identical underlying logic.
412+ *
413+ * @param symlink_kname - The operation to create a symlink for (e.g., cont)
414+ * @param target_kname - The target operation to symlink to (e.g., cpy)
415+ * @param symlink_op_type - The GGML operation type constant for the symlink (e.g., GGML_OP_CONT)
416+ *
417+ * Usage example:
418+ * NUMA_REGISTER_SYMLINK_KERNEL(cont, cpy, GGML_OP_CONT);
419+ *
420+ * This will register GGML_OP_CONT to use the CPY kernel's functions.
421+ * The target kernel must already be registered.
422+ */
423+ #define NUMA_REGISTER_SYMLINK_KERNEL (symlink_kname , target_kname , symlink_op_type ) do { \
424+ /* Get the target kernel's registration info */ \
425+ ggml_numa_kernel_registration_info_t target_info = ggml_numa_kernel_##target_kname##_register(); \
426+ ggml_numa_kernel_query_fn_t target_query_fn = ggml_numa_kernel_##target_kname##_query; \
427+ ggml_numa_kernel_work_buffer_calc_fn_t target_work_buffer_fn = NULL; \
428+ /* Check if target kernel provides work buffer calculation function */ \
429+ if (target_info .work_buffer_calc_fn != NULL ) { \
430+ target_work_buffer_fn = target_info .work_buffer_calc_fn ; \
431+ } \
432+ /* Create symlink registration info using target's functions but symlink's operation type */ \
433+ ggml_numa_kernel_registration_info_t symlink_info = {0 }; /* Initialize to zero */ \
434+ symlink_info .op_type = symlink_op_type ; /* Use the provided operation type */ \
435+ symlink_info .strategy_array = target_info .strategy_array ; \
436+ symlink_info .work_funcs = target_info .work_funcs ; \
437+ symlink_info .agg_funcs = target_info .agg_funcs ; \
438+ symlink_info .work_buffer_calc_fn = target_info .work_buffer_calc_fn ; \
439+ symlink_info .supported = target_info .supported ; \
440+ symlink_info .is_noop = target_info .is_noop ; \
441+ snprintf (symlink_info .kernel_name , sizeof (symlink_info .kernel_name ), "NUMA %s → %s Symlink" , \
442+ #symlink_kname , #target_kname ); \
443+ /* Register the symlink using target's functions */ \
444+ enum ggml_status symlink_result = ggml_numa_register_kernel_strategy ( \
445+ symlink_info .op_type , & target_info .strategy_array , \
446+ & target_info .work_funcs , & target_info .agg_funcs , target_query_fn , target_work_buffer_fn , \
447+ target_info .supported , target_info .is_noop ); \
448+ if (symlink_result != GGML_STATUS_SUCCESS ) { \
449+ NUMA_LOG_ERROR ("Failed to register " #symlink_kname " → " #target_kname " symlink"); \
450+ return symlink_result; \
451+ } \
452+ if (target_info.supported) { \
453+ NUMA_LOG_DEBUG("🔗 Symlinked %s → %s (thresholds: %zu/%zu%s%s)", \
454+ #symlink_kname, #target_kname, \
455+ target_info.strategy_array.thresholds[NUMA_STRATEGY_IDX_SINGLE_SINGLE], \
456+ target_info.strategy_array.thresholds[NUMA_STRATEGY_IDX_SINGLE_MULTI], \
457+ target_info.is_noop ? ", no-op" : "", \
458+ target_work_buffer_fn ? ", work-buffer" : ""); \
459+ } else { \
460+ NUMA_LOG_DEBUG("🚫 Disabled symlink %s → %s (target marked as unsupported)", \
461+ #symlink_kname, #target_kname); \
462+ } \
463+ } while(0)
464+
407465// =============================================================================
408466// SHARED KERNEL FUNCTION MACROS - Eliminate Code Duplication
409467// =============================================================================
0 commit comments