Skip to content

ROCm strix-halo build error #980

Description

@ngkz

Function declarations in ds4_gpu.h (ds4_gpu_add_tensor_tp_flag, ds4_gpu_dsv4_qkv_norm_defer_kv_next, etc.) were inside an #ifdef APPLE block but called unconditionally in ds4.c. On ROCm builds, the compiler did not see these declarations and causes "implicit declaration" errors.

The variable g_tp_block_ctx was declared under #if !defined(DS4_NO_GPU) && defined(__APPLE__) but used in TP code paths reachable on ROCm, causes undeclared g_tp_block_ctx error.

Build errors:

ds4_tp.c: In function 'ds4_tp_big_gate_exchange':
ds4_tp.c:2095:18: warning: unused variable 't_hs' [-Wunused-variable]
 2095 |     const double t_hs = dbg ? tp_now_sec() : 0.0;
      |                  ^~~~
ds4_tp.c:2090:18: warning: unused variable 't_start' [-Wunused-variable]
 2090 |     const double t_start = dbg ? tp_now_sec() : 0.0;
      |                  ^~~~~~~
ds4.c: In function 'metal_graph_encode_decode_layer_phase':
ds4.c:23350:55: error: implicit declaration of function 'ds4_gpu_dsv4_qkv_norm_defer_kv_next' [-Wimplicit-function-declaration]
23350 |                     if (defer_kv && g->tp_world == 2) ds4_gpu_dsv4_qkv_norm_defer_kv_next();
      |                                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ds4.c:26172:18: error: implicit declaration of function 'ds4_gpu_add_tensor_tp_flag'; did you mean 'ds4_gpu_add_tensor'? [-Wimplicit-function-declaration]
