#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ds4_gpu.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #define CUDA_QK_K 256 #define DS4_CUDA_UNUSED __attribute__((unused)) enum { /* attention_decode_mixed_kernel stores raw-window scores plus visible * compressed scores in shared memory. The host routes larger unmasked * decode calls to the online attention kernel so this fixed buffer never * becomes an out-of-bounds write at long context. */ DS4_CUDA_ATTENTION_SCORE_CAP = 8192u, DS4_CUDA_ATTENTION_RAW_SCORE_CAP = 256u, DS4_CUDA_TOPK_MERGE_GROUP = 8u, DS4_CUDA_STREAM_EXPERT_DEFAULT = 8u * 64u, DS4_CUDA_STREAM_EXPERT_MAX = 61u * 384u }; struct ds4_gpu_tensor { void *ptr; uint64_t bytes; int owner; }; typedef struct { uint8_t scales[CUDA_QK_K / 16]; uint8_t qs[CUDA_QK_K / 4]; uint16_t d; uint16_t dmin; } cuda_block_q2_K; typedef struct { uint16_t d; uint16_t dmin; uint8_t scales[12]; uint8_t qs[CUDA_QK_K / 2]; } cuda_block_q4_K; typedef struct { float d; int8_t qs[CUDA_QK_K]; int16_t bsums[CUDA_QK_K / 16]; } cuda_block_q8_K; typedef struct { uint16_t d; uint16_t qs[CUDA_QK_K / 8]; } cuda_block_iq2_xxs; #include "ds4_iq2_tables_cuda.inc" static const void *g_model_host_base; static const char *g_model_device_base; static uint64_t g_model_registered_size; static int g_model_registered; static int g_model_device_owned; static int g_model_range_mapping_supported = 1; static int g_model_hmm_direct; static int g_model_fd = -1; static const void *g_model_fd_host_base; static int g_model_direct_fd = -1; static uint64_t g_model_direct_align = 1; static uint64_t g_model_file_size; static int g_model_cache_full; static int g_model_mapping_failure_notice_printed; static cudaStream_t g_model_prefetch_stream; static cudaStream_t g_model_upload_stream; static cublasHandle_t g_cublas; static int g_cublas_ready; static int g_quality_mode; static int g_ssd_streaming_mode; struct cuda_model_range { const void *host_base; uint64_t offset; uint64_t bytes; char *device_ptr; void *registered_base; char *registered_device_base; uint64_t registered_bytes; int host_registered; int arena_allocated; }; struct cuda_model_arena { char *device_ptr; uint64_t bytes; uint64_t used; }; struct cuda_q8_f16_range { const void *host_base; uint64_t offset; uint64_t weight_bytes; uint64_t in_dim; uint64_t out_dim; __half *device_ptr; }; struct cuda_q8_f32_range { const void *host_base; uint64_t offset; uint64_t weight_bytes; uint64_t in_dim; uint64_t out_dim; float *device_ptr; }; struct cuda_stream_selected_cache { int valid; const void *model_map; uint32_t layer; uint32_t n_total_expert; uint32_t n_selected; uint32_t slot_count; uint32_t compact_count; uint64_t gate_offset; uint64_t up_offset; uint64_t down_offset; uint64_t gate_expert_bytes; uint64_t down_expert_bytes; char *gate_ptr; char *up_ptr; char *down_ptr; uint64_t gate_capacity; uint64_t up_capacity; uint64_t down_capacity; int32_t *slot_selected_ptr; uint64_t slot_selected_capacity; ds4_gpu_tensor slot_selected_tensor; }; struct cuda_stream_expert_cache_slot { int valid; const void *model_map; uint64_t model_size; uint32_t layer; uint32_t n_total_expert; uint32_t expert; uint64_t gate_offset; uint64_t up_offset; uint64_t down_offset; uint64_t gate_expert_bytes; uint64_t down_expert_bytes; uint64_t age; }; struct cuda_stream_expert_cache { int valid; uint32_t capacity; uint32_t count; uint64_t tick; uint64_t gate_expert_bytes; uint64_t down_expert_bytes; char *gate_ptr; char *up_ptr; char *down_ptr; uint64_t gate_capacity; uint64_t up_capacity; uint64_t down_capacity; std::vector slots; }; static std::vector g_model_ranges; static std::vector g_model_arenas; static std::unordered_map g_model_range_by_offset; static std::vector g_q8_f16_ranges; static std::unordered_map g_q8_f16_by_offset; static std::vector g_q8_f32_ranges; static std::unordered_map g_q8_f32_by_offset; static cuda_stream_selected_cache g_stream_selected_cache; static cuda_stream_expert_cache g_stream_expert_cache; static uint32_t g_stream_expert_budget_override; static uint32_t g_stream_expert_runtime_cap; static uint32_t g_stream_expert_memory_cap_notice; static uint64_t g_stream_expert_runtime_gate_bytes; static uint64_t g_stream_expert_runtime_down_bytes; static uint64_t g_model_range_bytes; static uint64_t g_q8_f16_bytes; static uint64_t g_q8_f32_bytes; static int g_q8_f16_disabled_after_oom; static int g_q8_f16_budget_notice_printed; static uint64_t g_model_load_progress_next; static uint64_t g_model_load_progress_last_bytes = UINT64_MAX; static uint64_t g_model_load_progress_last_cgib = UINT64_MAX; static double g_model_load_progress_last; static int g_model_load_progress_started; static int g_model_load_progress_tty; static void *g_cuda_tmp; static uint64_t g_cuda_tmp_bytes; static void *g_model_stage_raw[4]; static void *g_model_stage[4]; static cudaEvent_t g_model_stage_event[4]; static uint64_t g_model_stage_bytes; static void *g_stream_selected_stage_raw[4]; static void *g_stream_selected_stage[4]; static cudaEvent_t g_stream_selected_stage_event[4]; static uint64_t g_stream_selected_stage_bytes; static cudaStream_t g_stream_selected_upload_stream; static int cuda_ok(cudaError_t err, const char *what); static const char *cuda_model_range_ptr_from_fd( const void *model_map, uint64_t offset, uint64_t bytes, const char *what); static const char *cuda_model_direct_fallback_ptr(const void *model_map, uint64_t offset); static int cuda_model_copy_to_device_streamed( char *dst, const void *model_map, uint64_t model_size, uint64_t offset, uint64_t bytes, const char *what); static uint64_t cuda_model_cache_limit_bytes(void); static uint64_t cuda_model_local_model_limit_bytes(void); static int cuda_model_cache_limit_explicit(void); __global__ static void dequant_q8_0_to_f16_kernel( __half *out, const unsigned char *w, uint64_t in_dim, uint64_t out_dim, uint64_t blocks); __global__ static void dequant_q8_0_to_f32_kernel( float *out, const unsigned char *w, uint64_t in_dim, uint64_t out_dim, uint64_t blocks); static void *cuda_tmp_alloc(uint64_t bytes, const char *what) { if (bytes == 0) return NULL; if (g_cuda_tmp_bytes >= bytes) return g_cuda_tmp; if (g_cuda_tmp) { (void)cudaFree(g_cuda_tmp); g_cuda_tmp = NULL; g_cuda_tmp_bytes = 0; } void *ptr = NULL; cudaError_t err = cudaMalloc(&ptr, (size_t)bytes); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA temp alloc failed for %s (%.2f MiB): %s\n", what ? what : "scratch", (double)bytes / 1048576.0, cudaGetErrorString(err)); (void)cudaGetLastError(); return NULL; } g_cuda_tmp = ptr; g_cuda_tmp_bytes = bytes; return g_cuda_tmp; } static int cuda_attention_score_buffer_fits(uint32_t n_comp) { return n_comp <= DS4_CUDA_ATTENTION_SCORE_CAP - DS4_CUDA_ATTENTION_RAW_SCORE_CAP; } static const char *cuda_model_ptr(const void *model_map, uint64_t offset) { if (model_map == g_model_host_base && g_model_device_base) return g_model_device_base + offset; return (const char *)model_map + offset; } static const char *cuda_model_range_register_mapped(const void *model_map, uint64_t offset, uint64_t bytes, const char *what) { if (!g_model_range_mapping_supported || bytes == 0) return NULL; const long page_sz_l = sysconf(_SC_PAGESIZE); const uint64_t page_sz = page_sz_l > 0 ? (uint64_t)page_sz_l : 4096u; const uintptr_t host_addr = (uintptr_t)((const char *)model_map + offset); const uintptr_t reg_addr = host_addr & ~(uintptr_t)(page_sz - 1u); const uint64_t reg_delta = (uint64_t)(host_addr - reg_addr); uint64_t reg_bytes = (reg_delta + bytes + page_sz - 1u) & ~(page_sz - 1u); if (model_map == g_model_host_base && g_model_registered_size >= 88ull * 1073741824ull && g_model_registered_size <= 96ull * 1073741824ull && g_model_range_bytes >= 80ull * 1073741824ull) { const uintptr_t model_base = (uintptr_t)model_map; const uintptr_t model_end = model_base + (uintptr_t)g_model_registered_size; if (model_end > model_base && model_end > reg_addr) { const uint64_t tail_bytes = (uint64_t)(model_end - reg_addr); reg_bytes = (tail_bytes + page_sz - 1u) & ~(page_sz - 1u); } } void *reg_dev = NULL; unsigned int flags = cudaHostRegisterMapped | cudaHostRegisterReadOnly; if (getenv("DS4_CUDA_HOST_REGISTER_PLAIN") != NULL) { flags = cudaHostRegisterMapped; } cudaError_t err = cudaHostRegister((void *)reg_addr, (size_t)reg_bytes, flags); if (err != cudaSuccess && (flags & cudaHostRegisterReadOnly) != 0 && (err == cudaErrorNotSupported || err == cudaErrorInvalidValue)) { (void)cudaGetLastError(); err = cudaHostRegister((void *)reg_addr, (size_t)reg_bytes, cudaHostRegisterMapped); } if (err == cudaSuccess) { err = cudaHostGetDevicePointer(®_dev, (void *)reg_addr, 0); if (err == cudaSuccess && reg_dev) { char *dev_ptr = (char *)reg_dev + reg_delta; g_model_ranges.push_back({model_map, offset, bytes, dev_ptr, (void *)reg_addr, (char *)reg_dev, reg_bytes, 1, 0}); g_model_range_by_offset[offset] = g_model_ranges.size() - 1u; if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA mapped %s %.2f MiB\n", what ? what : "weights", (double)bytes / 1048576.0); } return dev_ptr; } fprintf(stderr, "ds4: CUDA model range map pointer failed for %s: %s\n", what ? what : "weights", cudaGetErrorString(err)); (void)cudaHostUnregister((void *)reg_addr); (void)cudaGetLastError(); return NULL; } if (err == cudaErrorNotSupported || err == cudaErrorInvalidValue) { g_model_range_mapping_supported = 0; } if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA model range map skipped for %s: %s\n", what ? what : "weights", cudaGetErrorString(err)); } (void)cudaGetLastError(); return NULL; } /* Allocate a device-resident copy of [offset, offset+bytes) from model_map and * push it into g_model_ranges so future cuda_model_range_ptr lookups hit it. * Returns the device pointer on success, NULL on cudaMalloc/cudaMemcpy failure. * Caller is responsible for any policy gating (budget cap, env opt-out, etc.) */ static const char *cuda_model_range_populate_device_copy(const void *model_map, uint64_t offset, uint64_t bytes, const char *what) { const uint64_t limit = cuda_model_cache_limit_bytes(); if (g_model_range_bytes > limit || bytes > limit - g_model_range_bytes) { if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA skipped device copy for %s %.2f MiB (cache budget %.2f GiB exhausted)\n", what ? what : "weights", (double)bytes / 1048576.0, (double)limit / 1073741824.0); } return NULL; } void *dev = NULL; cudaError_t err = cudaMalloc(&dev, (size_t)bytes); if (err != cudaSuccess) { (void)cudaGetLastError(); fprintf(stderr, "ds4: CUDA model range alloc failed for %s (%.2f MiB): %s\n", what ? what : "weights", (double)bytes / 1048576.0, cudaGetErrorString(err)); return NULL; } const char *src = (const char *)model_map + offset; const uint64_t chunk = 64ull * 1024ull * 1024ull; for (uint64_t done = 0; done < bytes; done += chunk) { uint64_t n = bytes - done < chunk ? bytes - done : chunk; err = cudaMemcpy((char *)dev + done, src + done, (size_t)n, cudaMemcpyHostToDevice); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model range copy failed for %s at %.2f/%.2f MiB: %s\n", what ? what : "weights", (double)done / 1048576.0, (double)bytes / 1048576.0, cudaGetErrorString(err)); (void)cudaFree(dev); (void)cudaGetLastError(); return NULL; } } g_model_ranges.push_back({model_map, offset, bytes, (char *)dev, NULL, NULL, 0, 0, 0}); g_model_range_by_offset[offset] = g_model_ranges.size() - 1u; g_model_range_bytes += bytes; if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA cached %s %.2f MiB (total %.2f GiB)\n", what ? what : "weights", (double)bytes / 1048576.0, (double)g_model_range_bytes / 1073741824.0); } return (const char *)dev; } static const char *cuda_model_range_ptr(const void *model_map, uint64_t offset, uint64_t bytes, const char *what) { if (bytes == 0) return cuda_model_ptr(model_map, offset); /* Device-resident HBM cache hits win over UVA-mapped registered pointers: * direct HBM reads are ~10% faster than mapped reads through host page * tables (measured on plain decode at GB10). Cache lookup runs first; the * registered-mapped shortcut below is the cold fallback when an allocation * hasn't been pre-populated. */ const uint64_t end = offset + bytes; auto exact = g_model_range_by_offset.find(offset); if (exact != g_model_range_by_offset.end()) { const cuda_model_range &r = g_model_ranges[exact->second]; if (r.host_base == model_map && end >= offset && bytes <= r.bytes) return r.device_ptr; } for (const cuda_model_range &r : g_model_ranges) { if (r.host_base == model_map && offset >= r.offset && end >= offset && end <= r.offset + r.bytes) { return r.device_ptr + (offset - r.offset); } if (r.host_base == model_map && r.host_registered && r.registered_base && r.registered_device_base) { const uintptr_t h0 = (uintptr_t)((const char *)model_map + offset); const uintptr_t h1 = h0 + bytes; const uintptr_t r0 = (uintptr_t)r.registered_base; const uintptr_t r1 = r0 + r.registered_bytes; if (h1 >= h0 && h0 >= r0 && h1 <= r1) return r.registered_device_base + (h0 - r0); } } if (g_model_device_owned || g_model_registered) return cuda_model_ptr(model_map, offset); if (g_model_hmm_direct && getenv("DS4_CUDA_WEIGHT_CACHE") == NULL && getenv("DS4_CUDA_WEIGHT_PRELOAD") == NULL) { return cuda_model_ptr(model_map, offset); } const char *direct_env = getenv("DS4_CUDA_DIRECT_MODEL"); if (direct_env && direct_env[0]) return cuda_model_ptr(model_map, offset); if (getenv("DS4_CUDA_NO_FD_CACHE") == NULL) { const char *fd_ptr = cuda_model_range_ptr_from_fd(model_map, offset, bytes, what); if (fd_ptr) return fd_ptr; } const char *mapped = cuda_model_range_register_mapped(model_map, offset, bytes, what); if (mapped) return mapped; return cuda_model_range_populate_device_copy(model_map, offset, bytes, what); } static int cuda_model_range_is_cached(const void *model_map, uint64_t offset, uint64_t bytes) { if (bytes == 0) return 1; if (g_model_device_owned || g_model_registered || g_model_hmm_direct) return 1; const uint64_t end = offset + bytes; if (end < offset) return 0; for (const cuda_model_range &r : g_model_ranges) { if (r.host_base == model_map && offset >= r.offset && end <= r.offset + r.bytes) { return 1; } if (r.host_base == model_map && r.host_registered && r.registered_base && r.registered_device_base) { const uintptr_t h0 = (uintptr_t)((const char *)model_map + offset); const uintptr_t h1 = h0 + bytes; const uintptr_t r0 = (uintptr_t)r.registered_base; const uintptr_t r1 = r0 + r.registered_bytes; if (h1 >= h0 && h0 >= r0 && h1 <= r1) return 1; } } return 0; } static void cuda_q8_f16_cache_release_all(void) { for (const cuda_q8_f16_range &r : g_q8_f16_ranges) { (void)cudaFree(r.device_ptr); } g_q8_f16_ranges.clear(); g_q8_f16_by_offset.clear(); g_q8_f16_bytes = 0; } static uint64_t cuda_parse_mib_env(const char *name, int *present) { const char *env = getenv(name); if (present) *present = 0; if (!env || !env[0]) return 0; char *end = NULL; unsigned long long v = strtoull(env, &end, 10); if (end == env || *end != '\0') return 0; if (present) *present = 1; if (v > UINT64_MAX / 1048576ull) return UINT64_MAX; return (uint64_t)v * 1048576ull; } static uint64_t cuda_q8_f16_cache_limit_bytes(void) { int present = 0; const uint64_t limit = cuda_parse_mib_env("DS4_CUDA_Q8_F16_CACHE_MB", &present); return present ? limit : UINT64_MAX; } static uint64_t cuda_q8_f16_cache_reserve_bytes(uint64_t total_bytes) { int present = 0; const uint64_t reserve = cuda_parse_mib_env("DS4_CUDA_Q8_F16_CACHE_RESERVE_MB", &present); if (present) return reserve; if (total_bytes >= 112ull * 1024ull * 1024ull * 1024ull) { return 512ull * 1048576ull; } /* The expanded Q8->F16 cache is only an acceleration path. Keep enough * device memory free for cuBLAS workspaces, transient graph buffers, and * driver bookkeeping instead of letting optional cached weights consume the * last few GiB on 96 GiB cards. */ const uint64_t min_reserve = 4096ull * 1048576ull; const uint64_t pct_reserve = total_bytes / 20u; /* 5% */ return pct_reserve > min_reserve ? pct_reserve : min_reserve; } static void cuda_q8_f16_cache_budget_notice( const char *reason, uint64_t request_bytes, uint64_t free_bytes, uint64_t total_bytes, uint64_t reserve_bytes, uint64_t limit_bytes) { if (g_q8_f16_budget_notice_printed && getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE") == NULL) return; g_q8_f16_budget_notice_printed = 1; if (limit_bytes != UINT64_MAX && free_bytes == 0 && total_bytes == 0 && reserve_bytes == 0) { fprintf(stderr, "ds4: CUDA q8 fp16 cache %s; using q8 kernels " "(request=%.2f MiB cached=%.2f GiB limit=%.2f GiB)\n", reason, (double)request_bytes / 1048576.0, (double)g_q8_f16_bytes / 1073741824.0, (double)limit_bytes / 1073741824.0); } else if (limit_bytes == UINT64_MAX) { fprintf(stderr, "ds4: CUDA q8 fp16 cache %s; using q8 kernels " "(request=%.2f MiB cached=%.2f GiB free=%.2f GiB reserve=%.2f GiB total=%.2f GiB)\n", reason, (double)request_bytes / 1048576.0, (double)g_q8_f16_bytes / 1073741824.0, (double)free_bytes / 1073741824.0, (double)reserve_bytes / 1073741824.0, (double)total_bytes / 1073741824.0); } else { fprintf(stderr, "ds4: CUDA q8 fp16 cache %s; using q8 kernels " "(request=%.2f MiB cached=%.2f GiB limit=%.2f GiB free=%.2f GiB reserve=%.2f GiB total=%.2f GiB)\n", reason, (double)request_bytes / 1048576.0, (double)g_q8_f16_bytes / 1073741824.0, (double)limit_bytes / 1073741824.0, (double)free_bytes / 1073741824.0, (double)reserve_bytes / 1073741824.0, (double)total_bytes / 1073741824.0); } } static int cuda_q8_f16_cache_has_budget(uint64_t request_bytes, const char *label) { (void)label; uint64_t limit = cuda_q8_f16_cache_limit_bytes(); if (limit == 0) return 0; if (g_q8_f16_bytes > limit || request_bytes > limit - g_q8_f16_bytes) { cuda_q8_f16_cache_budget_notice("limit reached", request_bytes, 0, 0, 0, limit); return 0; } size_t free_b = 0; size_t total_b = 0; cudaError_t err = cudaMemGetInfo(&free_b, &total_b); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA q8 fp16 cache memory query failed: %s; using q8 kernels\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } const uint64_t free_bytes = (uint64_t)free_b; const uint64_t total_bytes = (uint64_t)total_b; /* On 96/128 GB UMA Spark-class systems the expanded Q8->F16 cache can * pass a simple free-memory reserve check but still leave too little room * for long-prefill cuBLAS execution. Keep the startup cache useful but * bounded unless the caller explicitly sets DS4_CUDA_Q8_F16_CACHE_MB. */ if (limit == UINT64_MAX && total_bytes <= 128ull * 1073741824ull && (g_model_range_bytes >= 64ull * 1073741824ull || g_model_registered_size >= 64ull * 1073741824ull)) { if (g_model_registered_size >= 112ull * 1073741824ull) { limit = 4ull * 1073741824ull; } else if (g_model_registered_size >= 88ull * 1073741824ull || g_model_range_bytes >= 88ull * 1073741824ull) { limit = 16ull * 1073741824ull; } else if (g_model_range_bytes >= 64ull * 1073741824ull) { limit = 12ull * 1073741824ull; } else { limit = 8ull * 1073741824ull; } if (g_q8_f16_bytes > limit || request_bytes > limit - g_q8_f16_bytes) { cuda_q8_f16_cache_budget_notice("limit reached", request_bytes, 0, 0, 0, limit); return 0; } } const uint64_t reserve_bytes = cuda_q8_f16_cache_reserve_bytes(total_bytes); if (request_bytes > free_bytes || free_bytes - request_bytes < reserve_bytes) { cuda_q8_f16_cache_budget_notice("budget exhausted", request_bytes, free_bytes, total_bytes, reserve_bytes, limit); return 0; } return 1; } static void cuda_q8_f16_cache_disable_after_failure(const char *what, uint64_t request_bytes) { if (!g_q8_f16_disabled_after_oom) { fprintf(stderr, "ds4: CUDA q8 fp16 cache disabled after %s " "(request=%.2f MiB cached=%.2f GiB); using q8 kernels\n", what ? what : "allocation failure", (double)request_bytes / 1048576.0, (double)g_q8_f16_bytes / 1073741824.0); } g_q8_f16_disabled_after_oom = 1; if (!g_q8_f16_ranges.empty()) { (void)cudaDeviceSynchronize(); cuda_q8_f16_cache_release_all(); } (void)cudaGetLastError(); } static int cuda_q8_f16_cache_allowed(const char *label, uint64_t in_dim, uint64_t out_dim) { if (g_quality_mode) return 0; if (g_q8_f16_disabled_after_oom) return 0; if (getenv("DS4_CUDA_NO_Q8_F16_CACHE") != NULL) return 0; if (cuda_q8_f16_cache_limit_bytes() == 0) return 0; if (getenv("DS4_CUDA_Q8_F16_ALL") != NULL) return 1; if (!label) return 0; if (strstr(label, "attn_output_a") != NULL || strstr(label, "attn_output_b") != NULL || strstr(label, "attention_output_a") != NULL || strstr(label, "attention_output_b") != NULL) { return getenv("DS4_CUDA_NO_ATTENTION_OUTPUT_F16_CACHE") == NULL; } if (strstr(label, "attn_q_b") != NULL) { return getenv("DS4_CUDA_NO_ATTN_Q_B_F16_CACHE") == NULL; } if (strstr(label, "ffn_gate_shexp") != NULL || strstr(label, "ffn_up_shexp") != NULL || strstr(label, "ffn_down_shexp") != NULL) { return 1; } return (in_dim == 4096u && out_dim == 2048u) || (in_dim == 2048u && out_dim == 4096u) || (in_dim == 4096u && out_dim == 1024u) || (in_dim == 4096u && out_dim == 512u) || (getenv("DS4_CUDA_NO_ATTN_Q_B_F16_CACHE") == NULL && in_dim == 1024u && out_dim == 32768u); } static int cuda_q8_use_dp4a(void) { return getenv("DS4_CUDA_NO_Q8_DP4A") == NULL; } static int cuda_q8_f32_cache_allowed(const char *label, uint64_t in_dim, uint64_t out_dim) { if (getenv("DS4_CUDA_NO_Q8_F32_CACHE") != NULL) return 0; if (getenv("DS4_CUDA_Q8_F32_ALL") != NULL) return 1; if (label && strstr(label, "attn_q_b") != NULL) { return getenv("DS4_CUDA_ATTN_Q_B_F32_CACHE") != NULL; } return getenv("DS4_CUDA_Q8_F32_LARGE") != NULL && in_dim == 1024u && out_dim == 32768u; } static const __half *cuda_q8_f16_ptr( const void *model_map, uint64_t offset, uint64_t weight_bytes, uint64_t in_dim, uint64_t out_dim, const char *label) { auto exact = g_q8_f16_by_offset.find(offset); if (exact != g_q8_f16_by_offset.end()) { const cuda_q8_f16_range &r = g_q8_f16_ranges[exact->second]; if (r.host_base == model_map && r.weight_bytes == weight_bytes && r.in_dim == in_dim && r.out_dim == out_dim) { return r.device_ptr; } } if (!cuda_q8_f16_cache_allowed(label, in_dim, out_dim)) return NULL; const char *q8 = cuda_model_range_ptr(model_map, offset, weight_bytes, "q8_0"); if (!q8) return NULL; if (in_dim != 0 && out_dim > UINT64_MAX / in_dim / sizeof(__half)) return NULL; const uint64_t out_bytes = in_dim * out_dim * sizeof(__half); if (!cuda_q8_f16_cache_has_budget(out_bytes, label)) return NULL; __half *dev = NULL; cudaError_t err = cudaMalloc(&dev, (size_t)out_bytes); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA q8 fp16 cache alloc failed (%.2f MiB): %s\n", (double)out_bytes / 1048576.0, cudaGetErrorString(err)); cuda_q8_f16_cache_disable_after_failure("allocation failure", out_bytes); return NULL; } const uint64_t blocks = (in_dim + 31) / 32; const uint64_t n = in_dim * out_dim; dequant_q8_0_to_f16_kernel<<<(n + 255) / 256, 256>>>(dev, (const unsigned char *)q8, in_dim, out_dim, blocks); if (!cuda_ok(cudaGetLastError(), "q8 fp16 dequant launch")) { (void)cudaFree(dev); cuda_q8_f16_cache_disable_after_failure("dequant launch failure", out_bytes); return NULL; } g_q8_f16_ranges.push_back({model_map, offset, weight_bytes, in_dim, out_dim, dev}); g_q8_f16_by_offset[offset] = g_q8_f16_ranges.size() - 1u; g_q8_f16_bytes += out_bytes; if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA cached q8 fp16 %.2f MiB (total %.2f GiB)\n", (double)out_bytes / 1048576.0, (double)g_q8_f16_bytes / 1073741824.0); } return dev; } static float *cuda_q8_f32_ptr( const void *model_map, uint64_t offset, uint64_t weight_bytes, uint64_t in_dim, uint64_t out_dim, const char *label) { auto exact = g_q8_f32_by_offset.find(offset); if (exact != g_q8_f32_by_offset.end()) { const cuda_q8_f32_range &r = g_q8_f32_ranges[exact->second]; if (r.host_base == model_map && r.weight_bytes == weight_bytes && r.in_dim == in_dim && r.out_dim == out_dim) { return r.device_ptr; } } if (!cuda_q8_f32_cache_allowed(label, in_dim, out_dim)) return NULL; const char *q8 = cuda_model_range_ptr(model_map, offset, weight_bytes, label ? label : "q8_0"); if (!q8) return NULL; const uint64_t out_bytes = in_dim * out_dim * sizeof(float); float *dev = NULL; cudaError_t err = cudaMalloc(&dev, (size_t)out_bytes); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA q8 fp32 cache alloc failed (%.2f MiB): %s\n", (double)out_bytes / 1048576.0, cudaGetErrorString(err)); (void)cudaGetLastError(); return NULL; } const uint64_t blocks = (in_dim + 31) / 32; const uint64_t n = in_dim * out_dim; dequant_q8_0_to_f32_kernel<<<(n + 255) / 256, 256>>>(dev, (const unsigned char *)q8, in_dim, out_dim, blocks); if (!cuda_ok(cudaGetLastError(), "q8 fp32 dequant launch")) { (void)cudaFree(dev); return NULL; } g_q8_f32_ranges.push_back({model_map, offset, weight_bytes, in_dim, out_dim, dev}); g_q8_f32_by_offset[offset] = g_q8_f32_ranges.size() - 1u; g_q8_f32_bytes += out_bytes; if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA cached q8 fp32 %.2f MiB (total %.2f GiB)\n", (double)out_bytes / 1048576.0, (double)g_q8_f32_bytes / 1073741824.0); } return dev; } static int cuda_ok(cudaError_t err, const char *what) { if (err == cudaSuccess) return 1; fprintf(stderr, "ds4: CUDA %s failed: %s\n", what, cudaGetErrorString(err)); return 0; } static double cuda_wall_sec(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (double)ts.tv_sec + (double)ts.tv_nsec * 1.0e-9; } static int cuda_model_load_progress_enabled(void) { if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE") != NULL) return 0; return 1; } static void cuda_model_load_progress_reset(void) { g_model_load_progress_next = 0; g_model_load_progress_last_bytes = UINT64_MAX; g_model_load_progress_last_cgib = UINT64_MAX; g_model_load_progress_last = 0.0; g_model_load_progress_started = 0; g_model_load_progress_tty = 0; } static void cuda_model_load_progress_finish(void) { if (!g_model_load_progress_started) return; if (g_model_load_progress_tty) { fputc('\n', stderr); fflush(stderr); } g_model_load_progress_started = 0; } static void cuda_model_load_progress_note(uint64_t cached_bytes) { if (!cuda_model_load_progress_enabled()) return; const double now = cuda_wall_sec(); const int tty = isatty(STDERR_FILENO) != 0; const uint64_t step = (tty ? 2ull : 16ull) * 1024ull * 1024ull * 1024ull; const uint64_t gib = 1024ull * 1024ull * 1024ull; const uint64_t display_cgib = cached_bytes > (UINT64_MAX - gib / 2ull) / 100ull ? UINT64_MAX : (cached_bytes * 100ull + gib / 2ull) / gib; if (g_model_load_progress_next == 0) { g_model_load_progress_next = step; } if (g_model_load_progress_last != 0.0 && (cached_bytes == g_model_load_progress_last_bytes || display_cgib == g_model_load_progress_last_cgib)) { return; } if (g_model_load_progress_last != 0.0 && cached_bytes < g_model_load_progress_next && now - g_model_load_progress_last < (tty ? 2.0 : 10.0)) { return; } g_model_load_progress_started = 1; g_model_load_progress_tty = tty; if (g_model_load_progress_tty) { fprintf(stderr, "\r\033[Kds4: CUDA loading model tensors into device cache: %.2f GiB", (double)cached_bytes / 1073741824.0); } else { if (g_model_load_progress_last == 0.0) { fprintf(stderr, "ds4: CUDA loading model tensors into device cache\n"); } else { fprintf(stderr, "ds4: CUDA loading model tensors %.2f GiB cached\n", (double)cached_bytes / 1073741824.0); } } fflush(stderr); g_model_load_progress_last_bytes = cached_bytes; g_model_load_progress_last_cgib = display_cgib; g_model_load_progress_last = now; while (g_model_load_progress_next <= cached_bytes) { g_model_load_progress_next += step; } } static int cuda_model_prefetch_range(const void *model_map, uint64_t model_size, uint64_t map_offset, uint64_t map_size) { if (!model_map || map_size == 0 || map_offset > model_size || map_size > model_size - map_offset) return 0; if (getenv("DS4_CUDA_NO_MODEL_PREFETCH") != NULL || getenv("DS4_CUDA_COPY_MODEL") != NULL || getenv("DS4_CUDA_WEIGHT_CACHE") != NULL || getenv("DS4_CUDA_WEIGHT_PRELOAD") != NULL) { return 0; } int device = 0; if (cudaGetDevice(&device) != cudaSuccess) { (void)cudaGetLastError(); return 0; } int pageable = 0; cudaError_t err = cudaDeviceGetAttribute(&pageable, cudaDevAttrPageableMemoryAccess, device); if (err != cudaSuccess || !pageable) { (void)cudaGetLastError(); return 0; } cudaMemLocation loc; memset(&loc, 0, sizeof(loc)); loc.type = cudaMemLocationTypeDevice; loc.id = device; const long page_sz_l = sysconf(_SC_PAGESIZE); const uint64_t page_sz = page_sz_l > 0 ? (uint64_t)page_sz_l : 4096u; const uintptr_t host_addr = (uintptr_t)((const char *)model_map + map_offset); const uintptr_t pre_addr = host_addr & ~(uintptr_t)(page_sz - 1u); const uint64_t pre_delta = (uint64_t)(host_addr - pre_addr); const uint64_t pre_bytes = (pre_delta + map_size + page_sz - 1u) & ~(page_sz - 1u); void *pre_ptr = (void *)pre_addr; const double t0 = cuda_wall_sec(); err = cudaMemAdvise(pre_ptr, (size_t)pre_bytes, cudaMemAdviseSetReadMostly, loc); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model read-mostly advise skipped: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } err = cudaMemAdvise(pre_ptr, (size_t)pre_bytes, cudaMemAdviseSetPreferredLocation, loc); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model preferred-location advise skipped: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } if (!g_model_prefetch_stream) { err = cudaStreamCreateWithFlags(&g_model_prefetch_stream, cudaStreamNonBlocking); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model prefetch stream creation skipped: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } } err = cudaMemPrefetchAsync(pre_ptr, (size_t)pre_bytes, loc, 0, g_model_prefetch_stream); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model prefetch skipped: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } if (getenv("DS4_CUDA_MODEL_PREFETCH_SYNC") != NULL) { err = cudaStreamSynchronize(g_model_prefetch_stream); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model prefetch sync failed: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } } const double t1 = cuda_wall_sec(); fprintf(stderr, "ds4: CUDA ATS/HMM prefetch queued %.2f GiB of model tensors in %.3fs\n", (double)map_size / 1073741824.0, t1 - t0); g_model_hmm_direct = 1; return 1; } static uint64_t cuda_model_copy_chunk_bytes(void) { uint64_t mb = 64; const char *env = getenv("DS4_CUDA_MODEL_COPY_CHUNK_MB"); if (env && env[0]) { char *end = NULL; unsigned long long v = strtoull(env, &end, 10); if (end != env && v > 0) mb = (uint64_t)v; } if (mb < 16) mb = 16; if (mb > 4096) mb = 4096; return mb * 1048576ull; } static void cuda_model_discard_source_pages(const void *model_map, uint64_t model_size, uint64_t offset, uint64_t bytes) { #if defined(POSIX_MADV_DONTNEED) if (getenv("DS4_CUDA_KEEP_MODEL_PAGES") != NULL || !model_map || bytes == 0 || offset > model_size) return; if (bytes > model_size - offset) bytes = model_size - offset; const long page_sz_l = sysconf(_SC_PAGESIZE); const uint64_t page_sz = page_sz_l > 0 ? (uint64_t)page_sz_l : 4096u; const uintptr_t h0 = (uintptr_t)((const char *)model_map + offset); const uintptr_t h1 = h0 + bytes; const uintptr_t p0 = h0 & ~(uintptr_t)(page_sz - 1u); const uintptr_t p1 = (h1 + page_sz - 1u) & ~(uintptr_t)(page_sz - 1u); if (p1 > p0) (void)posix_madvise((void *)p0, (size_t)(p1 - p0), POSIX_MADV_DONTNEED); #else (void)model_map; (void)model_size; (void)offset; (void)bytes; #endif } static void cuda_model_drop_file_pages(uint64_t offset, uint64_t bytes) { #if defined(POSIX_FADV_DONTNEED) if (g_model_fd < 0 || getenv("DS4_CUDA_KEEP_MODEL_PAGES") != NULL || bytes == 0) return; (void)posix_fadvise(g_model_fd, (off_t)offset, (off_t)bytes, POSIX_FADV_DONTNEED); #else (void)offset; (void)bytes; #endif } static uint64_t cuda_round_down(uint64_t v, uint64_t align) { if (align <= 1) return v; return (v / align) * align; } static uint64_t cuda_round_up(uint64_t v, uint64_t align) { if (align <= 1) return v; const uint64_t rem = v % align; return rem == 0 ? v : v + (align - rem); } static void *cuda_align_ptr(void *ptr, uint64_t align) { if (align <= 1) return ptr; uintptr_t p = (uintptr_t)ptr; uintptr_t a = (uintptr_t)align; return (void *)(((p + a - 1u) / a) * a); } static int cuda_model_stage_pool_alloc(uint64_t bytes) { if (g_model_stage_bytes >= bytes) return 1; for (size_t i = 0; i < 4; i++) { if (g_model_stage_event[i]) { (void)cudaEventDestroy(g_model_stage_event[i]); g_model_stage_event[i] = NULL; } if (g_model_stage_raw[i]) { (void)cudaFreeHost(g_model_stage_raw[i]); g_model_stage_raw[i] = NULL; g_model_stage[i] = NULL; } } g_model_stage_bytes = 0; if (!g_model_upload_stream) { cudaError_t err = cudaStreamCreateWithFlags(&g_model_upload_stream, cudaStreamNonBlocking); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model upload stream creation failed: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } } for (size_t i = 0; i < 4; i++) { cudaError_t err = cudaMallocHost(&g_model_stage_raw[i], (size_t)bytes); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA pinned model staging allocation failed: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } g_model_stage[i] = cuda_align_ptr(g_model_stage_raw[i], g_model_direct_align); err = cudaEventCreateWithFlags(&g_model_stage_event[i], cudaEventDisableTiming); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model staging event creation failed: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } } g_model_stage_bytes = bytes; return 1; } static int cuda_pread_full(int fd, void *buf, uint64_t bytes, uint64_t offset) { uint64_t done = 0; while (done < bytes) { const size_t n_req = (bytes - done > (uint64_t)SSIZE_MAX) ? (size_t)SSIZE_MAX : (size_t)(bytes - done); ssize_t n = pread(fd, (char *)buf + done, n_req, (off_t)(offset + done)); if (n < 0) { if (errno == EINTR) continue; return 0; } if (n == 0) return 0; done += (uint64_t)n; } return 1; } static int cuda_model_stage_read(void *stage, uint64_t stage_bytes, uint64_t offset, uint64_t bytes, const char **payload) { *payload = (const char *)stage; #if defined(__linux__) && defined(O_DIRECT) if (g_model_direct_fd >= 0 && g_model_direct_align > 1 && g_model_file_size != 0) { const uint64_t aligned_off = cuda_round_down(offset, g_model_direct_align); const uint64_t delta = offset - aligned_off; uint64_t read_size = cuda_round_up(delta + bytes, g_model_direct_align); if (aligned_off <= g_model_file_size && read_size <= stage_bytes && read_size <= g_model_file_size - aligned_off) { const int saved_errno = errno; errno = 0; if (cuda_pread_full(g_model_direct_fd, stage, read_size, aligned_off)) { *payload = (const char *)stage + delta; errno = saved_errno; return 1; } const int direct_errno = errno; if (direct_errno == EINVAL || direct_errno == EFAULT || direct_errno == ENOTSUP || direct_errno == EOPNOTSUPP) { if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA direct model read disabled: %s\n", strerror(direct_errno)); } (void)close(g_model_direct_fd); g_model_direct_fd = -1; g_model_direct_align = 1; } errno = direct_errno; } } #else (void)stage_bytes; #endif return cuda_pread_full(g_model_fd, stage, bytes, offset); } static uint64_t cuda_model_cache_limit_bytes(void) { uint64_t gb = 0; const char *env = getenv("DS4_CUDA_WEIGHT_CACHE_LIMIT_GB"); if (env && env[0]) { char *end = NULL; unsigned long long v = strtoull(env, &end, 10); if (end != env) gb = (uint64_t)v; return gb * 1073741824ull; } /* One Spark can run the IQ2 model (~81 GiB) and the mixed q2/q4 model * (~91 GiB) via the old startup tensor cache. Keep enough headroom for * scratch, KV, and optional Q8->F16 buffers, and make the full-Q4 model * use distributed layer loading unless the operator opts into a larger * cache budget explicitly. */ return 96ull * 1073741824ull; } static uint64_t cuda_model_local_model_limit_bytes(void) { const uint64_t default_limit = 96ull * 1073741824ull; if (!cuda_model_cache_limit_explicit()) return default_limit; const uint64_t explicit_limit = cuda_model_cache_limit_bytes(); return explicit_limit > default_limit ? explicit_limit : default_limit; } static int cuda_model_cache_limit_explicit(void) { const char *env = getenv("DS4_CUDA_WEIGHT_CACHE_LIMIT_GB"); return env && env[0]; } static uint64_t cuda_model_arena_chunk_bytes(uint64_t need) { uint64_t mb = 1792; const char *env = getenv("DS4_CUDA_WEIGHT_ARENA_CHUNK_MB"); if (env && env[0]) { char *end = NULL; unsigned long long v = strtoull(env, &end, 10); if (end != env && v > 0) mb = (uint64_t)v; } if (mb < 256) mb = 256; if (mb > 8192) mb = 8192; uint64_t bytes = mb * 1048576ull; if (need > bytes / 2u) { const uint64_t align = 64ull * 1048576ull; return (need + align - 1u) & ~(align - 1u); } if (bytes < need) { const uint64_t align = 256ull * 1048576ull; bytes = (need + align - 1u) & ~(align - 1u); } return bytes; } static char *cuda_model_arena_alloc(uint64_t bytes, const char *what) { if (bytes == 0) return NULL; if (g_model_cache_full) return NULL; const uint64_t align = 256u; const uint64_t aligned = (bytes + align - 1u) & ~(align - 1u); for (cuda_model_arena &a : g_model_arenas) { const uint64_t used = (a.used + align - 1u) & ~(align - 1u); if (used <= a.bytes && aligned <= a.bytes - used) { char *ptr = a.device_ptr + used; a.used = used + aligned; return ptr; } } const uint64_t limit = cuda_model_cache_limit_bytes(); if (g_model_range_bytes > limit || aligned > limit - g_model_range_bytes) return NULL; const uint64_t chunk = cuda_model_arena_chunk_bytes(aligned); void *dev = NULL; cudaError_t err = cudaMalloc(&dev, (size_t)chunk); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model arena alloc failed for %s (%.2f MiB chunk): %s\n", what ? what : "weights", (double)chunk / 1048576.0, cudaGetErrorString(err)); (void)cudaGetLastError(); g_model_cache_full = 1; return NULL; } g_model_arenas.push_back({(char *)dev, chunk, aligned}); if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { uint64_t arena_bytes = 0; for (const cuda_model_arena &a : g_model_arenas) arena_bytes += a.bytes; fprintf(stderr, "ds4: CUDA model arena allocated %.2f MiB (arenas %.2f GiB)\n", (double)chunk / 1048576.0, (double)arena_bytes / 1073741824.0); } return (char *)dev; } /* A raw host pointer is safe for kernels only after CUDA owns, registered, or * HMM-prefetched the mapping. Otherwise let the caller try per-range mapping * or a device copy instead of surfacing an async illegal access later. */ static const char *cuda_model_direct_fallback_ptr(const void *model_map, uint64_t offset) { if (g_model_device_owned || g_model_registered || g_model_hmm_direct || getenv("DS4_CUDA_DIRECT_MODEL") != NULL) { return cuda_model_ptr(model_map, offset); } return NULL; } static const char *cuda_model_range_ptr_from_fd( const void *model_map, uint64_t offset, uint64_t bytes, const char *what) { if (g_model_fd < 0 || bytes == 0) return NULL; if (g_model_fd_host_base != NULL && model_map != g_model_fd_host_base) return NULL; const uint64_t limit = cuda_model_cache_limit_bytes(); if (g_model_range_bytes > limit || bytes > limit - g_model_range_bytes) { if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA direct %s %.2f MiB (cache budget %.2f GiB exhausted)\n", what ? what : "weights", (double)bytes / 1048576.0, (double)limit / 1073741824.0); } return cuda_model_direct_fallback_ptr(model_map, offset); } char *dev = cuda_model_arena_alloc(bytes, what); if (!dev) { if (getenv("DS4_CUDA_STRICT_WEIGHT_CACHE") != NULL) return NULL; return cuda_model_direct_fallback_ptr(model_map, offset); } cudaError_t err = cudaSuccess; const uint64_t chunk = cuda_model_copy_chunk_bytes(); const uint64_t stage_bytes = chunk + (g_model_direct_align > 1 ? g_model_direct_align : 1); if (!cuda_model_stage_pool_alloc(stage_bytes)) return NULL; uint64_t copied = 0; uint64_t chunk_idx = 0; while (copied < bytes) { const uint64_t n = (bytes - copied < chunk) ? (bytes - copied) : chunk; const uint64_t bi = chunk_idx % 4u; if (chunk_idx >= 4u) { err = cudaEventSynchronize(g_model_stage_event[bi]); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model staging wait failed for %s: %s\n", what ? what : "weights", cudaGetErrorString(err)); (void)cudaGetLastError(); return NULL; } } const char *payload = NULL; if (!cuda_model_stage_read(g_model_stage[bi], g_model_stage_bytes, offset + copied, n, &payload)) { fprintf(stderr, "ds4: CUDA model range read failed for %s at %.2f MiB: %s\n", what ? what : "weights", (double)copied / 1048576.0, strerror(errno)); return NULL; } err = cudaMemcpyAsync(dev + copied, payload, (size_t)n, cudaMemcpyHostToDevice, g_model_upload_stream); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model range copy failed for %s at %.2f MiB: %s\n", what ? what : "weights", (double)copied / 1048576.0, cudaGetErrorString(err)); (void)cudaGetLastError(); return NULL; } err = cudaEventRecord(g_model_stage_event[bi], g_model_upload_stream); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model staging record failed for %s: %s\n", what ? what : "weights", cudaGetErrorString(err)); (void)cudaGetLastError(); return NULL; } cuda_model_drop_file_pages(offset + copied, n); cuda_model_discard_source_pages(model_map, g_model_registered_size, offset + copied, n); copied += n; cuda_model_load_progress_note(g_model_range_bytes + copied); chunk_idx++; } err = cudaStreamSynchronize(g_model_upload_stream); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model range upload sync failed for %s: %s\n", what ? what : "weights", cudaGetErrorString(err)); (void)cudaGetLastError(); return NULL; } g_model_ranges.push_back({model_map, offset, bytes, dev, NULL, NULL, 0, 0, 1}); g_model_range_by_offset[offset] = g_model_ranges.size() - 1u; g_model_range_bytes += bytes; cuda_model_load_progress_note(g_model_range_bytes); if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA fd-cached %s %.2f MiB (total %.2f GiB)\n", what ? what : "weights", (double)bytes / 1048576.0, (double)g_model_range_bytes / 1073741824.0); } return (const char *)dev; } static int cuda_model_copy_chunked(const void *model_map, uint64_t model_size, uint64_t map_offset, uint64_t map_size) { if (!model_map || model_size == 0 || map_offset > model_size || map_size > model_size - map_offset) return 0; if (getenv("DS4_CUDA_NO_MODEL_COPY") != NULL || getenv("DS4_CUDA_DIRECT_MODEL") != NULL || getenv("DS4_CUDA_WEIGHT_CACHE") != NULL || getenv("DS4_CUDA_WEIGHT_PRELOAD") != NULL) { return 0; } if (g_model_device_owned || g_model_registered) return 1; void *dev = NULL; const double t0 = cuda_wall_sec(); cudaError_t err = cudaMalloc(&dev, (size_t)model_size); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model allocation skipped: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } fprintf(stderr, "ds4: CUDA chunk-copying %.2f GiB model image\n", (double)model_size / 1073741824.0); const uint64_t chunk = cuda_model_copy_chunk_bytes(); void *stage = NULL; err = cudaMallocHost(&stage, (size_t)chunk); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA pinned model staging allocation failed: %s\n", cudaGetErrorString(err)); (void)cudaFree(dev); (void)cudaGetLastError(); return 0; } if (map_offset > 0) { uint64_t copied_header = 0; while (copied_header < map_offset) { const uint64_t n = (map_offset - copied_header < chunk) ? (map_offset - copied_header) : chunk; memcpy(stage, (const char *)model_map + copied_header, (size_t)n); err = cudaMemcpy((char *)dev + copied_header, stage, (size_t)n, cudaMemcpyHostToDevice); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model header copy failed: %s\n", cudaGetErrorString(err)); (void)cudaFreeHost(stage); (void)cudaFree(dev); (void)cudaGetLastError(); return 0; } copied_header += n; } } uint64_t copied = 0; double last_report = t0; while (copied < map_size) { const uint64_t n = (map_size - copied < chunk) ? (map_size - copied) : chunk; const uint64_t off = map_offset + copied; memcpy(stage, (const char *)model_map + off, (size_t)n); err = cudaMemcpy((char *)dev + off, stage, (size_t)n, cudaMemcpyHostToDevice); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA model chunk copy failed at %.2f GiB: %s\n", (double)copied / 1073741824.0, cudaGetErrorString(err)); (void)cudaFreeHost(stage); (void)cudaFree(dev); (void)cudaGetLastError(); return 0; } cuda_model_discard_source_pages(model_map, model_size, off, n); copied += n; const double now = cuda_wall_sec(); if (getenv("DS4_CUDA_MODEL_COPY_VERBOSE") != NULL && now - last_report >= 2.0) { fprintf(stderr, "ds4: CUDA model chunk copy %.2f/%.2f GiB\n", (double)copied / 1073741824.0, (double)map_size / 1073741824.0); last_report = now; } } (void)cudaFreeHost(stage); g_model_device_base = (const char *)dev; g_model_device_owned = 1; g_model_hmm_direct = 0; const double t1 = cuda_wall_sec(); fprintf(stderr, "ds4: CUDA model chunk copy complete in %.3fs (%.2f GiB tensors)\n", t1 - t0, (double)map_size / 1073741824.0); return 1; } static void cuda_model_range_release_all(void) { cuda_model_load_progress_finish(); for (const cuda_model_range &r : g_model_ranges) { if (r.host_registered && r.registered_base) { (void)cudaHostUnregister(r.registered_base); } else if (r.device_ptr && !r.arena_allocated) { (void)cudaFree(r.device_ptr); } } for (const cuda_model_arena &a : g_model_arenas) { if (a.device_ptr) (void)cudaFree(a.device_ptr); } g_model_arenas.clear(); g_model_ranges.clear(); g_model_range_by_offset.clear(); g_model_range_bytes = 0; } static void cuda_stream_selected_cache_invalidate(void) { g_stream_selected_cache.valid = 0; } static void cuda_stream_selected_cache_release(void) { if (g_stream_selected_cache.gate_ptr) { (void)cudaFree(g_stream_selected_cache.gate_ptr); } if (g_stream_selected_cache.up_ptr) { (void)cudaFree(g_stream_selected_cache.up_ptr); } if (g_stream_selected_cache.down_ptr) { (void)cudaFree(g_stream_selected_cache.down_ptr); } if (g_stream_selected_cache.slot_selected_ptr) { (void)cudaFree(g_stream_selected_cache.slot_selected_ptr); } memset(&g_stream_selected_cache, 0, sizeof(g_stream_selected_cache)); } static void cuda_stream_expert_cache_release_all(void) { if (g_stream_expert_cache.gate_ptr) { (void)cudaFree(g_stream_expert_cache.gate_ptr); } if (g_stream_expert_cache.up_ptr) { (void)cudaFree(g_stream_expert_cache.up_ptr); } if (g_stream_expert_cache.down_ptr) { (void)cudaFree(g_stream_expert_cache.down_ptr); } g_stream_expert_cache.slots.clear(); memset(&g_stream_expert_cache, 0, sizeof(g_stream_expert_cache)); } static void cuda_stream_expert_cache_invalidate(void) { for (cuda_stream_expert_cache_slot &slot : g_stream_expert_cache.slots) { slot.valid = 0; } g_stream_expert_cache.valid = 0; g_stream_expert_cache.count = 0; g_stream_expert_cache.tick = 0; } static uint32_t cuda_stream_expert_cache_requested_budget(void) { uint32_t cap = g_stream_expert_budget_override != 0 ? g_stream_expert_budget_override : DS4_CUDA_STREAM_EXPERT_DEFAULT; const char *env = getenv("DS4_CUDA_STREAMING_EXPERT_CACHE_N"); if (env && env[0]) { char *end = NULL; errno = 0; unsigned long v = strtoul(env, &end, 10); while (end && (*end == ' ' || *end == '\t')) end++; if (end != env && errno == 0 && end && *end == '\0') { cap = v > DS4_CUDA_STREAM_EXPERT_MAX ? DS4_CUDA_STREAM_EXPERT_MAX : (uint32_t)v; } } if (cap > DS4_CUDA_STREAM_EXPERT_MAX) { cap = DS4_CUDA_STREAM_EXPERT_MAX; } return cap; } static uint32_t cuda_stream_expert_cache_configured_budget(void) { uint32_t cap = cuda_stream_expert_cache_requested_budget(); if (g_stream_expert_runtime_cap != 0 && cap > g_stream_expert_runtime_cap) { cap = g_stream_expert_runtime_cap; } return cap; } static int cuda_stream_expert_cache_budget_visible_to_shared(void) { if (!g_ssd_streaming_mode) return 0; if (g_stream_expert_budget_override != 0) return 1; const char *env = getenv("DS4_CUDA_STREAMING_EXPERT_CACHE_N"); if (env && env[0]) return 1; env = getenv("DS4_CUDA_ENABLE_STREAMING_EXPERT_HOTLIST"); if (!env || !env[0]) { env = getenv("DS4_CUDA_STREAMING_EXPERT_HOTLIST"); } return env && env[0] && strcmp(env, "0") != 0; } static uint64_t cuda_stream_expert_cache_reserve_bytes(void) { uint64_t gb = 16; const char *env = getenv("DS4_CUDA_STREAMING_EXPERT_CACHE_RESERVE_GB"); if (env && env[0]) { char *end = NULL; errno = 0; unsigned long long v = strtoull(env, &end, 10); while (end && (*end == ' ' || *end == '\t')) end++; if (end != env && errno == 0 && end && *end == '\0') { gb = (uint64_t)v; } } if (gb > UINT64_MAX / 1073741824ull) return UINT64_MAX; return gb * 1073741824ull; } static uint32_t cuda_stream_expert_cache_live_budget( uint32_t requested, uint64_t gate_expert_bytes, uint64_t down_expert_bytes, uint64_t reclaim_bytes, int report) { if (requested == 0 || gate_expert_bytes == 0 || down_expert_bytes == 0 || gate_expert_bytes > (UINT64_MAX - down_expert_bytes) / 2ull) { return 0; } const uint64_t per_expert_bytes = gate_expert_bytes * 2ull + down_expert_bytes; if (per_expert_bytes == 0) return 0; size_t free_b = 0; size_t total_b = 0; cudaError_t err = cudaMemGetInfo(&free_b, &total_b); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming expert cache memory query failed: %s; " "using direct selected loads\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } uint64_t free_bytes = (uint64_t)free_b; if (reclaim_bytes > UINT64_MAX - free_bytes) { free_bytes = UINT64_MAX; } else { free_bytes += reclaim_bytes; } uint64_t reserve = cuda_stream_expert_cache_reserve_bytes(); const uint64_t total_bytes = (uint64_t)total_b; if (total_bytes != 0 && reserve > total_bytes / 2ull) { reserve = total_bytes / 2ull; } if (free_bytes <= reserve) { if (report && g_stream_expert_memory_cap_notice != requested) { cuda_model_load_progress_finish(); fprintf(stderr, "ds4: CUDA streaming expert cache disabled: available %.2f GiB <= reserve %.2f GiB\n", (double)free_bytes / 1073741824.0, (double)reserve / 1073741824.0); g_stream_expert_memory_cap_notice = requested; } return 0; } uint64_t usable = free_bytes - reserve; uint64_t max_slots64 = usable / per_expert_bytes; if (max_slots64 > UINT32_MAX) max_slots64 = UINT32_MAX; uint32_t capped = requested; if ((uint64_t)capped > max_slots64) capped = (uint32_t)max_slots64; if (report && capped != requested && g_stream_expert_memory_cap_notice != capped) { cuda_model_load_progress_finish(); fprintf(stderr, "ds4: CUDA streaming expert cache capped from %u to %u experts " "(available %.2f GiB, reserve %.2f GiB, %.2f MiB/expert)\n", requested, capped, (double)free_bytes / 1073741824.0, (double)reserve / 1073741824.0, (double)per_expert_bytes / 1048576.0); g_stream_expert_memory_cap_notice = capped; } return capped; } static uint64_t cuda_stream_expert_cache_expert_bytes( uint64_t gate_expert_bytes, uint64_t down_expert_bytes) { if (gate_expert_bytes == 0 || down_expert_bytes == 0 || gate_expert_bytes > (UINT64_MAX - down_expert_bytes) / 2ull) { return 0; } return gate_expert_bytes * 2ull + down_expert_bytes; } static void cuda_stream_expert_cache_note_size( uint64_t gate_expert_bytes, uint64_t down_expert_bytes) { if (g_stream_expert_runtime_gate_bytes == gate_expert_bytes && g_stream_expert_runtime_down_bytes == down_expert_bytes) { return; } g_stream_expert_runtime_gate_bytes = gate_expert_bytes; g_stream_expert_runtime_down_bytes = down_expert_bytes; g_stream_expert_runtime_cap = 0; g_stream_expert_memory_cap_notice = 0; } static uint32_t cuda_stream_expert_cache_shrunken_cap(uint32_t cap) { if (cap == 0) return 0; const uint32_t release = (cap + 9u) / 10u; return cap > release ? cap - release : 0; } static void cuda_stream_expert_cache_note_oom_cap( uint32_t failed_cap, uint32_t new_cap, uint64_t expert_bytes, const char *errstr) { if (g_stream_expert_runtime_cap != 0 && g_stream_expert_runtime_cap <= new_cap) { return; } g_stream_expert_runtime_cap = new_cap; const uint32_t released = failed_cap > new_cap ? failed_cap - new_cap : 0; cuda_model_load_progress_finish(); fprintf(stderr, "ds4: CUDA streaming expert cache allocation failed at %u experts " "/ %.2f GiB%s%s\n", failed_cap, expert_bytes != 0 ? (double)((uint64_t)failed_cap * expert_bytes) / 1073741824.0 : 0.0, errstr && errstr[0] ? ": " : "", errstr && errstr[0] ? errstr : ""); if (new_cap != 0) { fprintf(stderr, "ds4: shrinking resident cache margin by %u experts / %.2f GiB; " "runtime cache cap now %u experts\n", released, expert_bytes != 0 ? (double)((uint64_t)released * expert_bytes) / 1073741824.0 : 0.0, new_cap); } else { fprintf(stderr, "ds4: disabling resident expert cache after OOM; using direct selected loads\n"); } } static int cuda_stream_expert_cache_try_alloc( uint32_t cap, uint64_t gate_expert_bytes, uint64_t down_expert_bytes, char **gate_ptr, char **up_ptr, char **down_ptr, const char **errstr) { *gate_ptr = NULL; *up_ptr = NULL; *down_ptr = NULL; if (errstr) *errstr = NULL; if (cap == 0 || (uint64_t)cap > UINT64_MAX / gate_expert_bytes || (uint64_t)cap > UINT64_MAX / down_expert_bytes) { return 0; } const uint64_t gate_bytes = (uint64_t)cap * gate_expert_bytes; const uint64_t down_bytes = (uint64_t)cap * down_expert_bytes; void *gate = NULL; void *up = NULL; void *down = NULL; cudaError_t err = cudaMalloc(&gate, (size_t)gate_bytes); if (err != cudaSuccess) goto fail; err = cudaMalloc(&up, (size_t)gate_bytes); if (err != cudaSuccess) goto fail; err = cudaMalloc(&down, (size_t)down_bytes); if (err != cudaSuccess) goto fail; *gate_ptr = (char *)gate; *up_ptr = (char *)up; *down_ptr = (char *)down; return 1; fail: if (errstr) *errstr = cudaGetErrorString(err); (void)cudaGetLastError(); if (gate) (void)cudaFree(gate); if (up) (void)cudaFree(up); if (down) (void)cudaFree(down); return 0; } static void cuda_stream_selected_stage_release(void) { for (size_t i = 0; i < 4; i++) { if (g_stream_selected_stage_event[i]) { (void)cudaEventDestroy(g_stream_selected_stage_event[i]); g_stream_selected_stage_event[i] = NULL; } if (g_stream_selected_stage_raw[i]) { (void)cudaFreeHost(g_stream_selected_stage_raw[i]); g_stream_selected_stage_raw[i] = NULL; g_stream_selected_stage[i] = NULL; } } g_stream_selected_stage_bytes = 0; if (g_stream_selected_upload_stream) { (void)cudaStreamDestroy(g_stream_selected_upload_stream); g_stream_selected_upload_stream = NULL; } } static int cuda_stream_selected_stage_pool_alloc(uint64_t bytes) { if (g_stream_selected_stage_bytes >= bytes) return 1; for (size_t i = 0; i < 4; i++) { if (g_stream_selected_stage_event[i]) { (void)cudaEventDestroy(g_stream_selected_stage_event[i]); g_stream_selected_stage_event[i] = NULL; } if (g_stream_selected_stage_raw[i]) { (void)cudaFreeHost(g_stream_selected_stage_raw[i]); g_stream_selected_stage_raw[i] = NULL; g_stream_selected_stage[i] = NULL; } } g_stream_selected_stage_bytes = 0; if (!g_stream_selected_upload_stream) { cudaError_t err = cudaStreamCreateWithFlags(&g_stream_selected_upload_stream, cudaStreamNonBlocking); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming selected upload stream creation failed: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } } for (size_t i = 0; i < 4; i++) { cudaError_t err = cudaMallocHost(&g_stream_selected_stage_raw[i], (size_t)bytes); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming selected staging allocation failed: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } g_stream_selected_stage[i] = cuda_align_ptr(g_stream_selected_stage_raw[i], g_model_direct_align); err = cudaEventCreateWithFlags(&g_stream_selected_stage_event[i], cudaEventDisableTiming); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming selected staging event creation failed: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } } g_stream_selected_stage_bytes = bytes; return 1; } static int cuda_stream_selected_ensure_bytes( char **ptr, uint64_t *capacity, uint64_t bytes, const char *what) { if (bytes == 0) return 1; if (*ptr && *capacity >= bytes) return 1; if (*ptr) { (void)cudaFree(*ptr); *ptr = NULL; *capacity = 0; } void *dev = NULL; cudaError_t err = cudaMalloc(&dev, (size_t)bytes); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming selected cache allocation failed for %s (%.2f MiB): %s\n", what ? what : "experts", (double)bytes / 1048576.0, cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } *ptr = (char *)dev; *capacity = bytes; return 1; } static int cuda_stream_selected_ensure_i32( int32_t **ptr, uint64_t *capacity, uint64_t count, const char *what) { if (count == 0 || count > UINT64_MAX / sizeof(int32_t)) return 0; const uint64_t bytes = count * sizeof(int32_t); if (*ptr && *capacity >= bytes) return 1; if (*ptr) { (void)cudaFree(*ptr); *ptr = NULL; *capacity = 0; } void *dev = NULL; cudaError_t err = cudaMalloc(&dev, (size_t)bytes); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming selected cache allocation failed for %s (%u entries): %s\n", what ? what : "selected slots", (unsigned)count, cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } *ptr = (int32_t *)dev; *capacity = bytes; return 1; } static cuda_stream_expert_cache *cuda_stream_expert_cache_prepare( uint64_t gate_expert_bytes, uint64_t down_expert_bytes, uint32_t target_cap) { const uint64_t expert_bytes = cuda_stream_expert_cache_expert_bytes(gate_expert_bytes, down_expert_bytes); if (expert_bytes == 0) return NULL; cuda_stream_expert_cache_note_size(gate_expert_bytes, down_expert_bytes); const uint32_t requested_cap = cuda_stream_expert_cache_configured_budget(); if (requested_cap == 0) return NULL; if (target_cap == 0 || target_cap > requested_cap) target_cap = requested_cap; if (target_cap == 0) return NULL; const int same_dims = g_stream_expert_cache.valid && g_stream_expert_cache.gate_expert_bytes == gate_expert_bytes && g_stream_expert_cache.down_expert_bytes == down_expert_bytes; if (!same_dims && g_stream_expert_cache.valid) { cuda_stream_expert_cache_release_all(); } if (same_dims && g_stream_expert_cache.capacity != 0 && g_stream_expert_cache.capacity >= target_cap && g_stream_expert_cache.slots.size() == g_stream_expert_cache.capacity) { return &g_stream_expert_cache; } uint64_t reclaim_bytes = 0; if (same_dims && g_stream_expert_cache.capacity != 0 && (uint64_t)g_stream_expert_cache.capacity <= UINT64_MAX / expert_bytes) { reclaim_bytes = (uint64_t)g_stream_expert_cache.capacity * expert_bytes; } uint32_t cap = cuda_stream_expert_cache_live_budget(target_cap, gate_expert_bytes, down_expert_bytes, reclaim_bytes, reclaim_bytes == 0); if (cap == 0) return NULL; if (same_dims && g_stream_expert_cache.capacity != 0 && g_stream_expert_cache.capacity >= cap && g_stream_expert_cache.slots.size() == g_stream_expert_cache.capacity) { return &g_stream_expert_cache; } cuda_stream_expert_cache_release_all(); while (cap != 0) { if ((uint64_t)cap > UINT64_MAX / gate_expert_bytes || (uint64_t)cap > UINT64_MAX / down_expert_bytes) { fprintf(stderr, "ds4: CUDA streaming expert cache size overflow\n"); return NULL; } char *gate_ptr = NULL; char *up_ptr = NULL; char *down_ptr = NULL; const char *alloc_error = NULL; if (!cuda_stream_expert_cache_try_alloc(cap, gate_expert_bytes, down_expert_bytes, &gate_ptr, &up_ptr, &down_ptr, &alloc_error)) { const uint32_t new_cap = cuda_stream_expert_cache_shrunken_cap(cap); cuda_stream_expert_cache_note_oom_cap(cap, new_cap, expert_bytes, alloc_error); cap = new_cap; if (cap != 0) { cap = cuda_stream_expert_cache_live_budget(cap, gate_expert_bytes, down_expert_bytes, 0, 1); } continue; } try { g_stream_expert_cache.slots.resize(cap); } catch (...) { fprintf(stderr, "ds4: CUDA streaming expert cache metadata allocation failed\n"); (void)cudaFree(gate_ptr); (void)cudaFree(up_ptr); (void)cudaFree(down_ptr); cuda_stream_expert_cache_release_all(); return NULL; } g_stream_expert_cache.valid = 1; g_stream_expert_cache.capacity = cap; g_stream_expert_cache.count = 0; g_stream_expert_cache.tick = 0; g_stream_expert_cache.gate_expert_bytes = gate_expert_bytes; g_stream_expert_cache.down_expert_bytes = down_expert_bytes; g_stream_expert_cache.gate_ptr = gate_ptr; g_stream_expert_cache.up_ptr = up_ptr; g_stream_expert_cache.down_ptr = down_ptr; g_stream_expert_cache.gate_capacity = (uint64_t)cap * gate_expert_bytes; g_stream_expert_cache.up_capacity = (uint64_t)cap * gate_expert_bytes; g_stream_expert_cache.down_capacity = (uint64_t)cap * down_expert_bytes; return &g_stream_expert_cache; } return NULL; } static int cuda_stream_expert_cache_find( cuda_stream_expert_cache *cache, const void *model_map, uint64_t model_size, uint32_t layer, uint32_t n_total_expert, uint32_t expert, uint64_t gate_offset, uint64_t up_offset, uint64_t down_offset, uint64_t gate_expert_bytes, uint64_t down_expert_bytes) { if (!cache || !cache->valid) return -1; for (uint32_t i = 0; i < cache->capacity; i++) { const cuda_stream_expert_cache_slot &slot = cache->slots[i]; if (slot.valid && slot.model_map == model_map && slot.model_size == model_size && slot.layer == layer && slot.n_total_expert == n_total_expert && slot.expert == expert && slot.gate_offset == gate_offset && slot.up_offset == up_offset && slot.down_offset == down_offset && slot.gate_expert_bytes == gate_expert_bytes && slot.down_expert_bytes == down_expert_bytes) { return (int)i; } } return -1; } static uint32_t cuda_stream_expert_cache_lru_slot( cuda_stream_expert_cache *cache) { for (uint32_t i = 0; i < cache->capacity; i++) { if (!cache->slots[i].valid) return i; } uint32_t slot = 0; uint64_t best_age = cache->slots[0].age; for (uint32_t i = 1; i < cache->capacity; i++) { if (cache->slots[i].age < best_age) { best_age = cache->slots[i].age; slot = i; } } return slot; } static int cuda_stream_expert_cache_copy_to_compact( cuda_stream_expert_cache *cache, uint32_t cache_slot, uint32_t compact_slot, char *compact_gate, char *compact_up, char *compact_down) { const uint64_t gate_src = (uint64_t)cache_slot * cache->gate_expert_bytes; const uint64_t down_src = (uint64_t)cache_slot * cache->down_expert_bytes; const uint64_t gate_dst = (uint64_t)compact_slot * cache->gate_expert_bytes; const uint64_t down_dst = (uint64_t)compact_slot * cache->down_expert_bytes; return cuda_ok(cudaMemcpy(compact_gate + gate_dst, cache->gate_ptr + gate_src, (size_t)cache->gate_expert_bytes, cudaMemcpyDeviceToDevice), "streaming selected gate cache copy") && cuda_ok(cudaMemcpy(compact_up + gate_dst, cache->up_ptr + gate_src, (size_t)cache->gate_expert_bytes, cudaMemcpyDeviceToDevice), "streaming selected up cache copy") && cuda_ok(cudaMemcpy(compact_down + down_dst, cache->down_ptr + down_src, (size_t)cache->down_expert_bytes, cudaMemcpyDeviceToDevice), "streaming selected down cache copy"); } static int cuda_stream_expert_cache_load_slot( cuda_stream_expert_cache *cache, const void *model_map, uint64_t model_size, uint32_t slot, uint32_t layer, uint32_t n_total_expert, uint32_t expert, uint64_t gate_offset, uint64_t up_offset, uint64_t down_offset, uint64_t gate_expert_bytes, uint64_t down_expert_bytes) { const uint64_t gate_src = gate_offset + (uint64_t)expert * gate_expert_bytes; const uint64_t up_src = up_offset + (uint64_t)expert * gate_expert_bytes; const uint64_t down_src = down_offset + (uint64_t)expert * down_expert_bytes; const uint64_t gate_dst = (uint64_t)slot * gate_expert_bytes; const uint64_t down_dst = (uint64_t)slot * down_expert_bytes; if (!cuda_model_copy_to_device_streamed(cache->gate_ptr + gate_dst, model_map, model_size, gate_src, gate_expert_bytes, "cached moe_gate") || !cuda_model_copy_to_device_streamed(cache->up_ptr + gate_dst, model_map, model_size, up_src, gate_expert_bytes, "cached moe_up") || !cuda_model_copy_to_device_streamed(cache->down_ptr + down_dst, model_map, model_size, down_src, down_expert_bytes, "cached moe_down")) { return 0; } cuda_stream_expert_cache_slot &entry = cache->slots[slot]; entry.valid = 1; entry.model_map = model_map; entry.model_size = model_size; entry.layer = layer; entry.n_total_expert = n_total_expert; entry.expert = expert; entry.gate_offset = gate_offset; entry.up_offset = up_offset; entry.down_offset = down_offset; entry.gate_expert_bytes = gate_expert_bytes; entry.down_expert_bytes = down_expert_bytes; entry.age = ++cache->tick; return 1; } static int cuda_stream_expert_cache_seed_one( cuda_stream_expert_cache *cache, const void *model_map, uint64_t model_size, uint32_t layer, uint32_t n_total_expert, uint32_t expert, uint64_t gate_offset, uint64_t up_offset, uint64_t down_offset, uint64_t gate_expert_bytes, uint64_t down_expert_bytes) { int cache_slot = cuda_stream_expert_cache_find(cache, model_map, model_size, layer, n_total_expert, expert, gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes); if (cache_slot >= 0) { cache->slots[(uint32_t)cache_slot].age = ++cache->tick; return 1; } const uint32_t load_slot = cuda_stream_expert_cache_lru_slot(cache); const int append = !cache->slots[load_slot].valid; if (!cuda_stream_expert_cache_load_slot(cache, model_map, model_size, load_slot, layer, n_total_expert, expert, gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes)) { return 0; } if (append && cache->count < cache->capacity) cache->count++; return 1; } static int cuda_stream_layer_expert_ranges_valid( uint64_t model_size, uint32_t n_total_expert, uint64_t gate_offset, uint64_t up_offset, uint64_t down_offset, uint64_t gate_expert_bytes, uint64_t down_expert_bytes, const char *what) { if (n_total_expert == 0 || gate_expert_bytes == 0 || down_expert_bytes == 0 || (uint64_t)n_total_expert > UINT64_MAX / gate_expert_bytes || (uint64_t)n_total_expert > UINT64_MAX / down_expert_bytes) { fprintf(stderr, "ds4: CUDA streaming %s expert size overflow\n", what ? what : "selected"); return 0; } const uint64_t full_gate_bytes = (uint64_t)n_total_expert * gate_expert_bytes; const uint64_t full_down_bytes = (uint64_t)n_total_expert * down_expert_bytes; if (gate_offset > model_size || up_offset > model_size || down_offset > model_size || full_gate_bytes > model_size - gate_offset || full_gate_bytes > model_size - up_offset || full_down_bytes > model_size - down_offset) { fprintf(stderr, "ds4: CUDA streaming %s expert range outside model map\n", what ? what : "selected"); return 0; } return 1; } static int cuda_model_copy_to_device_streamed( char *dst, const void *model_map, uint64_t model_size, uint64_t offset, uint64_t bytes, const char *what) { if (!dst || !model_map || offset > model_size || bytes > model_size - offset) { return 0; } if (bytes == 0) return 1; if (g_model_fd < 0 || (g_model_fd_host_base != NULL && model_map != g_model_fd_host_base)) { return cuda_ok(cudaMemcpy(dst, (const char *)model_map + offset, (size_t)bytes, cudaMemcpyHostToDevice), what ? what : "stream selected expert copy"); } const uint64_t chunk = cuda_model_copy_chunk_bytes(); const uint64_t stage_bytes = chunk + (g_model_direct_align > 1 ? g_model_direct_align : 1); if (!cuda_stream_selected_stage_pool_alloc(stage_bytes)) return 0; cudaError_t err = cudaSuccess; uint64_t copied = 0; uint64_t chunk_idx = 0; while (copied < bytes) { const uint64_t n = (bytes - copied < chunk) ? (bytes - copied) : chunk; const uint64_t bi = chunk_idx % 4u; if (chunk_idx >= 4u) { err = cudaEventSynchronize(g_stream_selected_stage_event[bi]); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming selected staging wait failed for %s: %s\n", what ? what : "expert", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } } const char *payload = NULL; if (!cuda_model_stage_read(g_stream_selected_stage[bi], g_stream_selected_stage_bytes, offset + copied, n, &payload)) { fprintf(stderr, "ds4: CUDA streaming selected read failed for %s at %.2f MiB: %s\n", what ? what : "expert", (double)copied / 1048576.0, strerror(errno)); return 0; } err = cudaMemcpyAsync(dst + copied, payload, (size_t)n, cudaMemcpyHostToDevice, g_stream_selected_upload_stream); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming selected copy failed for %s at %.2f MiB: %s\n", what ? what : "expert", (double)copied / 1048576.0, cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } err = cudaEventRecord(g_stream_selected_stage_event[bi], g_stream_selected_upload_stream); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming selected staging record failed for %s: %s\n", what ? what : "expert", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } cuda_model_drop_file_pages(offset + copied, n); cuda_model_discard_source_pages(model_map, model_size, offset + copied, n); copied += n; chunk_idx++; } err = cudaStreamSynchronize(g_stream_selected_upload_stream); if (err != cudaSuccess) { fprintf(stderr, "ds4: CUDA streaming selected upload sync failed for %s: %s\n", what ? what : "expert", cudaGetErrorString(err)); (void)cudaGetLastError(); return 0; } return 1; } static int cublas_ok(cublasStatus_t st, const char *what) { if (st == CUBLAS_STATUS_SUCCESS) return 1; fprintf(stderr, "ds4: cuBLAS %s failed: status %d\n", what, (int)st); return 0; } extern "C" int ds4_gpu_init(void) { int dev = 0; if (!cuda_ok(cudaSetDevice(dev), "set device")) return 0; cudaDeviceProp prop; if (cudaGetDeviceProperties(&prop, dev) == cudaSuccess) { fprintf(stderr, "ds4: CUDA backend initialized on %s (sm_%d%d)\n", prop.name, prop.major, prop.minor); } if (!g_cublas_ready) { if (!cublas_ok(cublasCreate(&g_cublas), "create handle")) return 0; const cublasMath_t math_mode = (g_quality_mode || getenv("DS4_CUDA_NO_TF32") != NULL) ? CUBLAS_DEFAULT_MATH : CUBLAS_TF32_TENSOR_OP_MATH; (void)cublasSetMathMode(g_cublas, math_mode); g_cublas_ready = 1; } return 1; } extern "C" void ds4_gpu_cleanup(void) { (void)cudaDeviceSynchronize(); if (g_cublas_ready) { (void)cublasDestroy(g_cublas); g_cublas_ready = 0; g_cublas = NULL; } cuda_stream_selected_cache_release(); cuda_stream_expert_cache_release_all(); cuda_stream_selected_stage_release(); cuda_model_range_release_all(); cuda_model_load_progress_reset(); cuda_q8_f16_cache_release_all(); g_q8_f16_disabled_after_oom = 0; g_q8_f16_budget_notice_printed = 0; for (const cuda_q8_f32_range &r : g_q8_f32_ranges) { (void)cudaFree(r.device_ptr); } g_q8_f32_ranges.clear(); g_q8_f32_by_offset.clear(); g_q8_f32_bytes = 0; if (g_cuda_tmp) { (void)cudaFree(g_cuda_tmp); g_cuda_tmp = NULL; g_cuda_tmp_bytes = 0; } for (size_t i = 0; i < 4; i++) { if (g_model_stage_event[i]) { (void)cudaEventDestroy(g_model_stage_event[i]); g_model_stage_event[i] = NULL; } if (g_model_stage_raw[i]) { (void)cudaFreeHost(g_model_stage_raw[i]); g_model_stage_raw[i] = NULL; g_model_stage[i] = NULL; } } g_model_stage_bytes = 0; if (g_model_upload_stream) { (void)cudaStreamDestroy(g_model_upload_stream); g_model_upload_stream = NULL; } if (g_model_device_owned && g_model_device_base) { (void)cudaFree((void *)g_model_device_base); } if (g_model_registered && g_model_host_base) { (void)cudaHostUnregister((void *)g_model_host_base); } g_model_host_base = NULL; g_model_device_base = NULL; g_model_registered_size = 0; g_model_registered = 0; g_model_device_owned = 0; g_model_range_mapping_supported = 1; g_model_hmm_direct = 0; g_model_fd = -1; if (g_model_direct_fd >= 0) { (void)close(g_model_direct_fd); g_model_direct_fd = -1; } g_model_direct_align = 1; g_model_file_size = 0; g_model_cache_full = 0; g_model_mapping_failure_notice_printed = 0; g_ssd_streaming_mode = 0; if (g_model_prefetch_stream) { (void)cudaStreamDestroy(g_model_prefetch_stream); g_model_prefetch_stream = NULL; } } __global__ static void fill_f32_kernel(float *x, uint64_t n, float v); extern "C" ds4_gpu_tensor *ds4_gpu_tensor_alloc(uint64_t bytes) { if (bytes == 0) bytes = 1; ds4_gpu_tensor *t = (ds4_gpu_tensor *)calloc(1, sizeof(*t)); if (!t) return NULL; if (!cuda_ok(cudaMalloc(&t->ptr, (size_t)bytes), "tensor alloc")) { free(t); return NULL; } t->bytes = bytes; t->owner = 1; return t; } extern "C" ds4_gpu_tensor *ds4_gpu_tensor_alloc_managed(uint64_t bytes) { if (bytes == 0) bytes = 1; ds4_gpu_tensor *t = (ds4_gpu_tensor *)calloc(1, sizeof(*t)); if (!t) return NULL; if (!cuda_ok(cudaMallocManaged(&t->ptr, (size_t)bytes), "managed tensor alloc")) { free(t); return NULL; } t->bytes = bytes; t->owner = 1; return t; } static uint64_t cuda_managed_kv_reserve_bytes(uint64_t total_bytes) { const uint64_t min_reserve = 8ull * 1073741824ull; const uint64_t max_reserve = 40ull * 1073741824ull; uint64_t reserve = total_bytes / 4u; if (reserve < min_reserve) reserve = min_reserve; if (reserve > max_reserve) reserve = max_reserve; return reserve; } extern "C" int ds4_gpu_should_use_managed_kv_cache(uint64_t kv_cache_bytes, uint64_t context_bytes) { if (kv_cache_bytes == 0) return 0; /* Very large KV caches are where device-only cudaMalloc() can make a * unified-memory machine unresponsive. Managed memory restores the old * demand-paged behavior for this one long-lived allocation class only. */ const uint64_t huge_kv = 8ull * 1073741824ull; if (kv_cache_bytes >= huge_kv) return 1; const uint64_t large_context = 8ull * 1073741824ull; if (context_bytes < large_context) return 0; size_t free_b = 0; size_t total_b = 0; cudaError_t err = cudaMemGetInfo(&free_b, &total_b); if (err != cudaSuccess) { (void)cudaGetLastError(); return 0; } const uint64_t free_bytes = (uint64_t)free_b; const uint64_t total_bytes = (uint64_t)total_b; const uint64_t reserve_bytes = cuda_managed_kv_reserve_bytes(total_bytes); if (context_bytes > free_bytes) return 1; return free_bytes - context_bytes < reserve_bytes; } extern "C" ds4_gpu_tensor *ds4_gpu_tensor_view(const ds4_gpu_tensor *base, uint64_t offset, uint64_t bytes) { if (!base || offset > base->bytes || bytes > base->bytes - offset) return NULL; ds4_gpu_tensor *t = (ds4_gpu_tensor *)calloc(1, sizeof(*t)); if (!t) return NULL; t->ptr = (char *)base->ptr + offset; t->bytes = bytes; t->owner = 0; return t; } extern "C" void ds4_gpu_tensor_free(ds4_gpu_tensor *tensor) { if (!tensor) return; if (tensor->owner && tensor->ptr) (void)cudaFree(tensor->ptr); free(tensor); } extern "C" uint64_t ds4_gpu_tensor_bytes(const ds4_gpu_tensor *tensor) { return tensor ? tensor->bytes : 0; } extern "C" void *ds4_gpu_tensor_contents(ds4_gpu_tensor *tensor) { if (!tensor) return NULL; (void)cudaDeviceSynchronize(); return tensor->ptr; } extern "C" int ds4_gpu_tensor_fill_f32(ds4_gpu_tensor *tensor, float value, uint64_t count) { if (!tensor || count > tensor->bytes / sizeof(float)) return 0; if (count == 0) return 1; fill_f32_kernel<<<(count + 255u) / 256u, 256>>>((float *)tensor->ptr, count, value); return cuda_ok(cudaGetLastError(), "tensor fill f32 launch"); } extern "C" int ds4_gpu_tensor_write(ds4_gpu_tensor *tensor, uint64_t offset, const void *data, uint64_t bytes) { if (!tensor || !data || offset > tensor->bytes || bytes > tensor->bytes - offset) return 0; return cuda_ok(cudaMemcpy((char *)tensor->ptr + offset, data, (size_t)bytes, cudaMemcpyHostToDevice), "tensor write"); } extern "C" int ds4_gpu_tensor_read(const ds4_gpu_tensor *tensor, uint64_t offset, void *data, uint64_t bytes) { if (!tensor || !data || offset > tensor->bytes || bytes > tensor->bytes - offset) return 0; return cuda_ok(cudaMemcpy(data, (const char *)tensor->ptr + offset, (size_t)bytes, cudaMemcpyDeviceToHost), "tensor read"); } extern "C" int ds4_gpu_tensor_read_after_selected_event(const ds4_gpu_tensor *tensor, uint64_t offset, void *data, uint64_t bytes, uint64_t event_value, const char *label) { (void)event_value; (void)label; return ds4_gpu_tensor_read(tensor, offset, data, bytes); } extern "C" int ds4_gpu_tensor_copy(ds4_gpu_tensor *dst, uint64_t dst_offset, const ds4_gpu_tensor *src, uint64_t src_offset, uint64_t bytes) { if (!dst || !src || dst_offset > dst->bytes || src_offset > src->bytes || bytes > dst->bytes - dst_offset || bytes > src->bytes - src_offset) { return 0; } if (bytes == 0) return 1; return cuda_ok(cudaMemcpy((char *)dst->ptr + dst_offset, (const char *)src->ptr + src_offset, (size_t)bytes, cudaMemcpyDeviceToDevice), "tensor copy"); } extern "C" int ds4_gpu_begin_commands(void) { return 1; } extern "C" int ds4_gpu_flush_commands(void) { return cuda_ok(cudaDeviceSynchronize(), "flush"); } extern "C" int ds4_gpu_signal_selected_readback_ready(uint64_t *event_value) { if (event_value) *event_value = 1; return cuda_ok(cudaDeviceSynchronize(), "selected readback signal"); } extern "C" int ds4_gpu_commit_and_wait_selected_readback(uint64_t event_value, const char *label) { (void)event_value; return cuda_ok(cudaDeviceSynchronize(), label ? label : "selected readback wait"); } extern "C" int ds4_gpu_wait_selected_readback_ready(uint64_t event_value, const char *label) { (void)event_value; (void)label; return cuda_ok(cudaDeviceSynchronize(), "selected readback wait"); } extern "C" int ds4_gpu_end_commands(void) { cuda_model_load_progress_finish(); return cuda_ok(cudaDeviceSynchronize(), "end commands"); } extern "C" int ds4_gpu_synchronize(void) { cuda_model_load_progress_finish(); return cuda_ok(cudaDeviceSynchronize(), "synchronize"); } static int cuda_model_set_host_map(const void *model_map, uint64_t model_size) { if (!model_map || model_size == 0) return 0; const int same_backing_model = g_model_host_base == model_map && g_model_registered_size == model_size; cuda_stream_selected_cache_invalidate(); if (!same_backing_model) { cuda_stream_expert_cache_release_all(); } cuda_model_range_release_all(); if (!same_backing_model) { cuda_model_load_progress_reset(); } cuda_q8_f16_cache_release_all(); g_q8_f16_disabled_after_oom = 0; g_q8_f16_budget_notice_printed = 0; for (const cuda_q8_f32_range &r : g_q8_f32_ranges) { (void)cudaFree(r.device_ptr); } g_q8_f32_ranges.clear(); g_q8_f32_by_offset.clear(); g_q8_f32_bytes = 0; if (!same_backing_model) { if (g_model_device_owned && g_model_device_base) { (void)cudaFree((void *)g_model_device_base); g_model_device_owned = 0; } if (g_model_registered && g_model_host_base) { (void)cudaHostUnregister((void *)g_model_host_base); g_model_registered = 0; } g_model_host_base = model_map; g_model_device_base = (const char *)model_map; g_model_registered_size = model_size; } else if (!g_model_device_owned && !g_model_registered) { g_model_device_base = (const char *)model_map; } g_model_range_mapping_supported = 1; g_model_hmm_direct = 0; g_model_cache_full = 0; g_model_mapping_failure_notice_printed = 0; if (g_model_fd >= 0 && g_model_fd_host_base == NULL) { g_model_fd_host_base = model_map; } return 1; } extern "C" int ds4_gpu_set_model_map(const void *model_map, uint64_t model_size) { if (!cuda_model_set_host_map(model_map, model_size)) return 0; const char *copy_env = getenv("DS4_CUDA_COPY_MODEL"); if (copy_env && copy_env[0]) { void *dev = NULL; const double t0 = clock() / (double)CLOCKS_PER_SEC; cudaError_t err = cudaMalloc(&dev, (size_t)model_size); if (err == cudaSuccess) { fprintf(stderr, "ds4: CUDA copying %.2f GiB model to device memory\n", (double)model_size / 1073741824.0); err = cudaMemcpy(dev, model_map, (size_t)model_size, cudaMemcpyHostToDevice); if (err == cudaSuccess) { g_model_device_base = (const char *)dev; g_model_device_owned = 1; const double t1 = clock() / (double)CLOCKS_PER_SEC; fprintf(stderr, "ds4: CUDA model copy complete in %.3fs\n", t1 - t0); return 1; } fprintf(stderr, "ds4: CUDA model copy failed: %s\n", cudaGetErrorString(err)); (void)cudaFree(dev); (void)cudaGetLastError(); } else { fprintf(stderr, "ds4: CUDA model allocation skipped: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); } } unsigned int flags = cudaHostRegisterMapped | cudaHostRegisterReadOnly; if (getenv("DS4_CUDA_HOST_REGISTER_PLAIN") != NULL) { flags = cudaHostRegisterMapped; } cudaError_t err = cudaHostRegister((void *)model_map, (size_t)model_size, flags); if (err == cudaSuccess) { void *dev = NULL; err = cudaHostGetDevicePointer(&dev, (void *)model_map, 0); if (err == cudaSuccess && dev) { g_model_device_base = (const char *)dev; g_model_registered = 1; fprintf(stderr, "ds4: CUDA registered %.2f GiB model mapping for device access\n", (double)model_size / 1073741824.0); } else { fprintf(stderr, "ds4: CUDA host registration pointer lookup failed: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); } } else { fprintf(stderr, "ds4: CUDA host registration skipped: %s\n", cudaGetErrorString(err)); (void)cudaGetLastError(); const uint64_t limit = cuda_model_local_model_limit_bytes(); if (!cuda_model_cache_limit_explicit() && model_size > limit) { fprintf(stderr, "ds4: CUDA model %.2f GiB exceeds the default single-GPU " "startup cache budget %.2f GiB; use distributed layer " "loading or set DS4_CUDA_WEIGHT_CACHE_LIMIT_GB explicitly\n", (double)model_size / 1073741824.0, (double)limit / 1073741824.0); return 0; } } return 1; } extern "C" int ds4_gpu_set_model_map_range(const void *model_map, uint64_t model_size, uint64_t map_offset, uint64_t map_size, uint64_t max_tensor_bytes) { (void)max_tensor_bytes; if (!ds4_gpu_set_model_map(model_map, model_size)) return 0; if (getenv("DS4_CUDA_COPY_MODEL_CHUNKED") != NULL && !cuda_model_copy_chunked(model_map, model_size, map_offset, map_size)) { (void)cuda_model_prefetch_range(model_map, model_size, map_offset, map_size); } return 1; } extern "C" int ds4_gpu_pro_q4_expert_table_auto_available(void) { return 0; } extern "C" int ds4_gpu_preload_q4_expert_tables(const void *model_map, uint64_t model_size, uint64_t gate_offset, uint64_t up_offset, uint64_t down_offset, uint64_t gate_expert_bytes, uint64_t down_expert_bytes, uint32_t n_total_expert) { (void)model_map; (void)model_size; (void)gate_offset; (void)up_offset; (void)down_offset; (void)gate_expert_bytes; (void)down_expert_bytes; (void)n_total_expert; return 1; } extern "C" int ds4_gpu_set_model_map_spans( const void *model_map, uint64_t model_size, const uint64_t *offsets, const uint64_t *sizes, uint32_t count, uint64_t max_tensor_bytes) { (void)max_tensor_bytes; if (!model_map || model_size == 0 || !offsets || !sizes || count == 0) return 0; for (uint32_t i = 0; i < count; i++) { if (offsets[i] > model_size || sizes[i] == 0 || sizes[i] > model_size - offsets[i]) { return 0; } } if (!cuda_model_set_host_map(model_map, model_size)) return 0; if (getenv("DS4_CUDA_COPY_MODEL_CHUNKED") != NULL) { for (uint32_t i = 0; i < count; i++) { (void)cuda_model_prefetch_range(model_map, model_size, offsets[i], sizes[i]); } } return 1; } extern "C" int ds4_gpu_set_model_fd_for_map(int fd, const void *model_map) { g_model_fd = fd; g_model_fd_host_base = model_map; g_model_file_size = 0; if (g_model_direct_fd >= 0) { (void)close(g_model_direct_fd); g_model_direct_fd = -1; } g_model_direct_align = 1; if (fd >= 0) { struct stat st; if (fstat(fd, &st) == 0 && st.st_size > 0) { g_model_file_size = (uint64_t)st.st_size; if (st.st_blksize > 1) g_model_direct_align = (uint64_t)st.st_blksize; } #if defined(__linux__) && defined(O_DIRECT) if (getenv("DS4_CUDA_NO_DIRECT_IO") == NULL) { char proc_path[64]; snprintf(proc_path, sizeof(proc_path), "/proc/self/fd/%d", fd); int direct_fd = open(proc_path, O_RDONLY | O_DIRECT); if (direct_fd >= 0) { g_model_direct_fd = direct_fd; if (g_model_direct_align < 512) g_model_direct_align = 512; if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA model direct I/O enabled (align=%llu)\n", (unsigned long long)g_model_direct_align); } } else if (getenv("DS4_CUDA_WEIGHT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA model direct I/O unavailable: %s\n", strerror(errno)); } } #endif } return 1; } extern "C" int ds4_gpu_set_model_fd(int fd) { return ds4_gpu_set_model_fd_for_map(fd, g_model_host_base); } extern "C" int ds4_gpu_cache_model_range(const void *model_map, uint64_t model_size, uint64_t offset, uint64_t bytes, const char *label) { if (!model_map || bytes == 0) return 1; if (offset > model_size || bytes > model_size - offset) return 0; if (cuda_model_range_is_cached(model_map, offset, bytes)) return 1; const char *ptr = cuda_model_range_ptr(model_map, offset, bytes, label ? label : "model_tensor"); if (!ptr || !cuda_model_range_is_cached(model_map, offset, bytes)) { if (!g_model_mapping_failure_notice_printed) { fprintf(stderr, "ds4: CUDA failed to prepare model tensor spans for device access\n"); g_model_mapping_failure_notice_printed = 1; } return 0; } return 1; } extern "C" int ds4_gpu_cache_q8_f16_range(const void *model_map, uint64_t model_size, uint64_t offset, uint64_t bytes, uint64_t in_dim, uint64_t out_dim, const char *label) { if (!model_map || bytes == 0) return 1; if (offset > model_size || bytes > model_size - offset) return 0; const char *cache_label = label ? label : "q8_0"; if (getenv("DS4_CUDA_Q8_F32_PRELOAD") != NULL && cuda_q8_f32_cache_allowed(cache_label, in_dim, out_dim)) { if (cuda_q8_f32_ptr(model_map, offset, bytes, in_dim, out_dim, cache_label)) return 1; return 1; } if (!cuda_q8_f16_cache_allowed(cache_label, in_dim, out_dim)) return 1; if (cuda_q8_f16_ptr(model_map, offset, bytes, in_dim, out_dim, cache_label)) return 1; return 1; } extern "C" void ds4_gpu_print_memory_report(const char *label) { size_t free_b = 0, total_b = 0; (void)cudaMemGetInfo(&free_b, &total_b); fprintf(stderr, "ds4: CUDA memory report %s: free %.2f MiB total %.2f MiB\n", label ? label : "", (double)free_b / 1048576.0, (double)total_b / 1048576.0); } extern "C" void ds4_gpu_set_quality(bool quality) { g_quality_mode = quality ? 1 : 0; if (g_cublas_ready) { const cublasMath_t math_mode = (g_quality_mode || getenv("DS4_CUDA_NO_TF32") != NULL) ? CUBLAS_DEFAULT_MATH : CUBLAS_TF32_TENSOR_OP_MATH; (void)cublasSetMathMode(g_cublas, math_mode); } } extern "C" void ds4_gpu_set_ssd_streaming(bool enabled) { g_ssd_streaming_mode = enabled ? 1 : 0; g_stream_expert_runtime_cap = 0; g_stream_expert_runtime_gate_bytes = 0; g_stream_expert_runtime_down_bytes = 0; g_stream_expert_memory_cap_notice = 0; if (!g_ssd_streaming_mode) { cuda_stream_selected_cache_release(); cuda_stream_expert_cache_release_all(); } } extern "C" void ds4_gpu_set_streaming_expert_cache_budget(uint32_t experts) { g_stream_expert_budget_override = experts; g_stream_expert_runtime_cap = 0; g_stream_expert_runtime_gate_bytes = 0; g_stream_expert_runtime_down_bytes = 0; g_stream_expert_memory_cap_notice = 0; cuda_stream_selected_cache_invalidate(); cuda_stream_expert_cache_release_all(); } extern "C" void ds4_gpu_set_streaming_expert_cache_expert_bytes(uint64_t bytes) { (void)bytes; } extern "C" uint64_t ds4_gpu_recommended_working_set_size(void) { return 0; } extern "C" uint32_t ds4_gpu_stream_expert_cache_configured_count(void) { if (!cuda_stream_expert_cache_budget_visible_to_shared()) return 0; return cuda_stream_expert_cache_configured_budget(); } extern "C" uint32_t ds4_gpu_stream_expert_cache_current_count(void) { return g_stream_expert_cache.count; } extern "C" void ds4_gpu_stream_expert_cache_reset_route_hotness(void) { } extern "C" void ds4_gpu_stream_expert_cache_release_resident(void) { cuda_stream_expert_cache_release_all(); } extern "C" uint32_t ds4_gpu_stream_expert_cache_budget_for_expert_size( uint64_t gate_expert_bytes, uint64_t down_expert_bytes) { if (!cuda_stream_expert_cache_budget_visible_to_shared() || cuda_stream_expert_cache_expert_bytes(gate_expert_bytes, down_expert_bytes) == 0) { return 0; } cuda_stream_expert_cache_note_size(gate_expert_bytes, down_expert_bytes); return cuda_stream_expert_cache_configured_budget(); } extern "C" int ds4_gpu_stream_expert_cache_seed_selected( const ds4_gpu_stream_expert_table *table, const int32_t *selected_ids, uint32_t n_selected) { if (!g_ssd_streaming_mode) return 1; if (!table) return 0; const void *model_map = table->model_map; const uint64_t model_size = table->model_size; const uint32_t layer = table->layer; const uint32_t n_total_expert = table->n_total_expert; const uint64_t gate_offset = table->gate_offset; const uint64_t up_offset = table->up_offset; const uint64_t down_offset = table->down_offset; const uint64_t gate_expert_bytes = table->gate_expert_bytes; const uint64_t down_expert_bytes = table->down_expert_bytes; if (!model_map || !selected_ids || n_selected == 0 || n_selected > n_total_expert || !cuda_stream_layer_expert_ranges_valid(model_size, n_total_expert, gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes, "seed selected")) { return 0; } cuda_stream_expert_cache *cache = cuda_stream_expert_cache_prepare(gate_expert_bytes, down_expert_bytes, n_selected); if (!cache) return 1; for (uint32_t i = 0; i < n_selected; i++) { if (selected_ids[i] < 0 || (uint32_t)selected_ids[i] >= n_total_expert) { fprintf(stderr, "ds4: CUDA streaming seed selected expert id %d is outside 0..%u at layer %u\n", selected_ids[i], n_total_expert, layer); return 0; } if (!cuda_stream_expert_cache_seed_one(cache, model_map, model_size, layer, n_total_expert, (uint32_t)selected_ids[i], gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes)) { cuda_stream_expert_cache_invalidate(); return 1; } } return 1; } static int cuda_stream_selected_cache_begin_compact_load( const void *model_map, uint64_t model_size, uint32_t layer, const int32_t *compact_ids, const int32_t *slot_ids, uint32_t n_total_expert, uint32_t compact_count, uint32_t slot_count, uint64_t gate_offset, uint64_t up_offset, uint64_t down_offset, uint64_t gate_expert_bytes, uint64_t down_expert_bytes, int strict_failure, int allow_global_cache) { cuda_stream_selected_cache_invalidate(); cuda_model_load_progress_finish(); if (!g_ssd_streaming_mode) return 1; if (!model_map || !compact_ids || !slot_ids || n_total_expert == 0 || compact_count == 0 || compact_count > n_total_expert || slot_count == 0 || gate_expert_bytes == 0 || down_expert_bytes == 0) { return 0; } if ((uint64_t)n_total_expert > UINT64_MAX / gate_expert_bytes || (uint64_t)n_total_expert > UINT64_MAX / down_expert_bytes || (uint64_t)compact_count > UINT64_MAX / gate_expert_bytes || (uint64_t)compact_count > UINT64_MAX / down_expert_bytes) { fprintf(stderr, "ds4: CUDA streaming selected expert size overflow\n"); return 0; } const uint64_t full_gate_bytes = (uint64_t)n_total_expert * gate_expert_bytes; const uint64_t full_down_bytes = (uint64_t)n_total_expert * down_expert_bytes; const uint64_t compact_gate_bytes = (uint64_t)compact_count * gate_expert_bytes; const uint64_t compact_down_bytes = (uint64_t)compact_count * down_expert_bytes; if (gate_offset > model_size || up_offset > model_size || down_offset > model_size || full_gate_bytes > model_size - gate_offset || full_gate_bytes > model_size - up_offset || full_down_bytes > model_size - down_offset) { fprintf(stderr, "ds4: CUDA streaming selected expert range outside model map\n"); return 0; } if (!allow_global_cache) { cuda_stream_expert_cache_release_all(); } if (!cuda_stream_selected_ensure_bytes(&g_stream_selected_cache.gate_ptr, &g_stream_selected_cache.gate_capacity, compact_gate_bytes, "selected gate experts") || !cuda_stream_selected_ensure_bytes(&g_stream_selected_cache.up_ptr, &g_stream_selected_cache.up_capacity, compact_gate_bytes, "selected up experts") || !cuda_stream_selected_ensure_bytes(&g_stream_selected_cache.down_ptr, &g_stream_selected_cache.down_capacity, compact_down_bytes, "selected down experts") || !cuda_stream_selected_ensure_i32(&g_stream_selected_cache.slot_selected_ptr, &g_stream_selected_cache.slot_selected_capacity, slot_count, "selected expert slots")) { return strict_failure ? 0 : 1; } if (allow_global_cache) { cuda_stream_expert_cache_note_size(gate_expert_bytes, down_expert_bytes); } const uint32_t configured_cache_budget = cuda_stream_expert_cache_configured_budget(); const int use_global_cache = allow_global_cache && configured_cache_budget != 0; cuda_stream_expert_cache *expert_cache = use_global_cache ? cuda_stream_expert_cache_prepare(gate_expert_bytes, down_expert_bytes, configured_cache_budget) : NULL; int expert_cache_disabled = expert_cache == NULL; const uint32_t cache_count_before = expert_cache && expert_cache->valid ? expert_cache->count : 0; uint32_t cache_hits = 0; uint32_t cache_misses = 0; uint32_t direct_loads = 0; for (uint32_t i = 0; i < compact_count; i++) { if (compact_ids[i] < 0 || (uint32_t)compact_ids[i] >= n_total_expert) { fprintf(stderr, "ds4: CUDA streaming selected expert id %d is outside 0..%u at layer %u\n", compact_ids[i], n_total_expert, layer); return 0; } const uint64_t expert = (uint64_t)(uint32_t)compact_ids[i]; const uint64_t gate_dst = (uint64_t)i * gate_expert_bytes; const uint64_t down_dst = (uint64_t)i * down_expert_bytes; int copied_from_global_cache = 0; if (!expert_cache_disabled) { int cache_slot = cuda_stream_expert_cache_find(expert_cache, model_map, model_size, layer, n_total_expert, (uint32_t)expert, gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes); if (cache_slot >= 0) { cache_hits++; expert_cache->slots[(uint32_t)cache_slot].age = ++expert_cache->tick; } else { cache_misses++; const uint32_t load_slot = cuda_stream_expert_cache_lru_slot(expert_cache); const int append = !expert_cache->slots[load_slot].valid; if (cuda_stream_expert_cache_load_slot(expert_cache, model_map, model_size, load_slot, layer, n_total_expert, (uint32_t)expert, gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes)) { if (append && expert_cache->count < expert_cache->capacity) { expert_cache->count++; } cache_slot = (int)load_slot; } else { cuda_stream_expert_cache_invalidate(); expert_cache_disabled = 1; cache_slot = -1; } } if (cache_slot >= 0) { copied_from_global_cache = cuda_stream_expert_cache_copy_to_compact( expert_cache, (uint32_t)cache_slot, i, g_stream_selected_cache.gate_ptr, g_stream_selected_cache.up_ptr, g_stream_selected_cache.down_ptr); if (!copied_from_global_cache) { cuda_stream_expert_cache_invalidate(); expert_cache_disabled = 1; } } } if (!copied_from_global_cache) { const uint64_t gate_src = gate_offset + expert * gate_expert_bytes; const uint64_t up_src = up_offset + expert * gate_expert_bytes; const uint64_t down_src = down_offset + expert * down_expert_bytes; direct_loads++; if (!cuda_model_copy_to_device_streamed(g_stream_selected_cache.gate_ptr + gate_dst, model_map, model_size, gate_src, gate_expert_bytes, "selected moe_gate") || !cuda_model_copy_to_device_streamed(g_stream_selected_cache.up_ptr + gate_dst, model_map, model_size, up_src, gate_expert_bytes, "selected moe_up") || !cuda_model_copy_to_device_streamed(g_stream_selected_cache.down_ptr + down_dst, model_map, model_size, down_src, down_expert_bytes, "selected moe_down")) { cuda_stream_selected_cache_invalidate(); return strict_failure ? 0 : 1; } } } if (!cuda_ok(cudaMemcpy(g_stream_selected_cache.slot_selected_ptr, slot_ids, (size_t)slot_count * sizeof(slot_ids[0]), cudaMemcpyHostToDevice), "streaming selected slot upload")) { cuda_stream_selected_cache_invalidate(); return strict_failure ? 0 : 1; } g_stream_selected_cache.model_map = model_map; g_stream_selected_cache.layer = layer; g_stream_selected_cache.n_total_expert = n_total_expert; g_stream_selected_cache.n_selected = slot_count; g_stream_selected_cache.slot_count = slot_count; g_stream_selected_cache.compact_count = compact_count; g_stream_selected_cache.gate_offset = gate_offset; g_stream_selected_cache.up_offset = up_offset; g_stream_selected_cache.down_offset = down_offset; g_stream_selected_cache.gate_expert_bytes = gate_expert_bytes; g_stream_selected_cache.down_expert_bytes = down_expert_bytes; g_stream_selected_cache.slot_selected_tensor.ptr = g_stream_selected_cache.slot_selected_ptr; g_stream_selected_cache.slot_selected_tensor.bytes = (uint64_t)slot_count * sizeof(int32_t); g_stream_selected_cache.slot_selected_tensor.owner = 0; g_stream_selected_cache.valid = 1; if (getenv("DS4_CUDA_STREAMING_EXPERT_CACHE_VERBOSE")) { cuda_model_load_progress_finish(); fprintf(stderr, "ds4: CUDA streaming selected layer=%u slots=%u compact=%u global_budget=%u before=%u after=%u hits=%u misses=%u direct=%u gate/up %.2f MiB down %.2f MiB\n", layer, slot_count, compact_count, expert_cache && expert_cache->valid ? expert_cache->capacity : 0, cache_count_before, expert_cache && expert_cache->valid ? expert_cache->count : 0, cache_hits, cache_misses, direct_loads, (double)compact_gate_bytes / 1048576.0, (double)compact_down_bytes / 1048576.0); } return 1; } extern "C" int ds4_gpu_stream_expert_cache_begin_selected_load( const ds4_gpu_stream_expert_table *table, const int32_t *selected_ids, uint32_t n_selected) { if (!g_ssd_streaming_mode) return 1; if (!table || !selected_ids || n_selected == 0) return 0; const void *model_map = table->model_map; const uint64_t model_size = table->model_size; const uint32_t layer = table->layer; const uint32_t n_total_expert = table->n_total_expert; const uint64_t gate_offset = table->gate_offset; const uint64_t up_offset = table->up_offset; const uint64_t down_offset = table->down_offset; const uint64_t gate_expert_bytes = table->gate_expert_bytes; const uint64_t down_expert_bytes = table->down_expert_bytes; std::vector expert_to_slot(n_total_expert, -1); std::vector compact_ids; std::vector slot_ids(n_selected); compact_ids.reserve(n_selected); for (uint32_t i = 0; i < n_selected; i++) { const int32_t expert_i = selected_ids[i]; if (expert_i < 0 || (uint32_t)expert_i >= n_total_expert) { fprintf(stderr, "ds4: CUDA streaming selected expert id %d is outside 0..%u at layer %u\n", expert_i, n_total_expert, layer); return 0; } expert_to_slot[(uint32_t)expert_i] = -2; } for (uint32_t e = 0; e < n_total_expert; e++) { if (expert_to_slot[e] != -2) continue; expert_to_slot[e] = (int32_t)compact_ids.size(); compact_ids.push_back((int32_t)e); } for (uint32_t i = 0; i < n_selected; i++) { slot_ids[i] = expert_to_slot[(uint32_t)selected_ids[i]]; } if (compact_ids.empty() || compact_ids.size() > UINT32_MAX) return 0; return cuda_stream_selected_cache_begin_compact_load( model_map, model_size, layer, compact_ids.data(), slot_ids.data(), n_total_expert, (uint32_t)compact_ids.size(), n_selected, gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes, 0, 1); } extern "C" int ds4_gpu_stream_expert_cache_prepare_selected_batch( const ds4_gpu_stream_expert_table *table, const int32_t *selected_ids, uint32_t n_tokens, uint32_t n_selected) { if (!g_ssd_streaming_mode) return 1; if (!table || !selected_ids || table->n_total_expert == 0 || n_selected == 0 || n_tokens == 0 || (uint64_t)n_tokens > UINT32_MAX / (uint64_t)n_selected) { return 0; } const void *model_map = table->model_map; const uint64_t model_size = table->model_size; const uint32_t layer = table->layer; const uint32_t n_total_expert = table->n_total_expert; const uint64_t gate_offset = table->gate_offset; const uint64_t up_offset = table->up_offset; const uint64_t down_offset = table->down_offset; const uint64_t gate_expert_bytes = table->gate_expert_bytes; const uint64_t down_expert_bytes = table->down_expert_bytes; std::vector expert_to_slot(n_total_expert, -1); std::vector compact_ids; const uint32_t slot_count = n_tokens * n_selected; std::vector slot_ids(slot_count); compact_ids.reserve(slot_count < n_total_expert ? slot_count : n_total_expert); for (uint32_t i = 0; i < slot_count; i++) { const int32_t expert_i = selected_ids[i]; if (expert_i < 0 || (uint32_t)expert_i >= n_total_expert) { fprintf(stderr, "ds4: CUDA streaming batch selected expert id %d is outside 0..%u at layer %u\n", expert_i, n_total_expert, layer); return 0; } expert_to_slot[(uint32_t)expert_i] = -2; } for (uint32_t e = 0; e < n_total_expert; e++) { if (expert_to_slot[e] != -2) continue; expert_to_slot[e] = (int32_t)compact_ids.size(); compact_ids.push_back((int32_t)e); } for (uint32_t i = 0; i < slot_count; i++) { slot_ids[i] = expert_to_slot[(uint32_t)selected_ids[i]]; } if (compact_ids.empty() || compact_ids.size() > UINT32_MAX) return 0; return cuda_stream_selected_cache_begin_compact_load( model_map, model_size, layer, compact_ids.data(), slot_ids.data(), n_total_expert, (uint32_t)compact_ids.size(), slot_count, gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes, 1, 0); } extern "C" int ds4_gpu_stream_expert_cache_seed_experts( const ds4_gpu_stream_expert_table *table, const int32_t *expert_ids, const uint32_t *expert_priorities, uint32_t n_experts) { if (!g_ssd_streaming_mode) return 1; if (!table) return 0; const void *model_map = table->model_map; const uint64_t model_size = table->model_size; const uint32_t layer = table->layer; const uint32_t n_total_expert = table->n_total_expert; const uint64_t gate_offset = table->gate_offset; const uint64_t up_offset = table->up_offset; const uint64_t down_offset = table->down_offset; const uint64_t gate_expert_bytes = table->gate_expert_bytes; const uint64_t down_expert_bytes = table->down_expert_bytes; if (!model_map || !expert_ids || n_experts == 0 || !cuda_stream_layer_expert_ranges_valid(model_size, n_total_expert, gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes, "seed hotlist")) { return 0; } cuda_stream_expert_cache *cache = cuda_stream_expert_cache_prepare(gate_expert_bytes, down_expert_bytes, n_experts); if (!cache || cache->capacity == 0) return 1; const uint32_t layer_seed_cap = n_experts < cache->capacity ? n_experts : cache->capacity; std::vector chosen; try { chosen.reserve(layer_seed_cap); } catch (...) { return 1; } for (uint32_t i = 0; i < n_experts; i++) { const int32_t expert = expert_ids[i]; if (expert < 0 || (uint32_t)expert >= n_total_expert) { fprintf(stderr, "ds4: CUDA streaming hotlist seed expert id %d is outside 0..%u at layer %u\n", expert, n_total_expert, layer); return 0; } const uint32_t priority = expert_priorities ? expert_priorities[i] : (n_experts - i); uint32_t pos = 0; while (pos < chosen.size()) { const uint32_t other = chosen[pos]; const uint32_t other_priority = expert_priorities ? expert_priorities[other] : (n_experts - other); if (priority > other_priority) break; pos++; } if (chosen.size() < layer_seed_cap) { chosen.insert(chosen.begin() + pos, i); } else if (pos < chosen.size()) { chosen.insert(chosen.begin() + pos, i); chosen.pop_back(); } } const uint32_t n = (uint32_t)chosen.size(); for (uint32_t ri = 0; ri < n; ri++) { const uint32_t i = chosen[n - 1u - ri]; if (!cuda_stream_expert_cache_seed_one(cache, model_map, model_size, layer, n_total_expert, (uint32_t)expert_ids[i], gate_offset, up_offset, down_offset, gate_expert_bytes, down_expert_bytes)) { cuda_stream_expert_cache_invalidate(); return 1; } } if (getenv("DS4_CUDA_STREAMING_EXPERT_CACHE_VERBOSE")) { fprintf(stderr, "ds4: CUDA streaming hotlist seeded layer=%u requested=%u cached=%u cap=%u\n", layer, n_experts, n, cache->capacity); } return 1; } __global__ static void embed_token_hc_kernel(float *out, const unsigned short *w, uint32_t token, uint32_t n_embd, uint32_t n_hc) { uint32_t i = blockIdx.x * blockDim.x + threadIdx.x; uint32_t n = n_embd * n_hc; if (i >= n) return; uint32_t e = i % n_embd; out[i] = __half2float(reinterpret_cast(w)[(uint64_t)token * n_embd + e]); } __global__ static void embed_tokens_hc_kernel( float *out, const int32_t *tokens, const __half *w, uint32_t n_vocab, uint32_t n_tokens, uint32_t n_embd, uint32_t n_hc) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_tokens * n_hc * n_embd; if (gid >= n) return; uint32_t d = gid % n_embd; uint64_t tmp = gid / n_embd; uint32_t t = tmp / n_hc; int32_t tok_i = tokens[t]; uint32_t tok = tok_i < 0 ? 0u : (uint32_t)tok_i; if (tok >= n_vocab) tok = 0; out[gid] = __half2float(w[(uint64_t)tok * n_embd + d]); } __global__ static void matmul_f16_kernel( float *out, const __half *w, const float *x, uint64_t in_dim, uint64_t out_dim, uint64_t n_tok) { uint64_t row = (uint64_t)blockIdx.x; uint64_t tok = (uint64_t)blockIdx.y; if (row >= out_dim || tok >= n_tok) return; float sum = 0.0f; const __half *wr = w + row * in_dim; const float *xr = x + tok * in_dim; for (uint64_t i = threadIdx.x; i < in_dim; i += blockDim.x) { sum += __half2float(wr[i]) * xr[i]; } __shared__ float partial[256]; partial[threadIdx.x] = sum; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) out[tok * out_dim + row] = partial[0]; } __global__ static void matmul_f16_serial_kernel( float *out, const __half *w, const float *x, uint64_t in_dim, uint64_t out_dim, uint64_t n_tok) { uint64_t row = (uint64_t)blockIdx.x; uint64_t tok = (uint64_t)blockIdx.y; if (row >= out_dim || tok >= n_tok || threadIdx.x != 0) return; float sum = 0.0f; const __half *wr = w + row * in_dim; const float *xr = x + tok * in_dim; for (uint64_t i = 0; i < in_dim; i++) { sum += __half2float(wr[i]) * xr[i]; } out[tok * out_dim + row] = sum; } __global__ static void matmul_f16_ordered_chunks_kernel( float *out, const __half *w, const float *x, uint64_t in_dim, uint64_t out_dim, uint64_t n_tok) { uint64_t row = (uint64_t)blockIdx.x; uint64_t tok = (uint64_t)blockIdx.y; if (row >= out_dim || tok >= n_tok) return; __shared__ float partial[32]; const uint32_t tid = threadIdx.x; float sum = 0.0f; const uint64_t chunk = (in_dim + 31u) / 32u; const uint64_t k0 = (uint64_t)tid * chunk; uint64_t k1 = k0 + chunk; if (k1 > in_dim) k1 = in_dim; const __half *wr = w + row * in_dim; const float *xr = x + tok * in_dim; for (uint64_t i = k0; i < k1; i++) { sum += __half2float(wr[i]) * xr[i]; } partial[tid] = sum; __syncthreads(); if (tid == 0) { float total = 0.0f; for (uint32_t i = 0; i < 32u; i++) total += partial[i]; out[tok * out_dim + row] = total; } } __global__ static void matmul_f16_pair_ordered_chunks_kernel( float *out0, float *out1, const __half *w0, const __half *w1, const float *x, uint64_t in_dim, uint64_t out0_dim, uint64_t out1_dim) { uint64_t row = (uint64_t)blockIdx.x; if (row >= out0_dim && row >= out1_dim) return; __shared__ float partial0[32]; __shared__ float partial1[32]; const uint32_t tid = threadIdx.x; float sum0 = 0.0f; float sum1 = 0.0f; const uint64_t chunk = (in_dim + 31u) / 32u; const uint64_t k0 = (uint64_t)tid * chunk; uint64_t k1 = k0 + chunk; if (k1 > in_dim) k1 = in_dim; const __half *wr0 = row < out0_dim ? w0 + row * in_dim : w0; const __half *wr1 = row < out1_dim ? w1 + row * in_dim : w1; for (uint64_t i = k0; i < k1; i++) { const float xv = x[i]; if (row < out0_dim) sum0 += __half2float(wr0[i]) * xv; if (row < out1_dim) sum1 += __half2float(wr1[i]) * xv; } partial0[tid] = sum0; partial1[tid] = sum1; __syncthreads(); if (tid == 0) { float total0 = 0.0f; float total1 = 0.0f; for (uint32_t i = 0; i < 32u; i++) { total0 += partial0[i]; total1 += partial1[i]; } if (row < out0_dim) out0[row] = total0; if (row < out1_dim) out1[row] = total1; } } __global__ static void matmul_f32_kernel( float *out, const float *w, const float *x, uint64_t in_dim, uint64_t out_dim, uint64_t n_tok) { uint64_t row = (uint64_t)blockIdx.x; uint64_t tok = (uint64_t)blockIdx.y; if (row >= out_dim || tok >= n_tok) return; float sum = 0.0f; const float *wr = w + row * in_dim; const float *xr = x + tok * in_dim; for (uint64_t i = threadIdx.x; i < in_dim; i += blockDim.x) { sum += wr[i] * xr[i]; } __shared__ float partial[256]; partial[threadIdx.x] = sum; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) out[tok * out_dim + row] = partial[0]; } __global__ static void repeat_hc_kernel(float *out, const float *row, uint32_t n_embd, uint32_t n_hc) { uint64_t i = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_embd * n_hc; if (i >= n) return; out[i] = row[i % n_embd]; } __global__ static void f32_to_f16_kernel(__half *out, const float *x, uint64_t n) { uint64_t i = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; if (i < n) out[i] = __float2half(x[i]); } __device__ static float warp_sum_f32(float v) { for (int offset = 16; offset > 0; offset >>= 1) { v += __shfl_down_sync(0xffffffffu, v, offset); } return v; } __device__ static float warp_max_f32(float v) { for (int offset = 16; offset > 0; offset >>= 1) { v = fmaxf(v, __shfl_down_sync(0xffffffffu, v, offset)); } return v; } __device__ static float dot4_f32(float4 a, float4 b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } __device__ __forceinline__ static int32_t load_i8x4_i32_aligned(const int8_t *p) { return *(const int32_t *)p; } __device__ __forceinline__ static int32_t load_i8x4_i32_unaligned(const int8_t *p) { const uint8_t *u = (const uint8_t *)p; return (int32_t)((uint32_t)u[0] | ((uint32_t)u[1] << 8) | ((uint32_t)u[2] << 16) | ((uint32_t)u[3] << 24)); } __device__ __forceinline__ static int32_t dot_i8x32_dp4a(const int8_t *a, const int8_t *b) { int32_t dot = 0; #pragma unroll for (uint32_t i = 0; i < 32u; i += 4u) { dot = __dp4a(load_i8x4_i32_unaligned(a + i), load_i8x4_i32_aligned(b + i), dot); } return dot; } __device__ __forceinline__ static int32_t dot_i8_block(const int8_t *a, const int8_t *b, uint64_t n, int use_dp4a) { if (use_dp4a && n == 32u) return dot_i8x32_dp4a(a, b); int32_t dot = 0; for (uint64_t i = 0; i < n; i++) dot += (int32_t)a[i] * (int32_t)b[i]; return dot; } __global__ static DS4_CUDA_UNUSED void matmul_q8_0_kernel( float *out, const unsigned char *w, const float *x, uint64_t in_dim, uint64_t out_dim, uint64_t n_tok) { uint64_t row = (uint64_t)blockIdx.x; uint64_t tok = (uint64_t)blockIdx.y; if (row >= out_dim || tok >= n_tok) return; const uint64_t blocks = (in_dim + 31) / 32; const unsigned char *wr = w + row * blocks * 34; const float *xr = x + tok * in_dim; float acc = 0.0f; for (uint64_t b = threadIdx.x; b < blocks; b += blockDim.x) { uint64_t i0 = b * 32; uint64_t bn = in_dim - i0 < 32 ? in_dim - i0 : 32; float amax = 0.0f; for (uint64_t i = 0; i < bn; i++) amax = fmaxf(amax, fabsf(xr[i0 + i])); float d = amax / 127.0f; float id = d != 0.0f ? 1.0f / d : 0.0f; const __half *scale_h = (const __half *)(wr + b * 34); const int8_t *qs = (const int8_t *)(wr + b * 34 + 2); int dot = 0; for (uint64_t i = 0; i < bn; i++) { int q = (int)lrintf(xr[i0 + i] * id); q = q > 127 ? 127 : (q < -128 ? -128 : q); dot += (int)qs[i] * q; } acc += __half2float(*scale_h) * d * (float)dot; } __shared__ float partial[256]; partial[threadIdx.x] = acc; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) out[tok * out_dim + row] = partial[0]; } __global__ static void quantize_q8_0_f32_kernel( int8_t *xq, float *xscale, const float *x, uint64_t in_dim, uint64_t blocks) { uint64_t b = blockIdx.x; uint64_t tok = blockIdx.y; if (b >= blocks) return; uint64_t i0 = b * 32; uint64_t bn = in_dim - i0 < 32 ? in_dim - i0 : 32; const float *xr = x + tok * in_dim + i0; float a = 0.0f; if (threadIdx.x < bn) a = fabsf(xr[threadIdx.x]); __shared__ float vals[32]; vals[threadIdx.x] = a; __syncthreads(); for (uint32_t stride = 16; stride > 0; stride >>= 1) { if (threadIdx.x < stride) vals[threadIdx.x] = fmaxf(vals[threadIdx.x], vals[threadIdx.x + stride]); __syncthreads(); } const float d = vals[0] / 127.0f; const float id = d != 0.0f ? 1.0f / d : 0.0f; if (threadIdx.x == 0) xscale[tok * blocks + b] = d; int8_t *dst = xq + (tok * blocks + b) * 32; if (threadIdx.x < bn) { int v = (int)lrintf(xr[threadIdx.x] * id); v = v > 127 ? 127 : (v < -128 ? -128 : v); dst[threadIdx.x] = (int8_t)v; } else { dst[threadIdx.x] = 0; } } __global__ static void matmul_q8_0_preq_kernel( float *out, const unsigned char *w, const int8_t *xq, const float *xscale, uint64_t in_dim, uint64_t out_dim, uint64_t n_tok, uint64_t blocks, int use_dp4a) { uint64_t row = (uint64_t)blockIdx.x; uint64_t tok = (uint64_t)blockIdx.y; if (row >= out_dim || tok >= n_tok) return; const unsigned char *wr = w + row * blocks * 34; const int8_t *xqr = xq + tok * blocks * 32; const float *xsr = xscale + tok * blocks; float acc = 0.0f; for (uint64_t b = threadIdx.x; b < blocks; b += blockDim.x) { uint64_t i0 = b * 32; uint64_t bn = in_dim - i0 < 32 ? in_dim - i0 : 32; const __half *scale_h = (const __half *)(wr + b * 34); const int8_t *qs = (const int8_t *)(wr + b * 34 + 2); const int8_t *xqb = xqr + b * 32; int dot = dot_i8_block(qs, xqb, bn, use_dp4a); acc += __half2float(*scale_h) * xsr[b] * (float)dot; } __shared__ float partial[256]; partial[threadIdx.x] = acc; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) out[tok * out_dim + row] = partial[0]; } __global__ static void matmul_q8_0_preq_warp8_kernel( float *out, const unsigned char *w, const int8_t *xq, const float *xscale, uint64_t in_dim, uint64_t out_dim, uint64_t blocks, int use_dp4a) { uint64_t row = (uint64_t)blockIdx.x * 8u + (threadIdx.x >> 5u); uint32_t lane = threadIdx.x & 31u; if (row >= out_dim) return; const unsigned char *wr = w + row * blocks * 34; float acc = 0.0f; for (uint64_t b = lane; b < blocks; b += 32u) { uint64_t i0 = b * 32; uint64_t bn = in_dim - i0 < 32 ? in_dim - i0 : 32; const __half *scale_h = (const __half *)(wr + b * 34); const int8_t *qs = (const int8_t *)(wr + b * 34 + 2); const int8_t *xqb = xq + b * 32; int dot = dot_i8_block(qs, xqb, bn, use_dp4a); acc += __half2float(*scale_h) * xscale[b] * (float)dot; } acc = warp_sum_f32(acc); if (lane == 0) out[row] = acc; } __global__ static void matmul_q8_0_pair_preq_warp8_kernel( float *out0, float *out1, const unsigned char *w0, const unsigned char *w1, const int8_t *xq, const float *xscale, uint64_t in_dim, uint64_t out0_dim, uint64_t out1_dim, uint64_t blocks, int use_dp4a) { uint64_t row = (uint64_t)blockIdx.x * 8u + (threadIdx.x >> 5u); uint32_t lane = threadIdx.x & 31u; if (row >= out0_dim && row >= out1_dim) return; float acc0 = 0.0f; float acc1 = 0.0f; const unsigned char *wr0 = row < out0_dim ? w0 + row * blocks * 34 : NULL; const unsigned char *wr1 = row < out1_dim ? w1 + row * blocks * 34 : NULL; for (uint64_t b = lane; b < blocks; b += 32u) { uint64_t i0 = b * 32; uint64_t bn = in_dim - i0 < 32 ? in_dim - i0 : 32; const int8_t *xqb = xq + b * 32; const float xs = xscale[b]; if (wr0) { const __half *scale_h = (const __half *)(wr0 + b * 34); const int8_t *qs = (const int8_t *)(wr0 + b * 34 + 2); int dot = dot_i8_block(qs, xqb, bn, use_dp4a); acc0 += __half2float(*scale_h) * xs * (float)dot; } if (wr1) { const __half *scale_h = (const __half *)(wr1 + b * 34); const int8_t *qs = (const int8_t *)(wr1 + b * 34 + 2); int dot = dot_i8_block(qs, xqb, bn, use_dp4a); acc1 += __half2float(*scale_h) * xs * (float)dot; } } acc0 = warp_sum_f32(acc0); acc1 = warp_sum_f32(acc1); if (lane == 0) { if (row < out0_dim) out0[row] = acc0; if (row < out1_dim) out1[row] = acc1; } } __global__ static void matmul_q8_0_hc_expand_preq_warp8_kernel( float *out_hc, float *block_out, const float *block_add, const float *residual_hc, const float *split, const unsigned char *w, const int8_t *xq, const float *xscale, uint64_t in_dim, uint64_t out_dim, uint32_t n_embd, uint32_t n_hc, uint64_t blocks, int has_add, int use_dp4a) { const uint64_t row = (uint64_t)blockIdx.x * 8u + (threadIdx.x >> 5u); const uint32_t lane = threadIdx.x & 31u; if (row >= out_dim) return; const unsigned char *wr = w + row * blocks * 34; float acc = 0.0f; for (uint64_t b = lane; b < blocks; b += 32u) { const uint64_t i0 = b * 32; const uint64_t bn = in_dim - i0 < 32 ? in_dim - i0 : 32; const __half *scale_h = (const __half *)(wr + b * 34); const int8_t *qs = (const int8_t *)(wr + b * 34 + 2); const int8_t *xqb = xq + b * 32; int dot = dot_i8_block(qs, xqb, bn, use_dp4a); acc += __half2float(*scale_h) * xscale[b] * (float)dot; } acc = warp_sum_f32(acc); if (lane == 0) { const uint32_t d = (uint32_t)row; block_out[d] = acc; float block_v = acc; if (has_add) block_v += block_add[d]; const float *post = split + n_hc; const float *comb = split + 2u * n_hc; for (uint32_t dst_hc = 0; dst_hc < n_hc; dst_hc++) { float hc_acc = block_v * post[dst_hc]; for (uint32_t src_hc = 0; src_hc < n_hc; src_hc++) { const float comb_v = comb[dst_hc + (uint64_t)src_hc * n_hc]; const float res_v = residual_hc[(uint64_t)src_hc * n_embd + d]; hc_acc += comb_v * res_v; } out_hc[(uint64_t)dst_hc * n_embd + d] = hc_acc; } } } __global__ static void matmul_q8_0_preq_batch_warp8_kernel( float *out, const unsigned char *w, const int8_t *xq, const float *xscale, uint64_t in_dim, uint64_t out_dim, uint64_t n_tok, uint64_t blocks, int use_dp4a) { const uint64_t row = (uint64_t)blockIdx.x * 8u + (threadIdx.x >> 5u); const uint64_t tok = (uint64_t)blockIdx.y; const uint32_t lane = threadIdx.x & 31u; if (row >= out_dim || tok >= n_tok) return; const unsigned char *wr = w + row * blocks * 34; const int8_t *xqr = xq + tok * blocks * 32; const float *xsr = xscale + tok * blocks; float acc = 0.0f; for (uint64_t b = lane; b < blocks; b += 32u) { const uint64_t i0 = b * 32; const uint64_t bn = in_dim - i0 < 32 ? in_dim - i0 : 32; const __half *scale_h = (const __half *)(wr + b * 34); const int8_t *qs = (const int8_t *)(wr + b * 34 + 2); const int8_t *xqb = xqr + b * 32; int dot = dot_i8_block(qs, xqb, bn, use_dp4a); acc += __half2float(*scale_h) * xsr[b] * (float)dot; } acc = warp_sum_f32(acc); if (lane == 0) out[tok * out_dim + row] = acc; } __global__ static void dequant_q8_0_to_f16_kernel( __half *out, const unsigned char *w, uint64_t in_dim, uint64_t out_dim, uint64_t blocks) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = in_dim * out_dim; if (gid >= n) return; uint64_t row = gid / in_dim; uint64_t i = gid - row * in_dim; uint64_t b = i / 32; uint64_t j = i - b * 32; const unsigned char *blk = w + (row * blocks + b) * 34; const __half scale = *(const __half *)blk; const int8_t q = *(const int8_t *)(blk + 2 + j); out[gid] = __hmul(scale, __float2half((float)q)); } __global__ static void dequant_q8_0_to_f32_kernel( float *out, const unsigned char *w, uint64_t in_dim, uint64_t out_dim, uint64_t blocks) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = in_dim * out_dim; if (gid >= n) return; uint64_t row = gid / in_dim; uint64_t i = gid - row * in_dim; uint64_t b = i / 32; uint64_t j = i - b * 32; const unsigned char *blk = w + (row * blocks + b) * 34; const float scale = __half2float(*(const __half *)blk); const int8_t q = *(const int8_t *)(blk + 2 + j); out[gid] = scale * (float)q; } __global__ static void grouped_q8_0_a_preq_warp8_kernel( float *low, const unsigned char *w, const int8_t *xq, const float *xscale, uint64_t group_dim, uint64_t rank, uint32_t n_groups, uint32_t n_tokens, uint64_t blocks, int use_dp4a) { const uint64_t row = (uint64_t)blockIdx.x * 8u + (threadIdx.x >> 5u); const uint64_t tok = (uint64_t)blockIdx.y; const uint32_t lane = threadIdx.x & 31u; const uint64_t low_dim = (uint64_t)n_groups * rank; if (row >= low_dim || tok >= n_tokens) return; const uint64_t group = row / rank; const uint64_t row_in_group = row - group * rank; const unsigned char *wr = w + (group * rank + row_in_group) * blocks * 34; const uint64_t xrow = tok * (uint64_t)n_groups + group; const int8_t *xqr = xq + xrow * blocks * 32; const float *xsr = xscale + xrow * blocks; float acc = 0.0f; for (uint64_t b = lane; b < blocks; b += 32u) { const uint64_t i0 = b * 32; const uint64_t bn = group_dim - i0 < 32 ? group_dim - i0 : 32; const __half *scale_h = (const __half *)(wr + b * 34); const int8_t *qs = (const int8_t *)(wr + b * 34 + 2); const int8_t *xqb = xqr + b * 32; int dot = dot_i8_block(qs, xqb, bn, use_dp4a); acc += __half2float(*scale_h) * xsr[b] * (float)dot; } acc = warp_sum_f32(acc); if (lane == 0) low[tok * low_dim + row] = acc; } __global__ static void rms_norm_plain_kernel(float *out, const float *x, uint32_t n, uint32_t rows, float eps) { uint32_t row = blockIdx.x; if (row >= rows) return; const float *xr = x + (uint64_t)row * n; float *orow = out + (uint64_t)row * n; float sum = 0.0f; for (uint32_t i = threadIdx.x; i < n; i += blockDim.x) { float v = xr[i]; sum += v * v; } __shared__ float partial[256]; partial[threadIdx.x] = sum; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } float scale = rsqrtf(partial[0] / (float)n + eps); for (uint32_t i = threadIdx.x; i < n; i += blockDim.x) { orow[i] = xr[i] * scale; } } __global__ static void rms_norm_weight_kernel(float *out, const float *x, const float *w, uint32_t n, uint32_t rows, float eps) { uint32_t row = blockIdx.x; if (row >= rows) return; const float *xr = x + (uint64_t)row * n; float *orow = out + (uint64_t)row * n; float sum = 0.0f; for (uint32_t i = threadIdx.x; i < n; i += blockDim.x) { float v = xr[i]; sum += v * v; } __shared__ float partial[256]; partial[threadIdx.x] = sum; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } float scale = rsqrtf(partial[0] / (float)n + eps); for (uint32_t i = threadIdx.x; i < n; i += blockDim.x) { orow[i] = xr[i] * scale * w[i]; } } __global__ static void dsv4_qkv_rms_norm_rows_kernel( float *q_out, const float *q, const float *q_w, uint32_t q_n, float *kv_out, const float *kv, const float *kv_w, uint32_t kv_n, uint32_t rows, float eps) { const uint32_t row = blockIdx.x; const uint32_t which = blockIdx.y; if (row >= rows || which > 1u) return; const uint32_t n = which == 0u ? q_n : kv_n; const float *xr = (which == 0u ? q : kv) + (uint64_t)row * n; float *orow = (which == 0u ? q_out : kv_out) + (uint64_t)row * n; const float *w = which == 0u ? q_w : kv_w; float sum = 0.0f; for (uint32_t i = threadIdx.x; i < n; i += blockDim.x) { const float v = xr[i]; sum += v * v; } __shared__ float partial[256]; partial[threadIdx.x] = sum; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } const float scale = rsqrtf(partial[0] / (float)n + eps); for (uint32_t i = threadIdx.x; i < n; i += blockDim.x) { orow[i] = xr[i] * scale * w[i]; } } __global__ static void head_rms_norm_kernel(float *x, uint32_t n_tok, uint32_t n_head, uint32_t head_dim, float eps) { uint32_t row = blockIdx.x; if (row >= n_tok * n_head) return; float *xr = x + (uint64_t)row * head_dim; float sum = 0.0f; for (uint32_t i = threadIdx.x; i < head_dim; i += blockDim.x) { float v = xr[i]; sum += v * v; } __shared__ float partial[256]; partial[threadIdx.x] = sum; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } float scale = rsqrtf(partial[0] / (float)head_dim + eps); for (uint32_t i = threadIdx.x; i < head_dim; i += blockDim.x) xr[i] *= scale; } __device__ static float rope_yarn_ramp_dev(float low, float high, int i0); __global__ static void head_rms_norm_rope_tail_kernel( float *x, uint32_t n_tok, uint32_t n_head, uint32_t head_dim, uint32_t n_rot, uint32_t pos0, uint32_t n_ctx_orig, int inverse, float freq_base, float freq_scale, float ext_factor, float attn_factor, float beta_fast, float beta_slow, float eps) { uint32_t row = blockIdx.x; if (row >= n_tok * n_head) return; uint32_t t = row / n_head; float *xr = x + (uint64_t)row * head_dim; float sum = 0.0f; for (uint32_t i = threadIdx.x; i < head_dim; i += blockDim.x) { float v = xr[i]; sum += v * v; } __shared__ float partial[256]; partial[threadIdx.x] = sum; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } const float scale = rsqrtf(partial[0] / (float)head_dim + eps); const uint32_t n_nope = head_dim - n_rot; for (uint32_t i = threadIdx.x; i < n_nope; i += blockDim.x) { xr[i] *= scale; } float corr0 = 0.0f, corr1 = 0.0f; if (ext_factor != 0.0f) { float denom = 2.0f * logf(freq_base); corr0 = floorf((float)n_rot * logf((float)n_ctx_orig / (beta_fast * 2.0f * (float)M_PI)) / denom); corr1 = ceilf((float)n_rot * logf((float)n_ctx_orig / (beta_slow * 2.0f * (float)M_PI)) / denom); corr0 = fmaxf(0.0f, corr0); corr1 = fminf((float)(n_rot - 1), corr1); } for (uint32_t pair = threadIdx.x; pair < n_rot / 2; pair += blockDim.x) { uint32_t i = pair * 2u; float theta_extrap = (float)(pos0 + t) * powf(freq_base, -((float)i) / (float)n_rot); float theta_interp = freq_scale * theta_extrap; float theta = theta_interp; float mscale = attn_factor; if (ext_factor != 0.0f) { float ramp_mix = rope_yarn_ramp_dev(corr0, corr1, (int)i) * ext_factor; theta = theta_interp * (1.0f - ramp_mix) + theta_extrap * ramp_mix; mscale *= 1.0f + 0.1f * logf(1.0f / freq_scale); } float c = cosf(theta) * mscale; float s = sinf(theta) * mscale; if (inverse) s = -s; float *tail = xr + n_nope; float x0 = tail[i] * scale; float x1 = tail[i + 1] * scale; tail[i] = x0 * c - x1 * s; tail[i + 1] = x0 * s + x1 * c; } } __device__ static float rope_yarn_ramp_dev(float low, float high, int i0) { float y = ((float)(i0 / 2) - low) / fmaxf(0.001f, high - low); return 1.0f - fminf(1.0f, fmaxf(0.0f, y)); } __global__ static void rope_tail_kernel( float *x, uint32_t n_tok, uint32_t n_head, uint32_t head_dim, uint32_t n_rot, uint32_t pos0, uint32_t pos_stride, uint32_t n_ctx_orig, int inverse, float freq_base, float freq_scale, float ext_factor, float attn_factor, float beta_fast, float beta_slow) { uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; uint32_t pairs = n_tok * n_head * (n_rot / 2); if (gid >= pairs) return; uint32_t pair = gid % (n_rot / 2); uint32_t tmp = gid / (n_rot / 2); uint32_t h = tmp % n_head; uint32_t t = tmp / n_head; uint32_t n_nope = head_dim - n_rot; uint32_t i = pair * 2; float corr0 = 0.0f, corr1 = 0.0f; if (ext_factor != 0.0f) { float denom = 2.0f * logf(freq_base); corr0 = floorf((float)n_rot * logf((float)n_ctx_orig / (beta_fast * 2.0f * (float)M_PI)) / denom); corr1 = ceilf((float)n_rot * logf((float)n_ctx_orig / (beta_slow * 2.0f * (float)M_PI)) / denom); corr0 = fmaxf(0.0f, corr0); corr1 = fminf((float)(n_rot - 1), corr1); } float theta_extrap = (float)(pos0 + t * pos_stride) * powf(freq_base, -((float)i) / (float)n_rot); float theta_interp = freq_scale * theta_extrap; float theta = theta_interp; float mscale = attn_factor; if (ext_factor != 0.0f) { float ramp_mix = rope_yarn_ramp_dev(corr0, corr1, (int)i) * ext_factor; theta = theta_interp * (1.0f - ramp_mix) + theta_extrap * ramp_mix; mscale *= 1.0f + 0.1f * logf(1.0f / freq_scale); } float c = cosf(theta) * mscale; float s = sinf(theta) * mscale; if (inverse) s = -s; float *tail = x + ((uint64_t)t * n_head + h) * head_dim + n_nope; float x0 = tail[i]; float x1 = tail[i + 1]; tail[i] = x0 * c - x1 * s; tail[i + 1] = x0 * s + x1 * c; } __device__ static float dsv4_e4m3fn_value_dev(int i) { int exp = (i >> 3) & 15; int mant = i & 7; if (exp == 0) return (float)mant * 0.001953125f; return (1.0f + (float)mant * 0.125f) * exp2f((float)exp - 7.0f); } __device__ static float dsv4_e4m3fn_dequant_dev(float x) { float sign = x < 0.0f ? -1.0f : 1.0f; float ax = fminf(fabsf(x), 448.0f); int lo = 0, hi = 126; while (lo < hi) { int mid = (lo + hi + 1) >> 1; if (dsv4_e4m3fn_value_dev(mid) <= ax) lo = mid; else hi = mid - 1; } int best = lo; if (best < 126) { float bd = fabsf(ax - dsv4_e4m3fn_value_dev(best)); float nd = fabsf(ax - dsv4_e4m3fn_value_dev(best + 1)); if (nd < bd || (nd == bd && (((best + 1) & 1) == 0) && ((best & 1) != 0))) best++; } return sign * dsv4_e4m3fn_value_dev(best); } __device__ static float dsv4_e2m1fn_value_dev(int i) { switch (i & 7) { case 0: return 0.0f; case 1: return 0.5f; case 2: return 1.0f; case 3: return 1.5f; case 4: return 2.0f; case 5: return 3.0f; case 6: return 4.0f; default: return 6.0f; } } __device__ static float dsv4_e2m1fn_dequant_dev(float x) { float sign = x < 0.0f ? -1.0f : 1.0f; float ax = fminf(fabsf(x), 6.0f); int best = 0; float best_diff = fabsf(ax - dsv4_e2m1fn_value_dev(0)); for (int i = 1; i < 8; i++) { float diff = fabsf(ax - dsv4_e2m1fn_value_dev(i)); if (diff < best_diff || (diff == best_diff && ((i & 1) == 0) && ((best & 1) != 0))) { best = i; best_diff = diff; } } return sign * dsv4_e2m1fn_value_dev(best); } __device__ static float model_scalar_dev(const void *base, uint64_t offset, uint32_t type, uint64_t idx) { const char *p = (const char *)base + offset; if (type == 1u) return __half2float(((const __half *)p)[idx]); return ((const float *)p)[idx]; } __device__ static float rope_yarn_ramp_cpu_equiv_dev(float low, float high, int i0) { float y = ((float)(i0 / 2) - low) / fmaxf(0.001f, high - low); return 1.0f - fminf(1.0f, fmaxf(0.0f, y)); } __device__ static DS4_CUDA_UNUSED void rope_tail_one_dev(float *x, uint32_t head_dim, uint32_t n_rot, uint32_t pos, uint32_t n_ctx_orig, float freq_base, float freq_scale, float ext_factor, float attn_factor, float beta_fast, float beta_slow) { uint32_t n_nope = head_dim - n_rot; float corr0 = 0.0f, corr1 = 0.0f; if (ext_factor != 0.0f) { float denom = 2.0f * logf(freq_base); corr0 = fmaxf(0.0f, floorf((float)n_rot * logf((float)n_ctx_orig / (beta_fast * 2.0f * (float)M_PI)) / denom)); corr1 = fminf((float)(n_rot - 1), ceilf((float)n_rot * logf((float)n_ctx_orig / (beta_slow * 2.0f * (float)M_PI)) / denom)); } for (uint32_t i = 0; i < n_rot; i += 2) { float theta_extrap = (float)pos * powf(freq_base, -((float)i) / (float)n_rot); float theta_interp = freq_scale * theta_extrap; float theta = theta_interp; float mscale = attn_factor; if (ext_factor != 0.0f) { float mix = rope_yarn_ramp_cpu_equiv_dev(corr0, corr1, (int)i) * ext_factor; theta = theta_interp * (1.0f - mix) + theta_extrap * mix; mscale *= 1.0f + 0.1f * logf(1.0f / freq_scale); } float c = cosf(theta) * mscale; float s = sinf(theta) * mscale; float x0 = x[n_nope + i]; float x1 = x[n_nope + i + 1]; x[n_nope + i] = x0 * c - x1 * s; x[n_nope + i + 1] = x0 * s + x1 * c; } } __global__ static void fp8_kv_quantize_kernel(float *x, uint32_t n_tok, uint32_t head_dim, uint32_t n_rot) { uint32_t row = blockIdx.x; uint32_t tid = threadIdx.x; uint32_t n_nope = head_dim - n_rot; float *xr = x + (uint64_t)row * head_dim; __shared__ float scratch[64]; for (uint32_t off = 0; off < n_nope; off += 64) { float v = 0.0f; if (off + tid < n_nope) v = xr[off + tid]; scratch[tid] = off + tid < n_nope ? fabsf(v) : 0.0f; __syncthreads(); for (uint32_t stride = 32; stride > 0; stride >>= 1) { if (tid < stride) scratch[tid] = fmaxf(scratch[tid], scratch[tid + stride]); __syncthreads(); } float scale = exp2f(ceilf(log2f(fmaxf(scratch[0], 1.0e-4f) / 448.0f))); if (off + tid < n_nope) { float q = dsv4_e4m3fn_dequant_dev(fminf(448.0f, fmaxf(-448.0f, v / scale))) * scale; xr[off + tid] = q; } __syncthreads(); } } __global__ static void indexer_hadamard_fp4_kernel(float *x, uint32_t n_rows, uint32_t head_dim) { uint32_t row = blockIdx.x; uint32_t tid = threadIdx.x; if (row >= n_rows || head_dim != 128u || tid >= 128u) return; __shared__ float vals[128]; __shared__ float absbuf[128]; float *xr = x + (uint64_t)row * head_dim; vals[tid] = xr[tid]; __syncthreads(); for (uint32_t stride = 1u; stride < 128u; stride <<= 1u) { if ((tid & stride) == 0u) { uint32_t base = (tid & ~(2u * stride - 1u)) + (tid & (stride - 1u)); float a = vals[base]; float b = vals[base + stride]; vals[base] = a + b; vals[base + stride] = a - b; } __syncthreads(); } float v = vals[tid] * 0.08838834764831845f; uint32_t fp4_block = tid >> 5u; uint32_t lane = tid & 31u; uint32_t block_base = fp4_block * 32u; absbuf[tid] = fabsf(v); __syncthreads(); for (uint32_t stride = 16u; stride > 0u; stride >>= 1u) { if (lane < stride) { absbuf[block_base + lane] = fmaxf(absbuf[block_base + lane], absbuf[block_base + lane + stride]); } __syncthreads(); } float amax = fmaxf(absbuf[block_base], 7.052966104933725e-38f); float scale = exp2f(ceilf(log2f(amax / 6.0f))); xr[tid] = dsv4_e2m1fn_dequant_dev(fminf(6.0f, fmaxf(-6.0f, v / scale))) * scale; } __global__ static void store_raw_kv_batch_kernel(float *raw, const float *kv, uint32_t raw_cap, uint32_t pos0, uint32_t n_tokens, uint32_t head_dim) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_tokens * head_dim; if (gid >= n) return; uint32_t d = gid % head_dim; uint32_t t = gid / head_dim; uint32_t row = (pos0 + t) % raw_cap; raw[(uint64_t)row * head_dim + d] = __half2float(__float2half(kv[(uint64_t)t * head_dim + d])); } __global__ static void attention_prefill_raw_kernel( float *heads, const float *sinks, const float *q, const float *raw_kv, uint32_t n_tokens, uint32_t window, uint32_t n_head, uint32_t head_dim) { uint32_t t = blockIdx.x; uint32_t h = blockIdx.y; if (t >= n_tokens || h >= n_head) return; uint32_t raw_count = t + 1 < window ? t + 1 : window; uint32_t raw_start = t + 1 - raw_count; const float *qh = q + ((uint64_t)t * n_head + h) * head_dim; __shared__ float scores[256]; __shared__ float partial[128]; __shared__ float max_s; __shared__ float denom; float scale = rsqrtf((float)head_dim); float local_max = sinks[h]; __syncthreads(); for (uint32_t r = threadIdx.x; r < raw_count; r += blockDim.x) { const float *kv = raw_kv + (uint64_t)(raw_start + r) * head_dim; float dot = 0.0f; for (uint32_t d = 0; d < head_dim; d++) dot += qh[d] * kv[d]; scores[r] = dot * scale; local_max = fmaxf(local_max, scores[r]); } partial[threadIdx.x] = local_max; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] = fmaxf(partial[threadIdx.x], partial[threadIdx.x + stride]); __syncthreads(); } if (threadIdx.x == 0) max_s = partial[0]; __syncthreads(); if (threadIdx.x == 0) { float den = expf(sinks[h] - max_s); for (uint32_t r = 0; r < raw_count; r++) { scores[r] = expf(scores[r] - max_s); den += scores[r]; } denom = den; } __syncthreads(); float *oh = heads + ((uint64_t)t * n_head + h) * head_dim; for (uint32_t d = threadIdx.x; d < head_dim; d += blockDim.x) { float acc = 0.0f; for (uint32_t r = 0; r < raw_count; r++) { acc += raw_kv[(uint64_t)(raw_start + r) * head_dim + d] * scores[r]; } oh[d] = acc / denom; } } __global__ static void attention_prefill_mixed_kernel( float *heads, const float *sinks, const float *q, const float *raw_kv, const float *comp_kv, const float *comp_mask, uint32_t use_comp_mask, uint32_t n_tokens, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { uint32_t t = blockIdx.x; uint32_t h = blockIdx.y; if (t >= n_tokens || h >= n_head) return; const float *qh = q + ((uint64_t)t * n_head + h) * head_dim; uint32_t raw_start = (window != 0 && t + 1u > window) ? t + 1u - window : 0u; uint32_t raw_count = t + 1u - raw_start; uint32_t visible_comp = (t + 1u) / ratio; if (visible_comp > n_comp) visible_comp = n_comp; __shared__ float scores[512]; __shared__ float partial[256]; __shared__ float max_s; __shared__ float denom; float scale = rsqrtf((float)head_dim); float local_max = sinks[h]; uint32_t n_score = raw_count + visible_comp; for (uint32_t r = threadIdx.x; r < raw_count; r += blockDim.x) { const float *kvrow = raw_kv + (uint64_t)(raw_start + r) * head_dim; float dot = 0.0f; for (uint32_t d = 0; d < head_dim; d++) dot += qh[d] * kvrow[d]; scores[r] = dot * scale; local_max = fmaxf(local_max, scores[r]); } for (uint32_t c = threadIdx.x; c < visible_comp; c += blockDim.x) { float add = use_comp_mask ? comp_mask[(uint64_t)t * n_comp + c] : 0.0f; float s = -INFINITY; if (add > -1.0e20f) { const float *kvrow = comp_kv + (uint64_t)c * head_dim; float dot = 0.0f; for (uint32_t d = 0; d < head_dim; d++) dot += qh[d] * kvrow[d]; s = dot * scale + add; } scores[raw_count + c] = s; local_max = fmaxf(local_max, s); } partial[threadIdx.x] = local_max; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] = fmaxf(partial[threadIdx.x], partial[threadIdx.x + stride]); __syncthreads(); } if (threadIdx.x == 0) max_s = partial[0]; __syncthreads(); float den_local = 0.0f; for (uint32_t i = threadIdx.x; i < n_score; i += blockDim.x) { scores[i] = expf(scores[i] - max_s); den_local += scores[i]; } partial[threadIdx.x] = den_local; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) denom = partial[0] + expf(sinks[h] - max_s); __syncthreads(); float *oh = heads + ((uint64_t)t * n_head + h) * head_dim; for (uint32_t d = threadIdx.x; d < head_dim; d += blockDim.x) { float acc = 0.0f; for (uint32_t r = 0; r < raw_count; r++) acc += raw_kv[(uint64_t)(raw_start + r) * head_dim + d] * scores[r]; for (uint32_t c = 0; c < visible_comp; c++) acc += comp_kv[(uint64_t)c * head_dim + d] * scores[raw_count + c]; oh[d] = acc / denom; } } __global__ static void attention_prefill_raw_softmax_kernel( float *scores, const float *sinks, uint32_t n_tokens, uint32_t window, uint32_t n_keys) { uint32_t t = blockIdx.x; uint32_t h = blockIdx.y; if (t >= n_tokens) return; float *row = scores + ((uint64_t)h * n_tokens + t) * n_keys; __shared__ float partial[256]; __shared__ float max_s; __shared__ float denom; float local_max = sinks[h]; for (uint32_t k = threadIdx.x; k < n_keys; k += blockDim.x) { bool valid = k <= t && (window == 0 || t - k < window); float s = valid ? row[k] : -INFINITY; row[k] = s; local_max = fmaxf(local_max, s); } partial[threadIdx.x] = local_max; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] = fmaxf(partial[threadIdx.x], partial[threadIdx.x + stride]); __syncthreads(); } if (threadIdx.x == 0) max_s = partial[0]; __syncthreads(); float den_local = 0.0f; for (uint32_t k = threadIdx.x; k < n_keys; k += blockDim.x) { float p = isfinite(row[k]) ? expf(row[k] - max_s) : 0.0f; row[k] = p; den_local += p; } partial[threadIdx.x] = den_local; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) denom = partial[0] + expf(sinks[h] - max_s); __syncthreads(); for (uint32_t k = threadIdx.x; k < n_keys; k += blockDim.x) row[k] /= denom; } __global__ static void attention_prefill_mixed_softmax_kernel( float *scores, const float *sinks, const float *comp_mask, uint32_t use_comp_mask, uint32_t n_tokens, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_keys) { uint32_t t = blockIdx.x; uint32_t h = blockIdx.y; if (t >= n_tokens || ratio == 0) return; float *row = scores + ((uint64_t)h * n_tokens + t) * n_keys; __shared__ float partial[256]; __shared__ float max_s; __shared__ float denom; float local_max = sinks[h]; const uint32_t visible_comp = (t + 1u) / ratio; for (uint32_t k = threadIdx.x; k < n_keys; k += blockDim.x) { float s = -INFINITY; if (k < n_tokens) { if (k <= t && (window == 0 || t - k < window)) s = row[k]; } else { uint32_t c = k - n_tokens; if (c < n_comp && c < visible_comp) { float add = use_comp_mask ? comp_mask[(uint64_t)t * n_comp + c] : 0.0f; if (add > -1.0e20f) s = row[k] + add; } } row[k] = s; local_max = fmaxf(local_max, s); } partial[threadIdx.x] = local_max; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] = fmaxf(partial[threadIdx.x], partial[threadIdx.x + stride]); __syncthreads(); } if (threadIdx.x == 0) max_s = partial[0]; __syncthreads(); float den_local = 0.0f; for (uint32_t k = threadIdx.x; k < n_keys; k += blockDim.x) { float p = isfinite(row[k]) ? expf(row[k] - max_s) : 0.0f; row[k] = p; den_local += p; } partial[threadIdx.x] = den_local; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) denom = partial[0] + expf(sinks[h] - max_s); __syncthreads(); for (uint32_t k = threadIdx.x; k < n_keys; k += blockDim.x) row[k] /= denom; } __global__ static void attention_prefill_pack_mixed_kv_kernel( float *dst, const float *raw_kv, const float *comp_kv, uint32_t n_tokens, uint32_t n_comp, uint32_t head_dim) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)(n_tokens + n_comp) * head_dim; if (gid >= n) return; uint32_t d = gid % head_dim; uint32_t r = gid / head_dim; dst[gid] = r < n_tokens ? raw_kv[(uint64_t)r * head_dim + d] : comp_kv[(uint64_t)(r - n_tokens) * head_dim + d]; } __global__ static void attention_prefill_unpack_heads_kernel( float *heads, const float *tmp, uint32_t n_tokens, uint32_t n_head, uint32_t head_dim) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_tokens * n_head * head_dim; if (gid >= n) return; uint32_t d = gid % head_dim; uint64_t q = gid / head_dim; uint32_t h = q % n_head; uint32_t t = q / n_head; heads[gid] = tmp[((uint64_t)h * n_tokens + t) * head_dim + d]; } __global__ static void attention_pack_group_heads_f16_kernel( __half *dst, const float *heads, uint32_t n_tokens, uint32_t n_groups, uint32_t group_dim) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_groups * n_tokens * group_dim; if (gid >= n) return; uint32_t d = gid % group_dim; uint64_t q = gid / group_dim; uint32_t t = q % n_tokens; uint32_t g = q / n_tokens; dst[gid] = __float2half(heads[((uint64_t)t * n_groups + g) * group_dim + d]); } __global__ static void attention_unpack_group_low_kernel( float *low, const float *tmp, uint32_t n_tokens, uint32_t n_groups, uint32_t rank) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_groups * n_tokens * rank; if (gid >= n) return; uint32_t r = gid % rank; uint64_t q = gid / rank; uint32_t t = q % n_tokens; uint32_t g = q / n_tokens; uint32_t low_dim = n_groups * rank; low[(uint64_t)t * low_dim + (uint64_t)g * rank + r] = tmp[gid]; } __global__ static void attention_decode_mixed_kernel( float *heads, const float *sinks, const float *q, const float *raw_kv, const float *comp_kv, const float *comp_mask, uint32_t use_comp_mask, uint32_t n_tokens, uint32_t pos0, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { uint32_t t = blockIdx.x; uint32_t h = blockIdx.y; if (t >= n_tokens || h >= n_head) return; const bool single_all = (n_tokens == 1u && ratio == 0u); uint32_t qpos = pos0 + t; uint32_t first_raw_pos = pos0 + n_tokens - n_raw; uint32_t visible_comp = single_all ? n_comp : (n_comp ? (qpos + 1u) / ratio : 0u); if (visible_comp > n_comp) visible_comp = n_comp; const float *qh = q + ((uint64_t)t * n_head + h) * head_dim; __shared__ float scores[DS4_CUDA_ATTENTION_SCORE_CAP]; __shared__ uint32_t raw_rows[256]; __shared__ float partial[256]; __shared__ float max_s; __shared__ float denom; __shared__ uint32_t raw_count; __shared__ uint32_t raw_first_idx; float scale = rsqrtf((float)head_dim); if (threadIdx.x == 0) { raw_count = 0; raw_first_idx = 0; if (n_raw != 0) { const uint32_t raw_last_pos = first_raw_pos + n_raw - 1u; if (single_all) { raw_count = n_raw > 256u ? 256u : n_raw; } else if (qpos >= first_raw_pos) { uint32_t lo = first_raw_pos; if (window != 0 && qpos + 1u > window) { const uint32_t wlo = qpos + 1u - window; if (wlo > lo) lo = wlo; } const uint32_t hi = qpos < raw_last_pos ? qpos : raw_last_pos; if (hi >= lo) { raw_first_idx = lo - first_raw_pos; raw_count = hi - lo + 1u; if (raw_count > 256u) raw_count = 256u; } } } } __syncthreads(); for (uint32_t r = threadIdx.x; r < raw_count; r += blockDim.x) { raw_rows[r] = (raw_start + raw_first_idx + r) % raw_cap; } __syncthreads(); uint32_t n_score = raw_count + visible_comp; float local_max = sinks[h]; if (visible_comp == 0 || n_tokens == 1u) { for (uint32_t r = threadIdx.x; r < raw_count; r += blockDim.x) { const float *kvrow = raw_kv + (uint64_t)raw_rows[r] * head_dim; float dot = 0.0f; for (uint32_t d = 0; d < head_dim; d++) dot += qh[d] * kvrow[d]; scores[r] = dot * scale; local_max = fmaxf(local_max, scores[r]); } for (uint32_t c = threadIdx.x; c < visible_comp; c += blockDim.x) { float add = use_comp_mask ? comp_mask[(uint64_t)t * n_comp + c] : 0.0f; float s = -INFINITY; if (add > -1.0e20f) { const float *kvrow = comp_kv + (uint64_t)c * head_dim; float dot = 0.0f; for (uint32_t d = 0; d < head_dim; d++) dot += qh[d] * kvrow[d]; s = dot * scale + add; } scores[raw_count + c] = s; local_max = fmaxf(local_max, s); } } else { uint32_t qlane = threadIdx.x & 7u; uint32_t qgroup = threadIdx.x >> 3u; for (uint32_t row0 = 0; row0 < n_score; row0 += 32u) { uint32_t row = row0 + qgroup; if (row < n_score) { float add = 0.0f; const float *kvrow = NULL; if (row < raw_count) { kvrow = raw_kv + (uint64_t)raw_rows[row] * head_dim; } else { uint32_t c = row - raw_count; add = use_comp_mask ? comp_mask[(uint64_t)t * n_comp + c] : 0.0f; if (add > -1.0e20f) kvrow = comp_kv + (uint64_t)c * head_dim; } float s = -INFINITY; if (kvrow) { float dot = 0.0f; for (uint32_t d = qlane; d < head_dim; d += 8u) dot += qh[d] * kvrow[d]; const uint32_t mask = 0xffu << (threadIdx.x & 24u); for (uint32_t off = 4u; off > 0u; off >>= 1u) { dot += __shfl_down_sync(mask, dot, off, 8); } s = dot * scale + add; } if (qlane == 0) scores[row] = s; } } __syncthreads(); for (uint32_t i = threadIdx.x; i < n_score; i += blockDim.x) { local_max = fmaxf(local_max, scores[i]); } } partial[threadIdx.x] = local_max; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] = fmaxf(partial[threadIdx.x], partial[threadIdx.x + stride]); __syncthreads(); } if (threadIdx.x == 0) max_s = partial[0]; __syncthreads(); float den_local = 0.0f; for (uint32_t i = threadIdx.x; i < n_score; i += blockDim.x) { scores[i] = expf(scores[i] - max_s); den_local += scores[i]; } partial[threadIdx.x] = den_local; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) denom = partial[0] + expf(sinks[h] - max_s); __syncthreads(); float *oh = heads + ((uint64_t)t * n_head + h) * head_dim; if (head_dim == 512u && blockDim.x == 256u) { uint32_t d0 = threadIdx.x; uint32_t d1 = d0 + 256u; float acc0 = 0.0f; float acc1 = 0.0f; for (uint32_t r = 0; r < raw_count; r++) { float s = scores[r]; const float *kv = raw_kv + (uint64_t)raw_rows[r] * head_dim; acc0 += kv[d0] * s; acc1 += kv[d1] * s; } for (uint32_t c = 0; c < visible_comp; c++) { float s = scores[raw_count + c]; const float *kv = comp_kv + (uint64_t)c * head_dim; acc0 += kv[d0] * s; acc1 += kv[d1] * s; } oh[d0] = acc0 / denom; oh[d1] = acc1 / denom; } else { for (uint32_t d = threadIdx.x; d < head_dim; d += blockDim.x) { float acc = 0.0f; for (uint32_t r = 0; r < raw_count; r++) acc += raw_kv[(uint64_t)raw_rows[r] * head_dim + d] * scores[r]; for (uint32_t c = 0; c < visible_comp; c++) acc += comp_kv[(uint64_t)c * head_dim + d] * scores[raw_count + c]; oh[d] = acc / denom; } } } __global__ static void attention_indexed_mixed_kernel( float *heads, const float *sinks, const float *q, const float *raw_kv, const float *comp_kv, const int32_t *topk, uint32_t n_tokens, uint32_t pos0, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, uint32_t n_comp, uint32_t top_k, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { uint32_t t = blockIdx.x; uint32_t h = blockIdx.y; if (t >= n_tokens || h >= n_head) return; uint32_t qpos = pos0 + t; uint32_t first_raw_pos = pos0 + n_tokens - n_raw; uint32_t visible_comp = n_comp; if (ratio != 0) { visible_comp = (qpos + 1u) / ratio; if (visible_comp > n_comp) visible_comp = n_comp; } const float *qh = q + ((uint64_t)t * n_head + h) * head_dim; __shared__ float scores[768]; __shared__ uint32_t raw_rows[256]; __shared__ uint32_t comp_rows[512]; __shared__ float partial[256]; __shared__ float max_s; __shared__ float denom; __shared__ uint32_t raw_count; __shared__ uint32_t raw_first_idx; __shared__ uint32_t comp_count; float scale = rsqrtf((float)head_dim); if (threadIdx.x == 0) { raw_count = 0; raw_first_idx = 0; comp_count = 0; if (n_raw != 0) { const uint32_t raw_last_pos = first_raw_pos + n_raw - 1u; if (qpos >= first_raw_pos) { uint32_t lo = first_raw_pos; if (window != 0 && qpos + 1u > window) { const uint32_t wlo = qpos + 1u - window; if (wlo > lo) lo = wlo; } const uint32_t hi = qpos < raw_last_pos ? qpos : raw_last_pos; if (hi >= lo) { raw_first_idx = lo - first_raw_pos; raw_count = hi - lo + 1u; if (raw_count > 256u) raw_count = 256u; } } } } __syncthreads(); for (uint32_t r = threadIdx.x; r < raw_count; r += blockDim.x) { raw_rows[r] = (raw_start + raw_first_idx + r) % raw_cap; } for (uint32_t i = threadIdx.x; i < top_k; i += blockDim.x) { int32_t c = topk[(uint64_t)t * top_k + i]; if (c >= 0 && (uint32_t)c < visible_comp) { uint32_t slot = atomicAdd(&comp_count, 1u); if (slot < 512u) comp_rows[slot] = (uint32_t)c; } } __syncthreads(); if (threadIdx.x == 0) { if (comp_count > 512u) comp_count = 512u; } __syncthreads(); uint32_t n_score = raw_count + comp_count; float local_max = sinks[h]; if (comp_count == 0) { for (uint32_t r = threadIdx.x; r < raw_count; r += blockDim.x) { const float *kvrow = raw_kv + (uint64_t)raw_rows[r] * head_dim; float dot = 0.0f; for (uint32_t d = 0; d < head_dim; d++) dot += qh[d] * kvrow[d]; scores[r] = dot * scale; local_max = fmaxf(local_max, scores[r]); } } else { uint32_t qlane = threadIdx.x & 7u; uint32_t qgroup = threadIdx.x >> 3u; for (uint32_t row0 = 0; row0 < n_score; row0 += 32u) { uint32_t row = row0 + qgroup; if (row < n_score) { const float *kvrow = row < raw_count ? raw_kv + (uint64_t)raw_rows[row] * head_dim : comp_kv + (uint64_t)comp_rows[row - raw_count] * head_dim; float dot = 0.0f; for (uint32_t d = qlane; d < head_dim; d += 8u) dot += qh[d] * kvrow[d]; const uint32_t mask = 0xffu << (threadIdx.x & 24u); for (uint32_t off = 4u; off > 0u; off >>= 1u) { dot += __shfl_down_sync(mask, dot, off, 8); } if (qlane == 0) scores[row] = dot * scale; } } __syncthreads(); for (uint32_t i = threadIdx.x; i < n_score; i += blockDim.x) { local_max = fmaxf(local_max, scores[i]); } } partial[threadIdx.x] = local_max; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] = fmaxf(partial[threadIdx.x], partial[threadIdx.x + stride]); __syncthreads(); } if (threadIdx.x == 0) max_s = partial[0]; __syncthreads(); float den_local = 0.0f; for (uint32_t i = threadIdx.x; i < n_score; i += blockDim.x) { scores[i] = expf(scores[i] - max_s); den_local += scores[i]; } partial[threadIdx.x] = den_local; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) denom = partial[0] + expf(sinks[h] - max_s); __syncthreads(); float *oh = heads + ((uint64_t)t * n_head + h) * head_dim; if (head_dim == 512u && blockDim.x == 256u) { uint32_t d0 = threadIdx.x; uint32_t d1 = d0 + 256u; float acc0 = 0.0f; float acc1 = 0.0f; for (uint32_t r = 0; r < raw_count; r++) { float s = scores[r]; const float *kv = raw_kv + (uint64_t)raw_rows[r] * head_dim; acc0 += kv[d0] * s; acc1 += kv[d1] * s; } for (uint32_t c = 0; c < comp_count; c++) { float s = scores[raw_count + c]; const float *kv = comp_kv + (uint64_t)comp_rows[c] * head_dim; acc0 += kv[d0] * s; acc1 += kv[d1] * s; } oh[d0] = acc0 / denom; oh[d1] = acc1 / denom; } else { for (uint32_t d = threadIdx.x; d < head_dim; d += blockDim.x) { float acc = 0.0f; for (uint32_t r = 0; r < raw_count; r++) acc += raw_kv[(uint64_t)raw_rows[r] * head_dim + d] * scores[r]; for (uint32_t s = 0; s < comp_count; s++) acc += comp_kv[(uint64_t)comp_rows[s] * head_dim + d] * scores[raw_count + s]; oh[d] = acc / denom; } } } __global__ static void attention_indexed_mixed_heads8_rb4_kernel( float *heads, const float *sinks, const float *q, const float *raw_kv, const float *comp_kv, const int32_t *topk, uint32_t n_tokens, uint32_t pos0, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, uint32_t n_comp, uint32_t top_k, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { uint32_t t = blockIdx.x; uint32_t head_group = blockIdx.y; if (t >= n_tokens || head_dim != 512u) return; const uint32_t lane = threadIdx.x & 31u; const uint32_t warp = threadIdx.x >> 5u; const uint32_t head = head_group * 8u + warp; const bool valid_head = head < n_head; __shared__ uint32_t raw_rows[256]; __shared__ uint32_t comp_rows[512]; __shared__ uint32_t raw_count; __shared__ uint32_t raw_first_idx; __shared__ uint32_t comp_count; __shared__ float4 kv_shared[4 * 128]; __shared__ float scores[8 * 768]; uint32_t qpos = pos0 + t; uint32_t first_raw_pos = pos0 + n_tokens - n_raw; uint32_t visible_comp = n_comp; if (ratio != 0) { visible_comp = (qpos + 1u) / ratio; if (visible_comp > n_comp) visible_comp = n_comp; } if (threadIdx.x == 0) { raw_count = 0; raw_first_idx = 0; comp_count = 0; if (n_raw != 0) { const uint32_t raw_last_pos = first_raw_pos + n_raw - 1u; if (qpos >= first_raw_pos) { uint32_t lo = first_raw_pos; if (window != 0 && qpos + 1u > window) { const uint32_t wlo = qpos + 1u - window; if (wlo > lo) lo = wlo; } const uint32_t hi = qpos < raw_last_pos ? qpos : raw_last_pos; if (hi >= lo) { raw_first_idx = lo - first_raw_pos; raw_count = hi - lo + 1u; if (raw_count > 256u) raw_count = 256u; } } } } __syncthreads(); for (uint32_t r = threadIdx.x; r < raw_count; r += blockDim.x) { raw_rows[r] = (raw_start + raw_first_idx + r) % raw_cap; } if (threadIdx.x == 0) { for (uint32_t i = 0; i < top_k && comp_count < 512u; i++) { int32_t c = topk[(uint64_t)t * top_k + i]; if (c >= 0 && (uint32_t)c < visible_comp) comp_rows[comp_count++] = (uint32_t)c; } } __syncthreads(); const uint32_t n_score = raw_count + comp_count; const float scale = rsqrtf((float)head_dim); const float4 *q4 = valid_head ? (const float4 *)(q + ((uint64_t)t * n_head + head) * head_dim) : NULL; float4 q0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float4 q1 = q0, q2 = q0, q3 = q0; if (valid_head) { q0 = q4[lane + 0u]; q1 = q4[lane + 32u]; q2 = q4[lane + 64u]; q3 = q4[lane + 96u]; } for (uint32_t row0 = 0; row0 < n_score; row0 += 4u) { const uint32_t nr = n_score - row0 < 4u ? n_score - row0 : 4u; for (uint32_t off = threadIdx.x; off < nr * 128u; off += blockDim.x) { const uint32_t rr = off >> 7u; const uint32_t c4 = off & 127u; const uint32_t sr = row0 + rr; const float4 *src = sr < raw_count ? (const float4 *)(raw_kv + (uint64_t)raw_rows[sr] * head_dim) : (const float4 *)(comp_kv + (uint64_t)comp_rows[sr - raw_count] * head_dim); kv_shared[off] = src[c4]; } __syncthreads(); if (valid_head) { for (uint32_t rr = 0; rr < nr; rr++) { const float4 *kv4 = kv_shared + rr * 128u; float dot = dot4_f32(q0, kv4[lane + 0u]) + dot4_f32(q1, kv4[lane + 32u]) + dot4_f32(q2, kv4[lane + 64u]) + dot4_f32(q3, kv4[lane + 96u]); dot = warp_sum_f32(dot); if (lane == 0) scores[warp * 768u + row0 + rr] = dot * scale; } } __syncthreads(); } float max_s = valid_head ? sinks[head] : -INFINITY; if (valid_head) { const float *score_row = scores + warp * 768u; for (uint32_t i = lane; i < n_score; i += 32u) max_s = fmaxf(max_s, score_row[i]); max_s = warp_max_f32(max_s); max_s = __shfl_sync(0xffffffffu, max_s, 0); } float den = 0.0f; if (valid_head) { float *score_row = scores + warp * 768u; for (uint32_t i = lane; i < n_score; i += 32u) { float p = expf(score_row[i] - max_s); score_row[i] = p; den += p; } den = warp_sum_f32(den); den += expf(sinks[head] - max_s); den = __shfl_sync(0xffffffffu, den, 0); } float4 o0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float4 o1 = o0, o2 = o0, o3 = o0; for (uint32_t row0 = 0; row0 < n_score; row0 += 4u) { const uint32_t nr = n_score - row0 < 4u ? n_score - row0 : 4u; for (uint32_t off = threadIdx.x; off < nr * 128u; off += blockDim.x) { const uint32_t rr = off >> 7u; const uint32_t c4 = off & 127u; const uint32_t sr = row0 + rr; const float4 *src = sr < raw_count ? (const float4 *)(raw_kv + (uint64_t)raw_rows[sr] * head_dim) : (const float4 *)(comp_kv + (uint64_t)comp_rows[sr - raw_count] * head_dim); kv_shared[off] = src[c4]; } __syncthreads(); if (valid_head) { const float *score_row = scores + warp * 768u; for (uint32_t rr = 0; rr < nr; rr++) { const float p = den == 0.0f ? 0.0f : score_row[row0 + rr] / den; const float4 *kv4 = kv_shared + rr * 128u; float4 k0 = kv4[lane + 0u]; float4 k1 = kv4[lane + 32u]; float4 k2 = kv4[lane + 64u]; float4 k3 = kv4[lane + 96u]; o0.x += k0.x * p; o0.y += k0.y * p; o0.z += k0.z * p; o0.w += k0.w * p; o1.x += k1.x * p; o1.y += k1.y * p; o1.z += k1.z * p; o1.w += k1.w * p; o2.x += k2.x * p; o2.y += k2.y * p; o2.z += k2.z * p; o2.w += k2.w * p; o3.x += k3.x * p; o3.y += k3.y * p; o3.z += k3.z * p; o3.w += k3.w * p; } } __syncthreads(); } if (valid_head) { float4 *out4 = (float4 *)(heads + ((uint64_t)t * n_head + head) * head_dim); out4[lane + 0u] = o0; out4[lane + 32u] = o1; out4[lane + 64u] = o2; out4[lane + 96u] = o3; } } template __global__ static void attention_indexed_mixed_heads8_online_kernel( float *heads, const float *sinks, const float *q, const float *raw_kv, const float *comp_kv, const int32_t *topk, uint32_t n_tokens, uint32_t pos0, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, uint32_t n_comp, uint32_t top_k, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { uint32_t t = blockIdx.x; uint32_t head_group = blockIdx.y; if (t >= n_tokens || head_dim != 512u) return; const uint32_t lane = threadIdx.x & 31u; const uint32_t warp = threadIdx.x >> 5u; const uint32_t head = head_group * HEADS_PER_GROUP + warp; const bool valid_head = head < n_head; __shared__ uint32_t raw_rows[256]; __shared__ uint32_t raw_count; __shared__ uint32_t raw_first_idx; __shared__ float4 kv_shared[ROWS_PER_STAGE * 128]; uint32_t qpos = pos0 + t; uint32_t first_raw_pos = pos0 + n_tokens - n_raw; uint32_t visible_comp = n_comp; if (ratio != 0) { visible_comp = (qpos + 1u) / ratio; if (visible_comp > n_comp) visible_comp = n_comp; } if (threadIdx.x == 0) { raw_count = 0; raw_first_idx = 0; if (n_raw != 0) { const uint32_t raw_last_pos = first_raw_pos + n_raw - 1u; if (qpos >= first_raw_pos) { uint32_t lo = first_raw_pos; if (window != 0 && qpos + 1u > window) { const uint32_t wlo = qpos + 1u - window; if (wlo > lo) lo = wlo; } const uint32_t hi = qpos < raw_last_pos ? qpos : raw_last_pos; if (hi >= lo) { raw_first_idx = lo - first_raw_pos; raw_count = hi - lo + 1u; if (raw_count > 256u) raw_count = 256u; } } } } __syncthreads(); for (uint32_t r = threadIdx.x; r < raw_count; r += blockDim.x) { raw_rows[r] = (raw_start + raw_first_idx + r) % raw_cap; } __syncthreads(); uint32_t comp_count = top_k < visible_comp ? top_k : visible_comp; if (comp_count > 512u) comp_count = 512u; const uint32_t n_score = raw_count + comp_count; const float scale = rsqrtf((float)head_dim); const float4 *q4 = valid_head ? (const float4 *)(q + ((uint64_t)t * n_head + head) * head_dim) : NULL; float4 q0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float4 q1 = q0, q2 = q0, q3 = q0; if (valid_head) { q0 = q4[lane + 0u]; q1 = q4[lane + 32u]; q2 = q4[lane + 64u]; q3 = q4[lane + 96u]; } float max_s = -INFINITY; float sum_s = 0.0f; float4 o0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float4 o1 = o0, o2 = o0, o3 = o0; for (uint32_t row0 = 0; row0 < n_score; row0 += ROWS_PER_STAGE) { const uint32_t nr = n_score - row0 < ROWS_PER_STAGE ? n_score - row0 : ROWS_PER_STAGE; for (uint32_t off = threadIdx.x; off < nr * 128u; off += blockDim.x) { const uint32_t rr = off >> 7u; const uint32_t c4 = off & 127u; const uint32_t sr = row0 + rr; const uint32_t comp_idx = sr < raw_count ? 0u : (uint32_t)topk[(uint64_t)t * top_k + (sr - raw_count)]; const float4 *src = sr < raw_count ? (const float4 *)(raw_kv + (uint64_t)raw_rows[sr] * head_dim) : (const float4 *)(comp_kv + (uint64_t)comp_idx * head_dim); kv_shared[off] = src[c4]; } __syncthreads(); if (valid_head) { for (uint32_t rr = 0; rr < nr; rr++) { const float4 *kv4 = kv_shared + rr * 128u; float4 k0 = kv4[lane + 0u]; float4 k1 = kv4[lane + 32u]; float4 k2 = kv4[lane + 64u]; float4 k3 = kv4[lane + 96u]; float score = dot4_f32(q0, k0) + dot4_f32(q1, k1) + dot4_f32(q2, k2) + dot4_f32(q3, k3); score = warp_sum_f32(score) * scale; score = __shfl_sync(0xffffffffu, score, 0); const float new_m = fmaxf(max_s, score); const float old_scale = expf(max_s - new_m); const float row_scale = expf(score - new_m); sum_s = sum_s * old_scale + row_scale; o0.x = o0.x * old_scale + k0.x * row_scale; o0.y = o0.y * old_scale + k0.y * row_scale; o0.z = o0.z * old_scale + k0.z * row_scale; o0.w = o0.w * old_scale + k0.w * row_scale; o1.x = o1.x * old_scale + k1.x * row_scale; o1.y = o1.y * old_scale + k1.y * row_scale; o1.z = o1.z * old_scale + k1.z * row_scale; o1.w = o1.w * old_scale + k1.w * row_scale; o2.x = o2.x * old_scale + k2.x * row_scale; o2.y = o2.y * old_scale + k2.y * row_scale; o2.z = o2.z * old_scale + k2.z * row_scale; o2.w = o2.w * old_scale + k2.w * row_scale; o3.x = o3.x * old_scale + k3.x * row_scale; o3.y = o3.y * old_scale + k3.y * row_scale; o3.z = o3.z * old_scale + k3.z * row_scale; o3.w = o3.w * old_scale + k3.w * row_scale; max_s = new_m; } } __syncthreads(); } if (valid_head) { const float sink = sinks[head]; const float new_m = fmaxf(max_s, sink); const float old_scale = expf(max_s - new_m); const float sink_scale = expf(sink - new_m); sum_s = sum_s * old_scale + sink_scale; o0.x *= old_scale; o0.y *= old_scale; o0.z *= old_scale; o0.w *= old_scale; o1.x *= old_scale; o1.y *= old_scale; o1.z *= old_scale; o1.w *= old_scale; o2.x *= old_scale; o2.y *= old_scale; o2.z *= old_scale; o2.w *= old_scale; o3.x *= old_scale; o3.y *= old_scale; o3.z *= old_scale; o3.w *= old_scale; const float inv_s = sum_s == 0.0f ? 0.0f : 1.0f / sum_s; o0.x *= inv_s; o0.y *= inv_s; o0.z *= inv_s; o0.w *= inv_s; o1.x *= inv_s; o1.y *= inv_s; o1.z *= inv_s; o1.w *= inv_s; o2.x *= inv_s; o2.y *= inv_s; o2.z *= inv_s; o2.w *= inv_s; o3.x *= inv_s; o3.y *= inv_s; o3.z *= inv_s; o3.w *= inv_s; float4 *out4 = (float4 *)(heads + ((uint64_t)t * n_head + head) * head_dim); out4[lane + 0u] = o0; out4[lane + 32u] = o1; out4[lane + 64u] = o2; out4[lane + 96u] = o3; } } __global__ static void attention_static_mixed_heads8_online_kernel( float *heads, const float *sinks, const float *q, const float *raw_kv, const float *comp_kv, uint32_t n_tokens, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { uint32_t t = blockIdx.x; uint32_t head_group = blockIdx.y; if (t >= n_tokens || head_dim != 512u) return; const uint32_t lane = threadIdx.x & 31u; const uint32_t warp = threadIdx.x >> 5u; const uint32_t head = head_group * 8u + warp; const bool valid_head = head < n_head; __shared__ float4 kv_shared[4 * 128]; const uint32_t raw_count = window != 0u && t + 1u > window ? window : t + 1u; const uint32_t raw_start = t + 1u - raw_count; uint32_t comp_count = 0; if (n_comp != 0u && ratio != 0u) { comp_count = (t + 1u) / ratio; if (comp_count > n_comp) comp_count = n_comp; } const uint32_t n_score = raw_count + comp_count; const float scale = rsqrtf((float)head_dim); const float4 *q4 = valid_head ? (const float4 *)(q + ((uint64_t)t * n_head + head) * head_dim) : NULL; float4 q0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float4 q1 = q0, q2 = q0, q3 = q0; if (valid_head) { q0 = q4[lane + 0u]; q1 = q4[lane + 32u]; q2 = q4[lane + 64u]; q3 = q4[lane + 96u]; } float max_s = -INFINITY; float sum_s = 0.0f; float4 o0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float4 o1 = o0, o2 = o0, o3 = o0; for (uint32_t row0 = 0; row0 < n_score; row0 += 4u) { const uint32_t nr = n_score - row0 < 4u ? n_score - row0 : 4u; for (uint32_t off = threadIdx.x; off < nr * 128u; off += blockDim.x) { const uint32_t rr = off >> 7u; const uint32_t c4 = off & 127u; const uint32_t sr = row0 + rr; const float4 *src = sr < raw_count ? (const float4 *)(raw_kv + (uint64_t)(raw_start + sr) * head_dim) : (const float4 *)(comp_kv + (uint64_t)(sr - raw_count) * head_dim); kv_shared[off] = src[c4]; } __syncthreads(); if (valid_head) { for (uint32_t rr = 0; rr < nr; rr++) { const float4 *kv4 = kv_shared + rr * 128u; float4 k0 = kv4[lane + 0u]; float4 k1 = kv4[lane + 32u]; float4 k2 = kv4[lane + 64u]; float4 k3 = kv4[lane + 96u]; float score = dot4_f32(q0, k0) + dot4_f32(q1, k1) + dot4_f32(q2, k2) + dot4_f32(q3, k3); score = warp_sum_f32(score) * scale; score = __shfl_sync(0xffffffffu, score, 0); const float new_m = fmaxf(max_s, score); const float old_scale = expf(max_s - new_m); const float row_scale = expf(score - new_m); sum_s = sum_s * old_scale + row_scale; o0.x = o0.x * old_scale + k0.x * row_scale; o0.y = o0.y * old_scale + k0.y * row_scale; o0.z = o0.z * old_scale + k0.z * row_scale; o0.w = o0.w * old_scale + k0.w * row_scale; o1.x = o1.x * old_scale + k1.x * row_scale; o1.y = o1.y * old_scale + k1.y * row_scale; o1.z = o1.z * old_scale + k1.z * row_scale; o1.w = o1.w * old_scale + k1.w * row_scale; o2.x = o2.x * old_scale + k2.x * row_scale; o2.y = o2.y * old_scale + k2.y * row_scale; o2.z = o2.z * old_scale + k2.z * row_scale; o2.w = o2.w * old_scale + k2.w * row_scale; o3.x = o3.x * old_scale + k3.x * row_scale; o3.y = o3.y * old_scale + k3.y * row_scale; o3.z = o3.z * old_scale + k3.z * row_scale; o3.w = o3.w * old_scale + k3.w * row_scale; max_s = new_m; } } __syncthreads(); } if (valid_head) { const float sink = sinks[head]; const float new_m = fmaxf(max_s, sink); const float old_scale = expf(max_s - new_m); const float sink_scale = expf(sink - new_m); sum_s = sum_s * old_scale + sink_scale; o0.x *= old_scale; o0.y *= old_scale; o0.z *= old_scale; o0.w *= old_scale; o1.x *= old_scale; o1.y *= old_scale; o1.z *= old_scale; o1.w *= old_scale; o2.x *= old_scale; o2.y *= old_scale; o2.z *= old_scale; o2.w *= old_scale; o3.x *= old_scale; o3.y *= old_scale; o3.z *= old_scale; o3.w *= old_scale; const float inv_s = sum_s == 0.0f ? 0.0f : 1.0f / sum_s; o0.x *= inv_s; o0.y *= inv_s; o0.z *= inv_s; o0.w *= inv_s; o1.x *= inv_s; o1.y *= inv_s; o1.z *= inv_s; o1.w *= inv_s; o2.x *= inv_s; o2.y *= inv_s; o2.z *= inv_s; o2.w *= inv_s; o3.x *= inv_s; o3.y *= inv_s; o3.z *= inv_s; o3.w *= inv_s; float4 *out4 = (float4 *)(heads + ((uint64_t)t * n_head + head) * head_dim); out4[lane + 0u] = o0; out4[lane + 32u] = o1; out4[lane + 64u] = o2; out4[lane + 96u] = o3; } } __global__ static void attention_decode_mixed_heads8_online_kernel( float *heads, const float *sinks, const float *q, const float *raw_kv, const float *comp_kv, uint32_t n_tokens, uint32_t pos0, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { uint32_t t = blockIdx.x; uint32_t head_group = blockIdx.y; if (t >= n_tokens || head_dim != 512u) return; const uint32_t lane = threadIdx.x & 31u; const uint32_t warp = threadIdx.x >> 5u; const uint32_t head = head_group * 8u + warp; const bool valid_head = head < n_head; __shared__ uint32_t raw_rows[256]; __shared__ uint32_t raw_count_s; __shared__ uint32_t raw_first_idx_s; __shared__ float4 kv_shared[4 * 128]; const uint32_t qpos = pos0 + t; const uint32_t first_raw_pos = pos0 + n_tokens - n_raw; uint32_t comp_count = 0; if (n_comp != 0u) { if (n_tokens == 1u && ratio == 0u) { comp_count = n_comp; } else if (ratio != 0u) { comp_count = (qpos + 1u) / ratio; if (comp_count > n_comp) comp_count = n_comp; } } if (threadIdx.x == 0) { uint32_t raw_count = 0; uint32_t raw_first_idx = 0; if (n_raw != 0u) { const uint32_t raw_last_pos = first_raw_pos + n_raw - 1u; if (qpos >= first_raw_pos) { uint32_t lo = first_raw_pos; if (window != 0u && qpos + 1u > window) { const uint32_t wlo = qpos + 1u - window; if (wlo > lo) lo = wlo; } const uint32_t hi = qpos < raw_last_pos ? qpos : raw_last_pos; if (hi >= lo) { raw_first_idx = lo - first_raw_pos; raw_count = hi - lo + 1u; if (raw_count > 256u) raw_count = 256u; } } } raw_count_s = raw_count; raw_first_idx_s = raw_first_idx; } __syncthreads(); const uint32_t raw_count = raw_count_s; const uint32_t raw_first_idx = raw_first_idx_s; for (uint32_t r = threadIdx.x; r < raw_count; r += blockDim.x) { raw_rows[r] = (raw_start + raw_first_idx + r) % raw_cap; } __syncthreads(); const uint32_t n_score = raw_count + comp_count; const float scale = rsqrtf((float)head_dim); const float4 *q4 = valid_head ? (const float4 *)(q + ((uint64_t)t * n_head + head) * head_dim) : NULL; float4 q0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float4 q1 = q0, q2 = q0, q3 = q0; if (valid_head) { q0 = q4[lane + 0u]; q1 = q4[lane + 32u]; q2 = q4[lane + 64u]; q3 = q4[lane + 96u]; } float max_s = -INFINITY; float sum_s = 0.0f; float4 o0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float4 o1 = o0, o2 = o0, o3 = o0; for (uint32_t row0 = 0; row0 < n_score; row0 += 4u) { const uint32_t nr = n_score - row0 < 4u ? n_score - row0 : 4u; for (uint32_t off = threadIdx.x; off < nr * 128u; off += blockDim.x) { const uint32_t rr = off >> 7u; const uint32_t c4 = off & 127u; const uint32_t sr = row0 + rr; const float4 *src = sr < raw_count ? (const float4 *)(raw_kv + (uint64_t)raw_rows[sr] * head_dim) : (const float4 *)(comp_kv + (uint64_t)(sr - raw_count) * head_dim); kv_shared[off] = src[c4]; } __syncthreads(); if (valid_head) { for (uint32_t rr = 0; rr < nr; rr++) { const float4 *kv4 = kv_shared + rr * 128u; float4 k0 = kv4[lane + 0u]; float4 k1 = kv4[lane + 32u]; float4 k2 = kv4[lane + 64u]; float4 k3 = kv4[lane + 96u]; float score = dot4_f32(q0, k0) + dot4_f32(q1, k1) + dot4_f32(q2, k2) + dot4_f32(q3, k3); score = warp_sum_f32(score) * scale; score = __shfl_sync(0xffffffffu, score, 0); const float new_m = fmaxf(max_s, score); const float old_scale = expf(max_s - new_m); const float row_scale = expf(score - new_m); sum_s = sum_s * old_scale + row_scale; o0.x = o0.x * old_scale + k0.x * row_scale; o0.y = o0.y * old_scale + k0.y * row_scale; o0.z = o0.z * old_scale + k0.z * row_scale; o0.w = o0.w * old_scale + k0.w * row_scale; o1.x = o1.x * old_scale + k1.x * row_scale; o1.y = o1.y * old_scale + k1.y * row_scale; o1.z = o1.z * old_scale + k1.z * row_scale; o1.w = o1.w * old_scale + k1.w * row_scale; o2.x = o2.x * old_scale + k2.x * row_scale; o2.y = o2.y * old_scale + k2.y * row_scale; o2.z = o2.z * old_scale + k2.z * row_scale; o2.w = o2.w * old_scale + k2.w * row_scale; o3.x = o3.x * old_scale + k3.x * row_scale; o3.y = o3.y * old_scale + k3.y * row_scale; o3.z = o3.z * old_scale + k3.z * row_scale; o3.w = o3.w * old_scale + k3.w * row_scale; max_s = new_m; } } __syncthreads(); } if (valid_head) { const float sink = sinks[head]; const float new_m = fmaxf(max_s, sink); const float old_scale = expf(max_s - new_m); const float sink_scale = expf(sink - new_m); sum_s = sum_s * old_scale + sink_scale; o0.x *= old_scale; o0.y *= old_scale; o0.z *= old_scale; o0.w *= old_scale; o1.x *= old_scale; o1.y *= old_scale; o1.z *= old_scale; o1.w *= old_scale; o2.x *= old_scale; o2.y *= old_scale; o2.z *= old_scale; o2.w *= old_scale; o3.x *= old_scale; o3.y *= old_scale; o3.z *= old_scale; o3.w *= old_scale; const float inv_s = sum_s == 0.0f ? 0.0f : 1.0f / sum_s; o0.x *= inv_s; o0.y *= inv_s; o0.z *= inv_s; o0.w *= inv_s; o1.x *= inv_s; o1.y *= inv_s; o1.z *= inv_s; o1.w *= inv_s; o2.x *= inv_s; o2.y *= inv_s; o2.z *= inv_s; o2.w *= inv_s; o3.x *= inv_s; o3.y *= inv_s; o3.z *= inv_s; o3.w *= inv_s; float4 *out4 = (float4 *)(heads + ((uint64_t)t * n_head + head) * head_dim); out4[lane + 0u] = o0; out4[lane + 32u] = o1; out4[lane + 64u] = o2; out4[lane + 96u] = o3; } } __device__ static void hc4_split_one(float *out, const float *mix, const float *scale, const float *base, uint32_t sinkhorn_iters, float epsv) { const float pre_scale = scale[0]; const float post_scale = scale[1]; const float comb_scale = scale[2]; for (int i = 0; i < 4; i++) { float z = mix[i] * pre_scale + base[i]; out[i] = 1.0f / (1.0f + expf(-z)) + epsv; } for (int i = 0; i < 4; i++) { float z = mix[4 + i] * post_scale + base[4 + i]; out[4 + i] = 2.0f / (1.0f + expf(-z)); } float c[16]; for (int r = 0; r < 4; r++) { float m = -INFINITY; for (int col = 0; col < 4; col++) { float v = mix[8 + r * 4 + col] * comb_scale + base[8 + r * 4 + col]; c[r * 4 + col] = v; m = fmaxf(m, v); } float s = 0.0f; for (int col = 0; col < 4; col++) { float v = expf(c[r * 4 + col] - m); c[r * 4 + col] = v; s += v; } for (int col = 0; col < 4; col++) c[r * 4 + col] = c[r * 4 + col] / s + epsv; } for (int col = 0; col < 4; col++) { float s = epsv; for (int r = 0; r < 4; r++) s += c[r * 4 + col]; for (int r = 0; r < 4; r++) c[r * 4 + col] /= s; } for (uint32_t iter = 1; iter < sinkhorn_iters; iter++) { for (int r = 0; r < 4; r++) { float s = epsv; for (int col = 0; col < 4; col++) s += c[r * 4 + col]; for (int col = 0; col < 4; col++) c[r * 4 + col] /= s; } for (int col = 0; col < 4; col++) { float s = epsv; for (int r = 0; r < 4; r++) s += c[r * 4 + col]; for (int r = 0; r < 4; r++) c[r * 4 + col] /= s; } } for (int i = 0; i < 16; i++) out[8 + i] = c[i]; } __global__ static void hc_split_sinkhorn_kernel(float *out, const float *mix, const float *scale, const float *base, uint32_t n_rows, uint32_t sinkhorn_iters, float epsv) { uint32_t row = blockIdx.x * blockDim.x + threadIdx.x; if (row >= n_rows) return; hc4_split_one(out + (uint64_t)row * 24, mix + (uint64_t)row * 24, scale, base, sinkhorn_iters, epsv); } __global__ static void hc_weighted_sum_kernel(float *out, const float *x, const float *w, uint32_t n_embd, uint32_t n_hc, uint32_t n_tokens, uint32_t weight_stride_f32) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_embd * n_tokens; if (gid >= n) return; uint32_t d = gid % n_embd; uint32_t t = gid / n_embd; float acc = 0.0f; for (uint32_t h = 0; h < n_hc; h++) { acc += x[(uint64_t)t * n_hc * n_embd + (uint64_t)h * n_embd + d] * w[(uint64_t)t * weight_stride_f32 + h]; } out[(uint64_t)t * n_embd + d] = acc; } __global__ static void hc_expand_kernel( float *out_hc, const float *block_out, const float *block_add, const float *residual_hc, const float *post, const float *comb, uint32_t n_embd, uint32_t n_hc, uint32_t n_tokens, uint32_t post_stride, uint32_t comb_stride, int has_add) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n_elem = (uint64_t)n_tokens * n_hc * n_embd; if (gid >= n_elem) return; uint32_t d = gid % n_embd; uint64_t tmp = gid / n_embd; uint32_t dst_hc = tmp % n_hc; uint32_t t = tmp / n_hc; float block_v = block_out[(uint64_t)t * n_embd + d]; if (has_add) block_v += block_add[(uint64_t)t * n_embd + d]; float acc = block_v * post[(uint64_t)t * post_stride + dst_hc]; for (uint32_t src_hc = 0; src_hc < n_hc; src_hc++) { float comb_v = comb[(uint64_t)t * comb_stride + dst_hc + (uint64_t)src_hc * n_hc]; float res_v = residual_hc[(uint64_t)t * n_hc * n_embd + (uint64_t)src_hc * n_embd + d]; acc += comb_v * res_v; } out_hc[(uint64_t)t * n_hc * n_embd + (uint64_t)dst_hc * n_embd + d] = acc; } __global__ static void hc_split_weighted_sum_fused_kernel( float *out, float *split, const float *mix, const float *residual_hc, const float *scale, const float *base, uint32_t n_embd, uint32_t n_hc, uint32_t n_rows, uint32_t sinkhorn_iters, float epsv) { uint32_t t = blockIdx.x; uint32_t d = threadIdx.x; if (t >= n_rows || n_hc != 4) return; const uint32_t mix_hc = 24; float *sp = split + (uint64_t)t * mix_hc; if (d == 0) hc4_split_one(sp, mix + (uint64_t)t * mix_hc, scale, base, sinkhorn_iters, epsv); __syncthreads(); for (uint32_t col = d; col < n_embd; col += blockDim.x) { float acc = 0.0f; for (uint32_t h = 0; h < 4; h++) { acc += residual_hc[(uint64_t)t * 4u * n_embd + (uint64_t)h * n_embd + col] * sp[h]; } out[(uint64_t)t * n_embd + col] = acc; } } __global__ static void hc_split_weighted_sum_norm_fused_kernel( float *out, float *norm_out, float *split, const float *mix, const float *residual_hc, const float *scale, const float *base, const float *norm_w, uint32_t n_embd, uint32_t n_hc, uint32_t n_rows, uint32_t sinkhorn_iters, float epsv, float norm_eps) { const uint32_t t = blockIdx.x; const uint32_t d = threadIdx.x; if (t >= n_rows || n_hc != 4) return; const uint32_t mix_hc = 24; float *sp = split + (uint64_t)t * mix_hc; if (d == 0) hc4_split_one(sp, mix + (uint64_t)t * mix_hc, scale, base, sinkhorn_iters, epsv); __syncthreads(); float sum = 0.0f; for (uint32_t col = d; col < n_embd; col += blockDim.x) { float acc = 0.0f; for (uint32_t h = 0; h < 4; h++) { acc += residual_hc[(uint64_t)t * 4u * n_embd + (uint64_t)h * n_embd + col] * sp[h]; } out[(uint64_t)t * n_embd + col] = acc; sum += acc * acc; } __shared__ float partial[256]; partial[d] = sum; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (d < stride) partial[d] += partial[d + stride]; __syncthreads(); } const float norm_scale = rsqrtf(partial[0] / (float)n_embd + norm_eps); for (uint32_t col = d; col < n_embd; col += blockDim.x) { const float v = out[(uint64_t)t * n_embd + col]; norm_out[(uint64_t)t * n_embd + col] = v * norm_scale * norm_w[col]; } } __global__ static void output_hc_weights_kernel( float *out, const float *pre, const float *scale, const float *base, uint32_t n_hc, uint32_t n_tokens, float epsv) { uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; uint32_t n = n_tokens * n_hc; if (gid >= n) return; uint32_t h = gid % n_hc; float z = pre[gid] * scale[0] + base[h]; out[gid] = 1.0f / (1.0f + expf(-z)) + epsv; } __global__ static void fill_f32_kernel(float *x, uint64_t n, float v) { uint64_t i = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; if (i < n) x[i] = v; } __global__ static void compressor_store_kernel( const float *kv, const float *sc, float *state_kv, float *state_score, const void *model_map, uint64_t ape_offset, uint32_t ape_type, uint32_t head_dim, uint32_t ratio, uint32_t pos0, uint32_t n_tokens) { uint32_t coff = ratio == 4u ? 2u : 1u; uint32_t width = coff * head_dim; uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_tokens * width; if (gid >= n) return; uint32_t t = gid / width; uint32_t j = gid - (uint64_t)t * width; uint32_t pos_mod = (pos0 + t) % ratio; uint32_t dst_row = ratio == 4u ? ratio + pos_mod : pos_mod; state_kv[(uint64_t)dst_row * width + j] = kv[(uint64_t)t * width + j]; state_score[(uint64_t)dst_row * width + j] = sc[(uint64_t)t * width + j] + model_scalar_dev(model_map, ape_offset, ape_type, (uint64_t)pos_mod * width + j); } __global__ static void compressor_set_rows_kernel( float *state_kv, float *state_score, const float *kv, const float *sc, const void *model_map, uint64_t ape_offset, uint32_t ape_type, uint32_t width, uint32_t ratio, uint32_t pos0, uint32_t src0, uint32_t dst0, uint32_t rows) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)rows * width; if (gid >= n) return; uint32_t r = gid / width; uint32_t j = gid - (uint64_t)r * width; uint32_t src = src0 + r; uint32_t dst = dst0 + r; uint32_t phase = (pos0 + src) % ratio; state_kv[(uint64_t)dst * width + j] = kv[(uint64_t)src * width + j]; state_score[(uint64_t)dst * width + j] = sc[(uint64_t)src * width + j] + model_scalar_dev(model_map, ape_offset, ape_type, (uint64_t)phase * width + j); } __global__ static void compressor_prefill_pool_kernel( float *comp, const float *kv, const float *sc, const float *state_kv, const float *state_score, const void *model_map, uint64_t ape_offset, uint32_t ape_type, uint32_t head_dim, uint32_t ratio, uint32_t pos0, uint32_t n_comp, uint32_t replay) { uint32_t d = blockIdx.x * blockDim.x + threadIdx.x; uint32_t c = blockIdx.y; if (d >= head_dim || c >= n_comp) return; uint32_t coff = ratio == 4u ? 2u : 1u; uint32_t width = coff * head_dim; float vals[128]; float scores[128]; float max_s = -INFINITY; uint32_t n_cand = 0; if (ratio == 4u) { if (replay && c == 0) { for (uint32_t r = 0; r < 4; r++) { vals[n_cand] = state_kv[(uint64_t)r * width + d]; scores[n_cand] = state_score[(uint64_t)r * width + d]; max_s = fmaxf(max_s, scores[n_cand++]); } } else if (c > 0) { uint32_t base = (c - 1u) * ratio; for (uint32_t r = 0; r < 4; r++) { uint32_t t = base + r; float ape = model_scalar_dev(model_map, ape_offset, ape_type, (uint64_t)((pos0 + t) % ratio) * width + d); vals[n_cand] = kv[(uint64_t)t * width + d]; scores[n_cand] = sc[(uint64_t)t * width + d] + ape; max_s = fmaxf(max_s, scores[n_cand++]); } } uint32_t base = c * ratio; for (uint32_t r = 0; r < 4; r++) { uint32_t t = base + r; float ape = model_scalar_dev(model_map, ape_offset, ape_type, (uint64_t)((pos0 + t) % ratio) * width + head_dim + d); vals[n_cand] = kv[(uint64_t)t * width + head_dim + d]; scores[n_cand] = sc[(uint64_t)t * width + head_dim + d] + ape; max_s = fmaxf(max_s, scores[n_cand++]); } } else { uint32_t base = c * ratio; for (uint32_t r = 0; r < ratio; r++) { uint32_t t = base + r; float ape = model_scalar_dev(model_map, ape_offset, ape_type, (uint64_t)((pos0 + t) % ratio) * width + d); vals[n_cand] = kv[(uint64_t)t * width + d]; scores[n_cand] = sc[(uint64_t)t * width + d] + ape; max_s = fmaxf(max_s, scores[n_cand++]); } } float den = 0.0f, acc = 0.0f; for (uint32_t i = 0; i < n_cand; i++) { float w = expf(scores[i] - max_s); den += w; acc += vals[i] * w; } comp[(uint64_t)c * head_dim + d] = den != 0.0f ? acc / den : 0.0f; } __global__ static void compressor_update_pool_kernel( float *row, const float *state_kv, const float *state_score, uint32_t head_dim, uint32_t ratio) { uint32_t d = blockIdx.x * blockDim.x + threadIdx.x; if (d >= head_dim) return; uint32_t coff = ratio == 4u ? 2u : 1u; uint32_t width = coff * head_dim; float vals[128]; float scores[128]; float max_s = -INFINITY; uint32_t n_cand = 0; if (ratio == 4u) { for (uint32_t r = 0; r < 4; r++) { vals[n_cand] = state_kv[(uint64_t)r * width + d]; scores[n_cand] = state_score[(uint64_t)r * width + d]; max_s = fmaxf(max_s, scores[n_cand++]); } for (uint32_t r = 0; r < 4; r++) { vals[n_cand] = state_kv[(uint64_t)(ratio + r) * width + head_dim + d]; scores[n_cand] = state_score[(uint64_t)(ratio + r) * width + head_dim + d]; max_s = fmaxf(max_s, scores[n_cand++]); } } else { for (uint32_t r = 0; r < ratio; r++) { vals[n_cand] = state_kv[(uint64_t)r * width + d]; scores[n_cand] = state_score[(uint64_t)r * width + d]; max_s = fmaxf(max_s, scores[n_cand++]); } } float den = 0.0f, acc = 0.0f; for (uint32_t i = 0; i < n_cand; i++) { float w = expf(scores[i] - max_s); den += w; acc += vals[i] * w; } row[d] = den != 0.0f ? acc / den : 0.0f; } __global__ static void compressor_shift_ratio4_kernel(float *state_kv, float *state_score, uint32_t width) { uint64_t i = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t half = 4ull * width; if (i >= half) return; float v = state_kv[half + i]; float s = state_score[half + i]; state_kv[i] = v; state_score[i] = s; state_kv[half + i] = v; state_score[half + i] = s; } __device__ static float softplus_dev(float x) { if (x > 20.0f) return x; if (x < -20.0f) return expf(x); return log1pf(expf(x)); } __global__ static void router_select_kernel( int32_t *selected, float *weights, float *probs, const float *bias, const int32_t *hash, const float *logits, const int32_t *tokens, int32_t token_scalar, uint32_t hash_rows, uint32_t n_tokens, int has_bias, int hash_mode) { uint32_t t = blockIdx.x; if (t >= n_tokens || threadIdx.x != 0) return; const float *log = logits + (uint64_t)t * 256; float *prob = probs + (uint64_t)t * 256; int32_t *sel = selected + (uint64_t)t * 6; float *w = weights + (uint64_t)t * 6; for (int i = 0; i < 256; i++) prob[i] = sqrtf(softplus_dev(log[i])); if (hash_mode) { int32_t tok = tokens ? tokens[t] : token_scalar; if (tok < 0 || (uint32_t)tok >= hash_rows) tok = 0; const int32_t *row = hash + (uint64_t)tok * 6; for (int i = 0; i < 6; i++) sel[i] = row[i]; } else { for (int i = 0; i < 6; i++) sel[i] = -1; for (int i = 0; i < 256; i++) { float score = prob[i] + (has_bias ? bias[i] : 0.0f); for (int j = 0; j < 6; j++) { if (sel[j] < 0 || score > prob[sel[j]] + (has_bias ? bias[sel[j]] : 0.0f)) { for (int k = 5; k > j; k--) sel[k] = sel[k - 1]; sel[j] = i; break; } } } } float sum = 0.0f; for (int i = 0; i < 6; i++) { int e = sel[i]; float v = (e >= 0 && e < 256) ? prob[e] : 0.0f; w[i] = v; sum += v; } sum = fmaxf(sum, 6.103515625e-5f); for (int i = 0; i < 6; i++) w[i] = w[i] / sum * 1.5f; } __global__ static void router_select_parallel_kernel( int32_t *selected, float *weights, float *probs, const float *bias, const int32_t *hash, const float *logits, const int32_t *tokens, int32_t token_scalar, uint32_t hash_rows, uint32_t n_tokens, int has_bias, int hash_mode) { uint32_t t = blockIdx.x; uint32_t i = threadIdx.x; if (t >= n_tokens || i >= 256u) return; const float *log = logits + (uint64_t)t * 256; float *prob = probs + (uint64_t)t * 256; int32_t *sel = selected + (uint64_t)t * 6; float *w = weights + (uint64_t)t * 6; __shared__ float sprob[256]; const float p = sqrtf(softplus_dev(log[i])); sprob[i] = p; prob[i] = p; __syncthreads(); if (i != 0) return; if (hash_mode) { int32_t tok = tokens ? tokens[t] : token_scalar; if (tok < 0 || (uint32_t)tok >= hash_rows) tok = 0; const int32_t *row = hash + (uint64_t)tok * 6; for (int j = 0; j < 6; j++) sel[j] = row[j]; } else { for (int j = 0; j < 6; j++) sel[j] = -1; for (int e = 0; e < 256; e++) { float score = sprob[e] + (has_bias ? bias[e] : 0.0f); for (int j = 0; j < 6; j++) { if (sel[j] < 0 || score > sprob[sel[j]] + (has_bias ? bias[sel[j]] : 0.0f)) { for (int k = 5; k > j; k--) sel[k] = sel[k - 1]; sel[j] = e; break; } } } } float sum = 0.0f; for (int j = 0; j < 6; j++) { int e = sel[j]; float v = (e >= 0 && e < 256) ? sprob[e] : 0.0f; w[j] = v; sum += v; } sum = fmaxf(sum, 6.103515625e-5f); for (int j = 0; j < 6; j++) w[j] = w[j] / sum * 1.5f; } __device__ __forceinline__ static bool router_score_better(float av, uint32_t ai, float bv, uint32_t bi) { return av > bv || (av == bv && ai < bi); } __global__ static void router_select_warp_topk_kernel( int32_t *selected, float *weights, float *probs, const float *bias, const int32_t *hash, const float *logits, const int32_t *tokens, int32_t token_scalar, uint32_t hash_rows, uint32_t n_tokens, int has_bias, int hash_mode) { const uint32_t lane = threadIdx.x; const uint32_t row_in_block = threadIdx.y; const uint32_t t = blockIdx.x * blockDim.y + row_in_block; if (t >= n_tokens || lane >= 32u) return; const float *log = logits + (uint64_t)t * 256u; float *prob = probs + (uint64_t)t * 256u; int32_t *sel = selected + (uint64_t)t * 6u; float *w = weights + (uint64_t)t * 6u; __shared__ float sprob[4][256]; float local_prob[8]; float local_score[8]; #pragma unroll for (uint32_t j = 0; j < 8u; j++) { const uint32_t e = lane + j * 32u; const float p = sqrtf(softplus_dev(log[e])); local_prob[j] = p; local_score[j] = p + (has_bias ? bias[e] : 0.0f); sprob[row_in_block][e] = p; prob[e] = p; } __syncwarp(); if (hash_mode) { if (lane == 0) { int32_t tok = tokens ? tokens[t] : token_scalar; if (tok < 0 || (uint32_t)tok >= hash_rows) tok = 0; const int32_t *row = hash + (uint64_t)tok * 6u; float sum = 0.0f; #pragma unroll for (uint32_t j = 0; j < 6u; j++) { const int32_t e = row[j]; sel[j] = e; const float v = (e >= 0 && e < 256) ? sprob[row_in_block][(uint32_t)e] : 0.0f; w[j] = v; sum += v; } sum = fmaxf(sum, 6.103515625e-5f); #pragma unroll for (uint32_t j = 0; j < 6u; j++) w[j] = w[j] / sum * 1.5f; } return; } float out_prob[6] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; uint32_t out_idx[6] = {0, 0, 0, 0, 0, 0}; #pragma unroll for (uint32_t k = 0; k < 6u; k++) { float best_score = -INFINITY; float best_prob = 0.0f; uint32_t best_idx = UINT32_MAX; #pragma unroll for (uint32_t j = 0; j < 8u; j++) { const uint32_t e = lane + j * 32u; const float s = local_score[j]; if (router_score_better(s, e, best_score, best_idx)) { best_score = s; best_prob = local_prob[j]; best_idx = e; } } #pragma unroll for (uint32_t mask = 16u; mask > 0u; mask >>= 1u) { const float other_score = __shfl_xor_sync(0xffffffffu, best_score, mask); const float other_prob = __shfl_xor_sync(0xffffffffu, best_prob, mask); const uint32_t other_idx = __shfl_xor_sync(0xffffffffu, best_idx, mask); if (router_score_better(other_score, other_idx, best_score, best_idx)) { best_score = other_score; best_prob = other_prob; best_idx = other_idx; } } #pragma unroll for (uint32_t j = 0; j < 8u; j++) { const uint32_t e = lane + j * 32u; if (e == best_idx) local_score[j] = -INFINITY; } if (lane == 0) { out_idx[k] = best_idx; out_prob[k] = best_prob; } } if (lane == 0) { float sum = 0.0f; #pragma unroll for (uint32_t j = 0; j < 6u; j++) { sel[j] = (int32_t)out_idx[j]; w[j] = out_prob[j]; sum += out_prob[j]; } sum = fmaxf(sum, 6.103515625e-5f); #pragma unroll for (uint32_t j = 0; j < 6u; j++) w[j] = w[j] / sum * 1.5f; } } __global__ static void swiglu_kernel(float *out, const float *gate, const float *up, uint32_t n, float clamp, float weight) { uint32_t i = blockIdx.x * blockDim.x + threadIdx.x; if (i >= n) return; float g = gate[i]; float u = up[i]; if (clamp > 1.0e-6f) { g = fminf(g, clamp); u = fminf(fmaxf(u, -clamp), clamp); } float s = g / (1.0f + expf(-g)); out[i] = s * u * weight; } __global__ static void add_kernel(float *out, const float *a, const float *b, uint32_t n) { uint32_t i = blockIdx.x * blockDim.x + threadIdx.x; if (i >= n) return; out[i] = a[i] + b[i]; } __global__ static void directional_steering_project_kernel( float *x, const float *directions, uint32_t layer, uint32_t width, uint32_t rows, float scale) { const uint32_t row = blockIdx.x; if (row >= rows || width == 0) return; float *xr = x + (uint64_t)row * width; const float *dir = directions + (uint64_t)layer * width; float sum = 0.0f; for (uint32_t i = threadIdx.x; i < width; i += blockDim.x) { sum += xr[i] * dir[i]; } __shared__ float partial[256]; partial[threadIdx.x] = sum; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } const float coeff = scale * partial[0]; for (uint32_t i = threadIdx.x; i < width; i += blockDim.x) { xr[i] -= coeff * dir[i]; } } __global__ static void zero_kernel(float *out, uint64_t n) { uint64_t i = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; if (i < n) out[i] = 0.0f; } __global__ static void indexer_scores_kernel( float *scores, const float *q, const float *weights, const float *index_comp, uint32_t n_comp, uint32_t n_tokens, uint32_t pos0, uint32_t n_head, uint32_t head_dim, uint32_t ratio, float scale, int causal) { uint32_t c = blockIdx.x; uint32_t t = blockIdx.y; if (c >= n_comp || t >= n_tokens) return; if (causal) { uint32_t n_visible = (pos0 + t + 1u) / ratio; if (c >= n_visible) { if (threadIdx.x == 0) scores[(uint64_t)t * n_comp + c] = -INFINITY; return; } } float total = 0.0f; for (uint32_t h = 0; h < n_head; h++) { const float *qh = q + ((uint64_t)t * n_head + h) * head_dim; const float *kh = index_comp + (uint64_t)c * head_dim; float dot = 0.0f; for (uint32_t d = threadIdx.x; d < head_dim; d += blockDim.x) dot += qh[d] * kh[d]; __shared__ float partial[256]; partial[threadIdx.x] = dot; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } total += fmaxf(partial[0], 0.0f) * weights[(uint64_t)t * n_head + h]; __syncthreads(); } if (threadIdx.x == 0) scores[(uint64_t)t * n_comp + c] = total * scale; } __global__ static void indexer_score_one_direct_kernel( float *scores, const float *q, const float *weights, const float *index_comp, uint32_t n_comp, uint32_t pos0, uint32_t ratio, float scale, int causal) { const uint32_t c = blockIdx.x; const uint32_t tid = threadIdx.x; const uint32_t lane = tid & 31u; const uint32_t warp = tid >> 5u; if (c >= n_comp || tid >= 128u) return; if (causal) { const uint32_t visible = ratio ? (pos0 + 1u) / ratio : n_comp; if (c >= visible) { if (tid == 0) scores[c] = -INFINITY; return; } } __shared__ float krow[128]; __shared__ float partial[4]; if (tid < 128u) krow[tid] = index_comp[(uint64_t)c * 128u + tid]; __syncthreads(); float total = 0.0f; for (uint32_t h0 = 0; h0 < 64u; h0 += 4u) { const uint32_t h = h0 + warp; const float4 qv = ((const float4 *)(q + (uint64_t)h * 128u))[lane]; const float4 kv = ((const float4 *)krow)[lane]; float dot = qv.x * kv.x + qv.y * kv.y + qv.z * kv.z + qv.w * kv.w; dot = warp_sum_f32(dot); if (lane == 0) partial[warp] = fmaxf(dot, 0.0f) * weights[h] * scale; __syncthreads(); if (tid == 0) total += partial[0] + partial[1] + partial[2] + partial[3]; __syncthreads(); } if (tid == 0) scores[c] = total; } __global__ static void indexer_scores_wmma_kernel( float *scores, const float *q, const float *weights, const float *index_comp, uint32_t n_comp, uint32_t n_tokens, uint32_t pos0, uint32_t n_head, uint32_t head_dim, uint32_t ratio, float scale, int causal) { #if __CUDA_ARCH__ >= 700 namespace wmma = nvcuda::wmma; const uint32_t tile_c = blockIdx.x * 16u; const uint32_t tile_t = blockIdx.y * 16u; const uint32_t tid = threadIdx.x; if (tid >= 32u || head_dim != 128u) return; if (causal) { const uint32_t last_token = min(tile_t + 16u, n_tokens); const uint32_t max_visible = last_token > tile_t ? min((pos0 + last_token) / ratio, n_comp) : 0u; if (tile_c >= max_visible) { for (uint32_t i = tid; i < 16u * 16u; i += 32u) { const uint32_t r = i >> 4u; const uint32_t c = i & 15u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + c; if (token < n_tokens && comp < n_comp) { scores[(uint64_t)token * n_comp + comp] = -INFINITY; } } return; } } __shared__ __half a_sh[16 * 128]; __shared__ __half b_sh[16 * 128]; __shared__ float c_sh[16 * 16]; __shared__ float acc_sh[16 * 16]; for (uint32_t i = tid; i < 16u * 16u; i += 32u) acc_sh[i] = 0.0f; for (uint32_t i = tid; i < 16u * 128u; i += 32u) { const uint32_t c = i >> 7u; const uint32_t d = i & 127u; const uint32_t comp = tile_c + c; float v = 0.0f; if (comp < n_comp) v = index_comp[(uint64_t)comp * head_dim + d]; b_sh[d + c * 128u] = __float2half(v); } __syncthreads(); for (uint32_t h = 0; h < n_head; h++) { for (uint32_t i = tid; i < 16u * 128u; i += 32u) { const uint32_t r = i >> 7u; const uint32_t d = i & 127u; const uint32_t token = tile_t + r; float v = 0.0f; if (token < n_tokens) { v = q[((uint64_t)token * n_head + h) * head_dim + d]; } a_sh[i] = __float2half(v); } __syncthreads(); wmma::fragment a_frag; wmma::fragment b_frag; wmma::fragment c_frag; wmma::fill_fragment(c_frag, 0.0f); for (uint32_t k0 = 0; k0 < 128u; k0 += 16u) { wmma::load_matrix_sync(a_frag, a_sh + k0, 128); wmma::load_matrix_sync(b_frag, b_sh + k0, 128); wmma::mma_sync(c_frag, a_frag, b_frag, c_frag); } wmma::store_matrix_sync(c_sh, c_frag, 16, wmma::mem_row_major); __syncthreads(); for (uint32_t i = tid; i < 16u * 16u; i += 32u) { const uint32_t r = i >> 4u; const uint32_t token = tile_t + r; if (token < n_tokens) { const float w = weights[(uint64_t)token * n_head + h]; acc_sh[i] += fmaxf(c_sh[i], 0.0f) * w; } } __syncthreads(); } for (uint32_t i = tid; i < 16u * 16u; i += 32u) { const uint32_t r = i >> 4u; const uint32_t c = i & 15u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + c; if (token < n_tokens && comp < n_comp) { float out = acc_sh[i] * scale; if (causal) { const uint32_t visible = (pos0 + token + 1u) / ratio; if (comp >= visible) out = -INFINITY; } scores[(uint64_t)token * n_comp + comp] = out; } } #endif } __global__ static void indexer_scores_wmma32_kernel( float *scores, const float *q, const float *weights, const float *index_comp, uint32_t n_comp, uint32_t n_tokens, uint32_t pos0, uint32_t n_head, uint32_t head_dim, uint32_t ratio, float scale, int causal) { #if __CUDA_ARCH__ >= 700 namespace wmma = nvcuda::wmma; const uint32_t tile_c = blockIdx.x * 32u; const uint32_t tile_t = blockIdx.y * 16u; const uint32_t tid = threadIdx.x; const uint32_t warp = tid >> 5u; if (tid >= 64u || head_dim != 128u) return; if (causal) { const uint32_t last_token = min(tile_t + 16u, n_tokens); const uint32_t max_visible = last_token > tile_t ? min((pos0 + last_token) / ratio, n_comp) : 0u; if (tile_c >= max_visible) { for (uint32_t i = tid; i < 16u * 32u; i += 64u) { const uint32_t r = i >> 5u; const uint32_t c = i & 31u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + c; if (token < n_tokens && comp < n_comp) { scores[(uint64_t)token * n_comp + comp] = -INFINITY; } } return; } } __shared__ __half a_sh[16 * 128]; __shared__ __half b_sh[32 * 128]; __shared__ float c_sh[2 * 16 * 16]; __shared__ float acc_sh[2 * 16 * 16]; for (uint32_t i = tid; i < 2u * 16u * 16u; i += 64u) acc_sh[i] = 0.0f; for (uint32_t i = tid; i < 32u * 128u; i += 64u) { const uint32_t c = i >> 7u; const uint32_t d = i & 127u; const uint32_t comp = tile_c + c; float v = 0.0f; if (comp < n_comp) v = index_comp[(uint64_t)comp * head_dim + d]; b_sh[d + c * 128u] = __float2half(v); } __syncthreads(); for (uint32_t h = 0; h < n_head; h++) { for (uint32_t i = tid; i < 16u * 128u; i += 64u) { const uint32_t r = i >> 7u; const uint32_t d = i & 127u; const uint32_t token = tile_t + r; float v = 0.0f; if (token < n_tokens) { v = q[((uint64_t)token * n_head + h) * head_dim + d]; } a_sh[i] = __float2half(v); } __syncthreads(); wmma::fragment a_frag; wmma::fragment b_frag; wmma::fragment c_frag; wmma::fill_fragment(c_frag, 0.0f); const uint32_t col0 = warp * 16u; for (uint32_t k0 = 0; k0 < 128u; k0 += 16u) { wmma::load_matrix_sync(a_frag, a_sh + k0, 128); wmma::load_matrix_sync(b_frag, b_sh + col0 * 128u + k0, 128); wmma::mma_sync(c_frag, a_frag, b_frag, c_frag); } wmma::store_matrix_sync(c_sh + warp * 16u * 16u, c_frag, 16, wmma::mem_row_major); __syncthreads(); for (uint32_t i = tid; i < 2u * 16u * 16u; i += 64u) { const uint32_t wtile = i >> 8u; const uint32_t local = i & 255u; const uint32_t r = local >> 4u; const uint32_t c = local & 15u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + wtile * 16u + c; if (token < n_tokens && comp < n_comp) { const float w = weights[(uint64_t)token * n_head + h]; acc_sh[i] += fmaxf(c_sh[i], 0.0f) * w; } } __syncthreads(); } for (uint32_t i = tid; i < 2u * 16u * 16u; i += 64u) { const uint32_t wtile = i >> 8u; const uint32_t local = i & 255u; const uint32_t r = local >> 4u; const uint32_t c = local & 15u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + wtile * 16u + c; if (token < n_tokens && comp < n_comp) { float out = acc_sh[i] * scale; if (causal) { const uint32_t visible = (pos0 + token + 1u) / ratio; if (comp >= visible) out = -INFINITY; } scores[(uint64_t)token * n_comp + comp] = out; } } #endif } __global__ static void indexer_scores_wmma64_kernel( float *scores, const float *q, const float *weights, const float *index_comp, uint32_t n_comp, uint32_t n_tokens, uint32_t pos0, uint32_t n_head, uint32_t head_dim, uint32_t ratio, float scale, int causal) { #if __CUDA_ARCH__ >= 700 namespace wmma = nvcuda::wmma; const uint32_t tile_c = blockIdx.x * 64u; const uint32_t tile_t = blockIdx.y * 16u; const uint32_t tid = threadIdx.x; const uint32_t warp = tid >> 5u; if (tid >= 128u || head_dim != 128u) return; if (causal) { const uint32_t last_token = min(tile_t + 16u, n_tokens); const uint32_t max_visible = last_token > tile_t ? min((pos0 + last_token) / ratio, n_comp) : 0u; if (tile_c >= max_visible) { for (uint32_t i = tid; i < 16u * 64u; i += 128u) { const uint32_t r = i >> 6u; const uint32_t c = i & 63u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + c; if (token < n_tokens && comp < n_comp) { scores[(uint64_t)token * n_comp + comp] = -INFINITY; } } return; } } __shared__ __half a_sh[16 * 128]; __shared__ __half b_sh[64 * 128]; __shared__ float c_sh[4 * 16 * 16]; __shared__ float acc_sh[4 * 16 * 16]; for (uint32_t i = tid; i < 4u * 16u * 16u; i += 128u) acc_sh[i] = 0.0f; for (uint32_t i = tid; i < 64u * 128u; i += 128u) { const uint32_t c = i >> 7u; const uint32_t d = i & 127u; const uint32_t comp = tile_c + c; float v = 0.0f; if (comp < n_comp) v = index_comp[(uint64_t)comp * head_dim + d]; b_sh[d + c * 128u] = __float2half(v); } __syncthreads(); for (uint32_t h = 0; h < n_head; h++) { for (uint32_t i = tid; i < 16u * 128u; i += 128u) { const uint32_t r = i >> 7u; const uint32_t d = i & 127u; const uint32_t token = tile_t + r; float v = 0.0f; if (token < n_tokens) { v = q[((uint64_t)token * n_head + h) * head_dim + d]; } a_sh[i] = __float2half(v); } __syncthreads(); wmma::fragment a_frag; wmma::fragment b_frag; wmma::fragment c_frag; wmma::fill_fragment(c_frag, 0.0f); const uint32_t col0 = warp * 16u; for (uint32_t k0 = 0; k0 < 128u; k0 += 16u) { wmma::load_matrix_sync(a_frag, a_sh + k0, 128); wmma::load_matrix_sync(b_frag, b_sh + col0 * 128u + k0, 128); wmma::mma_sync(c_frag, a_frag, b_frag, c_frag); } wmma::store_matrix_sync(c_sh + warp * 16u * 16u, c_frag, 16, wmma::mem_row_major); __syncthreads(); for (uint32_t i = tid; i < 4u * 16u * 16u; i += 128u) { const uint32_t wtile = i >> 8u; const uint32_t local = i & 255u; const uint32_t r = local >> 4u; const uint32_t c = local & 15u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + wtile * 16u + c; if (token < n_tokens && comp < n_comp) { const float w = weights[(uint64_t)token * n_head + h]; acc_sh[i] += fmaxf(c_sh[i], 0.0f) * w; } } __syncthreads(); } for (uint32_t i = tid; i < 4u * 16u * 16u; i += 128u) { const uint32_t wtile = i >> 8u; const uint32_t local = i & 255u; const uint32_t r = local >> 4u; const uint32_t c = local & 15u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + wtile * 16u + c; if (token < n_tokens && comp < n_comp) { float out = acc_sh[i] * scale; if (causal) { const uint32_t visible = (pos0 + token + 1u) / ratio; if (comp >= visible) out = -INFINITY; } scores[(uint64_t)token * n_comp + comp] = out; } } #endif } __global__ static void indexer_scores_wmma128_kernel( float *scores, const float *q, const float *weights, const float *index_comp, uint32_t n_comp, uint32_t n_tokens, uint32_t pos0, uint32_t n_head, uint32_t head_dim, uint32_t ratio, float scale, int causal) { #if __CUDA_ARCH__ >= 700 namespace wmma = nvcuda::wmma; const uint32_t tile_c = blockIdx.x * 128u; const uint32_t tile_t = blockIdx.y * 16u; const uint32_t tid = threadIdx.x; const uint32_t warp = tid >> 5u; if (tid >= 256u || head_dim != 128u) return; if (causal) { const uint32_t last_token = min(tile_t + 16u, n_tokens); const uint32_t max_visible = last_token > tile_t ? min((pos0 + last_token) / ratio, n_comp) : 0u; if (tile_c >= max_visible) { for (uint32_t i = tid; i < 16u * 128u; i += 256u) { const uint32_t r = i >> 7u; const uint32_t c = i & 127u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + c; if (token < n_tokens && comp < n_comp) { scores[(uint64_t)token * n_comp + comp] = -INFINITY; } } return; } } __shared__ __half a_sh[16 * 128]; __shared__ __half b_sh[128 * 128]; __shared__ float c_sh[8 * 16 * 16]; float acc[8]; #pragma unroll for (uint32_t i = 0; i < 8u; i++) acc[i] = 0.0f; for (uint32_t i = tid; i < 128u * 128u; i += 256u) { const uint32_t c = i >> 7u; const uint32_t d = i & 127u; const uint32_t comp = tile_c + c; float v = 0.0f; if (comp < n_comp) v = index_comp[(uint64_t)comp * head_dim + d]; b_sh[d + c * 128u] = __float2half(v); } __syncthreads(); for (uint32_t h = 0; h < n_head; h++) { for (uint32_t i = tid; i < 16u * 128u; i += 256u) { const uint32_t r = i >> 7u; const uint32_t d = i & 127u; const uint32_t token = tile_t + r; float v = 0.0f; if (token < n_tokens) { v = q[((uint64_t)token * n_head + h) * head_dim + d]; } a_sh[i] = __float2half(v); } __syncthreads(); wmma::fragment a_frag; wmma::fragment b_frag; wmma::fragment c_frag; wmma::fill_fragment(c_frag, 0.0f); const uint32_t col0 = warp * 16u; for (uint32_t k0 = 0; k0 < 128u; k0 += 16u) { wmma::load_matrix_sync(a_frag, a_sh + k0, 128); wmma::load_matrix_sync(b_frag, b_sh + col0 * 128u + k0, 128); wmma::mma_sync(c_frag, a_frag, b_frag, c_frag); } wmma::store_matrix_sync(c_sh + warp * 16u * 16u, c_frag, 16, wmma::mem_row_major); __syncthreads(); const uint32_t local0 = tid & 255u; const uint32_t token0 = tile_t + (local0 >> 4u); const float w0 = token0 < n_tokens ? weights[(uint64_t)token0 * n_head + h] : 0.0f; uint32_t slot = 0; for (uint32_t i = tid; i < 8u * 16u * 16u; i += 256u, slot++) { const uint32_t wtile = i >> 8u; const uint32_t local = i & 255u; const uint32_t r = local >> 4u; const uint32_t c = local & 15u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + wtile * 16u + c; if (token < n_tokens && comp < n_comp) { acc[slot] += fmaxf(c_sh[i], 0.0f) * w0; } } __syncthreads(); } uint32_t slot = 0; for (uint32_t i = tid; i < 8u * 16u * 16u; i += 256u, slot++) { const uint32_t wtile = i >> 8u; const uint32_t local = i & 255u; const uint32_t r = local >> 4u; const uint32_t c = local & 15u; const uint32_t token = tile_t + r; const uint32_t comp = tile_c + wtile * 16u + c; if (token < n_tokens && comp < n_comp) { float out = acc[slot] * scale; if (causal) { const uint32_t visible = (pos0 + token + 1u) / ratio; if (comp >= visible) out = -INFINITY; } scores[(uint64_t)token * n_comp + comp] = out; } } #endif } /* Single-block argmax over n_vocab F32 logits. One block of 1024 threads * cooperatively scans the vocab, tracking a (best_v, best_idx) pair per * thread, then reduces in shared memory with value-keyed comparison. * * Tie-breaking: lower index wins, matching the host sample_argmax used by * the CPU reference path. Replaces the indexer-as-argmax workaround used * in the MTP top-id sites, which fell through to the legacy single-thread * indexer_topk_kernel at top_k=1, costing ~17.5 ms per call on n_vocab=129280. */ __global__ static void argmax_kernel(int32_t *out_idx, const float *logits, uint32_t n_vocab) { enum { THREADS = 1024 }; __shared__ float sm_val[THREADS]; __shared__ int32_t sm_idx[THREADS]; const uint32_t tid = threadIdx.x; float local_v = -INFINITY; int32_t local_i = 0; for (uint32_t i = tid; i < n_vocab; i += THREADS) { const float v = logits[i]; if (v > local_v) { local_v = v; local_i = (int32_t)i; } } sm_val[tid] = local_v; sm_idx[tid] = local_i; __syncthreads(); for (uint32_t s = THREADS / 2u; s > 0u; s >>= 1) { if (tid < s) { const float vr = sm_val[tid + s]; const int32_t ir = sm_idx[tid + s]; const float vl = sm_val[tid]; const int32_t il = sm_idx[tid]; /* Larger value wins; on exact ties prefer the lower index. */ const bool take_right = (vr > vl) || (vr == vl && ir < il); if (take_right) { sm_val[tid] = vr; sm_idx[tid] = ir; } } __syncthreads(); } if (tid == 0) *out_idx = sm_idx[0]; } __global__ static void indexer_topk_kernel(uint32_t *selected, const float *scores, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k) { uint32_t t = blockIdx.x; if (t >= n_tokens || threadIdx.x != 0) return; const float *row = scores + (uint64_t)t * n_comp; uint32_t *sel = selected + (uint64_t)t * top_k; for (uint32_t k = 0; k < top_k; k++) sel[k] = 0; for (uint32_t c = 0; c < n_comp; c++) { float v = row[c]; for (uint32_t k = 0; k < top_k; k++) { if ((k >= c) || v > row[sel[k]]) { for (uint32_t j = top_k - 1; j > k; j--) sel[j] = sel[j - 1]; sel[k] = c; break; } } } } __device__ __forceinline__ static bool topk_score_better(float av, uint32_t ai, float bv, uint32_t bi) { return av > bv || (av == bv && ai < bi); } __device__ __forceinline__ static uint32_t topk_float_ordered_key(float v) { const uint32_t u = __float_as_uint(v); return (u & 0x80000000u) ? ~u : (u ^ 0x80000000u); } __device__ __forceinline__ static uint64_t topk_pack_key(float v, uint32_t idx) { return ((uint64_t)topk_float_ordered_key(v) << 32u) | (uint64_t)(0xffffffffu - idx); } __global__ static void indexer_topk_8192_cub_kernel( uint32_t *selected, const float *scores, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k) { constexpr uint32_t BLOCK_THREADS = 512u; constexpr uint32_t ITEMS_PER_THREAD = 16u; using BlockSort = cub::BlockRadixSort; extern __shared__ __align__(16) unsigned char sort_smem[]; typename BlockSort::TempStorage &sort_storage = *reinterpret_cast(sort_smem); const uint32_t t = blockIdx.x; const uint32_t tid = threadIdx.x; if (t >= n_tokens || tid >= BLOCK_THREADS) return; const float *row = scores + (uint64_t)t * n_comp; uint64_t keys[ITEMS_PER_THREAD]; #pragma unroll for (uint32_t item = 0; item < ITEMS_PER_THREAD; item++) { const uint32_t i = tid * ITEMS_PER_THREAD + item; if (i < n_comp) { keys[item] = topk_pack_key(row[i], i); } else { keys[item] = topk_pack_key(-INFINITY, UINT32_MAX); } } BlockSort(sort_storage).SortDescending(keys); #pragma unroll for (uint32_t item = 0; item < ITEMS_PER_THREAD; item++) { const uint32_t i = tid * ITEMS_PER_THREAD + item; if (i < top_k) { selected[(uint64_t)t * top_k + i] = 0xffffffffu - (uint32_t)keys[item]; } } } __global__ static void indexer_topk_1024_kernel( uint32_t *selected, const float *scores, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k) { uint32_t t = blockIdx.x; uint32_t tid = threadIdx.x; if (t >= n_tokens || tid >= 1024u) return; __shared__ float vals[1024]; __shared__ uint32_t idxs[1024]; const float *row = scores + (uint64_t)t * n_comp; if (tid < n_comp) { vals[tid] = row[tid]; idxs[tid] = tid; } else { vals[tid] = -INFINITY; idxs[tid] = UINT32_MAX; } __syncthreads(); for (uint32_t k = 2u; k <= 1024u; k <<= 1u) { for (uint32_t j = k >> 1u; j > 0u; j >>= 1u) { uint32_t other = tid ^ j; if (other > tid && other < 1024u) { const float av = vals[tid]; const float bv = vals[other]; const uint32_t ai = idxs[tid]; const uint32_t bi = idxs[other]; const bool desc_half = (tid & k) == 0u; const bool swap = desc_half ? topk_score_better(bv, bi, av, ai) : topk_score_better(av, ai, bv, bi); if (swap) { vals[tid] = bv; idxs[tid] = bi; vals[other] = av; idxs[other] = ai; } } __syncthreads(); } } if (tid < top_k) selected[(uint64_t)t * top_k + tid] = idxs[tid]; } template __global__ static void indexer_topk_pow2_kernel( uint32_t *selected, const float *scores, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k) { uint32_t t = blockIdx.x; uint32_t tid = threadIdx.x; if (t >= n_tokens) return; __shared__ float vals[SORT_N]; __shared__ uint32_t idxs[SORT_N]; const float *row = scores + (uint64_t)t * n_comp; for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { if (i < n_comp) { vals[i] = row[i]; idxs[i] = i; } else { vals[i] = -INFINITY; idxs[i] = UINT32_MAX; } } __syncthreads(); for (uint32_t k = 2u; k <= SORT_N; k <<= 1u) { for (uint32_t j = k >> 1u; j > 0u; j >>= 1u) { for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { uint32_t other = i ^ j; if (other > i && other < SORT_N) { const float av = vals[i]; const float bv = vals[other]; const uint32_t ai = idxs[i]; const uint32_t bi = idxs[other]; const bool desc_half = (i & k) == 0u; const bool swap = desc_half ? topk_score_better(bv, bi, av, ai) : topk_score_better(av, ai, bv, bi); if (swap) { vals[i] = bv; idxs[i] = bi; vals[other] = av; idxs[other] = ai; } } } __syncthreads(); } } for (uint32_t i = tid; i < top_k; i += blockDim.x) { selected[(uint64_t)t * top_k + i] = idxs[i]; } } template __global__ static void indexer_topk_pow2_u16_kernel( uint32_t *selected, const float *scores, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k) { uint32_t t = blockIdx.x; uint32_t tid = threadIdx.x; if (t >= n_tokens) return; __shared__ float vals[SORT_N]; __shared__ uint16_t idxs[SORT_N]; const float *row = scores + (uint64_t)t * n_comp; for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { if (i < n_comp) { vals[i] = row[i]; idxs[i] = (uint16_t)i; } else { vals[i] = -INFINITY; idxs[i] = UINT16_MAX; } } __syncthreads(); for (uint32_t k = 2u; k <= SORT_N; k <<= 1u) { for (uint32_t j = k >> 1u; j > 0u; j >>= 1u) { for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { uint32_t other = i ^ j; if (other > i && other < SORT_N) { const float av = vals[i]; const float bv = vals[other]; const uint32_t ai = idxs[i]; const uint32_t bi = idxs[other]; const bool desc_half = (i & k) == 0u; const bool swap = desc_half ? topk_score_better(bv, bi, av, ai) : topk_score_better(av, ai, bv, bi); if (swap) { vals[i] = bv; idxs[i] = (uint16_t)bi; vals[other] = av; idxs[other] = (uint16_t)ai; } } } __syncthreads(); } } for (uint32_t i = tid; i < top_k; i += blockDim.x) { selected[(uint64_t)t * top_k + i] = idxs[i]; } } template __global__ static void indexer_topk_chunk_pow2_kernel( uint32_t *candidates, const float *scores, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k, uint32_t candidate_stride) { uint32_t t = blockIdx.x; uint32_t chunk = blockIdx.y; uint32_t tid = threadIdx.x; if (t >= n_tokens) return; const uint32_t chunk_start = chunk * SORT_N; if (chunk_start >= n_comp) return; const uint32_t chunk_n = n_comp - chunk_start < SORT_N ? n_comp - chunk_start : SORT_N; __shared__ float vals[SORT_N]; __shared__ uint32_t idxs[SORT_N]; const float *row = scores + (uint64_t)t * n_comp; for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { if (i < chunk_n) { vals[i] = row[chunk_start + i]; idxs[i] = chunk_start + i; } else { vals[i] = -INFINITY; idxs[i] = UINT32_MAX; } } __syncthreads(); for (uint32_t k = 2u; k <= SORT_N; k <<= 1u) { for (uint32_t j = k >> 1u; j > 0u; j >>= 1u) { for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { uint32_t other = i ^ j; if (other > i && other < SORT_N) { const float av = vals[i]; const float bv = vals[other]; const uint32_t ai = idxs[i]; const uint32_t bi = idxs[other]; const bool desc_half = (i & k) == 0u; const bool swap = desc_half ? topk_score_better(bv, bi, av, ai) : topk_score_better(av, ai, bv, bi); if (swap) { vals[i] = bv; idxs[i] = bi; vals[other] = av; idxs[other] = ai; } } } __syncthreads(); } } uint32_t *out = candidates + (uint64_t)t * candidate_stride + chunk * top_k; for (uint32_t i = tid; i < top_k; i += blockDim.x) { out[i] = idxs[i]; } } template __global__ static void indexer_topk_merge_pow2_kernel( uint32_t *selected, const uint32_t *candidates, const float *scores, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k, uint32_t candidate_count, uint32_t candidate_stride) { uint32_t t = blockIdx.x; uint32_t tid = threadIdx.x; if (t >= n_tokens) return; __shared__ float vals[SORT_N]; __shared__ uint32_t idxs[SORT_N]; const float *row = scores + (uint64_t)t * n_comp; const uint32_t *cand = candidates + (uint64_t)t * candidate_stride; for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { uint32_t idx = UINT32_MAX; float v = -INFINITY; if (i < candidate_count) { idx = cand[i]; if (idx < n_comp) v = row[idx]; } vals[i] = v; idxs[i] = idx; } __syncthreads(); for (uint32_t k = 2u; k <= SORT_N; k <<= 1u) { for (uint32_t j = k >> 1u; j > 0u; j >>= 1u) { for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { uint32_t other = i ^ j; if (other > i && other < SORT_N) { const float av = vals[i]; const float bv = vals[other]; const uint32_t ai = idxs[i]; const uint32_t bi = idxs[other]; const bool desc_half = (i & k) == 0u; const bool swap = desc_half ? topk_score_better(bv, bi, av, ai) : topk_score_better(av, ai, bv, bi); if (swap) { vals[i] = bv; idxs[i] = bi; vals[other] = av; idxs[other] = ai; } } } __syncthreads(); } } for (uint32_t i = tid; i < top_k; i += blockDim.x) { selected[(uint64_t)t * top_k + i] = idxs[i]; } } template __global__ static void indexer_topk_tree_merge_pow2_kernel( uint32_t *out, const uint32_t *candidates, const float *scores, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k, uint32_t n_sets, uint32_t merge_group, uint32_t candidate_stride, uint32_t out_stride) { uint32_t t = blockIdx.x; uint32_t group = blockIdx.y; uint32_t tid = threadIdx.x; if (t >= n_tokens) return; const uint32_t set0 = group * merge_group; if (set0 >= n_sets) return; uint32_t set_count = n_sets - set0; if (set_count > merge_group) set_count = merge_group; const uint32_t candidate_count = set_count * top_k; __shared__ float vals[SORT_N]; __shared__ uint32_t idxs[SORT_N]; const float *row = scores + (uint64_t)t * n_comp; const uint32_t *cand = candidates + (uint64_t)t * candidate_stride + set0 * top_k; for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { uint32_t idx = UINT32_MAX; float v = -INFINITY; if (i < candidate_count) { idx = cand[i]; if (idx < n_comp) v = row[idx]; } vals[i] = v; idxs[i] = idx; } __syncthreads(); for (uint32_t k = 2u; k <= SORT_N; k <<= 1u) { for (uint32_t j = k >> 1u; j > 0u; j >>= 1u) { for (uint32_t i = tid; i < SORT_N; i += blockDim.x) { uint32_t other = i ^ j; if (other > i && other < SORT_N) { const float av = vals[i]; const float bv = vals[other]; const uint32_t ai = idxs[i]; const uint32_t bi = idxs[other]; const bool desc_half = (i & k) == 0u; const bool swap = desc_half ? topk_score_better(bv, bi, av, ai) : topk_score_better(av, ai, bv, bi); if (swap) { vals[i] = bv; idxs[i] = bi; vals[other] = av; idxs[other] = ai; } } } __syncthreads(); } } uint32_t *dst = out + (uint64_t)t * out_stride + group * top_k; for (uint32_t i = tid; i < top_k; i += blockDim.x) { dst[i] = idxs[i]; } } __global__ static void indexed_topk_sort_512_asc_kernel( int32_t *dst, const int32_t *src, uint32_t n_tokens) { const uint32_t t = blockIdx.x; const uint32_t tid = threadIdx.x; if (t >= n_tokens || tid >= 512u) return; __shared__ int32_t rows[512]; const int32_t *src_row = src + (uint64_t)t * 512u; int32_t *dst_row = dst + (uint64_t)t * 512u; rows[tid] = src_row[tid]; __syncthreads(); for (uint32_t k = 2u; k <= 512u; k <<= 1u) { for (uint32_t j = k >> 1u; j > 0u; j >>= 1u) { const uint32_t other = tid ^ j; if (other > tid && other < 512u) { const int32_t a = rows[tid]; const int32_t b = rows[other]; const bool up = (tid & k) == 0u; if ((up && a > b) || (!up && a < b)) { rows[tid] = b; rows[other] = a; } } __syncthreads(); } } dst_row[tid] = rows[tid]; } __global__ static void topk_mask_kernel(float *mask, const uint32_t *topk, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_tokens * n_comp; if (gid >= n) return; uint32_t t = gid / n_comp; uint32_t c = gid - (uint64_t)t * n_comp; float v = -INFINITY; for (uint32_t k = 0; k < top_k; k++) { if (topk[(uint64_t)t * top_k + k] == c) { v = 0.0f; break; } } mask[gid] = v; } extern "C" int ds4_gpu_embed_token_hc_tensor(ds4_gpu_tensor *out_hc, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint32_t n_vocab, uint32_t token, uint32_t n_embd, uint32_t n_hc) { (void)n_vocab; if (!out_hc || !model_map || weight_offset >= model_size) return 0; uint64_t weight_bytes = (uint64_t)n_vocab * n_embd * sizeof(uint16_t); if (weight_offset > model_size || weight_bytes > model_size - weight_offset) return 0; const char *wptr = cuda_model_range_ptr(model_map, weight_offset, weight_bytes, "token_embd"); if (!wptr) return 0; uint32_t n = n_embd * n_hc; embed_token_hc_kernel<<<(n + 255) / 256, 256>>>((float *)out_hc->ptr, (const unsigned short *)wptr, token, n_embd, n_hc); return cuda_ok(cudaGetLastError(), "embed token launch"); } extern "C" int ds4_gpu_embed_tokens_hc_tensor( ds4_gpu_tensor *out_hc, const ds4_gpu_tensor *tokens_t, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint32_t n_vocab, uint32_t n_tokens, uint32_t n_embd, uint32_t n_hc) { if (!out_hc || !tokens_t || !model_map || weight_offset > model_size || (uint64_t)n_vocab * n_embd * sizeof(uint16_t) > model_size - weight_offset || tokens_t->bytes < (uint64_t)n_tokens * sizeof(int32_t) || out_hc->bytes < (uint64_t)n_tokens * n_hc * n_embd * sizeof(float)) { return 0; } const char *wptr = cuda_model_range_ptr(model_map, weight_offset, (uint64_t)n_vocab * n_embd * sizeof(uint16_t), "token_embd"); if (!wptr) return 0; uint64_t n = (uint64_t)n_tokens * n_hc * n_embd; embed_tokens_hc_kernel<<<(n + 255) / 256, 256>>>( (float *)out_hc->ptr, (const int32_t *)tokens_t->ptr, (const __half *)wptr, n_vocab, n_tokens, n_embd, n_hc); return cuda_ok(cudaGetLastError(), "embed tokens launch"); } static int indexer_scores_launch( ds4_gpu_tensor *scores, const ds4_gpu_tensor *q, const ds4_gpu_tensor *weights, const ds4_gpu_tensor *index_comp, uint32_t n_comp, uint32_t n_tokens, uint32_t pos0, uint32_t n_head, uint32_t head_dim, uint32_t ratio, float scale, uint32_t causal) { if (!scores || !q || !weights || !index_comp || n_comp == 0 || n_tokens == 0 || n_head == 0 || head_dim == 0 || q->bytes < (uint64_t)n_tokens * n_head * head_dim * sizeof(float) || weights->bytes < (uint64_t)n_tokens * n_head * sizeof(float) || index_comp->bytes < (uint64_t)n_comp * head_dim * sizeof(float) || scores->bytes < (uint64_t)n_tokens * n_comp * sizeof(float)) { return 0; } if (causal && ratio == 0) return 0; if (n_tokens == 1u && head_dim == 128u && n_head == 64u && getenv("DS4_CUDA_NO_INDEXER_DIRECT_ONE") == NULL) { indexer_score_one_direct_kernel<<>>((float *)scores->ptr, (const float *)q->ptr, (const float *)weights->ptr, (const float *)index_comp->ptr, n_comp, pos0, ratio, scale, causal ? 1 : 0); return cuda_ok(cudaGetLastError(), "indexer score one direct launch"); } if (!g_quality_mode && head_dim == 128u && n_head == 64u && getenv("DS4_CUDA_NO_INDEXER_WMMA") == NULL) { if (getenv("DS4_CUDA_NO_INDEXER_WMMA128") == NULL) { dim3 grid((n_comp + 127u) / 128u, (n_tokens + 15u) / 16u, 1); indexer_scores_wmma128_kernel<<>>((float *)scores->ptr, (const float *)q->ptr, (const float *)weights->ptr, (const float *)index_comp->ptr, n_comp, n_tokens, pos0, n_head, head_dim, ratio, scale, causal ? 1 : 0); return cuda_ok(cudaGetLastError(), "indexer scores wmma128 launch"); } else if (getenv("DS4_CUDA_NO_INDEXER_WMMA64") == NULL) { dim3 grid((n_comp + 63u) / 64u, (n_tokens + 15u) / 16u, 1); indexer_scores_wmma64_kernel<<>>((float *)scores->ptr, (const float *)q->ptr, (const float *)weights->ptr, (const float *)index_comp->ptr, n_comp, n_tokens, pos0, n_head, head_dim, ratio, scale, causal ? 1 : 0); return cuda_ok(cudaGetLastError(), "indexer scores wmma64 launch"); } else if (getenv("DS4_CUDA_NO_INDEXER_WMMA32") == NULL) { dim3 grid((n_comp + 31u) / 32u, (n_tokens + 15u) / 16u, 1); indexer_scores_wmma32_kernel<<>>((float *)scores->ptr, (const float *)q->ptr, (const float *)weights->ptr, (const float *)index_comp->ptr, n_comp, n_tokens, pos0, n_head, head_dim, ratio, scale, causal ? 1 : 0); return cuda_ok(cudaGetLastError(), "indexer scores wmma32 launch"); } else { dim3 grid((n_comp + 15u) / 16u, (n_tokens + 15u) / 16u, 1); indexer_scores_wmma_kernel<<>>((float *)scores->ptr, (const float *)q->ptr, (const float *)weights->ptr, (const float *)index_comp->ptr, n_comp, n_tokens, pos0, n_head, head_dim, ratio, scale, causal ? 1 : 0); return cuda_ok(cudaGetLastError(), "indexer scores wmma launch"); } } dim3 grid(n_comp, n_tokens, 1); indexer_scores_kernel<<>>((float *)scores->ptr, (const float *)q->ptr, (const float *)weights->ptr, (const float *)index_comp->ptr, n_comp, n_tokens, pos0, n_head, head_dim, ratio, scale, causal ? 1 : 0); return cuda_ok(cudaGetLastError(), "indexer scores launch"); } extern "C" int ds4_gpu_indexer_score_one_tensor( ds4_gpu_tensor *scores, const ds4_gpu_tensor *q, const ds4_gpu_tensor *weights, const ds4_gpu_tensor *index_comp, uint32_t n_comp, uint32_t n_head, uint32_t head_dim, float scale) { return indexer_scores_launch(scores, q, weights, index_comp, n_comp, 1, 0, n_head, head_dim, 1, scale, 0); } extern "C" int ds4_gpu_indexer_scores_prefill_tensor( ds4_gpu_tensor *scores, const ds4_gpu_tensor *q, const ds4_gpu_tensor *weights, const ds4_gpu_tensor *index_comp, uint32_t n_comp, uint32_t n_tokens, uint32_t n_head, uint32_t head_dim, uint32_t ratio, float scale) { return indexer_scores_launch(scores, q, weights, index_comp, n_comp, n_tokens, 0, n_head, head_dim, ratio, scale, 1); } extern "C" int ds4_gpu_indexer_scores_decode_batch_tensor( ds4_gpu_tensor *scores, const ds4_gpu_tensor *q, const ds4_gpu_tensor *weights, const ds4_gpu_tensor *index_comp, uint32_t n_comp, uint32_t n_tokens, uint32_t pos0, uint32_t n_head, uint32_t head_dim, uint32_t ratio, float scale) { return indexer_scores_launch(scores, q, weights, index_comp, n_comp, n_tokens, pos0, n_head, head_dim, ratio, scale, 1); } extern "C" int ds4_gpu_indexer_topk_tensor( ds4_gpu_tensor *selected, const ds4_gpu_tensor *scores, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k) { if (!selected || !scores || n_comp == 0 || n_tokens == 0 || top_k == 0 || top_k > n_comp || scores->bytes < (uint64_t)n_tokens * n_comp * sizeof(float) || selected->bytes < (uint64_t)n_tokens * top_k * sizeof(uint32_t)) { return 0; } if (top_k == 512u && n_comp <= 1024u && getenv("DS4_CUDA_NO_TOPK1024") == NULL) { indexer_topk_1024_kernel<<>>((uint32_t *)selected->ptr, (const float *)scores->ptr, n_comp, n_tokens, top_k); return cuda_ok(cudaGetLastError(), "indexer topk 1024 launch"); } if (top_k == 512u && n_comp <= 2048u && getenv("DS4_CUDA_NO_TOPK2048") == NULL) { indexer_topk_pow2_kernel<2048><<>>((uint32_t *)selected->ptr, (const float *)scores->ptr, n_comp, n_tokens, top_k); return cuda_ok(cudaGetLastError(), "indexer topk 2048 launch"); } if (top_k == 512u && n_comp <= 4096u && getenv("DS4_CUDA_NO_TOPK2048") == NULL) { if (n_comp == 4096u) { using TopkCubSort = cub::BlockRadixSort; const int smem = (int)sizeof(typename TopkCubSort::TempStorage); int dev = 0; int max_optin_smem = 0; cudaError_t attr_err = cudaGetDevice(&dev); if (attr_err == cudaSuccess) { attr_err = cudaDeviceGetAttribute(&max_optin_smem, cudaDevAttrMaxSharedMemoryPerBlockOptin, dev); } if (attr_err == cudaSuccess && max_optin_smem >= smem) { attr_err = cudaFuncSetAttribute(indexer_topk_8192_cub_kernel, cudaFuncAttributeMaxDynamicSharedMemorySize, smem); if (attr_err == cudaSuccess) { indexer_topk_8192_cub_kernel<<>>((uint32_t *)selected->ptr, (const float *)scores->ptr, n_comp, n_tokens, top_k); return cuda_ok(cudaGetLastError(), "indexer topk 4096 cub launch"); } } } indexer_topk_pow2_kernel<4096><<>>((uint32_t *)selected->ptr, (const float *)scores->ptr, n_comp, n_tokens, top_k); return cuda_ok(cudaGetLastError(), "indexer topk 4096 launch"); } if (top_k == 512u && n_comp <= 8192u && getenv("DS4_CUDA_NO_TOPK2048") == NULL && getenv("DS4_CUDA_NO_TOPK8192") == NULL) { if (n_comp > 4096u) { using TopkCubSort = cub::BlockRadixSort; const int smem = (int)sizeof(typename TopkCubSort::TempStorage); int dev = 0; int max_optin_smem = 0; cudaError_t attr_err = cudaGetDevice(&dev); if (attr_err == cudaSuccess) { attr_err = cudaDeviceGetAttribute(&max_optin_smem, cudaDevAttrMaxSharedMemoryPerBlockOptin, dev); } if (attr_err == cudaSuccess && max_optin_smem >= smem) { attr_err = cudaFuncSetAttribute(indexer_topk_8192_cub_kernel, cudaFuncAttributeMaxDynamicSharedMemorySize, smem); if (attr_err == cudaSuccess) { indexer_topk_8192_cub_kernel<<>>((uint32_t *)selected->ptr, (const float *)scores->ptr, n_comp, n_tokens, top_k); return cuda_ok(cudaGetLastError(), "indexer topk 8192 cub launch"); } } } indexer_topk_pow2_u16_kernel<8192><<>>((uint32_t *)selected->ptr, (const float *)scores->ptr, n_comp, n_tokens, top_k); return cuda_ok(cudaGetLastError(), "indexer topk 8192 launch"); } if (top_k == 512u && getenv("DS4_CUDA_NO_TOPK2048") == NULL && getenv("DS4_CUDA_NO_TOPK_CHUNKED") == NULL) { const uint32_t chunk_n = 4096u; const uint32_t n_chunks = (n_comp + chunk_n - 1u) / chunk_n; const uint32_t candidate_stride = n_chunks * top_k; uint32_t n_sets = n_chunks; uint64_t scratch_u32_per_token = candidate_stride; while (n_sets > DS4_CUDA_TOPK_MERGE_GROUP) { n_sets = (n_sets + DS4_CUDA_TOPK_MERGE_GROUP - 1u) / DS4_CUDA_TOPK_MERGE_GROUP; scratch_u32_per_token += (uint64_t)n_sets * top_k; } if (scratch_u32_per_token > UINT64_MAX / n_tokens / sizeof(uint32_t)) return 0; const uint64_t tmp_bytes = (uint64_t)n_tokens * scratch_u32_per_token * sizeof(uint32_t); uint32_t *scratch = (uint32_t *)cuda_tmp_alloc(tmp_bytes, "indexer topk tree"); if (!scratch) return 0; uint32_t *cur = scratch; n_sets = n_chunks; uint32_t cur_stride = candidate_stride; dim3 grid_chunks(n_tokens, n_chunks, 1); indexer_topk_chunk_pow2_kernel<4096><<>>(cur, (const float *)scores->ptr, n_comp, n_tokens, top_k, candidate_stride); if (!cuda_ok(cudaGetLastError(), "indexer topk chunk launch")) return 0; while (n_sets > DS4_CUDA_TOPK_MERGE_GROUP) { const uint32_t next_sets = (n_sets + DS4_CUDA_TOPK_MERGE_GROUP - 1u) / DS4_CUDA_TOPK_MERGE_GROUP; const uint32_t next_stride = next_sets * top_k; uint32_t *next = cur + (uint64_t)n_tokens * cur_stride; dim3 grid_merge(n_tokens, next_sets, 1); indexer_topk_tree_merge_pow2_kernel<4096><<>>( next, cur, (const float *)scores->ptr, n_comp, n_tokens, top_k, n_sets, DS4_CUDA_TOPK_MERGE_GROUP, cur_stride, next_stride); if (!cuda_ok(cudaGetLastError(), "indexer topk tree merge launch")) return 0; cur = next; n_sets = next_sets; cur_stride = next_stride; } indexer_topk_merge_pow2_kernel<4096><<>>((uint32_t *)selected->ptr, cur, (const float *)scores->ptr, n_comp, n_tokens, top_k, n_sets * top_k, cur_stride); return cuda_ok(cudaGetLastError(), "indexer topk tree final launch"); } indexer_topk_kernel<<>>((uint32_t *)selected->ptr, (const float *)scores->ptr, n_comp, n_tokens, top_k); return cuda_ok(cudaGetLastError(), "indexer topk launch"); } extern "C" int ds4_gpu_argmax_tensor( ds4_gpu_tensor *out_idx, const ds4_gpu_tensor *logits, uint32_t n_vocab) { if (!out_idx || !logits || n_vocab == 0 || out_idx->bytes < sizeof(int32_t) || logits->bytes < (uint64_t)n_vocab * sizeof(float)) { return 0; } argmax_kernel<<<1, 1024>>>((int32_t *)out_idx->ptr, (const float *)logits->ptr, n_vocab); return cuda_ok(cudaGetLastError(), "argmax launch"); } extern "C" int ds4_gpu_dsv4_topk_mask_tensor( ds4_gpu_tensor *mask, const ds4_gpu_tensor *topk, uint32_t n_comp, uint32_t n_tokens, uint32_t top_k) { if (!mask || !topk || n_comp == 0 || n_tokens == 0 || top_k == 0 || mask->bytes < (uint64_t)n_tokens * n_comp * sizeof(float) || topk->bytes < (uint64_t)n_tokens * top_k * sizeof(uint32_t)) { return 0; } uint64_t n = (uint64_t)n_tokens * n_comp; uint64_t nk = (uint64_t)n_tokens * top_k; uint64_t blocks = ((n > nk ? n : nk) + 255) / 256; topk_mask_kernel<<>>((float *)mask->ptr, (const uint32_t *)topk->ptr, n_comp, n_tokens, top_k); return cuda_ok(cudaGetLastError(), "topk mask launch"); } static int cuda_matmul_q8_0_tensor_labeled(ds4_gpu_tensor *out, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, uint64_t n_tok, const char *label) { if (!out || !x || !model_map) return 0; uint64_t blocks = (in_dim + 31) / 32; if (weight_offset > model_size || out_dim > UINT64_MAX / (blocks * 34)) return 0; uint64_t weight_bytes = out_dim * blocks * 34; if (weight_bytes > model_size - weight_offset) return 0; if (x->bytes < n_tok * in_dim * sizeof(float) || out->bytes < n_tok * out_dim * sizeof(float)) return 0; const char *wptr = cuda_model_range_ptr(model_map, weight_offset, weight_bytes, "q8_0"); if (!wptr) return 0; if (g_cublas_ready && n_tok > 1) { const float *w_f32 = cuda_q8_f32_ptr(model_map, weight_offset, weight_bytes, in_dim, out_dim, label); if (w_f32) { const float alpha = 1.0f; const float beta = 0.0f; cublasStatus_t st = cublasSgemm(g_cublas, CUBLAS_OP_T, CUBLAS_OP_N, (int)out_dim, (int)n_tok, (int)in_dim, &alpha, w_f32, (int)in_dim, (const float *)x->ptr, (int)in_dim, &beta, (float *)out->ptr, (int)out_dim); return cublas_ok(st, "q8 fp32 matmul"); } const __half *w_f16 = cuda_q8_f16_ptr(model_map, weight_offset, weight_bytes, in_dim, out_dim, label); if (w_f16) { const uint64_t xh_count = n_tok * in_dim; __half *xh = (__half *)cuda_tmp_alloc(xh_count * sizeof(__half), "q8 f16 gemm activations"); if (!xh) return 0; f32_to_f16_kernel<<<(xh_count + 255) / 256, 256>>>(xh, (const float *)x->ptr, xh_count); if (!cuda_ok(cudaGetLastError(), "q8 f16 activation convert launch")) return 0; const float alpha = 1.0f; const float beta = 0.0f; cublasStatus_t st = cublasGemmEx(g_cublas, CUBLAS_OP_T, CUBLAS_OP_N, (int)out_dim, (int)n_tok, (int)in_dim, &alpha, w_f16, CUDA_R_16F, (int)in_dim, xh, CUDA_R_16F, (int)in_dim, &beta, out->ptr, CUDA_R_32F, (int)out_dim, CUDA_R_32F, CUBLAS_GEMM_DEFAULT); if (st == CUBLAS_STATUS_SUCCESS) return 1; fprintf(stderr, "ds4: cuBLAS q8 f16 matmul failed: status %d\n", (int)st); cuda_q8_f16_cache_disable_after_failure("cuBLAS f16 matmul failure", in_dim * out_dim * sizeof(__half)); /* The F16 expansion cache is only an optimization. If cuBLAS * rejects the cached path under memory pressure, retry the same * operation through the native Q8 kernels below. */ } } const uint64_t xq_bytes = n_tok * blocks * 32u; const uint64_t scale_offset = (xq_bytes + 15u) & ~15ull; const uint64_t tmp_bytes = scale_offset + n_tok * blocks * sizeof(float); void *tmp = cuda_tmp_alloc(tmp_bytes, "q8_0 prequant"); if (!tmp) return 0; int8_t *xq = (int8_t *)tmp; float *xscale = (float *)((char *)tmp + scale_offset); const int use_dp4a = cuda_q8_use_dp4a(); dim3 qgrid((unsigned)blocks, (unsigned)n_tok, 1); quantize_q8_0_f32_kernel<<>>(xq, xscale, (const float *)x->ptr, in_dim, blocks); if (!cuda_ok(cudaGetLastError(), "matmul_q8_0 quantize launch")) return 0; if (n_tok == 1) { matmul_q8_0_preq_warp8_kernel<<<((unsigned)out_dim + 7u) / 8u, 256>>>( (float *)out->ptr, reinterpret_cast(wptr), xq, xscale, in_dim, out_dim, blocks, use_dp4a); return cuda_ok(cudaGetLastError(), "matmul_q8_0 warp launch"); } if (getenv("DS4_CUDA_NO_Q8_BATCH_WARP") == NULL && blocks <= 32u) { dim3 bgrid(((unsigned)out_dim + 7u) / 8u, (unsigned)n_tok, 1); matmul_q8_0_preq_batch_warp8_kernel<<>>( (float *)out->ptr, reinterpret_cast(wptr), xq, xscale, in_dim, out_dim, n_tok, blocks, use_dp4a); return cuda_ok(cudaGetLastError(), "matmul_q8_0 batch warp launch"); } dim3 grid((unsigned)out_dim, (unsigned)n_tok, 1); matmul_q8_0_preq_kernel<<>>((float *)out->ptr, reinterpret_cast(wptr), xq, xscale, in_dim, out_dim, n_tok, blocks, use_dp4a); return cuda_ok(cudaGetLastError(), "matmul_q8_0 launch"); } extern "C" int ds4_gpu_matmul_q8_0_tensor(ds4_gpu_tensor *out, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, uint64_t n_tok) { return cuda_matmul_q8_0_tensor_labeled(out, model_map, model_size, weight_offset, in_dim, out_dim, x, n_tok, "q8_0"); } extern "C" int ds4_gpu_matmul_q8_0_pair_tensor( ds4_gpu_tensor *out0, ds4_gpu_tensor *out1, const void *model_map, uint64_t model_size, uint64_t weight0_offset, uint64_t weight1_offset, uint64_t in_dim, uint64_t out0_dim, uint64_t out1_dim, const ds4_gpu_tensor *x, uint64_t n_tok) { if (!out0 || !out1 || !x || !model_map || in_dim == 0 || out0_dim == 0 || out1_dim == 0 || n_tok == 0) { return 0; } if (n_tok != 1) { return cuda_matmul_q8_0_tensor_labeled(out0, model_map, model_size, weight0_offset, in_dim, out0_dim, x, n_tok, "q8_0_pair0") && cuda_matmul_q8_0_tensor_labeled(out1, model_map, model_size, weight1_offset, in_dim, out1_dim, x, n_tok, "q8_0_pair1"); } const uint64_t blocks = (in_dim + 31) / 32; if (weight0_offset > model_size || weight1_offset > model_size || out0_dim > UINT64_MAX / (blocks * 34) || out1_dim > UINT64_MAX / (blocks * 34)) { return 0; } const uint64_t weight0_bytes = out0_dim * blocks * 34; const uint64_t weight1_bytes = out1_dim * blocks * 34; if (weight0_bytes > model_size - weight0_offset || weight1_bytes > model_size - weight1_offset || x->bytes < in_dim * sizeof(float) || out0->bytes < out0_dim * sizeof(float) || out1->bytes < out1_dim * sizeof(float)) { return 0; } const char *w0 = cuda_model_range_ptr(model_map, weight0_offset, weight0_bytes, "q8_0_pair0"); const char *w1 = cuda_model_range_ptr(model_map, weight1_offset, weight1_bytes, "q8_0_pair1"); if (!w0 || !w1) return 0; const uint64_t xq_bytes = blocks * 32u; const uint64_t scale_offset = (xq_bytes + 15u) & ~15ull; const uint64_t tmp_bytes = scale_offset + blocks * sizeof(float); void *tmp = cuda_tmp_alloc(tmp_bytes, "q8_0 pair prequant"); if (!tmp) return 0; int8_t *xq = (int8_t *)tmp; float *xscale = (float *)((char *)tmp + scale_offset); const int use_dp4a = cuda_q8_use_dp4a(); dim3 qgrid((unsigned)blocks, 1, 1); quantize_q8_0_f32_kernel<<>>(xq, xscale, (const float *)x->ptr, in_dim, blocks); if (!cuda_ok(cudaGetLastError(), "matmul_q8_0 pair quantize launch")) return 0; const uint64_t max_out = out0_dim > out1_dim ? out0_dim : out1_dim; matmul_q8_0_pair_preq_warp8_kernel<<<((unsigned)max_out + 7u) / 8u, 256>>>( (float *)out0->ptr, (float *)out1->ptr, reinterpret_cast(w0), reinterpret_cast(w1), xq, xscale, in_dim, out0_dim, out1_dim, blocks, use_dp4a); return cuda_ok(cudaGetLastError(), "matmul_q8_0 pair warp launch"); } extern "C" int ds4_gpu_matmul_q8_0_f16_out_tensor( ds4_gpu_tensor *out_h, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, uint64_t n_tok) { (void)out_h; (void)model_map; (void)model_size; (void)weight_offset; (void)in_dim; (void)out_dim; (void)x; (void)n_tok; return 0; } static int cuda_matmul_q8_0_hc_expand_tensor_labeled( ds4_gpu_tensor *out_hc, ds4_gpu_tensor *block_out, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, const ds4_gpu_tensor *block_add, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *split, uint32_t n_embd, uint32_t n_hc, const char *label) { if (!out_hc || !block_out || !x || !residual_hc || !split || !model_map || in_dim == 0 || out_dim == 0 || n_embd == 0 || n_hc == 0 || out_dim != (uint64_t)n_embd) { return 0; } const uint64_t blocks = (in_dim + 31) / 32; if (weight_offset > model_size || out_dim > UINT64_MAX / (blocks * 34)) return 0; const uint64_t weight_bytes = out_dim * blocks * 34; const uint64_t hc_bytes = (uint64_t)n_hc * n_embd * sizeof(float); const uint64_t split_bytes = (uint64_t)(2u * n_hc + n_hc * n_hc) * sizeof(float); if (weight_bytes > model_size - weight_offset || x->bytes < in_dim * sizeof(float) || block_out->bytes < out_dim * sizeof(float) || residual_hc->bytes < hc_bytes || split->bytes < split_bytes || out_hc->bytes < hc_bytes || (block_add && block_add->bytes < out_dim * sizeof(float))) { return 0; } const char *wptr = cuda_model_range_ptr(model_map, weight_offset, weight_bytes, label ? label : "q8_0_hc_expand"); if (!wptr) return 0; const uint64_t xq_bytes = blocks * 32u; const uint64_t scale_offset = (xq_bytes + 15u) & ~15ull; const uint64_t tmp_bytes = scale_offset + blocks * sizeof(float); void *tmp = cuda_tmp_alloc(tmp_bytes, "q8_0 hc expand prequant"); if (!tmp) return 0; int8_t *xq = (int8_t *)tmp; float *xscale = (float *)((char *)tmp + scale_offset); const int use_dp4a = cuda_q8_use_dp4a(); quantize_q8_0_f32_kernel<<<(unsigned)blocks, 32>>>(xq, xscale, (const float *)x->ptr, in_dim, blocks); if (!cuda_ok(cudaGetLastError(), "matmul_q8_0_hc_expand quantize launch")) return 0; matmul_q8_0_hc_expand_preq_warp8_kernel<<<((unsigned)out_dim + 7u) / 8u, 256>>>( (float *)out_hc->ptr, (float *)block_out->ptr, block_add ? (const float *)block_add->ptr : (const float *)block_out->ptr, (const float *)residual_hc->ptr, (const float *)split->ptr, reinterpret_cast(wptr), xq, xscale, in_dim, out_dim, n_embd, n_hc, blocks, block_add ? 1 : 0, use_dp4a); return cuda_ok(cudaGetLastError(), "matmul_q8_0_hc_expand launch"); } extern "C" int ds4_gpu_matmul_f16_tensor(ds4_gpu_tensor *out, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, uint64_t n_tok) { if (!out || !x || !model_map) return 0; if (weight_offset > model_size || out_dim > UINT64_MAX / in_dim) return 0; uint64_t weight_bytes = out_dim * in_dim * sizeof(uint16_t); if (weight_bytes > model_size - weight_offset) return 0; if (x->bytes < n_tok * in_dim * sizeof(float) || out->bytes < n_tok * out_dim * sizeof(float)) return 0; const char *wptr = cuda_model_range_ptr(model_map, weight_offset, weight_bytes, "f16"); if (!wptr) return 0; const __half *w = (const __half *)wptr; const int serial_f16 = getenv("DS4_CUDA_SERIAL_F16_MATMUL") != NULL; const int router_shape = in_dim == 4096u && out_dim == 256u && n_tok == 1u; const int serial_router = !serial_f16 && router_shape && getenv("DS4_CUDA_SERIAL_ROUTER") != NULL; const int ordered_router = !serial_f16 && !serial_router && n_tok == 1u && getenv("DS4_CUDA_NO_ORDERED_F16_MATMUL") == NULL; if (!serial_f16 && g_cublas_ready && n_tok > 1) { const uint64_t xh_count = n_tok * in_dim; __half *xh = (__half *)cuda_tmp_alloc(xh_count * sizeof(__half), "f16 gemm activations"); if (!xh) return 0; f32_to_f16_kernel<<<(xh_count + 255) / 256, 256>>>(xh, (const float *)x->ptr, xh_count); if (!cuda_ok(cudaGetLastError(), "f16 activation convert launch")) return 0; const float alpha = 1.0f; const float beta = 0.0f; cublasStatus_t st = cublasGemmEx(g_cublas, CUBLAS_OP_T, CUBLAS_OP_N, (int)out_dim, (int)n_tok, (int)in_dim, &alpha, w, CUDA_R_16F, (int)in_dim, xh, CUDA_R_16F, (int)in_dim, &beta, out->ptr, CUDA_R_32F, (int)out_dim, CUDA_R_32F, CUBLAS_GEMM_DEFAULT); return cublas_ok(st, "f16 matmul"); } dim3 grid((unsigned)out_dim, (unsigned)n_tok, 1); if (serial_f16 || serial_router) { matmul_f16_serial_kernel<<>>((float *)out->ptr, w, (const float *)x->ptr, in_dim, out_dim, n_tok); return cuda_ok(cudaGetLastError(), serial_router ? "matmul_f16_router_serial launch" : "matmul_f16_serial launch"); } if (ordered_router) { matmul_f16_ordered_chunks_kernel<<>>((float *)out->ptr, w, (const float *)x->ptr, in_dim, out_dim, n_tok); return cuda_ok(cudaGetLastError(), "matmul_f16_ordered_chunks launch"); } matmul_f16_kernel<<>>((float *)out->ptr, w, (const float *)x->ptr, in_dim, out_dim, n_tok); return cuda_ok(cudaGetLastError(), "matmul_f16 launch"); } extern "C" int ds4_gpu_matmul_f16_pair_tensor( ds4_gpu_tensor *out0, ds4_gpu_tensor *out1, const void *model_map, uint64_t model_size, uint64_t weight0_offset, uint64_t weight1_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, uint64_t n_tok) { if (!out0 || !out1 || !x || !model_map || in_dim == 0 || out_dim == 0 || n_tok == 0) { return 0; } if (n_tok != 1 || getenv("DS4_CUDA_NO_F16_PAIR_MATMUL") != NULL || getenv("DS4_CUDA_SERIAL_F16_MATMUL") != NULL || getenv("DS4_CUDA_SERIAL_ROUTER") != NULL || getenv("DS4_CUDA_NO_ORDERED_F16_MATMUL") != NULL) { return ds4_gpu_matmul_f16_tensor(out0, model_map, model_size, weight0_offset, in_dim, out_dim, x, n_tok) && ds4_gpu_matmul_f16_tensor(out1, model_map, model_size, weight1_offset, in_dim, out_dim, x, n_tok); } if (weight0_offset > model_size || weight1_offset > model_size || out_dim > UINT64_MAX / in_dim) { return 0; } const uint64_t weight_bytes = out_dim * in_dim * sizeof(uint16_t); if (weight_bytes > model_size - weight0_offset || weight_bytes > model_size - weight1_offset || x->bytes < in_dim * sizeof(float) || out0->bytes < out_dim * sizeof(float) || out1->bytes < out_dim * sizeof(float)) { return 0; } const __half *w0 = (const __half *)cuda_model_range_ptr(model_map, weight0_offset, weight_bytes, "f16_pair0"); const __half *w1 = (const __half *)cuda_model_range_ptr(model_map, weight1_offset, weight_bytes, "f16_pair1"); if (!w0 || !w1) return 0; matmul_f16_pair_ordered_chunks_kernel<<<(unsigned)out_dim, 32>>>( (float *)out0->ptr, (float *)out1->ptr, w0, w1, (const float *)x->ptr, in_dim, out_dim, out_dim); return cuda_ok(cudaGetLastError(), "matmul_f16_pair_ordered_chunks launch"); } extern "C" int ds4_gpu_matmul_f32_tensor(ds4_gpu_tensor *out, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, uint64_t n_tok) { if (!out || !x || !model_map || in_dim == 0 || out_dim == 0 || n_tok == 0) return 0; if (weight_offset > model_size || out_dim > UINT64_MAX / in_dim) return 0; uint64_t weight_elems = out_dim * in_dim; if (weight_elems > UINT64_MAX / sizeof(float)) return 0; uint64_t weight_bytes = weight_elems * sizeof(float); if (weight_bytes > model_size - weight_offset) return 0; if (x->bytes < n_tok * in_dim * sizeof(float) || out->bytes < n_tok * out_dim * sizeof(float)) return 0; const char *wptr = cuda_model_range_ptr(model_map, weight_offset, weight_bytes, "f32"); if (!wptr) return 0; const float *w = (const float *)wptr; if (g_cublas_ready && n_tok > 1) { const float alpha = 1.0f; const float beta = 0.0f; cublasStatus_t st = cublasSgemm(g_cublas, CUBLAS_OP_T, CUBLAS_OP_N, (int)out_dim, (int)n_tok, (int)in_dim, &alpha, w, (int)in_dim, (const float *)x->ptr, (int)in_dim, &beta, (float *)out->ptr, (int)out_dim); return cublas_ok(st, "f32 matmul"); } dim3 grid((unsigned)out_dim, (unsigned)n_tok, 1); matmul_f32_kernel<<>>((float *)out->ptr, w, (const float *)x->ptr, in_dim, out_dim, n_tok); return cuda_ok(cudaGetLastError(), "matmul_f32 launch"); } extern "C" int ds4_gpu_repeat_hc_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *row, uint32_t n_embd, uint32_t n_hc) { if (!out || !row || n_embd == 0 || n_hc == 0 || row->bytes < (uint64_t)n_embd * sizeof(float) || out->bytes < (uint64_t)n_embd * n_hc * sizeof(float)) { return 0; } uint64_t n = (uint64_t)n_embd * n_hc; repeat_hc_kernel<<<(n + 255) / 256, 256>>>((float *)out->ptr, (const float *)row->ptr, n_embd, n_hc); return cuda_ok(cudaGetLastError(), "repeat_hc launch"); } extern "C" int ds4_gpu_rms_norm_plain_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *x, uint32_t n, float eps) { if (!out || !x || out->bytes < (uint64_t)n * sizeof(float) || x->bytes < (uint64_t)n * sizeof(float)) return 0; rms_norm_plain_kernel<<<1, 256>>>((float *)out->ptr, (const float *)x->ptr, n, 1, eps); return cuda_ok(cudaGetLastError(), "rms_norm_plain launch"); } extern "C" int ds4_gpu_rms_norm_plain_rows_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *x, uint32_t n, uint32_t rows, float eps) { if (!out || !x || out->bytes < (uint64_t)n * rows * sizeof(float) || x->bytes < (uint64_t)n * rows * sizeof(float)) return 0; rms_norm_plain_kernel<<>>((float *)out->ptr, (const float *)x->ptr, n, rows, eps); return cuda_ok(cudaGetLastError(), "rms_norm_plain launch"); } extern "C" int ds4_gpu_rms_norm_weight_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *x, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint32_t n, float eps) { if (!out || !x || !model_map || weight_offset > model_size || model_size - weight_offset < (uint64_t)n * sizeof(float) || out->bytes < (uint64_t)n * sizeof(float) || x->bytes < (uint64_t)n * sizeof(float)) return 0; const char *wptr = cuda_model_range_ptr(model_map, weight_offset, (uint64_t)n * sizeof(float), "rms_weight"); if (!wptr) return 0; const float *w = (const float *)wptr; rms_norm_weight_kernel<<<1, 256>>>((float *)out->ptr, (const float *)x->ptr, w, n, 1, eps); return cuda_ok(cudaGetLastError(), "rms_norm_weight launch"); } extern "C" int ds4_gpu_rms_norm_weight_rows_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *x, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint32_t n, uint32_t rows, float eps) { if (!out || !x || !model_map || weight_offset > model_size || model_size - weight_offset < (uint64_t)n * sizeof(float) || out->bytes < (uint64_t)n * rows * sizeof(float) || x->bytes < (uint64_t)n * rows * sizeof(float)) return 0; const char *wptr = cuda_model_range_ptr(model_map, weight_offset, (uint64_t)n * sizeof(float), "rms_weight"); if (!wptr) return 0; const float *w = (const float *)wptr; rms_norm_weight_kernel<<>>((float *)out->ptr, (const float *)x->ptr, w, n, rows, eps); return cuda_ok(cudaGetLastError(), "rms_norm_weight launch"); } extern "C" int ds4_gpu_dsv4_qkv_rms_norm_rows_tensor( ds4_gpu_tensor *q_out, const ds4_gpu_tensor *q, const void *model_map, uint64_t model_size, uint64_t q_weight_offset, uint32_t q_n, ds4_gpu_tensor *kv_out, const ds4_gpu_tensor *kv, uint64_t kv_weight_offset, uint32_t kv_n, uint32_t rows, float eps) { if (getenv("DS4_CUDA_DISABLE_QKV_RMS_FUSED") == NULL) { if (!q_out || !q || !kv_out || !kv || !model_map || q_weight_offset > model_size || kv_weight_offset > model_size || model_size - q_weight_offset < (uint64_t)q_n * sizeof(float) || model_size - kv_weight_offset < (uint64_t)kv_n * sizeof(float) || q_out->bytes < (uint64_t)q_n * rows * sizeof(float) || q->bytes < (uint64_t)q_n * rows * sizeof(float) || kv_out->bytes < (uint64_t)kv_n * rows * sizeof(float) || kv->bytes < (uint64_t)kv_n * rows * sizeof(float)) { return 0; } const float *q_w = (const float *)cuda_model_range_ptr(model_map, q_weight_offset, (uint64_t)q_n * sizeof(float), "q_rms_weight"); const float *kv_w = (const float *)cuda_model_range_ptr(model_map, kv_weight_offset, (uint64_t)kv_n * sizeof(float), "kv_rms_weight"); if (!q_w || !kv_w) return 0; dim3 grid(rows, 2u, 1u); dsv4_qkv_rms_norm_rows_kernel<<>>( (float *)q_out->ptr, (const float *)q->ptr, q_w, q_n, (float *)kv_out->ptr, (const float *)kv->ptr, kv_w, kv_n, rows, eps); return cuda_ok(cudaGetLastError(), "dsv4 qkv rms norm rows launch"); } return ds4_gpu_rms_norm_weight_rows_tensor(q_out, q, model_map, model_size, q_weight_offset, q_n, rows, eps) && ds4_gpu_rms_norm_weight_rows_tensor(kv_out, kv, model_map, model_size, kv_weight_offset, kv_n, rows, eps); } extern "C" int ds4_gpu_head_rms_norm_tensor(ds4_gpu_tensor *x, uint32_t n_tok, uint32_t n_head, uint32_t head_dim, float eps) { if (!x || x->bytes < (uint64_t)n_tok * n_head * head_dim * sizeof(float)) return 0; head_rms_norm_kernel<<>>((float *)x->ptr, n_tok, n_head, head_dim, eps); return cuda_ok(cudaGetLastError(), "head_rms_norm launch"); } extern "C" int ds4_gpu_head_rms_norm_rope_tail_tensor(ds4_gpu_tensor *x, uint32_t n_tok, uint32_t n_head, uint32_t head_dim, uint32_t n_rot, uint32_t pos0, uint32_t n_ctx_orig, bool inverse, float freq_base, float freq_scale, float ext_factor, float attn_factor, float beta_fast, float beta_slow, float eps) { if (!x || n_rot > head_dim || (n_rot & 1u) || x->bytes < (uint64_t)n_tok * n_head * head_dim * sizeof(float)) return 0; head_rms_norm_rope_tail_kernel<<>>((float *)x->ptr, n_tok, n_head, head_dim, n_rot, pos0, n_ctx_orig, inverse ? 1 : 0, freq_base, freq_scale, ext_factor, attn_factor, beta_fast, beta_slow, eps); return cuda_ok(cudaGetLastError(), "head_rms_norm_rope_tail launch"); } extern "C" int ds4_gpu_attn_q_b_f16_head_rms_rope_tail_tensor( ds4_gpu_tensor *out, ds4_gpu_tensor *q_half, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, uint32_t n_tok, uint32_t n_head, uint32_t head_dim, uint32_t n_rot, uint32_t pos0, uint32_t n_ctx_orig, bool inverse, float freq_base, float freq_scale, float ext_factor, float attn_factor, float beta_fast, float beta_slow, float eps) { (void)out; (void)q_half; (void)model_map; (void)model_size; (void)weight_offset; (void)in_dim; (void)out_dim; (void)x; (void)n_tok; (void)n_head; (void)head_dim; (void)n_rot; (void)pos0; (void)n_ctx_orig; (void)inverse; (void)freq_base; (void)freq_scale; (void)ext_factor; (void)attn_factor; (void)beta_fast; (void)beta_slow; (void)eps; return 0; } extern "C" int ds4_gpu_dsv4_fp8_kv_quantize_tensor(ds4_gpu_tensor *x, uint32_t n_tok, uint32_t head_dim, uint32_t n_rot) { if (!x || n_rot > head_dim || x->bytes < (uint64_t)n_tok * head_dim * sizeof(float)) return 0; fp8_kv_quantize_kernel<<>>((float *)x->ptr, n_tok, head_dim, n_rot); return cuda_ok(cudaGetLastError(), "fp8_kv_quantize launch"); } extern "C" int ds4_gpu_dsv4_indexer_qat_tensor(ds4_gpu_tensor *x, uint32_t n_rows, uint32_t head_dim) { if (!x || n_rows == 0 || head_dim != 128u || x->bytes < (uint64_t)n_rows * head_dim * sizeof(float)) { return 0; } indexer_hadamard_fp4_kernel<<>>((float *)x->ptr, n_rows, head_dim); return cuda_ok(cudaGetLastError(), "indexer_hadamard_fp4 launch"); } extern "C" int ds4_gpu_rope_tail_tensor(ds4_gpu_tensor *x, uint32_t n_tok, uint32_t n_head, uint32_t head_dim, uint32_t n_rot, uint32_t pos0, uint32_t n_ctx_orig, bool inverse, float freq_base, float freq_scale, float ext_factor, float attn_factor, float beta_fast, float beta_slow) { if (!x || n_rot > head_dim || (n_rot & 1) || x->bytes < (uint64_t)n_tok * n_head * head_dim * sizeof(float)) return 0; uint32_t pairs = n_tok * n_head * (n_rot / 2); rope_tail_kernel<<<(pairs + 255) / 256, 256>>>((float *)x->ptr, n_tok, n_head, head_dim, n_rot, pos0, 1, n_ctx_orig, inverse ? 1 : 0, freq_base, freq_scale, ext_factor, attn_factor, beta_fast, beta_slow); return cuda_ok(cudaGetLastError(), "rope_tail launch"); } extern "C" int ds4_gpu_store_raw_kv_tensor(ds4_gpu_tensor *raw_cache, const ds4_gpu_tensor *kv, uint32_t raw_cap, uint32_t row, uint32_t head_dim); extern "C" int ds4_gpu_kv_fp8_store_raw_tensor( ds4_gpu_tensor *kv, ds4_gpu_tensor *raw_cache, uint32_t raw_cap, uint32_t raw_row, uint32_t head_dim, uint32_t n_rot) { return ds4_gpu_dsv4_fp8_kv_quantize_tensor(kv, 1, head_dim, n_rot) && ds4_gpu_store_raw_kv_tensor(raw_cache, kv, raw_cap, raw_row, head_dim); } extern "C" int ds4_gpu_store_raw_kv_tensor(ds4_gpu_tensor *raw_cache, const ds4_gpu_tensor *kv, uint32_t raw_cap, uint32_t row, uint32_t head_dim) { if (!raw_cache || !kv || raw_cap == 0 || raw_cache->bytes < (uint64_t)raw_cap * head_dim * sizeof(float) || kv->bytes < (uint64_t)head_dim * sizeof(float)) return 0; store_raw_kv_batch_kernel<<<(head_dim + 255) / 256, 256>>>((float *)raw_cache->ptr, (const float *)kv->ptr, raw_cap, row, 1, head_dim); return cuda_ok(cudaGetLastError(), "store_raw_kv launch"); } extern "C" int ds4_gpu_store_raw_kv_batch_tensor(ds4_gpu_tensor *raw_cache, const ds4_gpu_tensor *kv, uint32_t raw_cap, uint32_t pos0, uint32_t n_tokens, uint32_t head_dim) { if (!raw_cache || !kv || raw_cap == 0 || raw_cache->bytes < (uint64_t)raw_cap * head_dim * sizeof(float) || kv->bytes < (uint64_t)n_tokens * head_dim * sizeof(float)) return 0; uint64_t n = (uint64_t)n_tokens * head_dim; store_raw_kv_batch_kernel<<<(n + 255) / 256, 256>>>((float *)raw_cache->ptr, (const float *)kv->ptr, raw_cap, pos0, n_tokens, head_dim); return cuda_ok(cudaGetLastError(), "store_raw_kv_batch launch"); } extern "C" int ds4_gpu_compressor_store_batch_tensor( const ds4_gpu_tensor *kv, const ds4_gpu_tensor *sc, ds4_gpu_tensor *state_kv, ds4_gpu_tensor *state_score, const void *model_map, uint64_t model_size, uint64_t ape_offset, uint32_t ape_type, uint32_t head_dim, uint32_t ratio, uint32_t pos0, uint32_t n_tokens) { if (!kv || !sc || !state_kv || !state_score || !model_map || head_dim == 0 || ratio == 0 || n_tokens == 0 || (ape_type != 0u && ape_type != 1u)) { return 0; } const uint32_t coff = ratio == 4u ? 2u : 1u; const uint32_t width = coff * head_dim; const uint32_t state_rows = coff * ratio; const uint64_t elem_ape = ape_type == 1u ? 2u : 4u; const uint64_t kv_bytes = (uint64_t)n_tokens * width * sizeof(float); const uint64_t state_bytes = (uint64_t)state_rows * width * sizeof(float); const uint64_t ape_bytes = (uint64_t)width * ratio * elem_ape; if (ape_offset > model_size || ape_bytes > model_size - ape_offset || kv->bytes < kv_bytes || sc->bytes < kv_bytes || state_kv->bytes < state_bytes || state_score->bytes < state_bytes) { return 0; } const char *ape = cuda_model_range_ptr(model_map, ape_offset, ape_bytes, "compressor_ape"); if (!ape) return 0; uint64_t n = (uint64_t)n_tokens * width; compressor_store_kernel<<<(n + 255) / 256, 256>>>( (const float *)kv->ptr, (const float *)sc->ptr, (float *)state_kv->ptr, (float *)state_score->ptr, ape, 0, ape_type, head_dim, ratio, pos0, n_tokens); return cuda_ok(cudaGetLastError(), "compressor store launch"); } extern "C" int ds4_gpu_compressor_update_tensor( const ds4_gpu_tensor *kv_cur, const ds4_gpu_tensor *sc_cur, ds4_gpu_tensor *state_kv, ds4_gpu_tensor *state_score, ds4_gpu_tensor *comp_cache, const void *model_map, uint64_t model_size, uint64_t ape_offset, uint32_t ape_type, uint64_t norm_offset, uint32_t norm_type, uint32_t head_dim, uint32_t ratio, uint32_t pos, uint32_t comp_row, uint32_t n_rot, uint32_t n_ctx_orig, float freq_base, float freq_scale, float ext_factor, float attn_factor, float beta_fast, float beta_slow, float rms_eps) { if (!kv_cur || !sc_cur || !state_kv || !state_score || !comp_cache || !model_map || head_dim == 0 || ratio == 0 || n_rot > head_dim || (n_rot & 1u) != 0 || (ape_type != 0u && ape_type != 1u) || norm_type != 0u) { return 0; } const uint32_t coff = ratio == 4u ? 2u : 1u; const uint32_t width = coff * head_dim; const uint32_t state_rows = coff * ratio; const uint32_t emit = ((pos + 1u) % ratio) == 0u ? 1u : 0u; const uint64_t elem_ape = ape_type == 1u ? 2u : 4u; const uint64_t kv_bytes = (uint64_t)width * sizeof(float); const uint64_t state_bytes = (uint64_t)state_rows * width * sizeof(float); const uint64_t comp_bytes = (uint64_t)(comp_row + (emit ? 1u : 0u)) * head_dim * sizeof(float); const uint64_t ape_bytes = (uint64_t)width * ratio * elem_ape; const uint64_t norm_bytes = (uint64_t)head_dim * sizeof(float); if (ape_offset > model_size || ape_bytes > model_size - ape_offset || norm_offset > model_size || norm_bytes > model_size - norm_offset || kv_cur->bytes < kv_bytes || sc_cur->bytes < kv_bytes || state_kv->bytes < state_bytes || state_score->bytes < state_bytes || (emit && comp_cache->bytes < comp_bytes)) { return 0; } if (!ds4_gpu_compressor_store_batch_tensor(kv_cur, sc_cur, state_kv, state_score, model_map, model_size, ape_offset, ape_type, head_dim, ratio, pos, 1)) { return 0; } if (!emit) return 1; ds4_gpu_tensor *comp_row_view = ds4_gpu_tensor_view( comp_cache, (uint64_t)comp_row * head_dim * sizeof(float), (uint64_t)head_dim * sizeof(float)); if (!comp_row_view) return 0; compressor_update_pool_kernel<<<(head_dim + 255) / 256, 256>>>( (float *)comp_row_view->ptr, (const float *)state_kv->ptr, (const float *)state_score->ptr, head_dim, ratio); int ok = cuda_ok(cudaGetLastError(), "compressor update pool launch"); if (ok) ok = ds4_gpu_rms_norm_weight_rows_tensor(comp_row_view, comp_row_view, model_map, model_size, norm_offset, head_dim, 1, rms_eps); if (ok) ok = ds4_gpu_rope_tail_tensor(comp_row_view, 1, 1, head_dim, n_rot, pos + 1u - ratio, n_ctx_orig, false, freq_base, freq_scale, ext_factor, attn_factor, beta_fast, beta_slow); ds4_gpu_tensor_free(comp_row_view); if (ok && ratio == 4u) { uint64_t half = 4ull * width; compressor_shift_ratio4_kernel<<<(half + 255) / 256, 256>>>( (float *)state_kv->ptr, (float *)state_score->ptr, width); ok = cuda_ok(cudaGetLastError(), "compressor ratio4 shift launch"); } return ok; } extern "C" int ds4_gpu_compressor_prefill_tensor( ds4_gpu_tensor *comp_cache, ds4_gpu_tensor *state_kv, ds4_gpu_tensor *state_score, const ds4_gpu_tensor *kv, const ds4_gpu_tensor *sc, const void *model_map, uint64_t model_size, uint64_t ape_offset, uint32_t ape_type, uint64_t norm_offset, uint32_t norm_type, uint32_t head_dim, uint32_t ratio, uint32_t pos0, uint32_t n_tokens, uint32_t n_rot, uint32_t n_ctx_orig, bool quantize_fp8, float freq_base, float freq_scale, float ext_factor, float attn_factor, float beta_fast, float beta_slow, float rms_eps) { if (!comp_cache || !state_kv || !state_score || !kv || !sc || !model_map || head_dim == 0 || ratio == 0 || n_tokens == 0 || n_rot > head_dim || (n_rot & 1u) != 0 || (ape_type != 0u && ape_type != 1u) || norm_type != 0u) { return 0; } const uint32_t coff = ratio == 4u ? 2u : 1u; const uint32_t width = coff * head_dim; const uint32_t state_rows = coff * ratio; const uint32_t n_comp = n_tokens / ratio; const uint32_t cutoff = n_comp * ratio; const uint32_t rem = n_tokens - cutoff; const uint64_t elem_ape = ape_type == 1u ? 2u : 4u; const uint64_t kv_bytes = (uint64_t)n_tokens * width * sizeof(float); const uint64_t state_bytes = (uint64_t)state_rows * width * sizeof(float); const uint64_t comp_bytes = (uint64_t)n_comp * head_dim * sizeof(float); const uint64_t ape_bytes = (uint64_t)width * ratio * elem_ape; const uint64_t norm_bytes = (uint64_t)head_dim * sizeof(float); if (ape_offset > model_size || ape_bytes > model_size - ape_offset || norm_offset > model_size || norm_bytes > model_size - norm_offset || kv->bytes < kv_bytes || sc->bytes < kv_bytes || state_kv->bytes < state_bytes || state_score->bytes < state_bytes || (n_comp && comp_cache->bytes < comp_bytes)) { return 0; } const char *ape = cuda_model_range_ptr(model_map, ape_offset, ape_bytes, "compressor_ape"); if (!ape) return 0; uint64_t state_n = (uint64_t)state_rows * width; if (!cuda_ok(cudaMemsetAsync(state_kv->ptr, 0, (size_t)(state_n * sizeof(float))), "compressor state kv zero")) return 0; fill_f32_kernel<<<(state_n + 255) / 256, 256>>>((float *)state_score->ptr, state_n, -INFINITY); if (!cuda_ok(cudaGetLastError(), "compressor state score fill launch")) return 0; if (ratio == 4u) { if (cutoff >= ratio) { uint32_t prev_start = cutoff - ratio; uint64_t n = (uint64_t)ratio * width; compressor_set_rows_kernel<<<(n + 255) / 256, 256>>>( (float *)state_kv->ptr, (float *)state_score->ptr, (const float *)kv->ptr, (const float *)sc->ptr, ape, 0, ape_type, width, ratio, pos0, prev_start, 0, ratio); if (!cuda_ok(cudaGetLastError(), "compressor prefill prev state launch")) return 0; } if (rem != 0) { uint64_t n = (uint64_t)rem * width; compressor_set_rows_kernel<<<(n + 255) / 256, 256>>>( (float *)state_kv->ptr, (float *)state_score->ptr, (const float *)kv->ptr, (const float *)sc->ptr, ape, 0, ape_type, width, ratio, pos0, cutoff, ratio, rem); if (!cuda_ok(cudaGetLastError(), "compressor prefill rem state launch")) return 0; } } else if (rem != 0) { uint64_t n = (uint64_t)rem * width; compressor_set_rows_kernel<<<(n + 255) / 256, 256>>>( (float *)state_kv->ptr, (float *)state_score->ptr, (const float *)kv->ptr, (const float *)sc->ptr, ape, 0, ape_type, width, ratio, pos0, cutoff, 0, rem); if (!cuda_ok(cudaGetLastError(), "compressor prefill rem state launch")) return 0; } if (n_comp != 0) { dim3 grid((head_dim + 255) / 256, n_comp, 1); compressor_prefill_pool_kernel<<>>( (float *)comp_cache->ptr, (const float *)kv->ptr, (const float *)sc->ptr, (const float *)state_kv->ptr, (const float *)state_score->ptr, ape, 0, ape_type, head_dim, ratio, pos0, n_comp, 0); if (!cuda_ok(cudaGetLastError(), "compressor prefill pool launch")) return 0; if (!ds4_gpu_rms_norm_weight_rows_tensor(comp_cache, comp_cache, model_map, model_size, norm_offset, head_dim, n_comp, rms_eps)) return 0; if (n_rot != 0) { const uint32_t pairs = n_comp * (n_rot / 2u); rope_tail_kernel<<<(pairs + 255) / 256, 256>>>( (float *)comp_cache->ptr, n_comp, 1, head_dim, n_rot, pos0, ratio, n_ctx_orig, 0, freq_base, freq_scale, ext_factor, attn_factor, beta_fast, beta_slow); if (!cuda_ok(cudaGetLastError(), "compressor prefill rope launch")) return 0; } if (quantize_fp8 && !ds4_gpu_dsv4_fp8_kv_quantize_tensor(comp_cache, n_comp, head_dim, n_rot)) return 0; } return 1; } extern "C" int ds4_gpu_compressor_prefill_ratio4_replay_tensor( ds4_gpu_tensor *comp_cache, ds4_gpu_tensor *state_kv, ds4_gpu_tensor *state_score, const ds4_gpu_tensor *kv, const ds4_gpu_tensor *sc, const void *model_map, uint64_t model_size, uint64_t ape_offset, uint32_t ape_type, uint64_t norm_offset, uint32_t norm_type, uint32_t head_dim, uint32_t pos0, uint32_t n_tokens, uint32_t n_rot, uint32_t n_ctx_orig, bool quantize_fp8, float freq_base, float freq_scale, float ext_factor, float attn_factor, float beta_fast, float beta_slow, float rms_eps) { if (!comp_cache || !state_kv || !state_score || !kv || !sc || !model_map || head_dim == 0 || n_tokens == 0 || (n_tokens & 3u) != 0 || (pos0 & 3u) != 0 || n_rot > head_dim || (n_rot & 1u) != 0 || (ape_type != 0u && ape_type != 1u) || norm_type != 0u) { return 0; } const uint32_t ratio = 4u; const uint32_t width = 2u * head_dim; const uint32_t state_rows = 8u; const uint32_t n_comp = n_tokens / ratio; const uint64_t elem_ape = ape_type == 1u ? 2u : 4u; const uint64_t kv_bytes = (uint64_t)n_tokens * width * sizeof(float); const uint64_t state_bytes = (uint64_t)state_rows * width * sizeof(float); const uint64_t comp_bytes = (uint64_t)n_comp * head_dim * sizeof(float); const uint64_t ape_bytes = (uint64_t)width * ratio * elem_ape; const uint64_t norm_bytes = (uint64_t)head_dim * sizeof(float); if (ape_offset > model_size || ape_bytes > model_size - ape_offset || norm_offset > model_size || norm_bytes > model_size - norm_offset || kv->bytes < kv_bytes || sc->bytes < kv_bytes || state_kv->bytes < state_bytes || state_score->bytes < state_bytes || comp_cache->bytes < comp_bytes) { return 0; } const char *ape = cuda_model_range_ptr(model_map, ape_offset, ape_bytes, "compressor_ape"); if (!ape) return 0; dim3 grid((head_dim + 255) / 256, n_comp, 1); compressor_prefill_pool_kernel<<>>( (float *)comp_cache->ptr, (const float *)kv->ptr, (const float *)sc->ptr, (const float *)state_kv->ptr, (const float *)state_score->ptr, ape, 0, ape_type, head_dim, ratio, pos0, n_comp, 1); if (!cuda_ok(cudaGetLastError(), "compressor replay pool launch")) return 0; if (!ds4_gpu_rms_norm_weight_rows_tensor(comp_cache, comp_cache, model_map, model_size, norm_offset, head_dim, n_comp, rms_eps)) return 0; if (n_rot != 0) { const uint32_t pairs = n_comp * (n_rot / 2u); rope_tail_kernel<<<(pairs + 255) / 256, 256>>>( (float *)comp_cache->ptr, n_comp, 1, head_dim, n_rot, pos0, ratio, n_ctx_orig, 0, freq_base, freq_scale, ext_factor, attn_factor, beta_fast, beta_slow); if (!cuda_ok(cudaGetLastError(), "compressor replay rope launch")) return 0; } if (quantize_fp8 && !ds4_gpu_dsv4_fp8_kv_quantize_tensor(comp_cache, n_comp, head_dim, n_rot)) return 0; uint64_t state_n = (uint64_t)state_rows * width; if (!cuda_ok(cudaMemsetAsync(state_kv->ptr, 0, (size_t)(state_n * sizeof(float))), "compressor replay state kv zero")) return 0; fill_f32_kernel<<<(state_n + 255) / 256, 256>>>((float *)state_score->ptr, state_n, -INFINITY); if (!cuda_ok(cudaGetLastError(), "compressor replay state score fill launch")) return 0; uint32_t prev_start = n_tokens - ratio; uint64_t n = (uint64_t)ratio * width; compressor_set_rows_kernel<<<(n + 255) / 256, 256>>>( (float *)state_kv->ptr, (float *)state_score->ptr, (const float *)kv->ptr, (const float *)sc->ptr, ape, 0, ape_type, width, ratio, pos0, prev_start, 0, ratio); return cuda_ok(cudaGetLastError(), "compressor replay state launch"); } extern "C" int ds4_gpu_compressor_prefill_state_ratio4_tensor( ds4_gpu_tensor *state_kv, ds4_gpu_tensor *state_score, const ds4_gpu_tensor *kv_tail, const ds4_gpu_tensor *sc_tail, const void *model_map, uint64_t model_size, uint64_t ape_offset, uint32_t ape_type, uint32_t head_dim, uint32_t pos0) { if (!state_kv || !state_score || !kv_tail || !sc_tail || !model_map || head_dim == 0 || (ape_type != 0u && ape_type != 1u)) { return 0; } const uint32_t ratio = 4u; const uint32_t width = 2u * head_dim; const uint32_t state_rows = 8u; const uint64_t elem_ape = ape_type == 1u ? 2u : 4u; const uint64_t tail_bytes = (uint64_t)ratio * width * sizeof(float); const uint64_t state_bytes = (uint64_t)state_rows * width * sizeof(float); const uint64_t ape_bytes = (uint64_t)ratio * width * elem_ape; if (ape_offset > model_size || ape_bytes > model_size - ape_offset || kv_tail->bytes < tail_bytes || sc_tail->bytes < tail_bytes || state_kv->bytes < state_bytes || state_score->bytes < state_bytes) { return 0; } const char *ape = cuda_model_range_ptr(model_map, ape_offset, ape_bytes, "compressor_ape"); if (!ape) return 0; uint64_t state_n = (uint64_t)state_rows * width; if (!cuda_ok(cudaMemsetAsync(state_kv->ptr, 0, (size_t)(state_n * sizeof(float))), "compressor state kv zero")) return 0; fill_f32_kernel<<<(state_n + 255) / 256, 256>>>((float *)state_score->ptr, state_n, -INFINITY); if (!cuda_ok(cudaGetLastError(), "compressor state score fill launch")) return 0; uint64_t n = (uint64_t)ratio * width; compressor_set_rows_kernel<<<(n + 255) / 256, 256>>>( (float *)state_kv->ptr, (float *)state_score->ptr, (const float *)kv_tail->ptr, (const float *)sc_tail->ptr, ape, 0, ape_type, width, ratio, pos0, 0, 0, ratio); return cuda_ok(cudaGetLastError(), "compressor state set launch"); } extern "C" int ds4_gpu_attention_decode_heads_tensor( ds4_gpu_tensor *heads, const void *model_map, uint64_t model_size, uint64_t sinks_offset, const ds4_gpu_tensor *q, const ds4_gpu_tensor *raw_kv, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, const ds4_gpu_tensor *comp_kv, uint32_t comp_kv_f16, uint32_t n_comp, const ds4_gpu_tensor *comp_mask, uint32_t use_mask, uint32_t n_head, uint32_t head_dim) { if (comp_kv_f16 || !heads || !q || !raw_kv || !model_map || n_raw == 0 || raw_cap < n_raw || raw_start >= raw_cap || (n_comp != 0 && !comp_kv) || (use_mask && !comp_mask) || sinks_offset > model_size || (uint64_t)n_head * sizeof(float) > model_size - sinks_offset || heads->bytes < (uint64_t)n_head * head_dim * sizeof(float) || q->bytes < (uint64_t)n_head * head_dim * sizeof(float) || raw_kv->bytes < (uint64_t)raw_cap * head_dim * sizeof(float) || (n_comp && comp_kv->bytes < (uint64_t)n_comp * head_dim * sizeof(float)) || (use_mask && comp_mask->bytes < (uint64_t)n_comp * sizeof(float))) { return 0; } const float *sinks = (const float *)cuda_model_range_ptr( model_map, sinks_offset, (uint64_t)n_head * sizeof(float), "attn_sinks"); if (!sinks) return 0; if (!cuda_attention_score_buffer_fits(n_comp)) { if (!use_mask && head_dim == 512u && getenv("DS4_CUDA_NO_WINDOW_ATTENTION") == NULL) { dim3 online_grid(1, (n_head + 7u) / 8u, 1); attention_decode_mixed_heads8_online_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, n_comp ? (const float *)comp_kv->ptr : (const float *)raw_kv->ptr, 1, 0, n_raw, raw_cap, raw_start, n_comp, 0, 0, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention decode online launch"); } fprintf(stderr, "ds4: CUDA attention score buffer too small for %u compressed rows\n", n_comp); return 0; } dim3 grid(1, n_head, 1); attention_decode_mixed_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, n_comp ? (const float *)comp_kv->ptr : (const float *)raw_kv->ptr, use_mask ? (const float *)comp_mask->ptr : NULL, use_mask, 1, 0, n_raw, raw_cap, raw_start, n_comp, 0, 0, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention decode launch"); } extern "C" int ds4_gpu_attention_prefill_raw_heads_tensor(ds4_gpu_tensor *heads, const void *model_map, uint64_t model_size, uint64_t sinks_offset, const ds4_gpu_tensor *q, const ds4_gpu_tensor *raw_kv, uint32_t n_tokens, uint32_t window, uint32_t n_head, uint32_t head_dim) { if (!heads || !q || !raw_kv || !model_map || sinks_offset > model_size || model_size - sinks_offset < (uint64_t)n_head * sizeof(float) || heads->bytes < (uint64_t)n_tokens * n_head * head_dim * sizeof(float) || q->bytes < (uint64_t)n_tokens * n_head * head_dim * sizeof(float) || raw_kv->bytes < (uint64_t)n_tokens * head_dim * sizeof(float) || window > 256) return 0; const float *sinks = (const float *)cuda_model_range_ptr( model_map, sinks_offset, (uint64_t)n_head * sizeof(float), "attn_sinks"); if (!sinks) return 0; if (n_tokens > 1 && head_dim == 512 && getenv("DS4_CUDA_NO_WINDOW_ATTENTION") == NULL && (getenv("DS4_CUDA_WINDOW_ATTENTION") != NULL || (!g_quality_mode && n_tokens >= 128u))) { dim3 grid(n_tokens, (n_head + 7u) / 8u, 1); attention_static_mixed_heads8_online_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, (const float *)raw_kv->ptr, n_tokens, 0, window, 1, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention raw window launch"); } if (g_cublas_ready && n_tokens > 1 && head_dim == 512 && getenv("DS4_CUDA_NO_CUBLAS_ATTENTION") == NULL) { const uint32_t n_keys = n_tokens; const uint64_t score_count = (uint64_t)n_head * n_tokens * n_keys; const uint64_t out_count = (uint64_t)n_head * n_tokens * head_dim; const uint64_t score_bytes = score_count * sizeof(float); const uint64_t out_offset = (score_bytes + 255u) & ~255ull; const uint64_t tmp_bytes = out_offset + out_count * sizeof(float); float *tmp = (float *)cuda_tmp_alloc(tmp_bytes, "attention raw cublas"); if (!tmp) return 0; float *scores = tmp; float *out_tmp = (float *)((char *)tmp + out_offset); const float alpha = rsqrtf((float)head_dim); const float beta = 0.0f; cublasStatus_t st = cublasSgemmStridedBatched(g_cublas, CUBLAS_OP_T, CUBLAS_OP_N, (int)n_keys, (int)n_tokens, (int)head_dim, &alpha, (const float *)raw_kv->ptr, (int)head_dim, 0, (const float *)q->ptr, (int)(n_head * head_dim), (long long)head_dim, &beta, scores, (int)n_keys, (long long)n_keys * n_tokens, (int)n_head); if (!cublas_ok(st, "attention raw score gemm")) return 0; dim3 sgrid(n_tokens, n_head, 1); attention_prefill_raw_softmax_kernel<<>>(scores, sinks, n_tokens, window, n_keys); if (!cuda_ok(cudaGetLastError(), "attention raw softmax launch")) return 0; const float one = 1.0f; st = cublasSgemmStridedBatched(g_cublas, CUBLAS_OP_N, CUBLAS_OP_N, (int)head_dim, (int)n_tokens, (int)n_keys, &one, (const float *)raw_kv->ptr, (int)head_dim, 0, scores, (int)n_keys, (long long)n_keys * n_tokens, &beta, out_tmp, (int)head_dim, (long long)head_dim * n_tokens, (int)n_head); if (!cublas_ok(st, "attention raw value gemm")) return 0; uint64_t n = (uint64_t)n_tokens * n_head * head_dim; attention_prefill_unpack_heads_kernel<<<(n + 255) / 256, 256>>>((float *)heads->ptr, out_tmp, n_tokens, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention raw unpack launch"); } dim3 grid(n_tokens, n_head, 1); attention_prefill_raw_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, n_tokens, window, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention_prefill_raw launch"); } static int attention_decode_batch_launch( ds4_gpu_tensor *heads, const void *model_map, uint64_t model_size, uint64_t sinks_offset, const ds4_gpu_tensor *q, const ds4_gpu_tensor *raw_kv, const ds4_gpu_tensor *comp_kv, uint32_t comp_kv_f16, const ds4_gpu_tensor *comp_mask, uint32_t use_comp_mask, uint32_t n_tokens, uint32_t pos0, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { if (comp_kv_f16 || !heads || !q || !raw_kv || !model_map || n_tokens == 0 || n_raw == 0 || raw_cap < n_raw || raw_start >= raw_cap || (n_comp != 0 && !comp_kv) || (use_comp_mask && !comp_mask) || sinks_offset > model_size || (uint64_t)n_head * sizeof(float) > model_size - sinks_offset || heads->bytes < (uint64_t)n_tokens * n_head * head_dim * sizeof(float) || q->bytes < (uint64_t)n_tokens * n_head * head_dim * sizeof(float) || raw_kv->bytes < (uint64_t)raw_cap * head_dim * sizeof(float) || (n_comp && comp_kv->bytes < (uint64_t)n_comp * head_dim * sizeof(float)) || (use_comp_mask && comp_mask->bytes < (uint64_t)n_tokens * n_comp * sizeof(float))) { return 0; } if (n_comp != 0 && ratio == 0) return 0; const float *sinks = (const float *)cuda_model_range_ptr( model_map, sinks_offset, (uint64_t)n_head * sizeof(float), "attn_sinks"); if (!sinks) return 0; if (!cuda_attention_score_buffer_fits(n_comp)) { if (!use_comp_mask && head_dim == 512u && getenv("DS4_CUDA_NO_WINDOW_ATTENTION") == NULL) { dim3 online_grid(n_tokens, (n_head + 7u) / 8u, 1); attention_decode_mixed_heads8_online_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, n_comp ? (const float *)comp_kv->ptr : (const float *)raw_kv->ptr, n_tokens, pos0, n_raw, raw_cap, raw_start, n_comp, window, ratio, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention decode online launch"); } fprintf(stderr, "ds4: CUDA attention score buffer too small for %u compressed rows\n", n_comp); return 0; } if (!use_comp_mask && n_tokens > 1 && head_dim == 512 && getenv("DS4_CUDA_NO_WINDOW_ATTENTION") == NULL && (getenv("DS4_CUDA_WINDOW_ATTENTION") != NULL || (!g_quality_mode && n_tokens >= 128u))) { dim3 grid(n_tokens, (n_head + 7u) / 8u, 1); attention_decode_mixed_heads8_online_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, n_comp ? (const float *)comp_kv->ptr : (const float *)raw_kv->ptr, n_tokens, pos0, n_raw, raw_cap, raw_start, n_comp, window, ratio, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention decode window launch"); } dim3 grid(n_tokens, n_head, 1); attention_decode_mixed_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, n_comp ? (const float *)comp_kv->ptr : (const float *)raw_kv->ptr, use_comp_mask ? (const float *)comp_mask->ptr : NULL, use_comp_mask, n_tokens, pos0, n_raw, raw_cap, raw_start, n_comp, window, ratio, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention decode batch launch"); } extern "C" int ds4_gpu_attention_decode_raw_batch_heads_tensor( ds4_gpu_tensor *heads, const void *model_map, uint64_t model_size, uint64_t sinks_offset, const ds4_gpu_tensor *q, const ds4_gpu_tensor *raw_kv, uint32_t n_tokens, uint32_t pos0, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, uint32_t window, uint32_t n_head, uint32_t head_dim) { return attention_decode_batch_launch(heads, model_map, model_size, sinks_offset, q, raw_kv, NULL, 0, NULL, 0, n_tokens, pos0, n_raw, raw_cap, raw_start, 0, window, 1, n_head, head_dim); } extern "C" int ds4_gpu_attention_decode_mixed_batch_heads_tensor( ds4_gpu_tensor *heads, const void *model_map, uint64_t model_size, uint64_t sinks_offset, const ds4_gpu_tensor *q, const ds4_gpu_tensor *raw_kv, const ds4_gpu_tensor *comp_kv, uint32_t comp_kv_f16, const ds4_gpu_tensor *comp_mask, uint32_t use_comp_mask, uint32_t n_tokens, uint32_t pos0, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { if (comp_kv_f16) return 0; return attention_decode_batch_launch(heads, model_map, model_size, sinks_offset, q, raw_kv, comp_kv, comp_kv_f16, comp_mask, use_comp_mask, n_tokens, pos0, n_raw, raw_cap, raw_start, n_comp, window, ratio, n_head, head_dim); } extern "C" int ds4_gpu_attention_indexed_mixed_batch_heads_tensor( ds4_gpu_tensor *heads, const void *model_map, uint64_t model_size, uint64_t sinks_offset, const ds4_gpu_tensor *q, const ds4_gpu_tensor *raw_kv, const ds4_gpu_tensor *comp_kv, uint32_t comp_kv_f16, const ds4_gpu_tensor *topk, uint32_t n_tokens, uint32_t pos0, uint32_t n_raw, uint32_t raw_cap, uint32_t raw_start, uint32_t n_comp, uint32_t top_k, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { if (comp_kv_f16 || !heads || !q || !raw_kv || !comp_kv || !topk || !model_map || n_tokens == 0 || n_raw == 0 || raw_cap < n_raw || raw_start >= raw_cap || n_comp == 0 || top_k == 0 || sinks_offset > model_size || (uint64_t)n_head * sizeof(float) > model_size - sinks_offset || heads->bytes < (uint64_t)n_tokens * n_head * head_dim * sizeof(float) || q->bytes < (uint64_t)n_tokens * n_head * head_dim * sizeof(float) || raw_kv->bytes < (uint64_t)raw_cap * head_dim * sizeof(float) || comp_kv->bytes < (uint64_t)n_comp * head_dim * sizeof(float) || topk->bytes < (uint64_t)n_tokens * top_k * sizeof(int32_t)) { return 0; } if (top_k > 512u) return 0; const float *sinks = (const float *)cuda_model_range_ptr( model_map, sinks_offset, (uint64_t)n_head * sizeof(float), "attn_sinks"); if (!sinks) return 0; const int32_t *topk_ptr = (const int32_t *)topk->ptr; if (n_tokens > 1u && top_k == 512u && getenv("DS4_CUDA_NO_INDEXED_TOPK_SORT") == NULL) { const uint64_t sort_bytes = (uint64_t)n_tokens * top_k * sizeof(int32_t); int32_t *sorted = (int32_t *)cuda_tmp_alloc(sort_bytes, "indexed attention topk sort"); if (!sorted) return 0; indexed_topk_sort_512_asc_kernel<<>>(sorted, topk_ptr, n_tokens); if (!cuda_ok(cudaGetLastError(), "indexed attention topk sort launch")) return 0; topk_ptr = sorted; } if (n_tokens > 1 && head_dim == 512 && top_k <= 512u && getenv("DS4_CUDA_NO_INDEXED_HEADS8") == NULL) { if (getenv("DS4_CUDA_INDEXED_TWOPASS") == NULL) { dim3 grid(n_tokens, (n_head + 15u) / 16u, 1); attention_indexed_mixed_heads8_online_kernel<8, 16><<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, (const float *)comp_kv->ptr, topk_ptr, n_tokens, pos0, n_raw, raw_cap, raw_start, n_comp, top_k, window, ratio, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention indexed online launch"); } dim3 grid(n_tokens, (n_head + 7u) / 8u, 1); attention_indexed_mixed_heads8_rb4_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, (const float *)comp_kv->ptr, topk_ptr, n_tokens, pos0, n_raw, raw_cap, raw_start, n_comp, top_k, window, ratio, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention indexed heads8 launch"); } dim3 grid(n_tokens, n_head, 1); attention_indexed_mixed_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, (const float *)comp_kv->ptr, topk_ptr, n_tokens, pos0, n_raw, raw_cap, raw_start, n_comp, top_k, window, ratio, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention indexed mixed launch"); } static int attention_prefill_mixed_launch( ds4_gpu_tensor *heads, const void *model_map, uint64_t model_size, uint64_t sinks_offset, const ds4_gpu_tensor *q, const ds4_gpu_tensor *raw_kv, const ds4_gpu_tensor *comp_kv, const ds4_gpu_tensor *comp_mask, uint32_t use_comp_mask, uint32_t n_tokens, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { if (!heads || !q || !raw_kv || !model_map || n_tokens == 0 || ratio == 0 || (n_comp != 0 && !comp_kv) || (use_comp_mask && !comp_mask) || sinks_offset > model_size || (uint64_t)n_head * sizeof(float) > model_size - sinks_offset || heads->bytes < (uint64_t)n_tokens * n_head * head_dim * sizeof(float) || q->bytes < (uint64_t)n_tokens * n_head * head_dim * sizeof(float) || raw_kv->bytes < (uint64_t)n_tokens * head_dim * sizeof(float) || (n_comp && comp_kv->bytes < (uint64_t)n_comp * head_dim * sizeof(float)) || (use_comp_mask && comp_mask->bytes < (uint64_t)n_tokens * n_comp * sizeof(float))) { return 0; } const float *sinks = (const float *)cuda_model_range_ptr( model_map, sinks_offset, (uint64_t)n_head * sizeof(float), "attn_sinks"); if (!sinks) return 0; if (!use_comp_mask && n_tokens > 1 && head_dim == 512 && getenv("DS4_CUDA_NO_WINDOW_ATTENTION") == NULL && (getenv("DS4_CUDA_WINDOW_ATTENTION") != NULL || (!g_quality_mode && n_tokens >= 128u))) { dim3 grid(n_tokens, (n_head + 7u) / 8u, 1); attention_static_mixed_heads8_online_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, n_comp ? (const float *)comp_kv->ptr : (const float *)raw_kv->ptr, n_tokens, n_comp, window, ratio, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention mixed window launch"); } if (g_cublas_ready && n_tokens > 1 && head_dim == 512 && getenv("DS4_CUDA_NO_CUBLAS_ATTENTION") == NULL) { const uint32_t n_keys = n_tokens + n_comp; const uint64_t kv_count = (uint64_t)n_keys * head_dim; const uint64_t score_count = (uint64_t)n_head * n_tokens * n_keys; const uint64_t out_count = (uint64_t)n_head * n_tokens * head_dim; const uint64_t kv_bytes = kv_count * sizeof(float); const uint64_t score_offset = (kv_bytes + 255u) & ~255ull; const uint64_t score_bytes = score_count * sizeof(float); const uint64_t out_offset = score_offset + ((score_bytes + 255u) & ~255ull); const uint64_t tmp_bytes = out_offset + out_count * sizeof(float); float *tmp = (float *)cuda_tmp_alloc(tmp_bytes, "attention mixed cublas"); if (!tmp) return 0; float *kv = tmp; float *scores = (float *)((char *)tmp + score_offset); float *out_tmp = (float *)((char *)tmp + out_offset); attention_prefill_pack_mixed_kv_kernel<<<(kv_count + 255) / 256, 256>>>( kv, (const float *)raw_kv->ptr, n_comp ? (const float *)comp_kv->ptr : (const float *)raw_kv->ptr, n_tokens, n_comp, head_dim); if (!cuda_ok(cudaGetLastError(), "attention mixed kv pack launch")) return 0; const float alpha = rsqrtf((float)head_dim); const float beta = 0.0f; cublasStatus_t st = cublasSgemmStridedBatched(g_cublas, CUBLAS_OP_T, CUBLAS_OP_N, (int)n_keys, (int)n_tokens, (int)head_dim, &alpha, kv, (int)head_dim, 0, (const float *)q->ptr, (int)(n_head * head_dim), (long long)head_dim, &beta, scores, (int)n_keys, (long long)n_keys * n_tokens, (int)n_head); if (!cublas_ok(st, "attention mixed score gemm")) return 0; dim3 sgrid(n_tokens, n_head, 1); attention_prefill_mixed_softmax_kernel<<>>( scores, sinks, use_comp_mask ? (const float *)comp_mask->ptr : NULL, use_comp_mask, n_tokens, n_comp, window, ratio, n_keys); if (!cuda_ok(cudaGetLastError(), "attention mixed softmax launch")) return 0; const float one = 1.0f; st = cublasSgemmStridedBatched(g_cublas, CUBLAS_OP_N, CUBLAS_OP_N, (int)head_dim, (int)n_tokens, (int)n_keys, &one, kv, (int)head_dim, 0, scores, (int)n_keys, (long long)n_keys * n_tokens, &beta, out_tmp, (int)head_dim, (long long)head_dim * n_tokens, (int)n_head); if (!cublas_ok(st, "attention mixed value gemm")) return 0; uint64_t n = (uint64_t)n_tokens * n_head * head_dim; attention_prefill_unpack_heads_kernel<<<(n + 255) / 256, 256>>>((float *)heads->ptr, out_tmp, n_tokens, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention mixed unpack launch"); } dim3 grid(n_tokens, n_head, 1); attention_prefill_mixed_kernel<<>>((float *)heads->ptr, sinks, (const float *)q->ptr, (const float *)raw_kv->ptr, n_comp ? (const float *)comp_kv->ptr : (const float *)raw_kv->ptr, use_comp_mask ? (const float *)comp_mask->ptr : NULL, use_comp_mask, n_tokens, n_comp, window, ratio, n_head, head_dim); return cuda_ok(cudaGetLastError(), "attention prefill mixed launch"); } extern "C" int ds4_gpu_attention_prefill_static_mixed_heads_tensor( ds4_gpu_tensor *heads, const void *model_map, uint64_t model_size, uint64_t sinks_offset, const ds4_gpu_tensor *q, const ds4_gpu_tensor *raw_kv, const ds4_gpu_tensor *comp_kv, uint32_t comp_kv_f16, uint32_t n_tokens, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { if (comp_kv_f16) return 0; return attention_prefill_mixed_launch(heads, model_map, model_size, sinks_offset, q, raw_kv, comp_kv, NULL, 0, n_tokens, n_comp, window, ratio, n_head, head_dim); } extern "C" int ds4_gpu_attention_prefill_masked_mixed_heads_tensor( ds4_gpu_tensor *heads, const void *model_map, uint64_t model_size, uint64_t sinks_offset, const ds4_gpu_tensor *q, const ds4_gpu_tensor *raw_kv, const ds4_gpu_tensor *comp_kv, uint32_t comp_kv_f16, const ds4_gpu_tensor *comp_mask, uint32_t n_tokens, uint32_t n_comp, uint32_t window, uint32_t ratio, uint32_t n_head, uint32_t head_dim) { if (comp_kv_f16) return 0; return attention_prefill_mixed_launch(heads, model_map, model_size, sinks_offset, q, raw_kv, comp_kv, comp_mask, 1, n_tokens, n_comp, window, ratio, n_head, head_dim); } extern "C" int ds4_gpu_attention_output_q8_batch_tensor( ds4_gpu_tensor *out, ds4_gpu_tensor *low, ds4_gpu_tensor *group_tmp, ds4_gpu_tensor *low_tmp, const void *model_map, uint64_t model_size, uint64_t out_a_offset, uint64_t out_b_offset, uint64_t group_dim, uint64_t rank, uint32_t n_groups, uint64_t out_dim, const ds4_gpu_tensor *heads, uint32_t n_tokens) { (void)group_tmp; (void)low_tmp; if (!out || !low || !heads || !model_map || group_dim == 0 || rank == 0 || n_groups == 0 || out_dim == 0 || n_tokens == 0) { return 0; } const uint64_t low_dim = (uint64_t)n_groups * rank; const uint64_t blocks_a = (group_dim + 31) / 32; const uint64_t blocks_b = (low_dim + 31) / 32; const uint64_t out_a_bytes = (uint64_t)n_groups * rank * blocks_a * 34; const uint64_t out_b_bytes = out_dim * blocks_b * 34; if (out_a_offset > model_size || out_b_offset > model_size || out_a_bytes > model_size - out_a_offset || out_b_bytes > model_size - out_b_offset || heads->bytes < (uint64_t)n_tokens * n_groups * group_dim * sizeof(float) || low->bytes < (uint64_t)n_tokens * low_dim * sizeof(float) || out->bytes < (uint64_t)n_tokens * out_dim * sizeof(float)) { return 0; } const unsigned char *out_a = reinterpret_cast( cuda_model_range_ptr(model_map, out_a_offset, out_a_bytes, "attn_out_a")); const unsigned char *out_b = reinterpret_cast( cuda_model_range_ptr(model_map, out_b_offset, out_b_bytes, "attn_out_b")); if (!out_a || !out_b) return 0; const __half *out_a_f16 = NULL; uint32_t out_a_cublas_min_tokens = 2u; const char *out_a_min_env = getenv("DS4_CUDA_ATTENTION_OUTPUT_A_CUBLAS_MIN"); if (out_a_min_env && out_a_min_env[0]) { char *endp = NULL; long v = strtol(out_a_min_env, &endp, 10); if (endp != out_a_min_env && v > 1 && v < 4096) out_a_cublas_min_tokens = (uint32_t)v; } if (!g_quality_mode && g_cublas_ready && n_tokens >= out_a_cublas_min_tokens && getenv("DS4_CUDA_NO_CUBLAS_ATTENTION_OUTPUT_A") == NULL) { out_a_f16 = cuda_q8_f16_ptr(model_map, out_a_offset, out_a_bytes, group_dim, low_dim, "attn_output_a"); } if (out_a_f16) { const uint64_t heads_h_count = (uint64_t)n_groups * n_tokens * group_dim; const uint64_t low_tmp_count = (uint64_t)n_groups * n_tokens * rank; const uint64_t heads_h_bytes = heads_h_count * sizeof(__half); const uint64_t low_tmp_offset = (heads_h_bytes + 255u) & ~255ull; const uint64_t tmp_bytes = low_tmp_offset + low_tmp_count * sizeof(float); void *tmp = cuda_tmp_alloc(tmp_bytes, "attention output a cublas"); if (!tmp) return 0; __half *heads_h = (__half *)tmp; float *low_packed = (float *)((char *)tmp + low_tmp_offset); attention_pack_group_heads_f16_kernel<<<(heads_h_count + 255) / 256, 256>>>( heads_h, (const float *)heads->ptr, n_tokens, n_groups, group_dim); if (!cuda_ok(cudaGetLastError(), "attention_output_q8_a pack launch")) return 0; const float alpha = 1.0f; const float beta = 0.0f; cublasStatus_t st = cublasGemmStridedBatchedEx(g_cublas, CUBLAS_OP_T, CUBLAS_OP_N, (int)rank, (int)n_tokens, (int)group_dim, &alpha, out_a_f16, CUDA_R_16F, (int)group_dim, (long long)rank * group_dim, heads_h, CUDA_R_16F, (int)group_dim, (long long)n_tokens * group_dim, &beta, low_packed, CUDA_R_32F, (int)rank, (long long)rank * n_tokens, (int)n_groups, CUDA_R_32F, CUBLAS_GEMM_DEFAULT); if (!cublas_ok(st, "attention output a gemm")) return 0; attention_unpack_group_low_kernel<<<(low_tmp_count + 255) / 256, 256>>>( (float *)low->ptr, low_packed, n_tokens, n_groups, rank); if (!cuda_ok(cudaGetLastError(), "attention_output_q8_a unpack launch")) return 0; } else { const uint64_t x_rows = (uint64_t)n_tokens * n_groups; const uint64_t xq_bytes = x_rows * blocks_a * 32u; const uint64_t scale_offset = (xq_bytes + 15u) & ~15ull; const uint64_t tmp_bytes = scale_offset + x_rows * blocks_a * sizeof(float); void *tmp = cuda_tmp_alloc(tmp_bytes, "attention output a q8 prequant"); if (!tmp) return 0; int8_t *xq = (int8_t *)tmp; float *xscale = (float *)((char *)tmp + scale_offset); const int use_dp4a = cuda_q8_use_dp4a(); dim3 qgrid((unsigned)blocks_a, (unsigned)x_rows, 1); quantize_q8_0_f32_kernel<<>>(xq, xscale, (const float *)heads->ptr, group_dim, blocks_a); if (!cuda_ok(cudaGetLastError(), "attention_output_q8_a prequant launch")) return 0; dim3 grid_a(((unsigned)low_dim + 7u) / 8u, (unsigned)n_tokens, 1); grouped_q8_0_a_preq_warp8_kernel<<>>((float *)low->ptr, out_a, xq, xscale, group_dim, rank, n_groups, n_tokens, blocks_a, use_dp4a); if (!cuda_ok(cudaGetLastError(), "attention_output_q8_a preq launch")) return 0; } (void)out_b; return cuda_matmul_q8_0_tensor_labeled(out, model_map, model_size, out_b_offset, low_dim, out_dim, low, n_tokens, "attn_output_b"); } extern "C" int ds4_gpu_attention_output_q8_batch_f16_tensor( ds4_gpu_tensor *out_h, ds4_gpu_tensor *low, const void *model_map, uint64_t model_size, uint64_t out_a_offset, uint64_t out_b_offset, uint64_t group_dim, uint64_t rank, uint32_t n_groups, uint64_t out_dim, const ds4_gpu_tensor *heads, uint32_t n_tokens) { (void)out_h; (void)low; (void)model_map; (void)model_size; (void)out_a_offset; (void)out_b_offset; (void)group_dim; (void)rank; (void)n_groups; (void)out_dim; (void)heads; (void)n_tokens; return 0; } extern "C" int ds4_gpu_attention_output_low_q8_tensor( ds4_gpu_tensor *low, const void *model_map, uint64_t model_size, uint64_t out_a_offset, uint64_t group_dim, uint64_t rank, uint32_t n_groups, const ds4_gpu_tensor *heads) { if (!low || !heads || !model_map || group_dim == 0 || rank == 0 || n_groups == 0) { return 0; } const uint64_t low_dim = (uint64_t)n_groups * rank; const uint64_t blocks_a = (group_dim + 31) / 32; const uint64_t out_a_bytes = (uint64_t)n_groups * rank * blocks_a * 34; if (out_a_offset > model_size || out_a_bytes > model_size - out_a_offset || heads->bytes < (uint64_t)n_groups * group_dim * sizeof(float) || low->bytes < low_dim * sizeof(float)) { return 0; } const unsigned char *out_a = reinterpret_cast( cuda_model_range_ptr(model_map, out_a_offset, out_a_bytes, "attn_out_a")); if (!out_a) return 0; const uint64_t x_rows = (uint64_t)n_groups; const uint64_t xq_bytes = x_rows * blocks_a * 32u; const uint64_t scale_offset = (xq_bytes + 15u) & ~15ull; const uint64_t tmp_bytes = scale_offset + x_rows * blocks_a * sizeof(float); void *tmp = cuda_tmp_alloc(tmp_bytes, "attention output low q8 prequant"); if (!tmp) return 0; int8_t *xq = (int8_t *)tmp; float *xscale = (float *)((char *)tmp + scale_offset); const int use_dp4a = cuda_q8_use_dp4a(); dim3 qgrid((unsigned)blocks_a, (unsigned)x_rows, 1); quantize_q8_0_f32_kernel<<>>(xq, xscale, (const float *)heads->ptr, group_dim, blocks_a); if (!cuda_ok(cudaGetLastError(), "attention_output_low_q8 prequant launch")) return 0; dim3 grid_a(((unsigned)low_dim + 7u) / 8u, 1, 1); grouped_q8_0_a_preq_warp8_kernel<<>>((float *)low->ptr, out_a, xq, xscale, group_dim, rank, n_groups, 1, blocks_a, use_dp4a); return cuda_ok(cudaGetLastError(), "attention_output_low_q8 launch"); } extern "C" int ds4_gpu_swiglu_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *gate, const ds4_gpu_tensor *up, uint32_t n, float clamp, float weight) { if (!out || !gate || !up || out->bytes < (uint64_t)n * sizeof(float) || gate->bytes < (uint64_t)n * sizeof(float) || up->bytes < (uint64_t)n * sizeof(float)) return 0; swiglu_kernel<<<(n + 255) / 256, 256>>>((float *)out->ptr, (const float *)gate->ptr, (const float *)up->ptr, n, clamp, weight); return cuda_ok(cudaGetLastError(), "swiglu launch"); } extern "C" int ds4_gpu_shared_gate_up_swiglu_q8_0_tensor( ds4_gpu_tensor *gate, ds4_gpu_tensor *up, ds4_gpu_tensor *mid, const void *model_map, uint64_t model_size, uint64_t gate_offset, uint64_t up_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, float clamp) { if (getenv("DS4_CUDA_DISABLE_SHARED_GATE_UP_PAIR") == NULL) { return ds4_gpu_matmul_q8_0_pair_tensor(gate, up, model_map, model_size, gate_offset, up_offset, in_dim, out_dim, out_dim, x, 1) && ds4_gpu_swiglu_tensor(mid, gate, up, (uint32_t)out_dim, clamp, 1.0f); } return ds4_gpu_matmul_q8_0_tensor(gate, model_map, model_size, gate_offset, in_dim, out_dim, x, 1) && ds4_gpu_matmul_q8_0_tensor(up, model_map, model_size, up_offset, in_dim, out_dim, x, 1) && ds4_gpu_swiglu_tensor(mid, gate, up, (uint32_t)out_dim, clamp, 1.0f); } extern "C" int ds4_gpu_add_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *a, const ds4_gpu_tensor *b, uint32_t n) { if (!out || !a || !b || out->bytes < (uint64_t)n * sizeof(float) || a->bytes < (uint64_t)n * sizeof(float) || b->bytes < (uint64_t)n * sizeof(float)) return 0; add_kernel<<<(n + 255) / 256, 256>>>((float *)out->ptr, (const float *)a->ptr, (const float *)b->ptr, n); return cuda_ok(cudaGetLastError(), "add launch"); } extern "C" int ds4_gpu_directional_steering_project_tensor( ds4_gpu_tensor *x, const ds4_gpu_tensor *directions, uint32_t layer, uint32_t width, uint32_t rows, float scale) { if (!x || !directions || width == 0 || rows == 0 || scale == 0.0f) return 0; const uint64_t x_bytes = (uint64_t)width * rows * sizeof(float); const uint64_t dir_bytes = (uint64_t)(layer + 1u) * width * sizeof(float); if (x->bytes < x_bytes || directions->bytes < dir_bytes) return 0; uint32_t nth = 256u; while (nth > width && nth > 1u) nth >>= 1; directional_steering_project_kernel<<>>( (float *)x->ptr, (const float *)directions->ptr, layer, width, rows, scale); return cuda_ok(cudaGetLastError(), "directional steering launch"); } extern "C" int ds4_gpu_router_select_tensor(ds4_gpu_tensor *selected, ds4_gpu_tensor *weights, ds4_gpu_tensor *probs, const void *model_map, uint64_t model_size, uint64_t bias_offset, uint64_t hash_offset, uint32_t hash_rows, uint32_t token, uint32_t n_expert, uint32_t n_expert_used, float expert_weight_scale, uint32_t n_expert_groups, uint32_t n_group_used, bool has_bias, bool hash_mode, const ds4_gpu_tensor *logits) { if (!selected || !weights || !probs || !logits || !model_map || n_expert_groups > 1u || n_group_used > 0u) return 0; if (n_expert != 256u || n_expert_used != 6u || fabsf(expert_weight_scale - 1.5f) > 1.0e-6f) return 0; int32_t tok = (int32_t)token; int ok = 1; const float *bias = NULL; const int32_t *hash = NULL; if (ok && has_bias && !hash_mode) { if (bias_offset > model_size || model_size - bias_offset < 256u * sizeof(float)) ok = 0; else bias = (const float *)cuda_model_range_ptr(model_map, bias_offset, 256u * sizeof(float), "router_bias"); if (!bias) ok = 0; } if (ok && hash_mode) { const uint64_t hash_bytes = (uint64_t)hash_rows * 6u * sizeof(int32_t); if (hash_offset > model_size || hash_bytes > model_size - hash_offset) ok = 0; else hash = (const int32_t *)cuda_model_range_ptr(model_map, hash_offset, hash_bytes, "router_hash"); if (!hash) ok = 0; } if (ok) { if (getenv("DS4_CUDA_NO_WARP_ROUTER_SELECT") == NULL && getenv("DS4_CUDA_NO_PARALLEL_ROUTER_SELECT") == NULL) { dim3 block(32, 4, 1); router_select_warp_topk_kernel<<<1, block>>>((int32_t *)selected->ptr, (float *)weights->ptr, (float *)probs->ptr, bias, hash, (const float *)logits->ptr, NULL, tok, hash_rows, 1, has_bias && !hash_mode, hash_mode); } else if (getenv("DS4_CUDA_NO_PARALLEL_ROUTER_SELECT") == NULL) { router_select_parallel_kernel<<<1, 256>>>((int32_t *)selected->ptr, (float *)weights->ptr, (float *)probs->ptr, bias, hash, (const float *)logits->ptr, NULL, tok, hash_rows, 1, has_bias && !hash_mode, hash_mode); } else { router_select_kernel<<<1, 1>>>((int32_t *)selected->ptr, (float *)weights->ptr, (float *)probs->ptr, bias, hash, (const float *)logits->ptr, NULL, tok, hash_rows, 1, has_bias && !hash_mode, hash_mode); } ok = cuda_ok(cudaGetLastError(), "router_select launch"); } return ok; } extern "C" int ds4_gpu_router_select_batch_tensor(ds4_gpu_tensor *selected, ds4_gpu_tensor *weights, ds4_gpu_tensor *probs, const void *model_map, uint64_t model_size, uint64_t bias_offset, uint64_t hash_offset, uint32_t hash_rows, uint32_t n_expert_groups, uint32_t n_group_used, bool has_bias, bool hash_mode, const ds4_gpu_tensor *logits, const ds4_gpu_tensor *tokens, uint32_t n_expert, uint32_t n_expert_used, float expert_weight_scale, uint32_t n_tokens) { if (n_expert != 256u || n_expert_used != 6u || fabsf(expert_weight_scale - 1.5f) > 1.0e-6f) return 0; if (!selected || !weights || !probs || !logits || !tokens || !model_map || n_tokens == 0 || n_expert_groups > 1u || n_group_used > 0u || logits->bytes < (uint64_t)n_tokens * 256u * sizeof(float) || probs->bytes < (uint64_t)n_tokens * 256u * sizeof(float) || selected->bytes < (uint64_t)n_tokens * 6u * sizeof(int32_t) || weights->bytes < (uint64_t)n_tokens * 6u * sizeof(float)) { return 0; } const float *bias = NULL; const int32_t *hash = NULL; if (has_bias && !hash_mode) { if (bias_offset > model_size || model_size - bias_offset < 256u * sizeof(float)) return 0; bias = (const float *)cuda_model_range_ptr(model_map, bias_offset, 256u * sizeof(float), "router_bias"); if (!bias) return 0; } if (hash_mode) { const uint64_t hash_bytes = (uint64_t)hash_rows * 6u * sizeof(int32_t); if (hash_offset > model_size || hash_bytes > model_size - hash_offset) return 0; hash = (const int32_t *)cuda_model_range_ptr(model_map, hash_offset, hash_bytes, "router_hash"); if (!hash) return 0; } if (getenv("DS4_CUDA_NO_WARP_ROUTER_SELECT") == NULL && getenv("DS4_CUDA_NO_PARALLEL_ROUTER_SELECT") == NULL) { dim3 block(32, 4, 1); router_select_warp_topk_kernel<<<(n_tokens + 3u) / 4u, block>>>((int32_t *)selected->ptr, (float *)weights->ptr, (float *)probs->ptr, bias, hash, (const float *)logits->ptr, (const int32_t *)tokens->ptr, 0, hash_rows, n_tokens, has_bias && !hash_mode, hash_mode); } else if (getenv("DS4_CUDA_NO_PARALLEL_ROUTER_SELECT") == NULL) { router_select_parallel_kernel<<>>((int32_t *)selected->ptr, (float *)weights->ptr, (float *)probs->ptr, bias, hash, (const float *)logits->ptr, (const int32_t *)tokens->ptr, 0, hash_rows, n_tokens, has_bias && !hash_mode, hash_mode); } else { router_select_kernel<<>>((int32_t *)selected->ptr, (float *)weights->ptr, (float *)probs->ptr, bias, hash, (const float *)logits->ptr, (const int32_t *)tokens->ptr, 0, hash_rows, n_tokens, has_bias && !hash_mode, hash_mode); } return cuda_ok(cudaGetLastError(), "router_select launch"); } __device__ static float dev_f16_to_f32(uint16_t v) { return __half2float(*reinterpret_cast(&v)); } __device__ __forceinline__ static uint32_t dev_unpack_iq2_signs(uint32_t v) { const uint32_t p = __popc(v) & 1u; const uint32_t s = v ^ (p << 7u); return s * 0x01010101u; } __device__ __forceinline__ static int32_t dev_iq2_dp4a_8(uint64_t grid, uint32_t sign, const int8_t *q8, int32_t acc) { const uint32_t signs = dev_unpack_iq2_signs(sign); const int32_t sm0 = __vcmpne4(signs & 0x08040201u, 0); const int32_t sm1 = __vcmpne4(signs & 0x80402010u, 0); const int32_t g0 = __vsub4((int32_t)(uint32_t)grid ^ sm0, sm0); const int32_t g1 = __vsub4((int32_t)(uint32_t)(grid >> 32) ^ sm1, sm1); acc = __dp4a(g0, *(const int32_t *)(q8 + 0), acc); acc = __dp4a(g1, *(const int32_t *)(q8 + 4), acc); return acc; } __device__ static int32_t dev_dot_q2_16(const uint8_t *q2, const int8_t *q8, int shift) { int32_t sum = 0; #pragma unroll for (uint32_t i = 0; i < 16; i += 4) { const int32_t v = (*(const int32_t *)(q2 + i) >> shift) & 0x03030303; sum = __dp4a(v, *(const int32_t *)(q8 + i), sum); } return sum; } __device__ static int32_t dev_dot_iq2_pair_16(uint8_t grid0, uint32_t sign0, uint8_t grid1, uint32_t sign1, const int8_t *q8) { int32_t sum = 0; sum = dev_iq2_dp4a_8(cuda_iq2xxs_grid[grid0], cuda_ksigns_iq2xs[sign0], q8, sum); sum = dev_iq2_dp4a_8(cuda_iq2xxs_grid[grid1], cuda_ksigns_iq2xs[sign1], q8 + 8, sum); return sum; } __device__ __forceinline__ static void dev_iq2_i8x8_lut( const uint64_t *grid, const uint8_t *signs, uint8_t grid_idx, uint32_t sign_idx, int32_t *w0, int32_t *w1) { const uint32_t s = dev_unpack_iq2_signs(signs[sign_idx]); const int32_t sm0 = __vcmpne4(s & 0x08040201u, 0); const int32_t sm1 = __vcmpne4(s & 0x80402010u, 0); const uint64_t g = grid[grid_idx]; *w0 = __vsub4((int32_t)(uint32_t)g ^ sm0, sm0); *w1 = __vsub4((int32_t)(uint32_t)(g >> 32) ^ sm1, sm1); } __device__ static float dev_dot_iq2_xxs_q8_K_block_lut( const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y, const uint64_t *grid, const uint8_t *signs) { const float xd = dev_f16_to_f32(x->d); const uint16_t *q2 = x->qs; const int8_t *q8 = y->qs; int32_t bsum = 0; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const int32_t ls = (int32_t)(2u * (aux1 >> 28) + 1u); int32_t w[8]; dev_iq2_i8x8_lut(grid, signs, (uint8_t)(aux0 & 0xffu), (aux1 >> 0) & 127u, &w[0], &w[1]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 8) & 0xffu), (aux1 >> 7) & 127u, &w[2], &w[3]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 16) & 0xffu), (aux1 >> 14) & 127u, &w[4], &w[5]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 24) & 0xffu), (aux1 >> 21) & 127u, &w[6], &w[7]); int32_t sumi = 0; sumi = __dp4a(w[0], *(const int32_t *)(q8 + ib32 * 32u + 0), sumi); sumi = __dp4a(w[1], *(const int32_t *)(q8 + ib32 * 32u + 4), sumi); sumi = __dp4a(w[2], *(const int32_t *)(q8 + ib32 * 32u + 8), sumi); sumi = __dp4a(w[3], *(const int32_t *)(q8 + ib32 * 32u + 12), sumi); sumi = __dp4a(w[4], *(const int32_t *)(q8 + ib32 * 32u + 16), sumi); sumi = __dp4a(w[5], *(const int32_t *)(q8 + ib32 * 32u + 20), sumi); sumi = __dp4a(w[6], *(const int32_t *)(q8 + ib32 * 32u + 24), sumi); sumi = __dp4a(w[7], *(const int32_t *)(q8 + ib32 * 32u + 28), sumi); bsum += sumi * ls; } return 0.125f * xd * y->d * (float)bsum; } __device__ static float dev_dot_iq2_xxs_q8_K_block(const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y) { const float d = dev_f16_to_f32(x->d) * y->d; const uint16_t *q2 = x->qs; const int8_t *q8 = y->qs; int32_t bsum = 0; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const uint32_t ls = 2u * (aux1 >> 28) + 1u; const uint8_t a0 = (uint8_t)(aux0 & 0xffu); const uint8_t a1 = (uint8_t)((aux0 >> 8) & 0xffu); const uint8_t a2 = (uint8_t)((aux0 >> 16) & 0xffu); const uint8_t a3 = (uint8_t)((aux0 >> 24) & 0xffu); int32_t sumi = 0; sumi += dev_dot_iq2_pair_16(a0, (aux1 >> 0) & 127u, a1, (aux1 >> 7) & 127u, q8); q8 += 16; sumi += dev_dot_iq2_pair_16(a2, (aux1 >> 14) & 127u, a3, (aux1 >> 21) & 127u, q8); q8 += 16; bsum += sumi * (int32_t)ls; } return 0.125f * d * (float)bsum; } __device__ static void dev_dot_iq2_xxs_q8_K_block8_deq_lut( const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, uint32_t n, float acc[8], const uint64_t *grid, const uint8_t *signs) { const float xd = dev_f16_to_f32(x->d); const uint16_t *q2 = x->qs; int32_t bsum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const int8_t *q8[8] = { y0 ? y0->qs : NULL, y1 ? y1->qs : NULL, y2 ? y2->qs : NULL, y3 ? y3->qs : NULL, y4 ? y4->qs : NULL, y5 ? y5->qs : NULL, y6 ? y6->qs : NULL, y7 ? y7->qs : NULL, }; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const int32_t ls = (int32_t)(2u * (aux1 >> 28) + 1u); int32_t w[8]; dev_iq2_i8x8_lut(grid, signs, (uint8_t)(aux0 & 0xffu), (aux1 >> 0) & 127u, &w[0], &w[1]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 8) & 0xffu), (aux1 >> 7) & 127u, &w[2], &w[3]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 16) & 0xffu), (aux1 >> 14) & 127u, &w[4], &w[5]); dev_iq2_i8x8_lut(grid, signs, (uint8_t)((aux0 >> 24) & 0xffu), (aux1 >> 21) & 127u, &w[6], &w[7]); for (uint32_t p = 0; p < n; p++) { const int8_t *q = q8[p] + ib32 * 32; int32_t sumi = 0; sumi = __dp4a(w[0], *(const int32_t *)(q + 0), sumi); sumi = __dp4a(w[1], *(const int32_t *)(q + 4), sumi); sumi = __dp4a(w[2], *(const int32_t *)(q + 8), sumi); sumi = __dp4a(w[3], *(const int32_t *)(q + 12), sumi); sumi = __dp4a(w[4], *(const int32_t *)(q + 16), sumi); sumi = __dp4a(w[5], *(const int32_t *)(q + 20), sumi); sumi = __dp4a(w[6], *(const int32_t *)(q + 24), sumi); sumi = __dp4a(w[7], *(const int32_t *)(q + 28), sumi); bsum[p] += sumi * ls; } } const cuda_block_q8_K *ys[8] = { y0, y1, y2, y3, y4, y5, y6, y7 }; for (uint32_t p = 0; p < n; p++) acc[p] += 0.125f * xd * ys[p]->d * (float)bsum[p]; } __device__ static void dev_dot_iq2_xxs_q8_K_block4( const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, uint32_t n, float acc[4]) { const float xd = dev_f16_to_f32(x->d); const uint16_t *q2 = x->qs; int32_t bsum[4] = {0, 0, 0, 0}; const int8_t *q8[4] = { y0 ? y0->qs : NULL, y1 ? y1->qs : NULL, y2 ? y2->qs : NULL, y3 ? y3->qs : NULL, }; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const uint32_t ls = 2u * (aux1 >> 28) + 1u; const uint8_t a0 = (uint8_t)(aux0 & 0xffu); const uint8_t a1 = (uint8_t)((aux0 >> 8) & 0xffu); const uint8_t a2 = (uint8_t)((aux0 >> 16) & 0xffu); const uint8_t a3 = (uint8_t)((aux0 >> 24) & 0xffu); for (uint32_t p = 0; p < n; p++) { int32_t sumi = 0; sumi += dev_dot_iq2_pair_16(a0, (aux1 >> 0) & 127u, a1, (aux1 >> 7) & 127u, q8[p] + ib32 * 32); sumi += dev_dot_iq2_pair_16(a2, (aux1 >> 14) & 127u, a3, (aux1 >> 21) & 127u, q8[p] + ib32 * 32 + 16); bsum[p] += sumi * (int32_t)ls; } } const cuda_block_q8_K *ys[4] = { y0, y1, y2, y3 }; for (uint32_t p = 0; p < n; p++) acc[p] += 0.125f * xd * ys[p]->d * (float)bsum[p]; } __device__ static DS4_CUDA_UNUSED void dev_dot_iq2_xxs_q8_K_block8( const cuda_block_iq2_xxs *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, uint32_t n, float acc[8]) { const float xd = dev_f16_to_f32(x->d); const uint16_t *q2 = x->qs; int32_t bsum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const int8_t *q8[8] = { y0 ? y0->qs : NULL, y1 ? y1->qs : NULL, y2 ? y2->qs : NULL, y3 ? y3->qs : NULL, y4 ? y4->qs : NULL, y5 ? y5->qs : NULL, y6 ? y6->qs : NULL, y7 ? y7->qs : NULL, }; for (int ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux0 = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux1 = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const uint32_t ls = 2u * (aux1 >> 28) + 1u; const uint8_t a0 = (uint8_t)(aux0 & 0xffu); const uint8_t a1 = (uint8_t)((aux0 >> 8) & 0xffu); const uint8_t a2 = (uint8_t)((aux0 >> 16) & 0xffu); const uint8_t a3 = (uint8_t)((aux0 >> 24) & 0xffu); for (uint32_t p = 0; p < n; p++) { int32_t sumi = 0; sumi += dev_dot_iq2_pair_16(a0, (aux1 >> 0) & 127u, a1, (aux1 >> 7) & 127u, q8[p] + ib32 * 32); sumi += dev_dot_iq2_pair_16(a2, (aux1 >> 14) & 127u, a3, (aux1 >> 21) & 127u, q8[p] + ib32 * 32 + 16); bsum[p] += sumi * (int32_t)ls; } } const cuda_block_q8_K *ys[8] = { y0, y1, y2, y3, y4, y5, y6, y7 }; for (uint32_t p = 0; p < n; p++) acc[p] += 0.125f * xd * ys[p]->d * (float)bsum[p]; } __device__ static void dev_q4_K_get_scale_min( uint32_t j, const uint8_t *scales, uint8_t *d_out, uint8_t *m_out) { if (j < 4u) { *d_out = scales[j] & 63u; *m_out = scales[j + 4u] & 63u; } else { *d_out = (scales[j + 4u] & 0x0fu) | ((scales[j - 4u] >> 6u) << 4u); *m_out = (scales[j + 4u] >> 4u) | ((scales[j] >> 6u) << 4u); } } __device__ __forceinline__ static int32_t dev_dot_q4_32(const uint8_t *qs, const int8_t *q8, int shift) { int32_t sum = 0; #pragma unroll for (uint32_t i = 0; i < 32u; i += 4u) { const int32_t v = (*(const int32_t *)(qs + i) >> shift) & 0x0f0f0f0f; sum = __dp4a(v, *(const int32_t *)(q8 + i), sum); } return sum; } __device__ static float dev_dot_q4_K_q8_K_block(const cuda_block_q4_K *x, const cuda_block_q8_K *y) { const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); int isum = 0; int summs = 0; #pragma unroll for (uint32_t j = 0; j < 8u; j++) { uint8_t sc, m; dev_q4_K_get_scale_min(j, x->scales, &sc, &m); summs += (int)m * (int)(y->bsums[2u * j] + y->bsums[2u * j + 1u]); const uint32_t byte_off = (j >> 1u) * 32u; const int shift = (j & 1u) ? 4 : 0; isum += (int)sc * dev_dot_q4_32(x->qs + byte_off, y->qs + j * 32u, shift); } return y->d * xd * (float)isum - y->d * xmin * (float)summs; } __device__ __forceinline__ static void dev_dot_q4_32_q8_K_block8( const uint8_t *qs, const cuda_block_q8_K *const ys[8], uint32_t n, uint32_t y_off, int shift, int32_t sums[8]) { #pragma unroll for (uint32_t i = 0; i < 32u; i += 4u) { const int32_t v = (*(const int32_t *)(qs + i) >> shift) & 0x0f0f0f0f; #pragma unroll for (uint32_t p = 0; p < 8u; p++) { if (p < n) sums[p] = __dp4a(v, *(const int32_t *)(ys[p]->qs + y_off + i), sums[p]); } } } __device__ __forceinline__ static void dev_dot_q4_32_q8_K_block8_full( const uint8_t *qs, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, uint32_t y_off, int shift, int32_t sums[8]) { #pragma unroll for (uint32_t i = 0; i < 32u; i += 4u) { const int32_t v = (*(const int32_t *)(qs + i) >> shift) & 0x0f0f0f0f; sums[0] = __dp4a(v, *(const int32_t *)(y0->qs + y_off + i), sums[0]); sums[1] = __dp4a(v, *(const int32_t *)(y1->qs + y_off + i), sums[1]); sums[2] = __dp4a(v, *(const int32_t *)(y2->qs + y_off + i), sums[2]); sums[3] = __dp4a(v, *(const int32_t *)(y3->qs + y_off + i), sums[3]); sums[4] = __dp4a(v, *(const int32_t *)(y4->qs + y_off + i), sums[4]); sums[5] = __dp4a(v, *(const int32_t *)(y5->qs + y_off + i), sums[5]); sums[6] = __dp4a(v, *(const int32_t *)(y6->qs + y_off + i), sums[6]); sums[7] = __dp4a(v, *(const int32_t *)(y7->qs + y_off + i), sums[7]); } } __device__ static void dev_dot_q4_K_q8_K_block8( const cuda_block_q4_K *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, uint32_t n, float acc[8]) { const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); const cuda_block_q8_K *ys[8] = { y0, y1, y2, y3, y4, y5, y6, y7 }; int isum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int summs[8] = {0, 0, 0, 0, 0, 0, 0, 0}; #pragma unroll for (uint32_t j = 0; j < 8u; j++) { uint8_t sc, m; dev_q4_K_get_scale_min(j, x->scales, &sc, &m); const uint32_t y_off = j * 32u; const uint32_t byte_off = (j >> 1u) * 32u; const int shift = (j & 1u) ? 4 : 0; int32_t dots[8] = {0, 0, 0, 0, 0, 0, 0, 0}; dev_dot_q4_32_q8_K_block8(x->qs + byte_off, ys, n, y_off, shift, dots); #pragma unroll for (uint32_t p = 0; p < 8u; p++) { if (p < n) { summs[p] += (int)m * (int)(ys[p]->bsums[2u * j] + ys[p]->bsums[2u * j + 1u]); isum[p] += (int)sc * dots[p]; } } } #pragma unroll for (uint32_t p = 0; p < 8u; p++) { if (p < n) { const float yd = ys[p]->d; acc[p] += yd * xd * (float)isum[p] - yd * xmin * (float)summs[p]; } } } __device__ static void dev_dot_q4_K_q8_K_block8_full( const cuda_block_q4_K *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, float acc[8]) { const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); int isum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int summs[8] = {0, 0, 0, 0, 0, 0, 0, 0}; #pragma unroll for (uint32_t j = 0; j < 8u; j++) { uint8_t sc, m; dev_q4_K_get_scale_min(j, x->scales, &sc, &m); const uint32_t y_off = j * 32u; const uint32_t byte_off = (j >> 1u) * 32u; const int shift = (j & 1u) ? 4 : 0; int32_t dots[8] = {0, 0, 0, 0, 0, 0, 0, 0}; dev_dot_q4_32_q8_K_block8_full( x->qs + byte_off, y0, y1, y2, y3, y4, y5, y6, y7, y_off, shift, dots); const int ms0 = (int)m * (int)(y0->bsums[2u * j] + y0->bsums[2u * j + 1u]); const int ms1 = (int)m * (int)(y1->bsums[2u * j] + y1->bsums[2u * j + 1u]); const int ms2 = (int)m * (int)(y2->bsums[2u * j] + y2->bsums[2u * j + 1u]); const int ms3 = (int)m * (int)(y3->bsums[2u * j] + y3->bsums[2u * j + 1u]); const int ms4 = (int)m * (int)(y4->bsums[2u * j] + y4->bsums[2u * j + 1u]); const int ms5 = (int)m * (int)(y5->bsums[2u * j] + y5->bsums[2u * j + 1u]); const int ms6 = (int)m * (int)(y6->bsums[2u * j] + y6->bsums[2u * j + 1u]); const int ms7 = (int)m * (int)(y7->bsums[2u * j] + y7->bsums[2u * j + 1u]); summs[0] += ms0; summs[1] += ms1; summs[2] += ms2; summs[3] += ms3; summs[4] += ms4; summs[5] += ms5; summs[6] += ms6; summs[7] += ms7; isum[0] += (int)sc * dots[0]; isum[1] += (int)sc * dots[1]; isum[2] += (int)sc * dots[2]; isum[3] += (int)sc * dots[3]; isum[4] += (int)sc * dots[4]; isum[5] += (int)sc * dots[5]; isum[6] += (int)sc * dots[6]; isum[7] += (int)sc * dots[7]; } acc[0] += y0->d * xd * (float)isum[0] - y0->d * xmin * (float)summs[0]; acc[1] += y1->d * xd * (float)isum[1] - y1->d * xmin * (float)summs[1]; acc[2] += y2->d * xd * (float)isum[2] - y2->d * xmin * (float)summs[2]; acc[3] += y3->d * xd * (float)isum[3] - y3->d * xmin * (float)summs[3]; acc[4] += y4->d * xd * (float)isum[4] - y4->d * xmin * (float)summs[4]; acc[5] += y5->d * xd * (float)isum[5] - y5->d * xmin * (float)summs[5]; acc[6] += y6->d * xd * (float)isum[6] - y6->d * xmin * (float)summs[6]; acc[7] += y7->d * xd * (float)isum[7] - y7->d * xmin * (float)summs[7]; } __device__ static float dev_dot_q2_K_q8_K_block(const cuda_block_q2_K *x, const cuda_block_q8_K *y) { const uint8_t *q2 = x->qs; const int8_t *q8 = y->qs; const uint8_t *sc = x->scales; int summs = 0; for (int j = 0; j < 16; j++) summs += y->bsums[j] * (sc[j] >> 4); const float dall = y->d * dev_f16_to_f32(x->d); const float dmin = y->d * dev_f16_to_f32(x->dmin); int isum = 0; int is = 0; for (int k = 0; k < CUDA_QK_K / 128; k++) { int shift = 0; for (int j = 0; j < 4; j++) { int d = sc[is++] & 0x0f; isum += d * dev_dot_q2_16(q2, q8, shift); d = sc[is++] & 0x0f; isum += d * dev_dot_q2_16(q2 + 16, q8 + 16, shift); shift += 2; q8 += 32; } q2 += 32; } return dall * (float)isum - dmin * (float)summs; } __device__ static void dev_dot_q2_K_q8_K_block4( const cuda_block_q2_K *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, uint32_t n, float acc[4]) { const uint8_t *sc = x->scales; const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); const cuda_block_q8_K *ys[4] = { y0, y1, y2, y3 }; int isum[4] = {0, 0, 0, 0}; int summs[4] = {0, 0, 0, 0}; for (uint32_t p = 0; p < n; p++) { for (int j = 0; j < 16; j++) summs[p] += ys[p]->bsums[j] * (sc[j] >> 4); } for (uint32_t p = 0; p < n; p++) { const uint8_t *q2 = x->qs; const int8_t *q8 = ys[p]->qs; int is = 0; for (int k = 0; k < CUDA_QK_K / 128; k++) { int shift = 0; for (int j = 0; j < 4; j++) { int d = sc[is++] & 0x0f; isum[p] += d * dev_dot_q2_16(q2, q8, shift); d = sc[is++] & 0x0f; isum[p] += d * dev_dot_q2_16(q2 + 16, q8 + 16, shift); shift += 2; q8 += 32; } q2 += 32; } } for (uint32_t p = 0; p < n; p++) { const float yd = ys[p]->d; acc[p] += yd * xd * (float)isum[p] - yd * xmin * (float)summs[p]; } } __device__ static void dev_dot_q2_K_q8_K_block8( const cuda_block_q2_K *x, const cuda_block_q8_K *y0, const cuda_block_q8_K *y1, const cuda_block_q8_K *y2, const cuda_block_q8_K *y3, const cuda_block_q8_K *y4, const cuda_block_q8_K *y5, const cuda_block_q8_K *y6, const cuda_block_q8_K *y7, uint32_t n, float acc[8]) { const uint8_t *sc = x->scales; const float xd = dev_f16_to_f32(x->d); const float xmin = dev_f16_to_f32(x->dmin); const cuda_block_q8_K *ys[8] = { y0, y1, y2, y3, y4, y5, y6, y7 }; int isum[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int summs[8] = {0, 0, 0, 0, 0, 0, 0, 0}; for (uint32_t p = 0; p < n; p++) { for (int j = 0; j < 16; j++) summs[p] += ys[p]->bsums[j] * (sc[j] >> 4); } for (uint32_t p = 0; p < n; p++) { const uint8_t *q2 = x->qs; const int8_t *q8 = ys[p]->qs; int is = 0; for (int k = 0; k < CUDA_QK_K / 128; k++) { int shift = 0; for (int j = 0; j < 4; j++) { int d = sc[is++] & 0x0f; isum[p] += d * dev_dot_q2_16(q2, q8, shift); d = sc[is++] & 0x0f; isum[p] += d * dev_dot_q2_16(q2 + 16, q8 + 16, shift); shift += 2; q8 += 32; } q2 += 32; } } for (uint32_t p = 0; p < n; p++) { const float yd = ys[p]->d; acc[p] += yd * xd * (float)isum[p] - yd * xmin * (float)summs[p]; } } __device__ static float half_warp_sum_f32(float v, uint32_t lane16) { uint32_t mask = 0xffffu << (threadIdx.x & 16u); for (int offset = 8; offset > 0; offset >>= 1) { v += __shfl_down_sync(mask, v, offset, 16); } (void)lane16; return v; } __device__ static float quarter_warp_sum_f32(float v, uint32_t lane8) { uint32_t mask = 0xffu << (threadIdx.x & 24u); for (int offset = 4; offset > 0; offset >>= 1) { v += __shfl_down_sync(mask, v, offset, 8); } (void)lane8; return v; } __global__ static void q8_K_quantize_kernel(cuda_block_q8_K *out, const float *x, uint32_t in_dim, uint32_t n_rows) { uint32_t b = blockIdx.x; uint32_t row = blockIdx.y; if (row >= n_rows || b >= in_dim / CUDA_QK_K) return; const float *xr = x + (uint64_t)row * in_dim + (uint64_t)b * CUDA_QK_K; cuda_block_q8_K *yb = out + (uint64_t)row * (in_dim / CUDA_QK_K) + b; __shared__ float abs_part[256]; __shared__ float val_part[256]; __shared__ float maxv_s; __shared__ float iscale_s; uint32_t tid = threadIdx.x; float v = tid < CUDA_QK_K ? xr[tid] : 0.0f; abs_part[tid] = tid < CUDA_QK_K ? fabsf(v) : 0.0f; val_part[tid] = v; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (tid < stride && abs_part[tid + stride] > abs_part[tid]) { abs_part[tid] = abs_part[tid + stride]; val_part[tid] = val_part[tid + stride]; } __syncthreads(); } float amax = abs_part[0]; if (amax == 0.0f) { if (tid == 0) yb->d = 0.0f; if (tid < CUDA_QK_K) yb->qs[tid] = 0; if (tid < CUDA_QK_K / 16) yb->bsums[tid] = 0; return; } if (tid == 0) { maxv_s = val_part[0]; iscale_s = -127.0f / maxv_s; } __syncthreads(); if (tid < CUDA_QK_K) { int qv = (int)lrintf(iscale_s * xr[tid]); if (qv > 127) qv = 127; if (qv < -128) qv = -128; yb->qs[tid] = (int8_t)qv; } __syncthreads(); if (tid < CUDA_QK_K / 16) { int sum = 0; for (int i = 0; i < 16; i++) sum += yb->qs[tid * 16 + i]; yb->bsums[tid] = (int16_t)sum; } if (tid == 0) yb->d = 1.0f / iscale_s; } __global__ static DS4_CUDA_UNUSED void moe_gate_up_mid_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t row = blockIdx.x; uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = threadIdx.x; b < xq_blocks; b += blockDim.x) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } __shared__ float partial_gate[256]; __shared__ float partial_up[256]; partial_gate[threadIdx.x] = gate; partial_up[threadIdx.x] = up; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) { partial_gate[threadIdx.x] += partial_gate[threadIdx.x + stride]; partial_up[threadIdx.x] += partial_up[threadIdx.x + stride]; } __syncthreads(); } if (threadIdx.x == 0) { gate = partial_gate[0]; up = partial_up[0]; if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static DS4_CUDA_UNUSED void moe_gate_up_mid_warp8_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t lane = threadIdx.x & 31u; uint32_t warp = threadIdx.x >> 5u; uint32_t row = blockIdx.x * 8u + warp; uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 32u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = warp_sum_f32(gate); up = warp_sum_f32(up); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static DS4_CUDA_UNUSED void moe_gate_up_mid_hwarp16_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t lane = threadIdx.x & 15u; uint32_t row = blockIdx.x * 16u + (threadIdx.x >> 4u); uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 16u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = half_warp_sum_f32(gate, lane); up = half_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static void moe_gate_up_mid_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t pair = blockIdx.y; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; for (uint32_t rr = 0; rr < 4u; rr++) { uint32_t row = blockIdx.x * 128u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_gate_up_mid_decode_lut_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t pair = blockIdx.y; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; __shared__ cuda_block_q8_K sxq[16]; __shared__ uint64_t s_iq2_grid[256]; __shared__ uint8_t s_iq2_signs[128]; if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < xq_blocks; i += blockDim.x) sxq[i] = xqb[i]; for (uint32_t i = threadIdx.x; i < 256u; i += blockDim.x) s_iq2_grid[i] = cuda_iq2xxs_grid[i]; for (uint32_t i = threadIdx.x; i < 128u; i += blockDim.x) s_iq2_signs[i] = cuda_ksigns_iq2xs[i]; __syncthreads(); xqb = sxq; } for (uint32_t rr = 0; rr < 4u; rr++) { uint32_t row = blockIdx.x * 128u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block_lut(gr + b, xqb + b, s_iq2_grid, s_iq2_signs); up += dev_dot_iq2_xxs_q8_K_block_lut(ur + b, xqb + b, s_iq2_grid, s_iq2_signs); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate; up_out[off] = up; } mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_count_sorted_pairs_kernel( uint32_t *counts, const int32_t *selected, uint32_t pair_count) { uint32_t pair = (uint32_t)((uint64_t)blockIdx.x * blockDim.x + threadIdx.x); if (pair >= pair_count) return; int32_t expert_i = selected[pair]; if (expert_i < 0) expert_i = 0; atomicAdd(counts + (uint32_t)expert_i, 1u); } __global__ static void moe_prefix_sorted_pairs_kernel( uint32_t *offsets, uint32_t *cursors, const uint32_t *counts, uint32_t expert_count) { if (threadIdx.x == 0) { uint32_t sum = 0; for (uint32_t e = 0; e < expert_count; e++) { offsets[e] = sum; cursors[e] = sum; sum += counts[e]; } offsets[expert_count] = sum; } } __global__ static void moe_scatter_sorted_pairs_kernel( uint32_t *sorted_pairs, uint32_t *cursors, const int32_t *selected, uint32_t pair_count) { uint32_t pair = (uint32_t)((uint64_t)blockIdx.x * blockDim.x + threadIdx.x); if (pair >= pair_count) return; int32_t expert_i = selected[pair]; if (expert_i < 0) expert_i = 0; uint32_t pos = atomicAdd(cursors + (uint32_t)expert_i, 1u); sorted_pairs[pos] = pair; } __global__ static void moe_build_expert_tile_offsets_kernel( uint32_t *tile_offsets, uint32_t *tile_total, const uint32_t *counts, uint32_t expert_count, uint32_t block_m) { if (threadIdx.x == 0) { uint32_t sum = 0; for (uint32_t e = 0; e < expert_count; e++) { tile_offsets[e] = sum; sum += (counts[e] + block_m - 1u) / block_m; } tile_offsets[expert_count] = sum; *tile_total = sum; } } __global__ static void moe_build_expert_tiles_kernel( uint32_t *tile_experts, uint32_t *tile_starts, const uint32_t *tile_offsets, const uint32_t *counts, uint32_t expert_count, uint32_t block_m) { uint32_t e = (uint32_t)((uint64_t)blockIdx.x * blockDim.x + threadIdx.x); if (e >= expert_count) return; uint32_t ntiles = (counts[e] + block_m - 1u) / block_m; uint32_t off = tile_offsets[e]; for (uint32_t t = 0; t < ntiles; t++) { tile_experts[off + t] = e; tile_starts[off + t] = t * block_m; } } __global__ static void moe_gate_up_mid_sorted_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = sorted_pairs[blockIdx.y]; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static DS4_CUDA_UNUSED void moe_gate_up_mid_expert_tile8_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t group = threadIdx.x >> 3u; uint32_t lane = threadIdx.x & 7u; uint32_t pair_slot = group & 7u; uint32_t row_lane = group >> 3u; uint32_t expert = tile_experts[tile]; uint32_t local_pair = tile_starts[tile] + pair_slot; if (local_pair >= counts[expert]) return; uint32_t sorted_idx = offsets[expert] + local_pair; uint32_t pair = sorted_pairs[sorted_idx]; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; for (uint32_t rr = 0; rr < 2u; rr++) { uint32_t row = blockIdx.x * 8u + row_lane + rr * 4u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } __global__ static void moe_gate_up_mid_expert_tile4_row32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[4][16]; uint32_t pair[4] = {0, 0, 0, 0}; uint32_t tok[4] = {0, 0, 0, 0}; uint32_t slot[4] = {0, 0, 0, 0}; const cuda_block_q8_K *xqb[4] = {NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 4u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= expert_mid_dim) return; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float up[4] = {0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_iq2_xxs_q8_K_block4(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, np, gate); dev_dot_iq2_xxs_q8_K_block4(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, np, up); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } __global__ static void moe_gate_up_mid_expert_tile8_row32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][16]; __shared__ uint64_t s_iq2_grid[256]; __shared__ uint8_t s_iq2_signs[128]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tok[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t slot[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } for (uint32_t i = threadIdx.x; i < 256u; i += blockDim.x) s_iq2_grid[i] = cuda_iq2xxs_grid[i]; for (uint32_t i = threadIdx.x; i < 128u; i += blockDim.x) s_iq2_signs[i] = cuda_ksigns_iq2xs[i]; __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= expert_mid_dim) return; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; float up[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_iq2_xxs_q8_K_block8_deq_lut(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, gate, s_iq2_grid, s_iq2_signs); dev_dot_iq2_xxs_q8_K_block8_deq_lut(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, up, s_iq2_grid, s_iq2_signs); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } __global__ static void moe_gate_up_mid_expert_tile8_row2048_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][16]; __shared__ uint64_t s_iq2_grid[256]; __shared__ uint8_t s_iq2_signs[128]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tok[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t slot[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } for (uint32_t i = threadIdx.x; i < 256u; i += blockDim.x) s_iq2_grid[i] = cuda_iq2xxs_grid[i]; for (uint32_t i = threadIdx.x; i < 128u; i += blockDim.x) s_iq2_signs[i] = cuda_ksigns_iq2xs[i]; __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < 64u; rr++) { uint32_t row = blockIdx.x * 2048u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; float up[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_iq2_xxs_q8_K_block8_deq_lut(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, gate, s_iq2_grid, s_iq2_signs); dev_dot_iq2_xxs_q8_K_block8_deq_lut(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, up, s_iq2_grid, s_iq2_signs); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } } template __global__ static void moe_gate_up_mid_expert_tile8_rowspan_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][16]; __shared__ uint64_t s_iq2_grid[256]; __shared__ uint8_t s_iq2_signs[128]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tok[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t slot[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } for (uint32_t i = threadIdx.x; i < 256u; i += blockDim.x) s_iq2_grid[i] = cuda_iq2xxs_grid[i]; for (uint32_t i = threadIdx.x; i < 128u; i += blockDim.x) s_iq2_signs[i] = cuda_ksigns_iq2xs[i]; __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < ROW_SPAN / 32u; rr++) { uint32_t row = blockIdx.x * ROW_SPAN + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; float up[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { dev_dot_iq2_xxs_q8_K_block8_deq_lut(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, gate, s_iq2_grid, s_iq2_signs); dev_dot_iq2_xxs_q8_K_block8_deq_lut(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, up, s_iq2_grid, s_iq2_signs); } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } } __global__ static void moe_gate_up_mid_sorted_p2_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t pair_count, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t pair_lane = (threadIdx.x >> 3u) & 1u; uint32_t row = blockIdx.x * 16u + (threadIdx.x >> 4u); uint32_t sorted_idx = blockIdx.y * 2u + pair_lane; if (row >= expert_mid_dim || sorted_idx >= pair_count) return; uint32_t pair = sorted_pairs[sorted_idx]; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_iq2_xxs_q8_K_block(gr + b, xqb + b); up += dev_dot_iq2_xxs_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static DS4_CUDA_UNUSED void moe_down_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t row = blockIdx.x; uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = threadIdx.x; b < midq_blocks; b += blockDim.x) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); __shared__ float partial[256]; partial[threadIdx.x] = acc; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) down_out[(uint64_t)pair * out_dim + row] = partial[0]; } __global__ static DS4_CUDA_UNUSED void moe_down_warp8_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 31u; uint32_t warp = threadIdx.x >> 5u; uint32_t row = blockIdx.x * 8u + warp; uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 32u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = warp_sum_f32(acc); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static DS4_CUDA_UNUSED void moe_down_hwarp16_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 15u; uint32_t row = blockIdx.x * 16u + (threadIdx.x >> 4u); uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 16u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = half_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static void moe_down_qwarp32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static void moe_gate_up_mid_q4K_qwarp32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, float clamp) { uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t pair = blockIdx.y; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const cuda_block_q8_K *xqb = xq + (uint64_t)tok * xq_blocks; for (uint32_t rr = 0; rr < 4u; rr++) { uint32_t row = blockIdx.x * 128u + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_q4_K *gr = (const cuda_block_q4_K *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q4_K *ur = (const cuda_block_q4_K *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate = 0.0f; float up = 0.0f; for (uint32_t b = lane; b < xq_blocks; b += 8u) { gate += dev_dot_q4_K_q8_K_block(gr + b, xqb + b); up += dev_dot_q4_K_q8_K_block(ur + b, xqb + b); } gate = quarter_warp_sum_f32(gate, lane); up = quarter_warp_sum_f32(up, lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate; up_out[off] = up; } mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } } template __global__ static void moe_gate_up_mid_q4K_expert_tile8_rowspan_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const cuda_block_q8_K *xq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t xq_blocks, uint32_t expert_mid_dim, uint32_t n_expert, uint32_t write_aux, float clamp) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][16]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t tok[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t slot[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; tok[np] = pair[np] / n_expert; slot[np] = pair[np] - tok[np] * n_expert; xqb[np] = xq + (uint64_t)tok[np] * xq_blocks; } if (xq_blocks <= 16u) { for (uint32_t i = threadIdx.x; i < np * xq_blocks; i += blockDim.x) { uint32_t p = i / xq_blocks; uint32_t b = i - p * xq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < ROW_SPAN / 32u; rr++) { uint32_t row = blockIdx.x * ROW_SPAN + row_lane + rr * 32u; if (row >= expert_mid_dim) continue; const cuda_block_q4_K *gr = (const cuda_block_q4_K *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_q4_K *ur = (const cuda_block_q4_K *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); float gate[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; float up[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < xq_blocks; b += 8u) { if (np == 8u) { dev_dot_q4_K_q8_K_block8_full(gr + b, xqb[0] + b, xqb[1] + b, xqb[2] + b, xqb[3] + b, xqb[4] + b, xqb[5] + b, xqb[6] + b, xqb[7] + b, gate); dev_dot_q4_K_q8_K_block8_full(ur + b, xqb[0] + b, xqb[1] + b, xqb[2] + b, xqb[3] + b, xqb[4] + b, xqb[5] + b, xqb[6] + b, xqb[7] + b, up); } else { dev_dot_q4_K_q8_K_block8(gr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, gate); dev_dot_q4_K_q8_K_block8(ur + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, up); } } for (uint32_t p = 0; p < np; p++) { gate[p] = quarter_warp_sum_f32(gate[p], lane); up[p] = quarter_warp_sum_f32(up[p], lane); if (lane == 0) { if (clamp > 1.0e-6f) { if (gate[p] > clamp) gate[p] = clamp; if (up[p] > clamp) up[p] = clamp; if (up[p] < -clamp) up[p] = -clamp; } const uint64_t off = (uint64_t)pair[p] * expert_mid_dim + row; if (write_aux) { gate_out[off] = gate[p]; up_out[off] = up[p]; } mid_out[off] = (gate[p] / (1.0f + expf(-gate[p]))) * up[p] * weights[(uint64_t)tok[p] * n_expert + slot[p]]; } } } } __global__ static void moe_down_sum6_qwarp32_kernel( float *out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); if (row >= out_dim) return; float total = 0.0f; #pragma unroll for (uint32_t slot = 0; slot < 6u; slot++) { int32_t expert_i = selected[slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)slot * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) total += acc; } if (lane == 0) out[row] = total; } __global__ static void moe_down_q4K_sum6_qwarp32_kernel( float *out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); if (row >= out_dim) return; float total = 0.0f; #pragma unroll for (uint32_t slot = 0; slot < 6u; slot++) { int32_t expert_i = selected[slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q4_K *wr = (const cuda_block_q4_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)slot * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q4_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) total += acc; } if (lane == 0) out[row] = total; } __global__ static void moe_down_q4K_qwarp32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q4_K *wr = (const cuda_block_q4_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q4_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } template __global__ static void moe_down_q4K_expert_tile8_rowspan_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][8]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < ROW_SPAN / 32u; rr++) { uint32_t row = blockIdx.x * ROW_SPAN + row_lane + rr * 32u; if (row >= out_dim) continue; const cuda_block_q4_K *wr = (const cuda_block_q4_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { if (np == 8u) { dev_dot_q4_K_q8_K_block8_full(wr + b, xqb[0] + b, xqb[1] + b, xqb[2] + b, xqb[3] + b, xqb[4] + b, xqb[5] + b, xqb[6] + b, xqb[7] + b, acc); } else { dev_dot_q4_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, acc); } } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } } template __global__ static void moe_down_q4K_expert_tile16_rowspan_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t local_start = tile_starts[tile]; if (local_start & 8u) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; __shared__ cuda_block_q8_K sxq[16][8]; uint32_t pair[16] = {0}; const cuda_block_q8_K *xqb[16] = {NULL}; uint32_t np = 0; for (; np < 16u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < ROW_SPAN / 32u; rr++) { uint32_t row = blockIdx.x * ROW_SPAN + row_lane + rr * 32u; if (row >= out_dim) continue; const cuda_block_q4_K *wr = (const cuda_block_q4_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[16] = {0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { if (np >= 8u) { dev_dot_q4_K_q8_K_block8_full(wr + b, xqb[0] + b, xqb[1] + b, xqb[2] + b, xqb[3] + b, xqb[4] + b, xqb[5] + b, xqb[6] + b, xqb[7] + b, acc); } else { dev_dot_q4_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, acc); } if (np > 8u) { if (np == 16u) { dev_dot_q4_K_q8_K_block8_full(wr + b, xqb[8] + b, xqb[9] + b, xqb[10] + b, xqb[11] + b, xqb[12] + b, xqb[13] + b, xqb[14] + b, xqb[15] + b, acc + 8); } else { dev_dot_q4_K_q8_K_block8(wr + b, xqb[8] ? xqb[8] + b : NULL, xqb[9] ? xqb[9] + b : NULL, xqb[10] ? xqb[10] + b : NULL, xqb[11] ? xqb[11] + b : NULL, xqb[12] ? xqb[12] + b : NULL, xqb[13] ? xqb[13] + b : NULL, xqb[14] ? xqb[14] + b : NULL, xqb[15] ? xqb[15] + b : NULL, np - 8u, acc + 8); } } } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } } __global__ static void moe_down_sorted_qwarp32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t pair = sorted_pairs[blockIdx.y]; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static DS4_CUDA_UNUSED void moe_down_expert_tile8_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t group = threadIdx.x >> 3u; uint32_t lane = threadIdx.x & 7u; uint32_t pair_slot = group & 7u; uint32_t row_lane = group >> 3u; uint32_t expert = tile_experts[tile]; uint32_t local_pair = tile_starts[tile] + pair_slot; if (local_pair >= counts[expert]) return; uint32_t sorted_idx = offsets[expert] + local_pair; uint32_t pair = sorted_pairs[sorted_idx]; const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; for (uint32_t rr = 0; rr < 2u; rr++) { uint32_t row = blockIdx.x * 8u + row_lane + rr * 4u; if (row >= out_dim) continue; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } } __global__ static void moe_down_expert_tile4_row32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[4][8]; uint32_t pair[4] = {0, 0, 0, 0}; const cuda_block_q8_K *xqb[4] = {NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 4u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= out_dim) return; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[4] = {0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block4(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, np, acc); } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } __global__ static void moe_down_expert_tile8_row32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; uint32_t local_start = tile_starts[tile]; __shared__ cuda_block_q8_K sxq[8][8]; uint32_t pair[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const cuda_block_q8_K *xqb[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint32_t np = 0; for (; np < 8u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= out_dim) return; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np, acc); } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } __global__ static void moe_down_expert_tile16_row32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t local_start = tile_starts[tile]; if (local_start & 8u) return; uint32_t lane = threadIdx.x & 7u; uint32_t row = blockIdx.x * 32u + (threadIdx.x >> 3u); uint32_t expert = tile_experts[tile]; __shared__ cuda_block_q8_K sxq[16][8]; uint32_t pair[16] = {0}; const cuda_block_q8_K *xqb[16] = {NULL}; uint32_t np = 0; for (; np < 16u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } if (row >= out_dim) return; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[16] = {0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np < 8u ? np : 8u, acc); if (np > 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[8] ? xqb[8] + b : NULL, xqb[9] ? xqb[9] + b : NULL, xqb[10] ? xqb[10] + b : NULL, xqb[11] ? xqb[11] + b : NULL, xqb[12] ? xqb[12] + b : NULL, xqb[13] ? xqb[13] + b : NULL, xqb[14] ? xqb[14] + b : NULL, xqb[15] ? xqb[15] + b : NULL, np - 8u, acc + 8); } } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } __global__ static void moe_down_expert_tile16_row2048_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t local_start = tile_starts[tile]; if (local_start & 8u) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; __shared__ cuda_block_q8_K sxq[16][8]; uint32_t pair[16] = {0}; const cuda_block_q8_K *xqb[16] = {NULL}; uint32_t np = 0; for (; np < 16u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < 64u; rr++) { uint32_t row = blockIdx.x * 2048u + row_lane + rr * 32u; if (row >= out_dim) continue; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[16] = {0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np < 8u ? np : 8u, acc); if (np > 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[8] ? xqb[8] + b : NULL, xqb[9] ? xqb[9] + b : NULL, xqb[10] ? xqb[10] + b : NULL, xqb[11] ? xqb[11] + b : NULL, xqb[12] ? xqb[12] + b : NULL, xqb[13] ? xqb[13] + b : NULL, xqb[14] ? xqb[14] + b : NULL, xqb[15] ? xqb[15] + b : NULL, np - 8u, acc + 8); } } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } } template __global__ static void moe_down_expert_tile16_rowspan_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const uint32_t *offsets, const uint32_t *counts, const uint32_t *tile_total, const uint32_t *tile_experts, const uint32_t *tile_starts, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t atomic_out) { uint32_t tile = blockIdx.y; if (tile >= *tile_total) return; uint32_t local_start = tile_starts[tile]; if (local_start & 8u) return; uint32_t lane = threadIdx.x & 7u; uint32_t row_lane = threadIdx.x >> 3u; uint32_t expert = tile_experts[tile]; __shared__ cuda_block_q8_K sxq[16][8]; uint32_t pair[16] = {0}; const cuda_block_q8_K *xqb[16] = {NULL}; uint32_t np = 0; for (; np < 16u; np++) { uint32_t local_pair = local_start + np; if (local_pair >= counts[expert]) break; pair[np] = sorted_pairs[offsets[expert] + local_pair]; xqb[np] = midq + (uint64_t)pair[np] * midq_blocks; } if (midq_blocks <= 8u) { for (uint32_t i = threadIdx.x; i < np * midq_blocks; i += blockDim.x) { uint32_t p = i / midq_blocks; uint32_t b = i - p * midq_blocks; sxq[p][b] = xqb[p][b]; } __syncthreads(); for (uint32_t p = 0; p < np; p++) xqb[p] = sxq[p]; } for (uint32_t rr = 0; rr < ROW_SPAN / 32u; rr++) { uint32_t row = blockIdx.x * ROW_SPAN + row_lane + rr * 32u; if (row >= out_dim) continue; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)expert * down_expert_bytes + (uint64_t)row * down_row_bytes); float acc[16] = {0.0f}; for (uint32_t b = lane; b < midq_blocks; b += 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[0] ? xqb[0] + b : NULL, xqb[1] ? xqb[1] + b : NULL, xqb[2] ? xqb[2] + b : NULL, xqb[3] ? xqb[3] + b : NULL, xqb[4] ? xqb[4] + b : NULL, xqb[5] ? xqb[5] + b : NULL, xqb[6] ? xqb[6] + b : NULL, xqb[7] ? xqb[7] + b : NULL, np < 8u ? np : 8u, acc); if (np > 8u) { dev_dot_q2_K_q8_K_block8(wr + b, xqb[8] ? xqb[8] + b : NULL, xqb[9] ? xqb[9] + b : NULL, xqb[10] ? xqb[10] + b : NULL, xqb[11] ? xqb[11] + b : NULL, xqb[12] ? xqb[12] + b : NULL, xqb[13] ? xqb[13] + b : NULL, xqb[14] ? xqb[14] + b : NULL, xqb[15] ? xqb[15] + b : NULL, np - 8u, acc + 8); } } for (uint32_t p = 0; p < np; p++) { acc[p] = quarter_warp_sum_f32(acc[p], lane); if (lane == 0) { if (atomic_out) { uint32_t tok = pair[p] / n_expert; atomicAdd(down_out + (uint64_t)tok * out_dim + row, acc[p]); } else { down_out[(uint64_t)pair[p] * out_dim + row] = acc[p]; } } } } } __global__ static void moe_down_sorted_p2_qwarp32_kernel( float *down_out, const char *down_base, const cuda_block_q8_K *midq, const uint32_t *sorted_pairs, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t midq_blocks, uint32_t out_dim, uint32_t n_expert, uint32_t pair_count) { uint32_t lane = threadIdx.x & 7u; uint32_t pair_lane = (threadIdx.x >> 3u) & 1u; uint32_t row = blockIdx.x * 16u + (threadIdx.x >> 4u); uint32_t sorted_idx = blockIdx.y * 2u + pair_lane; if (row >= out_dim || sorted_idx >= pair_count) return; uint32_t pair = sorted_pairs[sorted_idx]; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const cuda_block_q8_K *xq = midq + (uint64_t)pair * midq_blocks; float acc = 0.0f; for (uint32_t b = lane; b < midq_blocks; b += 8u) acc += dev_dot_q2_K_q8_K_block(wr + b, xq + b); acc = quarter_warp_sum_f32(acc, lane); if (lane == 0) down_out[(uint64_t)pair * out_dim + row] = acc; } __global__ static void moe_sum_kernel(float *out, const float *down, uint32_t out_dim, uint32_t n_expert, uint32_t n_tokens) { uint64_t gid = (uint64_t)blockIdx.x * blockDim.x + threadIdx.x; uint64_t n = (uint64_t)n_tokens * out_dim; if (gid >= n) return; uint32_t tok = gid / out_dim; uint32_t row = gid - (uint64_t)tok * out_dim; float acc = 0.0f; for (uint32_t e = 0; e < n_expert; e++) acc += down[((uint64_t)tok * n_expert + e) * out_dim + row]; out[gid] = acc; } __device__ static float dev_iq2_xxs_dot_f32(const cuda_block_iq2_xxs *row, const float *x, uint32_t nb) { float acc = 0.0f; for (uint32_t b = 0; b < nb; b++) { const cuda_block_iq2_xxs *xb = row + b; const float d = dev_f16_to_f32(xb->d); const uint16_t *q2 = xb->qs; const float *xf = x + (uint64_t)b * CUDA_QK_K; for (uint32_t ib32 = 0; ib32 < CUDA_QK_K / 32; ib32++) { const uint32_t aux_g = (uint32_t)q2[0] | ((uint32_t)q2[1] << 16); const uint32_t aux_s = (uint32_t)q2[2] | ((uint32_t)q2[3] << 16); q2 += 4; const float dl = d * (0.5f + (float)(aux_s >> 28)) * 0.25f; const uint8_t grids[4] = { (uint8_t)(aux_g & 0xffu), (uint8_t)((aux_g >> 8) & 0xffu), (uint8_t)((aux_g >> 16) & 0xffu), (uint8_t)((aux_g >> 24) & 0xffu), }; for (uint32_t half = 0; half < 2; half++) { for (uint32_t g = 0; g < 2; g++) { const uint32_t gi = half * 2 + g; const uint64_t grid = cuda_iq2xxs_grid[grids[gi]]; const uint8_t signs = cuda_ksigns_iq2xs[(aux_s >> (14u * half + 7u * g)) & 127u]; for (uint32_t i = 0; i < 8; i++) { float w = (float)((grid >> (8u * i)) & 0xffu); if (signs & (1u << i)) w = -w; acc += dl * w * xf[ib32 * 32u + half * 16u + g * 8u + i]; } } } } } return acc; } __device__ static float dev_q2_K_dot_f32(const cuda_block_q2_K *row, const float *x, uint32_t nb) { float acc = 0.0f; for (uint32_t b = 0; b < nb; b++) { const cuda_block_q2_K *xb = row + b; const float d = dev_f16_to_f32(xb->d); const float dmin = dev_f16_to_f32(xb->dmin); for (uint32_t il = 0; il < 16; il++) { const uint32_t chunk = il / 8u; const uint32_t pair = il & 1u; const uint32_t shift = ((il / 2u) & 3u) * 2u; const uint8_t sc = xb->scales[il]; const float dl = d * (float)(sc & 0x0fu); const float ml = dmin * (float)(sc >> 4); const uint8_t *q = xb->qs + 32u * chunk + 16u * pair; const float *xf = x + (uint64_t)b * CUDA_QK_K + chunk * 128u + ((il % 8u) / 2u) * 32u + pair * 16u; for (uint32_t i = 0; i < 16; i++) { const float w = dl * (float)((q[i] >> shift) & 3u) - ml; acc += w * xf[i]; } } } return acc; } __global__ static void moe_gate_up_mid_f32_kernel( float *gate_out, float *up_out, float *mid_out, const char *gate_base, const char *up_base, const float *x, const int32_t *selected, const float *weights, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint32_t n_expert, float clamp) { uint32_t row = blockIdx.x; uint32_t pair = blockIdx.y; if (row >= expert_mid_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; uint32_t expert = (uint32_t)expert_i; const uint32_t nb = expert_in_dim / CUDA_QK_K; const cuda_block_iq2_xxs *gr = (const cuda_block_iq2_xxs *)(gate_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const cuda_block_iq2_xxs *ur = (const cuda_block_iq2_xxs *)(up_base + (uint64_t)expert * gate_expert_bytes + (uint64_t)row * gate_row_bytes); const float *xr = x + (uint64_t)tok * expert_in_dim; float gate = 0.0f; float up = 0.0f; for (uint32_t b = threadIdx.x; b < nb; b += blockDim.x) { gate += dev_iq2_xxs_dot_f32(gr + b, xr + (uint64_t)b * CUDA_QK_K, 1); up += dev_iq2_xxs_dot_f32(ur + b, xr + (uint64_t)b * CUDA_QK_K, 1); } __shared__ float partial_gate[256]; __shared__ float partial_up[256]; partial_gate[threadIdx.x] = gate; partial_up[threadIdx.x] = up; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) { partial_gate[threadIdx.x] += partial_gate[threadIdx.x + stride]; partial_up[threadIdx.x] += partial_up[threadIdx.x + stride]; } __syncthreads(); } if (threadIdx.x == 0) { gate = partial_gate[0]; up = partial_up[0]; if (clamp > 1.0e-6f) { if (gate > clamp) gate = clamp; if (up > clamp) up = clamp; if (up < -clamp) up = -clamp; } const uint64_t off = (uint64_t)pair * expert_mid_dim + row; gate_out[off] = gate; up_out[off] = up; mid_out[off] = (gate / (1.0f + expf(-gate))) * up * weights[(uint64_t)tok * n_expert + slot]; } } __global__ static void moe_down_f32_kernel( float *down_out, const char *down_base, const float *mid, const int32_t *selected, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t expert_mid_dim, uint32_t out_dim, uint32_t n_expert) { uint32_t row = blockIdx.x; uint32_t pair = blockIdx.y; if (row >= out_dim) return; uint32_t tok = pair / n_expert; uint32_t slot = pair - tok * n_expert; int32_t expert_i = selected[(uint64_t)tok * n_expert + slot]; if (expert_i < 0) expert_i = 0; const uint32_t nb = expert_mid_dim / CUDA_QK_K; const cuda_block_q2_K *wr = (const cuda_block_q2_K *)(down_base + (uint64_t)(uint32_t)expert_i * down_expert_bytes + (uint64_t)row * down_row_bytes); const float *xr = mid + (uint64_t)pair * expert_mid_dim; float acc = 0.0f; for (uint32_t b = threadIdx.x; b < nb; b += blockDim.x) acc += dev_q2_K_dot_f32(wr + b, xr + (uint64_t)b * CUDA_QK_K, 1); __shared__ float partial[256]; partial[threadIdx.x] = acc; __syncthreads(); for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) { if (threadIdx.x < stride) partial[threadIdx.x] += partial[threadIdx.x + stride]; __syncthreads(); } if (threadIdx.x == 0) down_out[(uint64_t)pair * out_dim + row] = partial[0]; } static int routed_moe_launch( ds4_gpu_tensor *out, ds4_gpu_tensor *gate, ds4_gpu_tensor *up, ds4_gpu_tensor *mid, ds4_gpu_tensor *down, const void *model_map, uint64_t model_size, uint64_t gate_offset, uint64_t up_offset, uint64_t down_offset, uint32_t gate_type, uint32_t down_type, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint32_t out_dim, const ds4_gpu_tensor *selected, const ds4_gpu_tensor *weights, uint32_t n_total_expert, uint32_t n_expert, float clamp, const ds4_gpu_tensor *x, uint32_t layer_index, uint32_t n_tokens) { if (!out || !gate || !up || !mid || !down || !model_map || !selected || !weights || !x || n_tokens == 0 || n_total_expert == 0 || n_expert == 0 || expert_in_dim % CUDA_QK_K != 0 || expert_mid_dim % CUDA_QK_K != 0 || gate_offset > model_size || up_offset > model_size || down_offset > model_size || x->bytes < (uint64_t)n_tokens * expert_in_dim * sizeof(float) || selected->bytes < (uint64_t)n_tokens * n_expert * sizeof(int32_t) || weights->bytes < (uint64_t)n_tokens * n_expert * sizeof(float) || gate->bytes < (uint64_t)n_tokens * n_expert * expert_mid_dim * sizeof(float) || up->bytes < (uint64_t)n_tokens * n_expert * expert_mid_dim * sizeof(float) || mid->bytes < (uint64_t)n_tokens * n_expert * expert_mid_dim * sizeof(float) || down->bytes < (uint64_t)n_tokens * n_expert * out_dim * sizeof(float) || out->bytes < (uint64_t)n_tokens * out_dim * sizeof(float)) { return 0; } const int q4k_path = (gate_type == 12u && down_type == 12u); if (!q4k_path && (gate_type != 16u || down_type != 10u)) return 0; const uint64_t gate_bytes = (uint64_t)n_total_expert * gate_expert_bytes; const uint64_t down_bytes = (uint64_t)n_total_expert * down_expert_bytes; if (gate_bytes > model_size - gate_offset || gate_bytes > model_size - up_offset || down_bytes > model_size - down_offset) { return 0; } const uint64_t required_slot_count = (uint64_t)n_tokens * n_expert; const int use_stream_selected_cache = g_ssd_streaming_mode && g_stream_selected_cache.valid && g_stream_selected_cache.model_map == model_map && g_stream_selected_cache.layer == layer_index && g_stream_selected_cache.n_total_expert == n_total_expert && g_stream_selected_cache.slot_count >= required_slot_count && g_stream_selected_cache.gate_offset == gate_offset && g_stream_selected_cache.up_offset == up_offset && g_stream_selected_cache.down_offset == down_offset && g_stream_selected_cache.gate_expert_bytes == gate_expert_bytes && g_stream_selected_cache.down_expert_bytes == down_expert_bytes && g_stream_selected_cache.gate_ptr && g_stream_selected_cache.up_ptr && g_stream_selected_cache.down_ptr && g_stream_selected_cache.slot_selected_tensor.ptr && g_stream_selected_cache.slot_selected_tensor.bytes >= required_slot_count * sizeof(int32_t); const ds4_gpu_tensor *selected_tensor = use_stream_selected_cache ? &g_stream_selected_cache.slot_selected_tensor : selected; const int32_t *selected_ptr = (const int32_t *)selected_tensor->ptr; const char *gate_w = use_stream_selected_cache ? g_stream_selected_cache.gate_ptr : cuda_model_range_ptr(model_map, gate_offset, gate_bytes, "moe_gate"); const char *up_w = use_stream_selected_cache ? g_stream_selected_cache.up_ptr : cuda_model_range_ptr(model_map, up_offset, gate_bytes, "moe_up"); const char *down_w = use_stream_selected_cache ? g_stream_selected_cache.down_ptr : cuda_model_range_ptr(model_map, down_offset, down_bytes, "moe_down"); if (!gate_w || !up_w || !down_w) return 0; int ok = 1; const uint32_t xq_blocks = expert_in_dim / CUDA_QK_K; const uint32_t midq_blocks = expert_mid_dim / CUDA_QK_K; const uint64_t xq_count = (uint64_t)n_tokens * xq_blocks; const uint64_t midq_count = (uint64_t)n_tokens * n_expert * midq_blocks; const uint64_t xq_bytes = xq_count * sizeof(cuda_block_q8_K); const uint64_t midq_bytes = midq_count * sizeof(cuda_block_q8_K); if (down->bytes >= xq_bytes && gate->bytes >= midq_bytes) { cuda_block_q8_K *xq = (cuda_block_q8_K *)down->ptr; cuda_block_q8_K *midq = (cuda_block_q8_K *)gate->ptr; const uint32_t profile_moe = getenv("DS4_CUDA_MOE_PROFILE") != NULL; cudaEvent_t prof_ev[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; if (profile_moe) { for (uint32_t i = 0; i < 7u; i++) { if (cudaEventCreate(&prof_ev[i]) != cudaSuccess) { for (uint32_t j = 0; j < i; j++) (void)cudaEventDestroy(prof_ev[j]); memset(prof_ev, 0, sizeof(prof_ev)); break; } } if (prof_ev[0]) (void)cudaEventRecord(prof_ev[0], 0); } const uint32_t pair_count = n_tokens * n_expert; const uint32_t use_q4_expert_tiles = q4k_path && getenv("DS4_CUDA_MOE_NO_Q4_EXPERT_TILES") == NULL; const uint32_t use_sorted_pairs = n_tokens > 1u && (!q4k_path || use_q4_expert_tiles); const uint32_t use_expert_tiles = use_sorted_pairs && getenv("DS4_CUDA_MOE_NO_EXPERT_TILES") == NULL; const uint32_t expert_tile_m = (!q4k_path && getenv("DS4_CUDA_MOE_TILE4")) ? 4u : 8u; const uint32_t write_gate_up = getenv("DS4_CUDA_MOE_WRITE_GATE_UP") != NULL; const uint32_t use_p2_sorted = use_sorted_pairs && !q4k_path && getenv("DS4_CUDA_MOE_NO_P2") == NULL; const uint32_t use_atomic_down = use_expert_tiles && getenv("DS4_CUDA_MOE_NO_ATOMIC_DOWN") == NULL && (getenv("DS4_CUDA_MOE_ATOMIC_DOWN") != NULL || (!q4k_path && n_tokens >= 128u)); const uint32_t use_gate_row2048 = use_expert_tiles && expert_tile_m == 8u && (getenv("DS4_CUDA_MOE_GATE_ROW2048") != NULL || getenv("DS4_CUDA_MOE_GATE_ROW256") != NULL || getenv("DS4_CUDA_MOE_GATE_ROW128") != NULL || (n_tokens >= 128u && getenv("DS4_CUDA_MOE_NO_GATE_ROW2048") == NULL && getenv("DS4_CUDA_MOE_NO_GATE_ROW256") == NULL && getenv("DS4_CUDA_MOE_NO_GATE_ROW128") == NULL)); const uint32_t use_down_tile16 = expert_tile_m == 8u && n_tokens >= 128u && getenv("DS4_CUDA_MOE_NO_DOWN_TILE16") == NULL && (use_atomic_down || q4k_path); const uint32_t use_decode_lut_gate = !q4k_path && n_tokens == 1u && xq_blocks <= 16u && getenv("DS4_CUDA_MOE_NO_DECODE_LUT_GATE") == NULL; const uint32_t gate_row_span = getenv("DS4_CUDA_MOE_GATE_ROW512") != NULL ? 512u : getenv("DS4_CUDA_MOE_GATE_ROW2048") != NULL ? 2048u : 1024u; const uint32_t down_row_span = getenv("DS4_CUDA_MOE_DOWN_ROW512") != NULL ? 512u : getenv("DS4_CUDA_MOE_DOWN_ROW1024") != NULL ? 1024u : 2048u; const uint32_t use_down_row2048 = use_expert_tiles && expert_tile_m == 8u && (getenv("DS4_CUDA_MOE_DOWN_ROW2048") != NULL || getenv("DS4_CUDA_MOE_DOWN_ROW256") != NULL || getenv("DS4_CUDA_MOE_DOWN_ROW128") != NULL || getenv("DS4_CUDA_MOE_DOWN_ROW64") != NULL || (use_down_tile16 && getenv("DS4_CUDA_MOE_NO_DOWN_ROW2048") == NULL && getenv("DS4_CUDA_MOE_NO_DOWN_ROW256") == NULL && getenv("DS4_CUDA_MOE_NO_DOWN_ROW128") == NULL && getenv("DS4_CUDA_MOE_NO_DOWN_ROW64") == NULL)); const uint32_t use_direct_down_sum6 = n_tokens == 1u && n_expert == 6u && getenv("DS4_CUDA_MOE_NO_DIRECT_DOWN_SUM6") == NULL; uint32_t *sorted_pairs = NULL; uint32_t *sorted_offsets = NULL; uint32_t *sorted_counts = NULL; uint32_t *tile_total = NULL; uint32_t *tile_experts = NULL; uint32_t *tile_starts = NULL; uint32_t *tile16_total = NULL; uint32_t *tile16_experts = NULL; uint32_t *tile16_starts = NULL; uint32_t tile_capacity = 0; uint32_t tile16_capacity = 0; dim3 xq_grid(xq_blocks, n_tokens, 1); q8_K_quantize_kernel<<>>(xq, (const float *)x->ptr, expert_in_dim, n_tokens); ok = cuda_ok(cudaGetLastError(), "routed_moe x quantize launch"); if (prof_ev[1]) (void)cudaEventRecord(prof_ev[1], 0); if (ok && use_sorted_pairs) { const uint32_t sort_expert_count = use_stream_selected_cache ? g_stream_selected_cache.compact_count : n_total_expert; if (sort_expert_count == 0) ok = 0; const uint64_t counts_bytes = (uint64_t)sort_expert_count * sizeof(uint32_t); const uint64_t offsets_bytes = ((uint64_t)sort_expert_count + 1ull) * sizeof(uint32_t); const uint64_t cursors_bytes = (uint64_t)sort_expert_count * sizeof(uint32_t); const uint64_t sorted_bytes = (uint64_t)pair_count * sizeof(uint32_t); tile_capacity = (pair_count + expert_tile_m - 1u) / expert_tile_m + sort_expert_count; tile16_capacity = use_down_tile16 ? ((pair_count + 15u) / 16u + sort_expert_count) : 0u; const uint64_t tile_offsets_bytes = ((uint64_t)sort_expert_count + 1ull) * sizeof(uint32_t); const uint64_t tile_total_bytes = sizeof(uint32_t); const uint64_t tile_experts_bytes = (uint64_t)tile_capacity * sizeof(uint32_t); const uint64_t tile_starts_bytes = (uint64_t)tile_capacity * sizeof(uint32_t); const uint64_t tile16_offsets_bytes = use_down_tile16 ? ((uint64_t)sort_expert_count + 1ull) * sizeof(uint32_t) : 0u; const uint64_t tile16_total_bytes = use_down_tile16 ? sizeof(uint32_t) : 0u; const uint64_t tile16_experts_bytes = (uint64_t)tile16_capacity * sizeof(uint32_t); const uint64_t tile16_starts_bytes = (uint64_t)tile16_capacity * sizeof(uint32_t); const uint64_t tile_offsets_off = counts_bytes + offsets_bytes + cursors_bytes + sorted_bytes; const uint64_t tile_total_off = tile_offsets_off + tile_offsets_bytes; const uint64_t tile_experts_off = tile_total_off + tile_total_bytes; const uint64_t tile_starts_off = tile_experts_off + tile_experts_bytes; const uint64_t tile16_offsets_off = tile_starts_off + tile_starts_bytes; const uint64_t tile16_total_off = tile16_offsets_off + tile16_offsets_bytes; const uint64_t tile16_experts_off = tile16_total_off + tile16_total_bytes; const uint64_t tile16_starts_off = tile16_experts_off + tile16_experts_bytes; const uint64_t scratch_bytes = tile16_starts_off + tile16_starts_bytes; uint8_t *scratch = (uint8_t *)cuda_tmp_alloc(scratch_bytes, "routed_moe sorted pairs"); if (!scratch) { ok = 0; } else { uint32_t *counts = (uint32_t *)scratch; uint32_t *offsets = (uint32_t *)(scratch + counts_bytes); uint32_t *cursors = (uint32_t *)(scratch + counts_bytes + offsets_bytes); sorted_pairs = (uint32_t *)(scratch + counts_bytes + offsets_bytes + cursors_bytes); sorted_offsets = offsets; sorted_counts = counts; uint32_t *tile_offsets = (uint32_t *)(scratch + tile_offsets_off); tile_total = (uint32_t *)(scratch + tile_total_off); tile_experts = (uint32_t *)(scratch + tile_experts_off); tile_starts = (uint32_t *)(scratch + tile_starts_off); uint32_t *tile16_offsets = use_down_tile16 ? (uint32_t *)(scratch + tile16_offsets_off) : NULL; tile16_total = use_down_tile16 ? (uint32_t *)(scratch + tile16_total_off) : NULL; tile16_experts = use_down_tile16 ? (uint32_t *)(scratch + tile16_experts_off) : NULL; tile16_starts = use_down_tile16 ? (uint32_t *)(scratch + tile16_starts_off) : NULL; ok = cuda_ok(cudaMemset(counts, 0, counts_bytes), "routed_moe sorted counts clear"); if (ok) { moe_count_sorted_pairs_kernel<<<(pair_count + 255u) / 256u, 256>>>( counts, selected_ptr, pair_count); ok = cuda_ok(cudaGetLastError(), "routed_moe sorted count launch"); } if (ok) { moe_prefix_sorted_pairs_kernel<<<1, 1>>>(offsets, cursors, counts, sort_expert_count); ok = cuda_ok(cudaGetLastError(), "routed_moe sorted prefix launch"); } if (ok) { moe_scatter_sorted_pairs_kernel<<<(pair_count + 255u) / 256u, 256>>>( sorted_pairs, cursors, selected_ptr, pair_count); ok = cuda_ok(cudaGetLastError(), "routed_moe sorted scatter launch"); } if (ok && use_expert_tiles) { moe_build_expert_tile_offsets_kernel<<<1, 1>>>(tile_offsets, tile_total, counts, sort_expert_count, expert_tile_m); ok = cuda_ok(cudaGetLastError(), "routed_moe expert tile offsets launch"); } if (ok && use_expert_tiles) { moe_build_expert_tiles_kernel<<<(sort_expert_count + 255u) / 256u, 256>>>(tile_experts, tile_starts, tile_offsets, counts, sort_expert_count, expert_tile_m); ok = cuda_ok(cudaGetLastError(), "routed_moe expert tiles launch"); } if (ok && use_expert_tiles && use_down_tile16) { moe_build_expert_tile_offsets_kernel<<<1, 1>>>(tile16_offsets, tile16_total, counts, sort_expert_count, 16u); ok = cuda_ok(cudaGetLastError(), "routed_moe expert tile16 offsets launch"); } if (ok && use_expert_tiles && use_down_tile16) { moe_build_expert_tiles_kernel<<<(sort_expert_count + 255u) / 256u, 256>>>(tile16_experts, tile16_starts, tile16_offsets, counts, sort_expert_count, 16u); ok = cuda_ok(cudaGetLastError(), "routed_moe expert tile16 launch"); } } } if (prof_ev[2]) (void)cudaEventRecord(prof_ev[2], 0); if (ok) { dim3 mgrid((expert_mid_dim + 31u) / 32u, n_tokens * n_expert, 1); if (ok && sorted_pairs && use_expert_tiles && sorted_offsets && sorted_counts && tile_total && tile_experts && tile_starts) { if (q4k_path) { if (use_gate_row2048) { if (gate_row_span == 512u) { dim3 tgrid((expert_mid_dim + 511u) / 512u, tile_capacity, 1); moe_gate_up_mid_q4K_expert_tile8_rowspan_kernel<512><<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, sorted_offsets, sorted_counts, tile_total, tile_experts, tile_starts, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } else if (gate_row_span == 1024u) { dim3 tgrid((expert_mid_dim + 1023u) / 1024u, tile_capacity, 1); moe_gate_up_mid_q4K_expert_tile8_rowspan_kernel<1024><<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, sorted_offsets, sorted_counts, tile_total, tile_experts, tile_starts, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } else { dim3 tgrid((expert_mid_dim + 2047u) / 2048u, tile_capacity, 1); moe_gate_up_mid_q4K_expert_tile8_rowspan_kernel<2048><<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, sorted_offsets, sorted_counts, tile_total, tile_experts, tile_starts, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } } else { dim3 tgrid((expert_mid_dim + 31u) / 32u, tile_capacity, 1); moe_gate_up_mid_q4K_expert_tile8_rowspan_kernel<32><<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, sorted_offsets, sorted_counts, tile_total, tile_experts, tile_starts, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } } else if (use_gate_row2048) { if (gate_row_span == 512u) { dim3 tgrid((expert_mid_dim + 511u) / 512u, tile_capacity, 1); moe_gate_up_mid_expert_tile8_rowspan_kernel<512><<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, sorted_offsets, sorted_counts, tile_total, tile_experts, tile_starts, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } else if (gate_row_span == 1024u) { dim3 tgrid((expert_mid_dim + 1023u) / 1024u, tile_capacity, 1); moe_gate_up_mid_expert_tile8_rowspan_kernel<1024><<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, sorted_offsets, sorted_counts, tile_total, tile_experts, tile_starts, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } else { dim3 tgrid((expert_mid_dim + 2047u) / 2048u, tile_capacity, 1); moe_gate_up_mid_expert_tile8_row2048_kernel<<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, sorted_offsets, sorted_counts, tile_total, tile_experts, tile_starts, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } } else if (expert_tile_m == 8u) { dim3 tgrid((expert_mid_dim + 31u) / 32u, tile_capacity, 1); moe_gate_up_mid_expert_tile8_row32_kernel<<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, sorted_offsets, sorted_counts, tile_total, tile_experts, tile_starts, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } else { dim3 tgrid((expert_mid_dim + 31u) / 32u, tile_capacity, 1); moe_gate_up_mid_expert_tile4_row32_kernel<<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, sorted_offsets, sorted_counts, tile_total, tile_experts, tile_starts, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } } else if (ok && sorted_pairs && use_p2_sorted) { dim3 p2_mgrid((expert_mid_dim + 15u) / 16u, (pair_count + 1u) / 2u, 1); moe_gate_up_mid_sorted_p2_qwarp32_kernel<<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, selected_ptr, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, pair_count, clamp); } else if (ok && !q4k_path && sorted_pairs) { moe_gate_up_mid_sorted_qwarp32_kernel<<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, sorted_pairs, selected_ptr, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, clamp); } else if (ok) { dim3 qgrid((expert_mid_dim + 127u) / 128u, n_tokens * n_expert, 1); if (q4k_path) { moe_gate_up_mid_q4K_qwarp32_kernel<<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, selected_ptr, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } else if (use_decode_lut_gate) { moe_gate_up_mid_decode_lut_qwarp32_kernel<<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, selected_ptr, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, write_gate_up, clamp); } else { moe_gate_up_mid_qwarp32_kernel<<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, xq, selected_ptr, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, xq_blocks, expert_mid_dim, n_expert, clamp); } } ok = cuda_ok(cudaGetLastError(), "routed_moe gate/up launch"); } if (prof_ev[3]) (void)cudaEventRecord(prof_ev[3], 0); if (ok) { dim3 midq_grid(midq_blocks, n_tokens * n_expert, 1); q8_K_quantize_kernel<<>>(midq, (const float *)mid->ptr, expert_mid_dim, n_tokens * n_expert); ok = cuda_ok(cudaGetLastError(), "routed_moe mid quantize launch"); } if (prof_ev[4]) (void)cudaEventRecord(prof_ev[4], 0); if (ok) { dim3 dgrid((out_dim + 31u) / 32u, n_tokens * n_expert, 1); uint32_t *down_tile_total = tile_total; uint32_t *down_tile_experts = tile_experts; uint32_t *down_tile_starts = tile_starts; uint32_t down_tile_capacity = tile_capacity; if (use_down_tile16 && tile16_total && tile16_experts && tile16_starts) { down_tile_total = tile16_total; down_tile_experts = tile16_experts; down_tile_starts = tile16_starts; down_tile_capacity = tile16_capacity; } if (use_direct_down_sum6) { dim3 sgrid((out_dim + 31u) / 32u, 1, 1); if (q4k_path) { moe_down_q4K_sum6_qwarp32_kernel<<>>( (float *)out->ptr, down_w, midq, selected_ptr, down_expert_bytes, down_row_bytes, midq_blocks, out_dim); } else { moe_down_sum6_qwarp32_kernel<<>>( (float *)out->ptr, down_w, midq, selected_ptr, down_expert_bytes, down_row_bytes, midq_blocks, out_dim); } } else if (use_atomic_down) { uint64_t n = (uint64_t)n_tokens * out_dim; zero_kernel<<<(n + 255u) / 256u, 256>>>((float *)out->ptr, n); ok = cuda_ok(cudaGetLastError(), "routed_moe atomic zero launch"); } if (use_direct_down_sum6) { /* The direct decode kernel writes the final token row. */ } else if (sorted_pairs && use_expert_tiles && sorted_offsets && sorted_counts && down_tile_total && down_tile_experts && down_tile_starts) { if (q4k_path) { if (use_down_row2048) { if (down_row_span == 512u) { dim3 tgrid((out_dim + 511u) / 512u, down_tile_capacity, 1); if (use_down_tile16) { moe_down_q4K_expert_tile16_rowspan_kernel<512><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } else { moe_down_q4K_expert_tile8_rowspan_kernel<512><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } } else if (down_row_span == 1024u) { dim3 tgrid((out_dim + 1023u) / 1024u, down_tile_capacity, 1); if (use_down_tile16) { moe_down_q4K_expert_tile16_rowspan_kernel<1024><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } else { moe_down_q4K_expert_tile8_rowspan_kernel<1024><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } } else { dim3 tgrid((out_dim + 2047u) / 2048u, down_tile_capacity, 1); if (use_down_tile16) { moe_down_q4K_expert_tile16_rowspan_kernel<2048><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } else { moe_down_q4K_expert_tile8_rowspan_kernel<2048><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } } } else if (use_down_tile16) { dim3 tgrid((out_dim + 31u) / 32u, down_tile_capacity, 1); moe_down_q4K_expert_tile16_rowspan_kernel<32><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } else { dim3 tgrid((out_dim + 31u) / 32u, down_tile_capacity, 1); moe_down_q4K_expert_tile8_rowspan_kernel<32><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } } else if (use_down_row2048) { if (down_row_span == 512u) { dim3 tgrid((out_dim + 511u) / 512u, down_tile_capacity, 1); moe_down_expert_tile16_rowspan_kernel<512><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } else if (down_row_span == 1024u) { dim3 tgrid((out_dim + 1023u) / 1024u, down_tile_capacity, 1); moe_down_expert_tile16_rowspan_kernel<1024><<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } else { dim3 tgrid((out_dim + 2047u) / 2048u, down_tile_capacity, 1); moe_down_expert_tile16_row2048_kernel<<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } } else if (use_down_tile16) { dim3 tgrid((out_dim + 31u) / 32u, down_tile_capacity, 1); moe_down_expert_tile16_row32_kernel<<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } else if (expert_tile_m == 8u) { dim3 tgrid((out_dim + 31u) / 32u, down_tile_capacity, 1); moe_down_expert_tile8_row32_kernel<<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } else { dim3 tgrid((out_dim + 31u) / 32u, down_tile_capacity, 1); moe_down_expert_tile4_row32_kernel<<>>( use_atomic_down ? (float *)out->ptr : (float *)down->ptr, down_w, midq, sorted_pairs, sorted_offsets, sorted_counts, down_tile_total, down_tile_experts, down_tile_starts, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, use_atomic_down); } } else if (sorted_pairs && use_p2_sorted) { dim3 p2_dgrid((out_dim + 15u) / 16u, (pair_count + 1u) / 2u, 1); moe_down_sorted_p2_qwarp32_kernel<<>>( (float *)down->ptr, down_w, midq, sorted_pairs, selected_ptr, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert, pair_count); } else if (!q4k_path && sorted_pairs) { moe_down_sorted_qwarp32_kernel<<>>( (float *)down->ptr, down_w, midq, sorted_pairs, selected_ptr, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert); } else { if (q4k_path) { moe_down_q4K_qwarp32_kernel<<>>( (float *)down->ptr, down_w, midq, selected_ptr, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert); } else { moe_down_qwarp32_kernel<<>>( (float *)down->ptr, down_w, midq, selected_ptr, down_expert_bytes, down_row_bytes, midq_blocks, out_dim, n_expert); } } ok = cuda_ok(cudaGetLastError(), "routed_moe down launch"); } if (prof_ev[5]) (void)cudaEventRecord(prof_ev[5], 0); if (ok && !use_atomic_down && !use_direct_down_sum6) { uint64_t n = (uint64_t)n_tokens * out_dim; moe_sum_kernel<<<(n + 255) / 256, 256>>>((float *)out->ptr, (const float *)down->ptr, out_dim, n_expert, n_tokens); ok = cuda_ok(cudaGetLastError(), "routed_moe sum launch"); } if (prof_ev[6]) { (void)cudaEventRecord(prof_ev[6], 0); if (cudaEventSynchronize(prof_ev[6]) == cudaSuccess) { float ms_xq = 0.0f, ms_sort = 0.0f, ms_gate = 0.0f, ms_midq = 0.0f, ms_down = 0.0f, ms_sum = 0.0f, ms_total = 0.0f; (void)cudaEventElapsedTime(&ms_xq, prof_ev[0], prof_ev[1]); (void)cudaEventElapsedTime(&ms_sort, prof_ev[1], prof_ev[2]); (void)cudaEventElapsedTime(&ms_gate, prof_ev[2], prof_ev[3]); (void)cudaEventElapsedTime(&ms_midq, prof_ev[3], prof_ev[4]); (void)cudaEventElapsedTime(&ms_down, prof_ev[4], prof_ev[5]); (void)cudaEventElapsedTime(&ms_sum, prof_ev[5], prof_ev[6]); (void)cudaEventElapsedTime(&ms_total, prof_ev[0], prof_ev[6]); fprintf(stderr, "ds4: CUDA MoE profile tokens=%u pairs=%u xq=%.3f sort=%.3f gateup=%.3f midq=%.3f down=%.3f sum=%.3f total=%.3f ms\n", n_tokens, pair_count, ms_xq, ms_sort, ms_gate, ms_midq, ms_down, ms_sum, ms_total); } for (uint32_t i = 0; i < 7u; i++) (void)cudaEventDestroy(prof_ev[i]); } return ok; } if (ok) { dim3 mgrid(expert_mid_dim, n_tokens * n_expert, 1); moe_gate_up_mid_f32_kernel<<>>( (float *)gate->ptr, (float *)up->ptr, (float *)mid->ptr, gate_w, up_w, (const float *)x->ptr, selected_ptr, (const float *)weights->ptr, gate_expert_bytes, gate_row_bytes, expert_in_dim, expert_mid_dim, n_expert, clamp); ok = cuda_ok(cudaGetLastError(), "routed_moe gate/up launch"); } if (ok) { dim3 dgrid(out_dim, n_tokens * n_expert, 1); moe_down_f32_kernel<<>>( (float *)down->ptr, down_w, (const float *)mid->ptr, selected_ptr, down_expert_bytes, down_row_bytes, expert_mid_dim, out_dim, n_expert); ok = cuda_ok(cudaGetLastError(), "routed_moe down launch"); } if (ok) { uint64_t n = (uint64_t)n_tokens * out_dim; moe_sum_kernel<<<(n + 255) / 256, 256>>>((float *)out->ptr, (const float *)down->ptr, out_dim, n_expert, n_tokens); ok = cuda_ok(cudaGetLastError(), "routed_moe sum launch"); } return ok; } extern "C" int ds4_gpu_routed_moe_set_selected_override(const int32_t *selected, uint32_t n_selected) { (void)selected; (void)n_selected; return 1; } extern "C" int ds4_gpu_routed_moe_one_tensor(ds4_gpu_tensor *out, ds4_gpu_tensor *gate, ds4_gpu_tensor *up, ds4_gpu_tensor *mid, ds4_gpu_tensor *down, const void *model_map, uint64_t model_size, uint64_t gate_offset, uint64_t up_offset, uint64_t down_offset, uint32_t gate_type, uint32_t down_type, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint32_t out_dim, const ds4_gpu_tensor *selected, const ds4_gpu_tensor *weights, uint32_t n_total_expert, uint32_t n_expert, float clamp, const ds4_gpu_tensor *x, uint32_t layer_index) { return routed_moe_launch(out, gate, up, mid, down, model_map, model_size, gate_offset, up_offset, down_offset, gate_type, down_type, gate_expert_bytes, gate_row_bytes, down_expert_bytes, down_row_bytes, expert_in_dim, expert_mid_dim, out_dim, selected, weights, n_total_expert, n_expert, clamp, x, layer_index, 1); } extern "C" int ds4_gpu_routed_moe_batch_tensor(ds4_gpu_tensor *out, ds4_gpu_tensor *gate, ds4_gpu_tensor *up, ds4_gpu_tensor *mid, ds4_gpu_tensor *down, const void *model_map, uint64_t model_size, uint64_t gate_offset, uint64_t up_offset, uint64_t down_offset, uint32_t gate_type, uint32_t down_type, uint64_t gate_expert_bytes, uint64_t gate_row_bytes, uint64_t down_expert_bytes, uint64_t down_row_bytes, uint32_t expert_in_dim, uint32_t expert_mid_dim, uint32_t out_dim, const ds4_gpu_tensor *selected, const ds4_gpu_tensor *weights, uint32_t n_total_expert, uint32_t n_expert, float clamp, const ds4_gpu_tensor *x, uint32_t layer_index, uint32_t n_tokens, bool *mid_is_f16) { if (mid_is_f16) *mid_is_f16 = false; return routed_moe_launch(out, gate, up, mid, down, model_map, model_size, gate_offset, up_offset, down_offset, gate_type, down_type, gate_expert_bytes, gate_row_bytes, down_expert_bytes, down_row_bytes, expert_in_dim, expert_mid_dim, out_dim, selected, weights, n_total_expert, n_expert, clamp, x, layer_index, n_tokens); } extern "C" int ds4_gpu_hc_split_sinkhorn_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *mix, const void *model_map, uint64_t model_size, uint64_t scale_offset, uint64_t base_offset, uint32_t n_hc, uint32_t sinkhorn_iters, float eps) { if (!out || !mix || !model_map || n_hc != 4) return 0; const uint64_t mix_bytes = 24ull * sizeof(float); if (scale_offset > model_size || model_size - scale_offset < 3ull * sizeof(float) || base_offset > model_size || model_size - base_offset < mix_bytes || mix->bytes < mix_bytes || out->bytes < mix_bytes) return 0; const float *scale = (const float *)cuda_model_range_ptr(model_map, scale_offset, 3ull * sizeof(float), "hc_scale"); const float *base = (const float *)cuda_model_range_ptr(model_map, base_offset, mix_bytes, "hc_base"); if (!scale || !base) return 0; uint32_t n_rows = (uint32_t)(mix->bytes / mix_bytes); if (out->bytes / mix_bytes < n_rows) n_rows = (uint32_t)(out->bytes / mix_bytes); hc_split_sinkhorn_kernel<<<(n_rows + 255) / 256, 256>>>( (float *)out->ptr, (const float *)mix->ptr, scale, base, n_rows, sinkhorn_iters, eps); return cuda_ok(cudaGetLastError(), "hc_split_sinkhorn launch"); } extern "C" int ds4_gpu_hc_weighted_sum_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *weights, uint32_t n_embd, uint32_t n_hc) { if (!out || !residual_hc || !weights || n_embd == 0 || n_hc == 0) return 0; uint32_t n_tokens = (uint32_t)(out->bytes / ((uint64_t)n_embd * sizeof(float))); hc_weighted_sum_kernel<<<((uint64_t)n_embd * n_tokens + 255) / 256, 256>>>( (float *)out->ptr, (const float *)residual_hc->ptr, (const float *)weights->ptr, n_embd, n_hc, n_tokens, n_hc); return cuda_ok(cudaGetLastError(), "hc_weighted_sum launch"); } extern "C" int ds4_gpu_hc_weighted_sum_split_tensor(ds4_gpu_tensor *out, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *split, uint32_t n_embd, uint32_t n_hc) { if (!out || !residual_hc || !split || n_embd == 0 || n_hc == 0) return 0; uint32_t n_tokens = (uint32_t)(out->bytes / ((uint64_t)n_embd * sizeof(float))); uint32_t stride = (uint32_t)(2u * n_hc + n_hc * n_hc); hc_weighted_sum_kernel<<<((uint64_t)n_embd * n_tokens + 255) / 256, 256>>>( (float *)out->ptr, (const float *)residual_hc->ptr, (const float *)split->ptr, n_embd, n_hc, n_tokens, stride); return cuda_ok(cudaGetLastError(), "hc_weighted_sum_split launch"); } extern "C" int ds4_gpu_hc_split_weighted_sum_tensor( ds4_gpu_tensor *out, ds4_gpu_tensor *split, const ds4_gpu_tensor *mix, const ds4_gpu_tensor *residual_hc, const void *model_map, uint64_t model_size, uint64_t scale_offset, uint64_t base_offset, uint32_t n_embd, uint32_t n_hc, uint32_t sinkhorn_iters, float eps) { if (!out || !split || !mix || !residual_hc || !model_map || n_embd == 0 || n_hc != 4) { return 0; } const uint64_t mix_hc = 2ull * n_hc + (uint64_t)n_hc * n_hc; const uint64_t mix_bytes = mix_hc * sizeof(float); const uint64_t out_row_bytes = (uint64_t)n_embd * sizeof(float); const uint64_t residual_row_bytes = (uint64_t)n_hc * n_embd * sizeof(float); if (out->bytes < out_row_bytes || out->bytes % out_row_bytes != 0 || scale_offset > model_size || 3ull * sizeof(float) > model_size - scale_offset || base_offset > model_size || mix_bytes > model_size - base_offset) { return 0; } uint64_t n_rows = out->bytes / out_row_bytes; if (mix->bytes < n_rows * mix_bytes || split->bytes < n_rows * mix_bytes || residual_hc->bytes < n_rows * residual_row_bytes) { return 0; } const float *scale = (const float *)cuda_model_range_ptr(model_map, scale_offset, 3ull * sizeof(float), "hc_scale"); const float *base = (const float *)cuda_model_range_ptr(model_map, base_offset, mix_bytes, "hc_base"); if (!scale || !base) return 0; hc_split_weighted_sum_fused_kernel<<<(uint32_t)n_rows, 256>>>( (float *)out->ptr, (float *)split->ptr, (const float *)mix->ptr, (const float *)residual_hc->ptr, scale, base, n_embd, n_hc, (uint32_t)n_rows, sinkhorn_iters, eps); return cuda_ok(cudaGetLastError(), "hc split weighted sum launch"); } extern "C" int ds4_gpu_hc_split_weighted_sum_norm_tensor( ds4_gpu_tensor *out, ds4_gpu_tensor *norm_out, ds4_gpu_tensor *split, const ds4_gpu_tensor *mix, const ds4_gpu_tensor *residual_hc, const void *model_map, uint64_t model_size, uint64_t scale_offset, uint64_t base_offset, uint64_t norm_weight_offset, uint32_t n_embd, uint32_t n_hc, uint32_t sinkhorn_iters, float eps, float norm_eps) { if (getenv("DS4_CUDA_DISABLE_HC_SPLIT_NORM_FUSED") == NULL) { if (!out || !norm_out || !split || !mix || !residual_hc || !model_map || n_embd == 0 || n_hc != 4) { return 0; } const uint64_t mix_hc = 2ull * n_hc + (uint64_t)n_hc * n_hc; const uint64_t mix_bytes = mix_hc * sizeof(float); const uint64_t out_row_bytes = (uint64_t)n_embd * sizeof(float); const uint64_t residual_row_bytes = (uint64_t)n_hc * n_embd * sizeof(float); if (out->bytes < out_row_bytes || out->bytes % out_row_bytes != 0 || norm_out->bytes < out->bytes || scale_offset > model_size || 3ull * sizeof(float) > model_size - scale_offset || base_offset > model_size || mix_bytes > model_size - base_offset || norm_weight_offset > model_size || (uint64_t)n_embd * sizeof(float) > model_size - norm_weight_offset) { return 0; } uint64_t n_rows = out->bytes / out_row_bytes; if (n_rows == 1) { if (mix->bytes < n_rows * mix_bytes || split->bytes < n_rows * mix_bytes || residual_hc->bytes < n_rows * residual_row_bytes) { return 0; } const float *scale = (const float *)cuda_model_range_ptr(model_map, scale_offset, 3ull * sizeof(float), "hc_scale"); const float *base = (const float *)cuda_model_range_ptr(model_map, base_offset, mix_bytes, "hc_base"); const float *norm_w = (const float *)cuda_model_range_ptr(model_map, norm_weight_offset, (uint64_t)n_embd * sizeof(float), "hc_norm_weight"); if (!scale || !base || !norm_w) return 0; hc_split_weighted_sum_norm_fused_kernel<<<(uint32_t)n_rows, 256>>>( (float *)out->ptr, (float *)norm_out->ptr, (float *)split->ptr, (const float *)mix->ptr, (const float *)residual_hc->ptr, scale, base, norm_w, n_embd, n_hc, (uint32_t)n_rows, sinkhorn_iters, eps, norm_eps); return cuda_ok(cudaGetLastError(), "hc split weighted sum norm launch"); } } return ds4_gpu_hc_split_weighted_sum_tensor(out, split, mix, residual_hc, model_map, model_size, scale_offset, base_offset, n_embd, n_hc, sinkhorn_iters, eps) && ds4_gpu_rms_norm_weight_tensor(norm_out, out, model_map, model_size, norm_weight_offset, n_embd, norm_eps); } extern "C" int ds4_gpu_output_hc_weights_tensor( ds4_gpu_tensor *out, const ds4_gpu_tensor *pre, const void *model_map, uint64_t model_size, uint64_t scale_offset, uint64_t base_offset, uint32_t n_hc, float eps) { if (!out || !pre || !model_map || n_hc == 0) return 0; const uint64_t row_bytes = (uint64_t)n_hc * sizeof(float); if (row_bytes == 0 || out->bytes < row_bytes || out->bytes % row_bytes != 0 || pre->bytes < out->bytes || scale_offset > model_size || sizeof(float) > model_size - scale_offset || base_offset > model_size || row_bytes > model_size - base_offset) { return 0; } const uint64_t n_tokens = out->bytes / row_bytes; const float *scale = (const float *)cuda_model_range_ptr(model_map, scale_offset, sizeof(float), "output_hc_scale"); const float *base = (const float *)cuda_model_range_ptr(model_map, base_offset, row_bytes, "output_hc_base"); if (!scale || !base) return 0; uint64_t n = n_tokens * n_hc; output_hc_weights_kernel<<<(n + 255) / 256, 256>>>( (float *)out->ptr, (const float *)pre->ptr, scale, base, n_hc, (uint32_t)n_tokens, eps); return cuda_ok(cudaGetLastError(), "output hc weights launch"); } extern "C" int ds4_gpu_hc_expand_tensor(ds4_gpu_tensor *out_hc, const ds4_gpu_tensor *block_out, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *post, const ds4_gpu_tensor *comb, uint32_t n_embd, uint32_t n_hc) { if (!out_hc || !block_out || !residual_hc || !post || !comb || n_embd == 0 || n_hc == 0) return 0; uint32_t n_tokens = (uint32_t)(out_hc->bytes / ((uint64_t)n_hc * n_embd * sizeof(float))); uint64_t n_elem = (uint64_t)n_tokens * n_hc * n_embd; hc_expand_kernel<<<(n_elem + 255) / 256, 256>>>((float *)out_hc->ptr, (const float *)block_out->ptr, (const float *)block_out->ptr, (const float *)residual_hc->ptr, (const float *)post->ptr, (const float *)comb->ptr, n_embd, n_hc, n_tokens, n_hc, n_hc * n_hc, 0); return cuda_ok(cudaGetLastError(), "hc_expand launch"); } extern "C" int ds4_gpu_hc_expand_split_tensor(ds4_gpu_tensor *out_hc, const ds4_gpu_tensor *block_out, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *split, uint32_t n_embd, uint32_t n_hc) { if (!out_hc || !block_out || !residual_hc || !split || n_embd == 0 || n_hc == 0) return 0; uint32_t n_tokens = (uint32_t)(out_hc->bytes / ((uint64_t)n_hc * n_embd * sizeof(float))); uint32_t mix_hc = 2u * n_hc + n_hc * n_hc; uint64_t n_elem = (uint64_t)n_tokens * n_hc * n_embd; const float *base = (const float *)split->ptr; hc_expand_kernel<<<(n_elem + 255) / 256, 256>>>((float *)out_hc->ptr, (const float *)block_out->ptr, (const float *)block_out->ptr, (const float *)residual_hc->ptr, base + n_hc, base + 2u * n_hc, n_embd, n_hc, n_tokens, mix_hc, mix_hc, 0); return cuda_ok(cudaGetLastError(), "hc_expand_split launch"); } extern "C" int ds4_gpu_hc_expand_split_half_tensor( ds4_gpu_tensor *out_hc, const ds4_gpu_tensor *block_out_h, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *split, uint32_t n_embd, uint32_t n_hc) { (void)out_hc; (void)block_out_h; (void)residual_hc; (void)split; (void)n_embd; (void)n_hc; return 0; } extern "C" int ds4_gpu_hc_expand_add_split_tensor(ds4_gpu_tensor *out_hc, const ds4_gpu_tensor *block_out, const ds4_gpu_tensor *block_add, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *split, uint32_t n_embd, uint32_t n_hc) { if (!out_hc || !block_out || !block_add || !residual_hc || !split || n_embd == 0 || n_hc == 0) return 0; uint32_t n_tokens = (uint32_t)(out_hc->bytes / ((uint64_t)n_hc * n_embd * sizeof(float))); uint32_t mix_hc = 2u * n_hc + n_hc * n_hc; uint64_t n_elem = (uint64_t)n_tokens * n_hc * n_embd; const float *base = (const float *)split->ptr; hc_expand_kernel<<<(n_elem + 255) / 256, 256>>>((float *)out_hc->ptr, (const float *)block_out->ptr, (const float *)block_add->ptr, (const float *)residual_hc->ptr, base + n_hc, base + 2u * n_hc, n_embd, n_hc, n_tokens, mix_hc, mix_hc, 1); return cuda_ok(cudaGetLastError(), "hc_expand_add_split launch"); } extern "C" int ds4_gpu_hc_expand_add_split_half_add_tensor( ds4_gpu_tensor *out_hc, const ds4_gpu_tensor *block_out, const ds4_gpu_tensor *block_add_h, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *split, uint32_t n_embd, uint32_t n_hc) { (void)out_hc; (void)block_out; (void)block_add_h; (void)residual_hc; (void)split; (void)n_embd; (void)n_hc; return 0; } extern "C" int ds4_gpu_shared_down_hc_expand_q8_0_tensor( ds4_gpu_tensor *out_hc, ds4_gpu_tensor *shared_out, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *shared_mid, const ds4_gpu_tensor *routed_out, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *split, uint32_t n_embd, uint32_t n_hc) { if (getenv("DS4_CUDA_DISABLE_Q8_HC_EXPAND_FUSED") == NULL) { return cuda_matmul_q8_0_hc_expand_tensor_labeled(out_hc, shared_out, model_map, model_size, weight_offset, in_dim, out_dim, shared_mid, routed_out, residual_hc, split, n_embd, n_hc, "shared_down_hc_expand"); } return ds4_gpu_matmul_q8_0_tensor(shared_out, model_map, model_size, weight_offset, in_dim, out_dim, shared_mid, 1) && ds4_gpu_hc_expand_add_split_tensor(out_hc, shared_out, routed_out, residual_hc, split, n_embd, n_hc); } extern "C" int ds4_gpu_matmul_q8_0_hc_expand_tensor( ds4_gpu_tensor *out_hc, ds4_gpu_tensor *block_out, const void *model_map, uint64_t model_size, uint64_t weight_offset, uint64_t in_dim, uint64_t out_dim, const ds4_gpu_tensor *x, const ds4_gpu_tensor *residual_hc, const ds4_gpu_tensor *split, uint32_t n_embd, uint32_t n_hc) { if (getenv("DS4_CUDA_DISABLE_Q8_HC_EXPAND_FUSED") == NULL) { return cuda_matmul_q8_0_hc_expand_tensor_labeled(out_hc, block_out, model_map, model_size, weight_offset, in_dim, out_dim, x, NULL, residual_hc, split, n_embd, n_hc, "q8_hc_expand"); } return ds4_gpu_matmul_q8_0_tensor(block_out, model_map, model_size, weight_offset, in_dim, out_dim, x, 1) && ds4_gpu_hc_expand_split_tensor(out_hc, block_out, residual_hc, split, n_embd, n_hc); }