26172 |             ok = ds4_gpu_add_tensor_tp_flag(g->tp_out[tp_slot], metal_graph_shared_out(g),
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~
      |                  ds4_gpu_add_tensor
ds4.c: In function 'metal_graph_verify_suffix_tops_impl':
ds4.c:37047:52: error: 'g_tp_block_ctx' undeclared (first use in this function)
37047 |     const bool tp_block = g->tp_batch_rows != 0 && g_tp_block_ctx != NULL;
      |                                                    ^~~~~~~~~~~~~~
ds4.c:37047:52: note: each undeclared identifier is reported only once for each function it appears in
In file included from ds4_rocm.cu:2:
In file included from ./ds4_rocm.h:6:
In file included from /nix/store/qkd8b0pclwmblj5qa0bqqnrfvrx1m4wj-hipcub-7.2.3/include/hipcub/hipcub.hpp:31:
In file included from /nix/store/qkd8b0pclwmblj5qa0bqqnrfvrx1m4wj-hipcub-7.2.3/include/hipcub/config.hpp:78:
In file included from /nix/store/gjz93g88fm3rkkkk9iplsl8ak38bcarg-rocprim-7.2.3/include/rocprim/device/config_types.hpp:33:
In file included from /nix/store/gjz93g88fm3rkkkk9iplsl8ak38bcarg-rocprim-7.2.3/include/rocprim/device/../detail/various.hpp:26:
In file included from /nix/store/gjz93g88fm3rkkkk9iplsl8ak38bcarg-rocprim-7.2.3/include/rocprim/device/../detail/../type_traits.hpp:24:
In file included from /nix/store/gjz93g88fm3rkkkk9iplsl8ak38bcarg-rocprim-7.2.3/include/rocprim/device/../detail/../type_traits_functions.hpp:25:
/nix/store/gjz93g88fm3rkkkk9iplsl8ak38bcarg-rocprim-7.2.3/include/rocprim/device/../detail/../functional.hpp:37:1: warning: GPU printf warnings for invalid rocPRIM warp operations on Navi GPUs temporarily disabled, due to performance issues with printf. [-W#pragma-messages]
   37 | ROCPRIM_PRAGMA_MESSAGE("GPU printf warnings for invalid rocPRIM warp operations on Navi GPUs "
      | ^
/nix/store/gjz93g88fm3rkkkk9iplsl8ak38bcarg-rocprim-7.2.3/include/rocprim/device/../config.hpp:331:39: note: expanded from macro 'ROCPRIM_PRAGMA_MESSAGE'
  331 |     #define ROCPRIM_PRAGMA_MESSAGE(x) _Pragma(ROCPRIM_STRINGIZE(message(x)))
      |                                       ^
<scratch space>:221:2: note: expanded from here
  221 |  message("GPU printf warnings for invalid rocPRIM warp operations on Navi GPUs " "temporarily disabled, due to performance issues with printf.")
      |  ^
make[1]: *** [Makefile:255: ds4.o] Error 1
make[1]: *** Waiting for unfinished jobs....
Job completed: cuda/mmq/mmvq.rocm.o
1 warning generated when compiling for gfx1151.
Job completed: /build/ds4_rocm-gfx1151-1ae7e3.o
Job completed: ds4_rocm.o
Job completed: /build/ds4_mmq-gfx1151-675de4.o
Job completed: cuda/mmq/ds4_mmq.rocm.o
make[1]: Leaving directory '/build/source'
make: *** [Makefile:187: strix-halo] Error 2

Workaround slop:

diff -ruN ds4-source/ds4.c ds4-patched/ds4.c
--- ds4-source/ds4.c    2026-09-05 11:59:47.829471238 +0900
+++ ds4-patched/ds4.c   2026-09-05 12:05:39.538731145 +0900
@@ -46,7 +46,7 @@
 #include "ds4_tp.h"
 
 /* TP context for the verify-block RDMA window (set with the gate callbacks). */
-#if !defined(DS4_NO_GPU) && defined(__APPLE__)
+#if !defined(DS4_NO_GPU)
 static ds4_tp *g_tp_block_ctx;
 #endif
 
@@ -358,6 +358,26 @@
 int         g_gpu_peer_ok[DS4_MAX_GPUS][DS4_MAX_GPUS];
 #endif
 
+/* ROCm / CUDA stubs: the TP lane-split and KV-norm helpers are Metal-only
+ * optimisations.  Provide no-op stubs so the declarations in ds4_gpu.h are
+ * satisfied without pulling in Apple-specific code. */
+#if !defined(__APPLE__)
+int ds4_gpu_add_tensor_tp_flag(ds4_gpu_tensor *out, const ds4_gpu_tensor *a,
+                               const ds4_gpu_tensor *b, uint32_t n,
+                               uint32_t layer, uint32_t gate) {
+    (void)out; (void)a; (void)b; (void)n; (void)layer; (void)gate;
+    return 1;
+}
+void ds4_gpu_tp_flag_fold_request(uint32_t layer, uint32_t gate) {
+    (void)layer; (void)gate;
+}
+void ds4_gpu_dsv4_qkv_norm_defer_kv_next(void) { }
+int ds4_gpu_kv_norm_task_pending(void) { return 0; }
+int ds4_gpu_kv_norm_task_flush(void) { return 0; }
+int ds4_gpu_kv_norm_task_begin_concurrent(void) { return 0; }
+void ds4_gpu_kv_norm_task_end_concurrent(void) { }
+#endif
+
 #if defined(DS4_NO_GPU)
 /* CPU-only build: even though no multi-tier code is reached, the engine
  * struct still embeds ds4_gpu_config and the global decls in
diff -ruN ds4-source/ds4_gpu.h ds4-patched/ds4_gpu.h
--- ds4-source/ds4_gpu.h    2026-09-05 11:59:47.833471203 +0900
+++ ds4-patched/ds4_gpu.h   2026-09-05 12:04:39.499936763 +0900
@@ -78,6 +78,31 @@
 int ds4_gpu_flush_encoder(void);
 int ds4_gpu_flush_commands(void);
 int ds4_gpu_commands_active(void);
+/* TP lane split and KV-norm helpers used in ds4.c.  On Apple these have full
+ * implementations; on ROCm/CUDA they are stubbed as no-ops (Metal-only
+ * optimisations). */
+int ds4_gpu_add_tensor_tp_flag(
+        ds4_gpu_tensor       *out,
+        const ds4_gpu_tensor *a,
+        const ds4_gpu_tensor *b,
+        uint32_t              n,
+        uint32_t              layer,
+        uint32_t              gate);
+
+/* Register that the next TP partial producer for (layer, gate) may publish
+ * the gate's checked flag itself (taken by the attention output K-slice
+ * matvec when its output is that slot; otherwise ignored). */
+void ds4_gpu_tp_flag_fold_request(uint32_t layer, uint32_t gate);
+
+/* Deferred kv norm task: call before ds4_gpu_dsv4_qkv_rms_norm_kv_rope_fp8_store_tensor
+ * to run only its q task now and fold the kv task into the KV staging
+ * kernel of the same layer; flush runs it standalone if nothing consumed it. */
+void ds4_gpu_dsv4_qkv_norm_defer_kv_next(void);
+int ds4_gpu_kv_norm_task_pending(void);
+int ds4_gpu_kv_norm_task_flush(void);
+int ds4_gpu_kv_norm_task_begin_concurrent(void);
+void ds4_gpu_kv_norm_task_end_concurrent(void);
+
 #ifdef __APPLE__
 int ds4_gpu_parallel_ffn_finish(void);
 void ds4_gpu_parallel_ffn_abort(void);
@@ -137,31 +162,10 @@
         uint32_t              n_expert_used,
         uint32_t              shift_q16);
 
+#endif
 /* out = a + b into this rank's TP slab slot for (layer, gate), publishing the
  * gate's checked flag from the same kernel; falls back to ds4_gpu_add_tensor
  * when the fold does not apply.  Call right before ds4_gpu_tp_gate_encode. */
-int ds4_gpu_add_tensor_tp_flag(
-        ds4_gpu_tensor       *out,
-        const ds4_gpu_tensor *a,
-        const ds4_gpu_tensor *b,
-        uint32_t              n,
-        uint32_t              layer,
-        uint32_t              gate);
-
-/* Register that the next TP partial producer for (layer, gate) may publish
- * the gate's checked flag itself (taken by the attention output K-slice
- * matvec when its output is that slot; otherwise ignored). */
-void ds4_gpu_tp_flag_fold_request(uint32_t layer, uint32_t gate);
-
-/* Deferred kv norm task: call before ds4_gpu_dsv4_qkv_rms_norm_kv_rope_fp8_store_tensor
- * to run only its q task now and fold the kv task into the KV staging
- * kernel of the same layer; flush runs it standalone if nothing consumed it. */
-void ds4_gpu_dsv4_qkv_norm_defer_kv_next(void);
-int ds4_gpu_kv_norm_task_pending(void);
-int ds4_gpu_kv_norm_task_flush(void);
-int ds4_gpu_kv_norm_task_begin_concurrent(void);
-void ds4_gpu_kv_norm_task_end_concurrent(void);
-#endif
 int ds4_gpu_signal_selected_readback_ready(uint64_t *event_value);
 int ds4_gpu_commit_and_wait_selected_readback(uint64_t event_value, const char *label);
 int ds4_gpu_wait_selected_readback_ready(uint64_t event_value, const char *label);

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions