From a133f08ed6453c7c75ae1608fec21c5eb3a4bc53 Mon Sep 17 00:00:00 2001 From: "riseproject-dev[bot]" <330740410+riseproject-dev[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 12:11:41 +0000 Subject: [PATCH 01/17] rerun-sdk: Add versions 0.39.0, 0.40.0 Signed-off-by: riseproject-dev[bot] <330740410+riseproject-dev[bot]@users.noreply.github.com> --- docs/packages/rerun-sdk.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/packages/rerun-sdk.yaml b/docs/packages/rerun-sdk.yaml index 0edf132fab35..affc7b864bbc 100644 --- a/docs/packages/rerun-sdk.yaml +++ b/docs/packages/rerun-sdk.yaml @@ -30,3 +30,5 @@ versions: - filename: rerun_sdk-0.38.1-cp310-abi3-manylinux_2_39_riscv64.whl sha256: 0c0189df56778c3a6256500d6c49f33f83c43e1783119e39932f29c2fafbc96e requires-python: '>=3.10' +- version: 0.39.0 +- version: 0.40.0 From dcb529bb2f60946a0df34acdf5d3cd582998d126 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 23 Oct 2026 12:06:05 +0800 Subject: [PATCH 02/17] rerun-sdk: carry the lance-linalg riscv64 SIMD fallback patch to 0.39.0 --- ...3-lance-linalg-riscv64-simd-fallback.patch | 1400 +++++++++++++++++ 1 file changed, 1400 insertions(+) create mode 100644 patches/rerun-sdk/0.39.0/0003-lance-linalg-riscv64-simd-fallback.patch diff --git a/patches/rerun-sdk/0.39.0/0003-lance-linalg-riscv64-simd-fallback.patch b/patches/rerun-sdk/0.39.0/0003-lance-linalg-riscv64-simd-fallback.patch new file mode 100644 index 000000000000..5ec028114f7c --- /dev/null +++ b/patches/rerun-sdk/0.39.0/0003-lance-linalg-riscv64-simd-fallback.patch @@ -0,0 +1,1400 @@ +Upstream-Status: To upstream [lance-linalg's per-arch SIMD structs (f32x8/f32x16/f64x4/f64x8/i32x8) have no fallback for architectures without a dedicated tier (riscv64 included); not filed upstream per this session's policy against opening external issues/PRs] + +--- lance-linalg-orig/src/simd/f32.rs 2006-07-24 03:21:28 ++++ lance-linalg-10.0.0-riscv64/src/simd/f32.rs 2026-09-07 02:16:55 +@@ -35,6 +35,17 @@ + #[derive(Clone, Copy)] + pub struct f32x8(v8f32); + ++/// 8 of 32-bit `f32` values. Portable scalar fallback for architectures with ++/// no dedicated SIMD tier above (riscv64 included) -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f32x8([f32; 8]); ++ + impl std::fmt::Debug for f32x8 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f32; 8]; +@@ -119,6 +130,27 @@ + ]; + Self::load_unaligned(values.as_ptr()) + } ++ ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ let ptr = slice.as_ptr(); ++ ++ let values = [ ++ *ptr.add(indices[0] as usize), ++ *ptr.add(indices[1] as usize), ++ *ptr.add(indices[2] as usize), ++ *ptr.add(indices[3] as usize), ++ *ptr.add(indices[4] as usize), ++ *ptr.add(indices[5] as usize), ++ *ptr.add(indices[6] as usize), ++ *ptr.add(indices[7] as usize), ++ ]; ++ Self::load_unaligned(values.as_ptr()) ++ } + } + } + +@@ -172,6 +204,14 @@ + unsafe { + Self(transmute(lasx_xvreplgr2vr_w(transmute(val)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 8]) ++ } + } + + fn zeros() -> Self { +@@ -186,6 +226,14 @@ + #[cfg(target_arch = "loongarch64")] + { + Self::splat(0.0) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 8]) + } + } + +@@ -203,6 +251,14 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -219,6 +275,18 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + unsafe fn store(&self, ptr: *mut f32) { +@@ -234,6 +302,14 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + unsafe fn store_unaligned(&self, ptr: *mut f32) { +@@ -249,6 +325,16 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -277,6 +363,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + fn reduce_min(&self) -> f32 { +@@ -311,6 +405,14 @@ + let m2 = lasx_xvfmin_s(transmute(m1), transmute(m2)); + transmute(lasx_xvpickve2gr_w::<0>(transmute(m2))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f32::INFINITY, f32::min) ++ } + } + + fn min(&self, rhs: &Self) -> Self { +@@ -329,6 +431,18 @@ + unsafe { + Self(lasx_xvfmin_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + fn find(&self, val: f32) -> Option { +@@ -362,6 +476,18 @@ + } + } + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ if self.0[i] == val { ++ return Some(i as i32); ++ } ++ } ++ } + None + } + } +@@ -380,6 +506,16 @@ + #[cfg(target_arch = "loongarch64")] + unsafe { + self.0 = lasx_xvfmadd_s(a.0, b.0, self.0); ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } + } + } + } +@@ -404,6 +540,18 @@ + unsafe { + Self(lasx_xvfadd_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -423,6 +571,16 @@ + unsafe { + self.0 = lasx_xvfadd_s(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += rhs.0[i]; ++ } ++ } + } + } + +@@ -446,6 +604,18 @@ + unsafe { + Self(lasx_xvfsub_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -465,6 +635,16 @@ + unsafe { + self.0 = lasx_xvfsub_s(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +@@ -488,6 +668,18 @@ + unsafe { + Self(lasx_xvfmul_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -516,6 +708,16 @@ + #[derive(Clone, Copy)] + pub struct f32x16(v8f32, v8f32); + ++/// 16 of 32-bit `f32` values. Portable scalar fallback -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f32x16([f32; 16]); ++ + impl std::fmt::Debug for f32x16 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f32; 16]; +@@ -561,6 +763,14 @@ + transmute(lasx_xvreplgr2vr_w(transmute(val))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 16]) ++ } + } + + #[inline] +@@ -577,6 +787,14 @@ + { + Self::splat(0.0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 16]) ++ } + } + + #[inline] +@@ -596,6 +814,14 @@ + transmute(lasx_xvld::<32>(transmute(ptr))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -614,6 +840,18 @@ + transmute(lasx_xvld::<0>(transmute(ptr))), + transmute(lasx_xvld::<32>(transmute(ptr))), + ) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) + } + } + +@@ -633,6 +871,14 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + #[inline] +@@ -651,6 +897,16 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -681,6 +937,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + #[inline] +@@ -715,6 +979,14 @@ + let m1 = lasx_xvfmin_s(transmute(m1), transmute(m2)); + transmute(lasx_xvpickve2gr_w::<0>(transmute(m1))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f32::INFINITY, f32::min) ++ } + } + + #[inline] +@@ -736,6 +1008,18 @@ + unsafe { + Self(lasx_xvfmin_s(self.0, rhs.0), lasx_xvfmin_s(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -782,6 +1066,19 @@ + } + None + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ if self.0[i] == val { ++ return Some(i as i32); ++ } ++ } ++ None ++ } + } + } + +@@ -805,6 +1102,16 @@ + self.0 = lasx_xvfmadd_s(a.0, b.0, self.0); + self.1 = lasx_xvfmadd_s(a.1, b.1, self.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } ++ } + } + } + +@@ -829,6 +1136,18 @@ + #[cfg(target_arch = "loongarch64")] + unsafe { + Self(lasx_xvfadd_s(self.0, rhs.0), lasx_xvfadd_s(self.1, rhs.1)) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) + } + } + } +@@ -853,6 +1172,16 @@ + self.0 = lasx_xvfadd_s(self.0, rhs.0); + self.1 = lasx_xvfadd_s(self.1, rhs.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ self.0[i] += rhs.0[i]; ++ } ++ } + } + } + +@@ -877,6 +1206,18 @@ + #[cfg(target_arch = "loongarch64")] + unsafe { + Self(lasx_xvfmul_s(self.0, rhs.0), lasx_xvfmul_s(self.1, rhs.1)) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) + } + } + } +@@ -903,6 +1244,18 @@ + unsafe { + Self(lasx_xvfsub_s(self.0, rhs.0), lasx_xvfsub_s(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -926,6 +1279,16 @@ + self.0 = lasx_xvfsub_s(self.0, rhs.0); + self.1 = lasx_xvfsub_s(self.1, rhs.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +--- lance-linalg-orig/src/simd/f64.rs 2006-07-24 03:21:28 ++++ lance-linalg-10.0.0-riscv64/src/simd/f64.rs 2026-09-07 02:18:45 +@@ -33,6 +33,17 @@ + #[derive(Clone, Copy)] + pub struct f64x4(v4f64); + ++/// Portable scalar fallback for architectures with no dedicated SIMD tier ++/// above (riscv64 included) -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f64x4([f64; 4]); ++ + impl std::fmt::Debug for f64x4 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f64; 4]; +@@ -69,6 +80,14 @@ + unsafe { + Self(transmute(lasx_xvreplgr2vr_d(transmute(val)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 4]) ++ } + } + + fn zeros() -> Self { +@@ -84,6 +103,14 @@ + { + Self::splat(0.0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 4]) ++ } + } + + #[inline] +@@ -100,6 +127,14 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -116,6 +151,18 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + unsafe fn store(&self, ptr: *mut f64) { +@@ -131,6 +178,14 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + unsafe fn store_unaligned(&self, ptr: *mut f64) { +@@ -146,6 +201,16 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -169,6 +234,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + fn reduce_min(&self) -> f64 { +@@ -194,6 +267,14 @@ + .copied() + .fold(f64::INFINITY, f64::min) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f64::INFINITY, f64::min) ++ } + } + + fn min(&self, rhs: &Self) -> Self { +@@ -212,6 +293,18 @@ + unsafe { + Self(lasx_xvfmin_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + fn find(&self, val: f64) -> Option { +@@ -241,6 +334,16 @@ + unsafe { + self.0 = lasx_xvfmadd_d(a.0, b.0, self.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..4 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } ++ } + } + } + +@@ -264,6 +367,18 @@ + unsafe { + Self(lasx_xvfadd_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -283,6 +398,16 @@ + unsafe { + self.0 = lasx_xvfadd_d(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..4 { ++ self.0[i] += rhs.0[i]; ++ } ++ } + } + } + +@@ -306,6 +431,18 @@ + unsafe { + Self(lasx_xvfsub_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -325,6 +462,16 @@ + unsafe { + self.0 = lasx_xvfsub_d(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..4 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +@@ -348,6 +495,18 @@ + unsafe { + Self(lasx_xvfmul_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -377,6 +536,16 @@ + #[derive(Clone, Copy)] + pub struct f64x8(v4f64, v4f64); + ++/// Portable scalar fallback -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f64x8([f64; 8]); ++ + impl std::fmt::Debug for f64x8 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f64; 8]; +@@ -416,6 +585,14 @@ + let v = transmute(lasx_xvreplgr2vr_d(transmute(val))); + Self(v, v) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 8]) ++ } + } + + #[inline] +@@ -432,6 +609,14 @@ + { + Self::splat(0.0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 8]) ++ } + } + + #[inline] +@@ -451,6 +636,14 @@ + transmute(lasx_xvld::<32>(transmute(ptr))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -470,6 +663,18 @@ + transmute(lasx_xvld::<32>(transmute(ptr))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -489,6 +694,14 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + #[inline] +@@ -508,6 +721,16 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -531,6 +754,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + #[inline] +@@ -557,6 +788,14 @@ + .iter() + .copied() + .fold(f64::INFINITY, f64::min) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f64::INFINITY, f64::min) + } + } + +@@ -577,6 +816,18 @@ + unsafe { + Self(lasx_xvfmin_d(self.0, rhs.0), lasx_xvfmin_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -612,6 +863,16 @@ + self.0 = lasx_xvfmadd_d(a.0, b.0, self.0); + self.1 = lasx_xvfmadd_d(a.1, b.1, self.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } ++ } + } + } + +@@ -635,6 +896,18 @@ + unsafe { + Self(lasx_xvfadd_d(self.0, rhs.0), lasx_xvfadd_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -657,6 +930,16 @@ + unsafe { + self.0 = lasx_xvfadd_d(self.0, rhs.0); + self.1 = lasx_xvfadd_d(self.1, rhs.1); ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += rhs.0[i]; ++ } + } + } + } +@@ -681,6 +964,18 @@ + unsafe { + Self(lasx_xvfmul_d(self.0, rhs.0), lasx_xvfmul_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -704,6 +999,18 @@ + unsafe { + Self(lasx_xvfsub_d(self.0, rhs.0), lasx_xvfsub_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -727,6 +1034,16 @@ + self.0 = lasx_xvfsub_d(self.0, rhs.0); + self.1 = lasx_xvfsub_d(self.1, rhs.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +--- lance-linalg-orig/src/simd/i32.rs 2006-07-24 03:21:28 ++++ lance-linalg-10.0.0-riscv64/src/simd/i32.rs 2026-09-07 02:19:36 +@@ -30,6 +30,17 @@ + #[derive(Clone, Copy)] + pub struct i32x8(v8i32); + ++/// Portable scalar fallback for architectures with no dedicated SIMD tier ++/// above (riscv64 included) -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct i32x8(pub(crate) [i32; 8]); ++ + impl std::fmt::Debug for i32x8 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0; 8]; +@@ -67,6 +78,14 @@ + unsafe { + Self(lasx_xvreplgr2vr_w(val)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 8]) ++ } + } + + #[inline] +@@ -83,6 +102,14 @@ + { + Self::splat(0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0; 8]) ++ } + } + + #[inline] +@@ -99,6 +126,14 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -115,6 +150,18 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -135,6 +182,16 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + fn reduce_sum(&self) -> i32 { +@@ -151,6 +208,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + fn reduce_min(&self) -> i32 { +@@ -173,6 +238,18 @@ + unsafe { + Self(lasx_xvmin_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + fn find(&self, val: i32) -> Option { +@@ -206,6 +283,18 @@ + } + } + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ if self.0[i] == val { ++ return Some(i as i32); ++ } ++ } ++ } + None + } + } +@@ -230,6 +319,18 @@ + unsafe { + Self(lasx_xvadd_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_add(rhs.0[i]); ++ } ++ Self(result) ++ } + } + } + +@@ -249,6 +350,16 @@ + unsafe { + self.0 = lasx_xvadd_w(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] = self.0[i].wrapping_add(rhs.0[i]); ++ } ++ } + } + } + +@@ -272,6 +383,18 @@ + unsafe { + Self(lasx_xvsub_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_sub(rhs.0[i]); ++ } ++ Self(result) ++ } + } + } + +@@ -291,6 +414,16 @@ + unsafe { + self.0 = lasx_xvsub_w(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] = self.0[i].wrapping_sub(rhs.0[i]); ++ } ++ } + } + } + +@@ -314,6 +447,18 @@ + unsafe { + Self(lasx_xvmul_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_mul(rhs.0[i]); ++ } ++ Self(result) ++ } + } + } + From 97f0d024b84aff9cddb88c4878c60bf8330e4c35 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 23 Oct 2026 12:07:20 +0800 Subject: [PATCH 03/17] rerun-sdk: carry the lance-linalg riscv64 SIMD fallback patch to 0.40.0 --- ...3-lance-linalg-riscv64-simd-fallback.patch | 1400 +++++++++++++++++ 1 file changed, 1400 insertions(+) create mode 100644 patches/rerun-sdk/0.40.0/0003-lance-linalg-riscv64-simd-fallback.patch diff --git a/patches/rerun-sdk/0.40.0/0003-lance-linalg-riscv64-simd-fallback.patch b/patches/rerun-sdk/0.40.0/0003-lance-linalg-riscv64-simd-fallback.patch new file mode 100644 index 000000000000..5ec028114f7c --- /dev/null +++ b/patches/rerun-sdk/0.40.0/0003-lance-linalg-riscv64-simd-fallback.patch @@ -0,0 +1,1400 @@ +Upstream-Status: To upstream [lance-linalg's per-arch SIMD structs (f32x8/f32x16/f64x4/f64x8/i32x8) have no fallback for architectures without a dedicated tier (riscv64 included); not filed upstream per this session's policy against opening external issues/PRs] + +--- lance-linalg-orig/src/simd/f32.rs 2006-07-24 03:21:28 ++++ lance-linalg-10.0.0-riscv64/src/simd/f32.rs 2026-09-07 02:16:55 +@@ -35,6 +35,17 @@ + #[derive(Clone, Copy)] + pub struct f32x8(v8f32); + ++/// 8 of 32-bit `f32` values. Portable scalar fallback for architectures with ++/// no dedicated SIMD tier above (riscv64 included) -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f32x8([f32; 8]); ++ + impl std::fmt::Debug for f32x8 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f32; 8]; +@@ -119,6 +130,27 @@ + ]; + Self::load_unaligned(values.as_ptr()) + } ++ ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ let ptr = slice.as_ptr(); ++ ++ let values = [ ++ *ptr.add(indices[0] as usize), ++ *ptr.add(indices[1] as usize), ++ *ptr.add(indices[2] as usize), ++ *ptr.add(indices[3] as usize), ++ *ptr.add(indices[4] as usize), ++ *ptr.add(indices[5] as usize), ++ *ptr.add(indices[6] as usize), ++ *ptr.add(indices[7] as usize), ++ ]; ++ Self::load_unaligned(values.as_ptr()) ++ } + } + } + +@@ -172,6 +204,14 @@ + unsafe { + Self(transmute(lasx_xvreplgr2vr_w(transmute(val)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 8]) ++ } + } + + fn zeros() -> Self { +@@ -186,6 +226,14 @@ + #[cfg(target_arch = "loongarch64")] + { + Self::splat(0.0) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 8]) + } + } + +@@ -203,6 +251,14 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -219,6 +275,18 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + unsafe fn store(&self, ptr: *mut f32) { +@@ -234,6 +302,14 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + unsafe fn store_unaligned(&self, ptr: *mut f32) { +@@ -249,6 +325,16 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -277,6 +363,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + fn reduce_min(&self) -> f32 { +@@ -311,6 +405,14 @@ + let m2 = lasx_xvfmin_s(transmute(m1), transmute(m2)); + transmute(lasx_xvpickve2gr_w::<0>(transmute(m2))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f32::INFINITY, f32::min) ++ } + } + + fn min(&self, rhs: &Self) -> Self { +@@ -329,6 +431,18 @@ + unsafe { + Self(lasx_xvfmin_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + fn find(&self, val: f32) -> Option { +@@ -362,6 +476,18 @@ + } + } + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ if self.0[i] == val { ++ return Some(i as i32); ++ } ++ } ++ } + None + } + } +@@ -380,6 +506,16 @@ + #[cfg(target_arch = "loongarch64")] + unsafe { + self.0 = lasx_xvfmadd_s(a.0, b.0, self.0); ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } + } + } + } +@@ -404,6 +540,18 @@ + unsafe { + Self(lasx_xvfadd_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -423,6 +571,16 @@ + unsafe { + self.0 = lasx_xvfadd_s(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += rhs.0[i]; ++ } ++ } + } + } + +@@ -446,6 +604,18 @@ + unsafe { + Self(lasx_xvfsub_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -465,6 +635,16 @@ + unsafe { + self.0 = lasx_xvfsub_s(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +@@ -488,6 +668,18 @@ + unsafe { + Self(lasx_xvfmul_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -516,6 +708,16 @@ + #[derive(Clone, Copy)] + pub struct f32x16(v8f32, v8f32); + ++/// 16 of 32-bit `f32` values. Portable scalar fallback -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f32x16([f32; 16]); ++ + impl std::fmt::Debug for f32x16 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f32; 16]; +@@ -561,6 +763,14 @@ + transmute(lasx_xvreplgr2vr_w(transmute(val))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 16]) ++ } + } + + #[inline] +@@ -577,6 +787,14 @@ + { + Self::splat(0.0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 16]) ++ } + } + + #[inline] +@@ -596,6 +814,14 @@ + transmute(lasx_xvld::<32>(transmute(ptr))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -614,6 +840,18 @@ + transmute(lasx_xvld::<0>(transmute(ptr))), + transmute(lasx_xvld::<32>(transmute(ptr))), + ) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) + } + } + +@@ -633,6 +871,14 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + #[inline] +@@ -651,6 +897,16 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -681,6 +937,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + #[inline] +@@ -715,6 +979,14 @@ + let m1 = lasx_xvfmin_s(transmute(m1), transmute(m2)); + transmute(lasx_xvpickve2gr_w::<0>(transmute(m1))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f32::INFINITY, f32::min) ++ } + } + + #[inline] +@@ -736,6 +1008,18 @@ + unsafe { + Self(lasx_xvfmin_s(self.0, rhs.0), lasx_xvfmin_s(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -782,6 +1066,19 @@ + } + None + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ if self.0[i] == val { ++ return Some(i as i32); ++ } ++ } ++ None ++ } + } + } + +@@ -805,6 +1102,16 @@ + self.0 = lasx_xvfmadd_s(a.0, b.0, self.0); + self.1 = lasx_xvfmadd_s(a.1, b.1, self.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } ++ } + } + } + +@@ -829,6 +1136,18 @@ + #[cfg(target_arch = "loongarch64")] + unsafe { + Self(lasx_xvfadd_s(self.0, rhs.0), lasx_xvfadd_s(self.1, rhs.1)) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) + } + } + } +@@ -853,6 +1172,16 @@ + self.0 = lasx_xvfadd_s(self.0, rhs.0); + self.1 = lasx_xvfadd_s(self.1, rhs.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ self.0[i] += rhs.0[i]; ++ } ++ } + } + } + +@@ -877,6 +1206,18 @@ + #[cfg(target_arch = "loongarch64")] + unsafe { + Self(lasx_xvfmul_s(self.0, rhs.0), lasx_xvfmul_s(self.1, rhs.1)) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) + } + } + } +@@ -903,6 +1244,18 @@ + unsafe { + Self(lasx_xvfsub_s(self.0, rhs.0), lasx_xvfsub_s(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -926,6 +1279,16 @@ + self.0 = lasx_xvfsub_s(self.0, rhs.0); + self.1 = lasx_xvfsub_s(self.1, rhs.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +--- lance-linalg-orig/src/simd/f64.rs 2006-07-24 03:21:28 ++++ lance-linalg-10.0.0-riscv64/src/simd/f64.rs 2026-09-07 02:18:45 +@@ -33,6 +33,17 @@ + #[derive(Clone, Copy)] + pub struct f64x4(v4f64); + ++/// Portable scalar fallback for architectures with no dedicated SIMD tier ++/// above (riscv64 included) -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f64x4([f64; 4]); ++ + impl std::fmt::Debug for f64x4 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f64; 4]; +@@ -69,6 +80,14 @@ + unsafe { + Self(transmute(lasx_xvreplgr2vr_d(transmute(val)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 4]) ++ } + } + + fn zeros() -> Self { +@@ -84,6 +103,14 @@ + { + Self::splat(0.0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 4]) ++ } + } + + #[inline] +@@ -100,6 +127,14 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -116,6 +151,18 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + unsafe fn store(&self, ptr: *mut f64) { +@@ -131,6 +178,14 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + unsafe fn store_unaligned(&self, ptr: *mut f64) { +@@ -146,6 +201,16 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -169,6 +234,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + fn reduce_min(&self) -> f64 { +@@ -194,6 +267,14 @@ + .copied() + .fold(f64::INFINITY, f64::min) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f64::INFINITY, f64::min) ++ } + } + + fn min(&self, rhs: &Self) -> Self { +@@ -212,6 +293,18 @@ + unsafe { + Self(lasx_xvfmin_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + fn find(&self, val: f64) -> Option { +@@ -241,6 +334,16 @@ + unsafe { + self.0 = lasx_xvfmadd_d(a.0, b.0, self.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..4 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } ++ } + } + } + +@@ -264,6 +367,18 @@ + unsafe { + Self(lasx_xvfadd_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -283,6 +398,16 @@ + unsafe { + self.0 = lasx_xvfadd_d(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..4 { ++ self.0[i] += rhs.0[i]; ++ } ++ } + } + } + +@@ -306,6 +431,18 @@ + unsafe { + Self(lasx_xvfsub_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -325,6 +462,16 @@ + unsafe { + self.0 = lasx_xvfsub_d(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..4 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +@@ -348,6 +495,18 @@ + unsafe { + Self(lasx_xvfmul_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -377,6 +536,16 @@ + #[derive(Clone, Copy)] + pub struct f64x8(v4f64, v4f64); + ++/// Portable scalar fallback -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f64x8([f64; 8]); ++ + impl std::fmt::Debug for f64x8 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f64; 8]; +@@ -416,6 +585,14 @@ + let v = transmute(lasx_xvreplgr2vr_d(transmute(val))); + Self(v, v) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 8]) ++ } + } + + #[inline] +@@ -432,6 +609,14 @@ + { + Self::splat(0.0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 8]) ++ } + } + + #[inline] +@@ -451,6 +636,14 @@ + transmute(lasx_xvld::<32>(transmute(ptr))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -470,6 +663,18 @@ + transmute(lasx_xvld::<32>(transmute(ptr))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -489,6 +694,14 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + #[inline] +@@ -508,6 +721,16 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -531,6 +754,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + #[inline] +@@ -557,6 +788,14 @@ + .iter() + .copied() + .fold(f64::INFINITY, f64::min) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f64::INFINITY, f64::min) + } + } + +@@ -577,6 +816,18 @@ + unsafe { + Self(lasx_xvfmin_d(self.0, rhs.0), lasx_xvfmin_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -612,6 +863,16 @@ + self.0 = lasx_xvfmadd_d(a.0, b.0, self.0); + self.1 = lasx_xvfmadd_d(a.1, b.1, self.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } ++ } + } + } + +@@ -635,6 +896,18 @@ + unsafe { + Self(lasx_xvfadd_d(self.0, rhs.0), lasx_xvfadd_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -657,6 +930,16 @@ + unsafe { + self.0 = lasx_xvfadd_d(self.0, rhs.0); + self.1 = lasx_xvfadd_d(self.1, rhs.1); ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += rhs.0[i]; ++ } + } + } + } +@@ -681,6 +964,18 @@ + unsafe { + Self(lasx_xvfmul_d(self.0, rhs.0), lasx_xvfmul_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -704,6 +999,18 @@ + unsafe { + Self(lasx_xvfsub_d(self.0, rhs.0), lasx_xvfsub_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -727,6 +1034,16 @@ + self.0 = lasx_xvfsub_d(self.0, rhs.0); + self.1 = lasx_xvfsub_d(self.1, rhs.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +--- lance-linalg-orig/src/simd/i32.rs 2006-07-24 03:21:28 ++++ lance-linalg-10.0.0-riscv64/src/simd/i32.rs 2026-09-07 02:19:36 +@@ -30,6 +30,17 @@ + #[derive(Clone, Copy)] + pub struct i32x8(v8i32); + ++/// Portable scalar fallback for architectures with no dedicated SIMD tier ++/// above (riscv64 included) -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct i32x8(pub(crate) [i32; 8]); ++ + impl std::fmt::Debug for i32x8 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0; 8]; +@@ -67,6 +78,14 @@ + unsafe { + Self(lasx_xvreplgr2vr_w(val)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 8]) ++ } + } + + #[inline] +@@ -83,6 +102,14 @@ + { + Self::splat(0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0; 8]) ++ } + } + + #[inline] +@@ -99,6 +126,14 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -115,6 +150,18 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -135,6 +182,16 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + fn reduce_sum(&self) -> i32 { +@@ -151,6 +208,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + fn reduce_min(&self) -> i32 { +@@ -173,6 +238,18 @@ + unsafe { + Self(lasx_xvmin_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + fn find(&self, val: i32) -> Option { +@@ -206,6 +283,18 @@ + } + } + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ if self.0[i] == val { ++ return Some(i as i32); ++ } ++ } ++ } + None + } + } +@@ -230,6 +319,18 @@ + unsafe { + Self(lasx_xvadd_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_add(rhs.0[i]); ++ } ++ Self(result) ++ } + } + } + +@@ -249,6 +350,16 @@ + unsafe { + self.0 = lasx_xvadd_w(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] = self.0[i].wrapping_add(rhs.0[i]); ++ } ++ } + } + } + +@@ -272,6 +383,18 @@ + unsafe { + Self(lasx_xvsub_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_sub(rhs.0[i]); ++ } ++ Self(result) ++ } + } + } + +@@ -291,6 +414,16 @@ + unsafe { + self.0 = lasx_xvsub_w(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] = self.0[i].wrapping_sub(rhs.0[i]); ++ } ++ } + } + } + +@@ -314,6 +447,18 @@ + unsafe { + Self(lasx_xvmul_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_mul(rhs.0[i]); ++ } ++ Self(result) ++ } + } + } + From 29dd44a64ceb930042157ba9a4f855eff88d2cfd Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 23 Oct 2026 12:07:26 +0800 Subject: [PATCH 04/17] rerun-sdk: carry the lance-core riscv64 SIMD fallback patch to 0.39.0 --- ...001-lance-core-riscv64-simd-fallback.patch | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 patches/rerun-sdk/0.39.0/0001-lance-core-riscv64-simd-fallback.patch diff --git a/patches/rerun-sdk/0.39.0/0001-lance-core-riscv64-simd-fallback.patch b/patches/rerun-sdk/0.39.0/0001-lance-core-riscv64-simd-fallback.patch new file mode 100644 index 000000000000..9ed0d008314d --- /dev/null +++ b/patches/rerun-sdk/0.39.0/0001-lance-core-riscv64-simd-fallback.patch @@ -0,0 +1,22 @@ +Upstream-Status: To upstream [lance's own SIMD-tier cfg arms have no catch-all for architectures without a dedicated tier (riscv64 included); not filed upstream per this session's policy against opening external issues/PRs] + +--- a/src/utils/cpu.rs ++++ b/src/utils/cpu.rs +@@ -210,6 +210,17 @@ + SimdSupport::None + } + } ++ // riscv64 (and any other architecture without a dedicated tier above) has ++ // no SIMD kernels in lance yet; upstream's cfg arms have no catch-all, so ++ // this closure otherwise evaluates to `()` here instead of `SimdSupport`. ++ #[cfg(not(any( ++ target_arch = "aarch64", ++ target_arch = "x86_64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ SimdSupport::None ++ } + }); + + #[cfg(target_arch = "x86_64")] From def333f130229b20e32520a3c8451282cf5ce323 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 23 Oct 2026 12:07:29 +0800 Subject: [PATCH 05/17] rerun-sdk: carry the lance-core riscv64 SIMD fallback patch to 0.40.0 --- ...001-lance-core-riscv64-simd-fallback.patch | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 patches/rerun-sdk/0.40.0/0001-lance-core-riscv64-simd-fallback.patch diff --git a/patches/rerun-sdk/0.40.0/0001-lance-core-riscv64-simd-fallback.patch b/patches/rerun-sdk/0.40.0/0001-lance-core-riscv64-simd-fallback.patch new file mode 100644 index 000000000000..9ed0d008314d --- /dev/null +++ b/patches/rerun-sdk/0.40.0/0001-lance-core-riscv64-simd-fallback.patch @@ -0,0 +1,22 @@ +Upstream-Status: To upstream [lance's own SIMD-tier cfg arms have no catch-all for architectures without a dedicated tier (riscv64 included); not filed upstream per this session's policy against opening external issues/PRs] + +--- a/src/utils/cpu.rs ++++ b/src/utils/cpu.rs +@@ -210,6 +210,17 @@ + SimdSupport::None + } + } ++ // riscv64 (and any other architecture without a dedicated tier above) has ++ // no SIMD kernels in lance yet; upstream's cfg arms have no catch-all, so ++ // this closure otherwise evaluates to `()` here instead of `SimdSupport`. ++ #[cfg(not(any( ++ target_arch = "aarch64", ++ target_arch = "x86_64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ SimdSupport::None ++ } + }); + + #[cfg(target_arch = "x86_64")] From 8420b31a74ecc11f1923f4b655d343b1957c9bd0 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 23 Oct 2026 12:07:38 +0800 Subject: [PATCH 06/17] rerun-sdk: carry the cargo [patch] wiring for lance crates to 0.39.0 --- ...cargo-patch-lance-crates-for-riscv64.patch | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 patches/rerun-sdk/0.39.0/0002-cargo-patch-lance-crates-for-riscv64.patch diff --git a/patches/rerun-sdk/0.39.0/0002-cargo-patch-lance-crates-for-riscv64.patch b/patches/rerun-sdk/0.39.0/0002-cargo-patch-lance-crates-for-riscv64.patch new file mode 100644 index 000000000000..9a4144e5adf0 --- /dev/null +++ b/patches/rerun-sdk/0.39.0/0002-cargo-patch-lance-crates-for-riscv64.patch @@ -0,0 +1,37 @@ +Upstream-Status: Inappropriate [points at a directory this port's workflow materializes at runtime; not a fix rerun itself would carry] + +diff --git a/Cargo.lock b/Cargo.lock +index f4ad0ef..620282b 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -5693,8 +5693,6 @@ dependencies = [ + [[package]] + name = "lance-core" + version = "10.0.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "21f4fd872bfe948150a6878d983327c4f150dc1b629e94ae7677310fa6a3f35f" + dependencies = [ + "arrow-array", + "arrow-buffer", +@@ -5992,8 +5990,6 @@ dependencies = [ + [[package]] + name = "lance-linalg" + version = "10.0.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "5a1dd49fdf61da86650dc335fbe1f239803f9d73bc2bc5ffbc0c905dd8809892" + dependencies = [ + "arrow-array", + "arrow-buffer", +diff --git a/Cargo.toml b/Cargo.toml +index 3717ef5..bf40033 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -868,6 +868,8 @@ self_named_module_files = "allow" # Disabled waiting on https://github.com/rust- + significant_drop_tightening = "allow" # An update of parking_lot made this trigger in a lot of places. TODO(emilk): fix those places + + [patch.crates-io] ++lance-core = { path = "lance-core-10.0.0-riscv64" } ++lance-linalg = { path = "lance-linalg-10.0.0-riscv64" } + # Try to avoid patching crates! It prevents us from publishing the crates on crates.io. + # If you do patch always prefer to patch to the trunk branch of the upstream repo (i.e. `main`, `master`, …). + # If that is not possible, patch to a branch that has a PR open on the upstream repo. From e16e994033668196dda61fb401db054e5feb6241 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 23 Oct 2026 12:07:45 +0800 Subject: [PATCH 07/17] rerun-sdk: carry the cargo [patch] wiring for lance crates to 0.40.0 --- ...cargo-patch-lance-crates-for-riscv64.patch | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 patches/rerun-sdk/0.40.0/0002-cargo-patch-lance-crates-for-riscv64.patch diff --git a/patches/rerun-sdk/0.40.0/0002-cargo-patch-lance-crates-for-riscv64.patch b/patches/rerun-sdk/0.40.0/0002-cargo-patch-lance-crates-for-riscv64.patch new file mode 100644 index 000000000000..9a4144e5adf0 --- /dev/null +++ b/patches/rerun-sdk/0.40.0/0002-cargo-patch-lance-crates-for-riscv64.patch @@ -0,0 +1,37 @@ +Upstream-Status: Inappropriate [points at a directory this port's workflow materializes at runtime; not a fix rerun itself would carry] + +diff --git a/Cargo.lock b/Cargo.lock +index f4ad0ef..620282b 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -5693,8 +5693,6 @@ dependencies = [ + [[package]] + name = "lance-core" + version = "10.0.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "21f4fd872bfe948150a6878d983327c4f150dc1b629e94ae7677310fa6a3f35f" + dependencies = [ + "arrow-array", + "arrow-buffer", +@@ -5992,8 +5990,6 @@ dependencies = [ + [[package]] + name = "lance-linalg" + version = "10.0.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "5a1dd49fdf61da86650dc335fbe1f239803f9d73bc2bc5ffbc0c905dd8809892" + dependencies = [ + "arrow-array", + "arrow-buffer", +diff --git a/Cargo.toml b/Cargo.toml +index 3717ef5..bf40033 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -868,6 +868,8 @@ self_named_module_files = "allow" # Disabled waiting on https://github.com/rust- + significant_drop_tightening = "allow" # An update of parking_lot made this trigger in a lot of places. TODO(emilk): fix those places + + [patch.crates-io] ++lance-core = { path = "lance-core-10.0.0-riscv64" } ++lance-linalg = { path = "lance-linalg-10.0.0-riscv64" } + # Try to avoid patching crates! It prevents us from publishing the crates on crates.io. + # If you do patch always prefer to patch to the trunk branch of the upstream repo (i.e. `main`, `master`, …). + # If that is not possible, patch to a branch that has a PR open on the upstream repo. From 83909a22340b2812c50f5afd1dd331211ce6e2e2 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 23 Oct 2026 12:07:57 +0800 Subject: [PATCH 08/17] rerun-sdk: keep the 0.39.0 cargo [patch] file byte-identical to 0.38.1 --- .../0.39.0/0002-cargo-patch-lance-crates-for-riscv64.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/rerun-sdk/0.39.0/0002-cargo-patch-lance-crates-for-riscv64.patch b/patches/rerun-sdk/0.39.0/0002-cargo-patch-lance-crates-for-riscv64.patch index 9a4144e5adf0..0f53cb10c844 100644 --- a/patches/rerun-sdk/0.39.0/0002-cargo-patch-lance-crates-for-riscv64.patch +++ b/patches/rerun-sdk/0.39.0/0002-cargo-patch-lance-crates-for-riscv64.patch @@ -28,7 +28,7 @@ index 3717ef5..bf40033 100644 +++ b/Cargo.toml @@ -868,6 +868,8 @@ self_named_module_files = "allow" # Disabled waiting on https://github.com/rust- significant_drop_tightening = "allow" # An update of parking_lot made this trigger in a lot of places. TODO(emilk): fix those places - + [patch.crates-io] +lance-core = { path = "lance-core-10.0.0-riscv64" } +lance-linalg = { path = "lance-linalg-10.0.0-riscv64" } From c4fb7b06017ce636d09082e36633962f1879731e Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 23 Oct 2026 12:08:08 +0800 Subject: [PATCH 09/17] rerun-sdk: keep the 0.40.0 cargo [patch] file byte-identical to 0.38.1 --- .../0.40.0/0002-cargo-patch-lance-crates-for-riscv64.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/rerun-sdk/0.40.0/0002-cargo-patch-lance-crates-for-riscv64.patch b/patches/rerun-sdk/0.40.0/0002-cargo-patch-lance-crates-for-riscv64.patch index 9a4144e5adf0..0f53cb10c844 100644 --- a/patches/rerun-sdk/0.40.0/0002-cargo-patch-lance-crates-for-riscv64.patch +++ b/patches/rerun-sdk/0.40.0/0002-cargo-patch-lance-crates-for-riscv64.patch @@ -28,7 +28,7 @@ index 3717ef5..bf40033 100644 +++ b/Cargo.toml @@ -868,6 +868,8 @@ self_named_module_files = "allow" # Disabled waiting on https://github.com/rust- significant_drop_tightening = "allow" # An update of parking_lot made this trigger in a lot of places. TODO(emilk): fix those places - + [patch.crates-io] +lance-core = { path = "lance-core-10.0.0-riscv64" } +lance-linalg = { path = "lance-linalg-10.0.0-riscv64" } From d0941126816b5a4e1d47e38b11e5bf987c1c583a Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Tue, 27 Oct 2026 13:46:58 +0100 Subject: [PATCH 10/17] rerun-sdk: ignore test files that need the unbuilt rerun-cli or av 0.39.0 adds tests/integration/test_rrd_route.py, which shells out to `rerun rrd route` and fails with "Could not find rerun binary" because rerun-cli is not built here (same reason as test_headless_viewer.py). 0.40.0 adds tests/unit/test_dataloader_video_conversion.py and test_dataloader_video_rgb_bank.py, which import av (no riscv64 wheel, same as test_dataloader_video.py) and abort collection. Ignore the three files alongside their existing siblings. --- .github/workflows/build-rerun-sdk.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-rerun-sdk.yml b/.github/workflows/build-rerun-sdk.yml index 1f5056d3336e..471b114087ef 100644 --- a/.github/workflows/build-rerun-sdk.yml +++ b/.github/workflows/build-rerun-sdk.yml @@ -245,7 +245,10 @@ jobs: # upstream-labelled sandboxes/integration suites, not the SDK's # regression tests. test_headless_viewer.py spawns the (unbuilt) # rerun-cli binary, same as test_rrd_reader_multi_store.py's - # session fixture (`rerun rrd merge`). test_server.py needs the + # session fixture (`rerun rrd merge`); test_rrd_route.py (0.39+) + # shells out to `rerun rrd route` the same way, and + # test_dataloader_video_conversion.py / test_dataloader_video_rgb_bank.py + # (0.40+) import av, like test_dataloader_video.py. test_server.py needs the # `datafusion` Python package (no riscv64 wheel anywhere, same as # test_datafusion_utils.py and, new in 0.38.x, test_chunk_index.py, # which imports `from datafusion import col, lit` at module scope); @@ -288,10 +291,13 @@ jobs: --ignore=tests/integration/test_chunk_store_reader.py --ignore=tests/integration/test_chunk_index.py --ignore=tests/integration/test_rrd_reader_multi_store.py + --ignore=tests/integration/test_rrd_route.py --ignore=tests/unit/test_dataloader_decoder_helpers.py --ignore=tests/unit/test_dataloader_manifest.py --ignore=tests/unit/test_dataloader_query_indices.py --ignore=tests/unit/test_dataloader_skip_incomplete.py + --ignore=tests/unit/test_dataloader_video_conversion.py + --ignore=tests/unit/test_dataloader_video_rgb_bank.py --ignore=tests/unit/test_sample_index.py --ignore=tests/unit/test_datafusion_utils.py --ignore=tests/unit/test_viewer_client.py From 675387471c691f4c4d59e983dac51bc44370f1d0 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Wed, 28 Oct 2026 13:00:27 +0100 Subject: [PATCH 11/17] rerun-sdk: deselect test_gop_batching (needs the datafusion package) 0.40.0 adds tests/integration/test_optimized_stream.py::test_gop_batching, which goes through ChunkStore.reader() and fails with ModuleNotFoundError: No module named 'datafusion', like the other test_optimized_stream tests already deselected. The wheel built and 1091 other tests passed. --- .github/workflows/build-rerun-sdk.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-rerun-sdk.yml b/.github/workflows/build-rerun-sdk.yml index 471b114087ef..77e5c7df7767 100644 --- a/.github/workflows/build-rerun-sdk.yml +++ b/.github/workflows/build-rerun-sdk.yml @@ -279,6 +279,8 @@ jobs: # test_laziness, test_own_chunk_rules) don't touch `.reader()` and # pass, so they're deselected individually rather than the whole # file ignored. + # 0.40.0 adds test_gop_batching, which fails the same way (it reaches + # `ChunkStore.reader()`), so it is deselected too. CIBW_TEST_COMMAND: >- cd rerun_py && python -c "import rerun_bindings.rerun_bindings as m; assert m.__file__.endswith('.so'), m.__file__" && @@ -312,6 +314,7 @@ jobs: --deselect=tests/integration/test_optimized_stream.py::test_chunk_store_path --deselect=tests/integration/test_optimized_stream.py::test_sweep_order_observable --deselect=tests/integration/test_optimized_stream.py::test_own_chunk_default + --deselect=tests/integration/test_optimized_stream.py::test_gop_batching - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: From 25a4745fc40fdfab5067c87316f35780969c97bd Mon Sep 17 00:00:00 2001 From: "riseproject-dev[bot]" <330740410+riseproject-dev[bot]@users.noreply.github.com> Date: Thu, 29 Oct 2026 09:06:20 +0000 Subject: [PATCH 12/17] rerun-sdk: Add versions 0.39.0, 0.40.0, 0.41.0 Signed-off-by: riseproject-dev[bot] <330740410+riseproject-dev[bot]@users.noreply.github.com> --- docs/packages/rerun-sdk.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/packages/rerun-sdk.yaml b/docs/packages/rerun-sdk.yaml index affc7b864bbc..004198440b2e 100644 --- a/docs/packages/rerun-sdk.yaml +++ b/docs/packages/rerun-sdk.yaml @@ -32,3 +32,4 @@ versions: requires-python: '>=3.10' - version: 0.39.0 - version: 0.40.0 +- version: 0.41.0 From fa4c3e8992bc1e36302c5d3b06be867b9e750d2c Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 31 Oct 2026 00:52:36 +0100 Subject: [PATCH 13/17] rerun-sdk: copy the lance riscv64 patches to 0.41.0 0.41.0 still pins lance-core and lance-linalg 10.0.0, the same as 0.40.0, so the three patches apply unchanged; without a 0.41.0 directory the vendoring step fails on the missing patch file. --- ...001-lance-core-riscv64-simd-fallback.patch | 22 +++++++++++ ...cargo-patch-lance-crates-for-riscv64.patch | 37 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 patches/rerun-sdk/0.41.0/0001-lance-core-riscv64-simd-fallback.patch create mode 100644 patches/rerun-sdk/0.41.0/0002-cargo-patch-lance-crates-for-riscv64.patch diff --git a/patches/rerun-sdk/0.41.0/0001-lance-core-riscv64-simd-fallback.patch b/patches/rerun-sdk/0.41.0/0001-lance-core-riscv64-simd-fallback.patch new file mode 100644 index 000000000000..9ed0d008314d --- /dev/null +++ b/patches/rerun-sdk/0.41.0/0001-lance-core-riscv64-simd-fallback.patch @@ -0,0 +1,22 @@ +Upstream-Status: To upstream [lance's own SIMD-tier cfg arms have no catch-all for architectures without a dedicated tier (riscv64 included); not filed upstream per this session's policy against opening external issues/PRs] + +--- a/src/utils/cpu.rs ++++ b/src/utils/cpu.rs +@@ -210,6 +210,17 @@ + SimdSupport::None + } + } ++ // riscv64 (and any other architecture without a dedicated tier above) has ++ // no SIMD kernels in lance yet; upstream's cfg arms have no catch-all, so ++ // this closure otherwise evaluates to `()` here instead of `SimdSupport`. ++ #[cfg(not(any( ++ target_arch = "aarch64", ++ target_arch = "x86_64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ SimdSupport::None ++ } + }); + + #[cfg(target_arch = "x86_64")] diff --git a/patches/rerun-sdk/0.41.0/0002-cargo-patch-lance-crates-for-riscv64.patch b/patches/rerun-sdk/0.41.0/0002-cargo-patch-lance-crates-for-riscv64.patch new file mode 100644 index 000000000000..0f53cb10c844 --- /dev/null +++ b/patches/rerun-sdk/0.41.0/0002-cargo-patch-lance-crates-for-riscv64.patch @@ -0,0 +1,37 @@ +Upstream-Status: Inappropriate [points at a directory this port's workflow materializes at runtime; not a fix rerun itself would carry] + +diff --git a/Cargo.lock b/Cargo.lock +index f4ad0ef..620282b 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -5693,8 +5693,6 @@ dependencies = [ + [[package]] + name = "lance-core" + version = "10.0.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "21f4fd872bfe948150a6878d983327c4f150dc1b629e94ae7677310fa6a3f35f" + dependencies = [ + "arrow-array", + "arrow-buffer", +@@ -5992,8 +5990,6 @@ dependencies = [ + [[package]] + name = "lance-linalg" + version = "10.0.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "5a1dd49fdf61da86650dc335fbe1f239803f9d73bc2bc5ffbc0c905dd8809892" + dependencies = [ + "arrow-array", + "arrow-buffer", +diff --git a/Cargo.toml b/Cargo.toml +index 3717ef5..bf40033 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -868,6 +868,8 @@ self_named_module_files = "allow" # Disabled waiting on https://github.com/rust- + significant_drop_tightening = "allow" # An update of parking_lot made this trigger in a lot of places. TODO(emilk): fix those places + + [patch.crates-io] ++lance-core = { path = "lance-core-10.0.0-riscv64" } ++lance-linalg = { path = "lance-linalg-10.0.0-riscv64" } + # Try to avoid patching crates! It prevents us from publishing the crates on crates.io. + # If you do patch always prefer to patch to the trunk branch of the upstream repo (i.e. `main`, `master`, …). + # If that is not possible, patch to a branch that has a PR open on the upstream repo. From f456212b07218154019c5e993ab65c2c632fb562 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 31 Oct 2026 00:54:05 +0100 Subject: [PATCH 14/17] rerun-sdk: copy the lance-linalg riscv64 patch to 0.41.0 --- ...3-lance-linalg-riscv64-simd-fallback.patch | 1400 +++++++++++++++++ 1 file changed, 1400 insertions(+) create mode 100644 patches/rerun-sdk/0.41.0/0003-lance-linalg-riscv64-simd-fallback.patch diff --git a/patches/rerun-sdk/0.41.0/0003-lance-linalg-riscv64-simd-fallback.patch b/patches/rerun-sdk/0.41.0/0003-lance-linalg-riscv64-simd-fallback.patch new file mode 100644 index 000000000000..91d7840650af --- /dev/null +++ b/patches/rerun-sdk/0.41.0/0003-lance-linalg-riscv64-simd-fallback.patch @@ -0,0 +1,1400 @@ +Upstream-Status: To upstream [lance-linalg's per-arch SIMD structs (f32x8/f32x16/f64x4/f64x8/i32x8) have no fallback for architectures without a dedicated tier (riscv64 included); not filed upstream per this session's policy against opening external issues/PRs] + +--- lance-linalg-orig/src/simd/f32.rs 2006-07-24 03:21:28 ++++ lance-linalg-10.0.0-riscv64/src/simd/f32.rs 2026-09-07 02:16:55 +@@ -35,6 +35,17 @@ + #[derive(Clone, Copy)] + pub struct f32x8(v8f32); + ++/// 8 of 32-bit `f32` values. Portable scalar fallback for architectures with ++/// no dedicated SIMD tier above (riscv64 included) -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f32x8([f32; 8]); ++ + impl std::fmt::Debug for f32x8 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f32; 8]; +@@ -119,6 +130,27 @@ + ]; + Self::load_unaligned(values.as_ptr()) + } ++ ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ let ptr = slice.as_ptr(); ++ ++ let values = [ ++ *ptr.add(indices[0] as usize), ++ *ptr.add(indices[1] as usize), ++ *ptr.add(indices[2] as usize), ++ *ptr.add(indices[3] as usize), ++ *ptr.add(indices[4] as usize), ++ *ptr.add(indices[5] as usize), ++ *ptr.add(indices[6] as usize), ++ *ptr.add(indices[7] as usize), ++ ]; ++ Self::load_unaligned(values.as_ptr()) ++ } + } + } + +@@ -172,6 +204,14 @@ + unsafe { + Self(transmute(lasx_xvreplgr2vr_w(transmute(val)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 8]) ++ } + } + + fn zeros() -> Self { +@@ -186,6 +226,14 @@ + #[cfg(target_arch = "loongarch64")] + { + Self::splat(0.0) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 8]) + } + } + +@@ -203,6 +251,14 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -219,6 +275,18 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + unsafe fn store(&self, ptr: *mut f32) { +@@ -234,6 +302,14 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + unsafe fn store_unaligned(&self, ptr: *mut f32) { +@@ -249,6 +325,16 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -277,6 +363,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + fn reduce_min(&self) -> f32 { +@@ -311,6 +405,14 @@ + let m2 = lasx_xvfmin_s(transmute(m1), transmute(m2)); + transmute(lasx_xvpickve2gr_w::<0>(transmute(m2))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f32::INFINITY, f32::min) ++ } + } + + fn min(&self, rhs: &Self) -> Self { +@@ -329,6 +431,18 @@ + unsafe { + Self(lasx_xvfmin_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + fn find(&self, val: f32) -> Option { +@@ -362,6 +476,18 @@ + } + } + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ if self.0[i] == val { ++ return Some(i as i32); ++ } ++ } ++ } + None + } + } +@@ -380,6 +506,16 @@ + #[cfg(target_arch = "loongarch64")] + unsafe { + self.0 = lasx_xvfmadd_s(a.0, b.0, self.0); ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } + } + } + } +@@ -404,6 +540,18 @@ + unsafe { + Self(lasx_xvfadd_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -423,6 +571,16 @@ + unsafe { + self.0 = lasx_xvfadd_s(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += rhs.0[i]; ++ } ++ } + } + } + +@@ -446,6 +604,18 @@ + unsafe { + Self(lasx_xvfsub_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -465,6 +635,16 @@ + unsafe { + self.0 = lasx_xvfsub_s(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +@@ -488,6 +668,18 @@ + unsafe { + Self(lasx_xvfmul_s(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -516,6 +708,16 @@ + #[derive(Clone, Copy)] + pub struct f32x16(v8f32, v8f32); + ++/// 16 of 32-bit `f32` values. Portable scalar fallback -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f32x16([f32; 16]); ++ + impl std::fmt::Debug for f32x16 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f32; 16]; +@@ -561,6 +763,14 @@ + transmute(lasx_xvreplgr2vr_w(transmute(val))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 16]) ++ } + } + + #[inline] +@@ -577,6 +787,14 @@ + { + Self::splat(0.0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 16]) ++ } + } + + #[inline] +@@ -596,6 +814,14 @@ + transmute(lasx_xvld::<32>(transmute(ptr))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -614,6 +840,18 @@ + transmute(lasx_xvld::<0>(transmute(ptr))), + transmute(lasx_xvld::<32>(transmute(ptr))), + ) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) + } + } + +@@ -633,6 +871,14 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + #[inline] +@@ -651,6 +897,16 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -681,6 +937,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + #[inline] +@@ -715,6 +979,14 @@ + let m1 = lasx_xvfmin_s(transmute(m1), transmute(m2)); + transmute(lasx_xvpickve2gr_w::<0>(transmute(m1))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f32::INFINITY, f32::min) ++ } + } + + #[inline] +@@ -736,6 +1008,18 @@ + unsafe { + Self(lasx_xvfmin_s(self.0, rhs.0), lasx_xvfmin_s(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -782,6 +1066,19 @@ + } + None + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ if self.0[i] == val { ++ return Some(i as i32); ++ } ++ } ++ None ++ } + } + } + +@@ -805,6 +1102,16 @@ + self.0 = lasx_xvfmadd_s(a.0, b.0, self.0); + self.1 = lasx_xvfmadd_s(a.1, b.1, self.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } ++ } + } + } + +@@ -829,6 +1136,18 @@ + #[cfg(target_arch = "loongarch64")] + unsafe { + Self(lasx_xvfadd_s(self.0, rhs.0), lasx_xvfadd_s(self.1, rhs.1)) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) + } + } + } +@@ -853,6 +1172,16 @@ + self.0 = lasx_xvfadd_s(self.0, rhs.0); + self.1 = lasx_xvfadd_s(self.1, rhs.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ self.0[i] += rhs.0[i]; ++ } ++ } + } + } + +@@ -877,6 +1206,18 @@ + #[cfg(target_arch = "loongarch64")] + unsafe { + Self(lasx_xvfmul_s(self.0, rhs.0), lasx_xvfmul_s(self.1, rhs.1)) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) + } + } + } +@@ -903,6 +1244,18 @@ + unsafe { + Self(lasx_xvfsub_s(self.0, rhs.0), lasx_xvfsub_s(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f32; 16]; ++ for i in 0..16 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -926,6 +1279,16 @@ + self.0 = lasx_xvfsub_s(self.0, rhs.0); + self.1 = lasx_xvfsub_s(self.1, rhs.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..16 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +--- lance-linalg-orig/src/simd/f64.rs 2006-07-24 03:21:28 ++++ lance-linalg-10.0.0-riscv64/src/simd/f64.rs 2026-09-07 02:18:45 +@@ -33,6 +33,17 @@ + #[derive(Clone, Copy)] + pub struct f64x4(v4f64); + ++/// Portable scalar fallback for architectures with no dedicated SIMD tier ++/// above (riscv64 included) -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f64x4([f64; 4]); ++ + impl std::fmt::Debug for f64x4 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f64; 4]; +@@ -69,6 +80,14 @@ + unsafe { + Self(transmute(lasx_xvreplgr2vr_d(transmute(val)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 4]) ++ } + } + + fn zeros() -> Self { +@@ -84,6 +103,14 @@ + { + Self::splat(0.0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 4]) ++ } + } + + #[inline] +@@ -100,6 +127,14 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -116,6 +151,18 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + unsafe fn store(&self, ptr: *mut f64) { +@@ -131,6 +178,14 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + unsafe fn store_unaligned(&self, ptr: *mut f64) { +@@ -146,6 +201,16 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -169,6 +234,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + fn reduce_min(&self) -> f64 { +@@ -194,6 +267,14 @@ + .copied() + .fold(f64::INFINITY, f64::min) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f64::INFINITY, f64::min) ++ } + } + + fn min(&self, rhs: &Self) -> Self { +@@ -212,6 +293,18 @@ + unsafe { + Self(lasx_xvfmin_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + fn find(&self, val: f64) -> Option { +@@ -241,6 +334,16 @@ + unsafe { + self.0 = lasx_xvfmadd_d(a.0, b.0, self.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..4 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } ++ } + } + } + +@@ -264,6 +367,18 @@ + unsafe { + Self(lasx_xvfadd_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -283,6 +398,16 @@ + unsafe { + self.0 = lasx_xvfadd_d(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..4 { ++ self.0[i] += rhs.0[i]; ++ } ++ } + } + } + +@@ -306,6 +431,18 @@ + unsafe { + Self(lasx_xvfsub_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -325,6 +462,16 @@ + unsafe { + self.0 = lasx_xvfsub_d(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..4 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +@@ -348,6 +495,18 @@ + unsafe { + Self(lasx_xvfmul_d(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 4]; ++ for i in 0..4 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -377,6 +536,16 @@ + #[derive(Clone, Copy)] + pub struct f64x8(v4f64, v4f64); + ++/// Portable scalar fallback -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct f64x8([f64; 8]); ++ + impl std::fmt::Debug for f64x8 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0.0_f64; 8]; +@@ -416,6 +585,14 @@ + let v = transmute(lasx_xvreplgr2vr_d(transmute(val))); + Self(v, v) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 8]) ++ } + } + + #[inline] +@@ -432,6 +609,14 @@ + { + Self::splat(0.0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0.0; 8]) ++ } + } + + #[inline] +@@ -451,6 +636,14 @@ + transmute(lasx_xvld::<32>(transmute(ptr))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -470,6 +663,18 @@ + transmute(lasx_xvld::<32>(transmute(ptr))), + ) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -489,6 +694,14 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ self.store_unaligned(ptr); ++ } + } + + #[inline] +@@ -508,6 +721,16 @@ + lasx_xvst::<0>(transmute(self.0), transmute(ptr)); + lasx_xvst::<32>(transmute(self.1), transmute(ptr)); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + #[inline] +@@ -531,6 +754,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + #[inline] +@@ -557,6 +788,14 @@ + .iter() + .copied() + .fold(f64::INFINITY, f64::min) ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().copied().fold(f64::INFINITY, f64::min) + } + } + +@@ -577,6 +816,18 @@ + unsafe { + Self(lasx_xvfmin_d(self.0, rhs.0), lasx_xvfmin_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -612,6 +863,16 @@ + self.0 = lasx_xvfmadd_d(a.0, b.0, self.0); + self.1 = lasx_xvfmadd_d(a.1, b.1, self.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += a.0[i] * b.0[i]; ++ } ++ } + } + } + +@@ -635,6 +896,18 @@ + unsafe { + Self(lasx_xvfadd_d(self.0, rhs.0), lasx_xvfadd_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] + rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -657,6 +930,16 @@ + unsafe { + self.0 = lasx_xvfadd_d(self.0, rhs.0); + self.1 = lasx_xvfadd_d(self.1, rhs.1); ++ } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] += rhs.0[i]; ++ } + } + } + } +@@ -681,6 +964,18 @@ + unsafe { + Self(lasx_xvfmul_d(self.0, rhs.0), lasx_xvfmul_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] * rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -704,6 +999,18 @@ + unsafe { + Self(lasx_xvfsub_d(self.0, rhs.0), lasx_xvfsub_d(self.1, rhs.1)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0.0f64; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i] - rhs.0[i]; ++ } ++ Self(result) ++ } + } + } + +@@ -727,6 +1034,16 @@ + self.0 = lasx_xvfsub_d(self.0, rhs.0); + self.1 = lasx_xvfsub_d(self.1, rhs.1); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] -= rhs.0[i]; ++ } ++ } + } + } + +--- lance-linalg-orig/src/simd/i32.rs 2006-07-24 03:21:28 ++++ lance-linalg-10.0.0-riscv64/src/simd/i32.rs 2026-09-07 02:19:36 +@@ -30,6 +30,17 @@ + #[derive(Clone, Copy)] + pub struct i32x8(v8i32); + ++/// Portable scalar fallback for architectures with no dedicated SIMD tier ++/// above (riscv64 included) -- CLAUDE.md gotcha 300. ++#[allow(non_camel_case_types)] ++#[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++)))] ++#[derive(Clone, Copy)] ++pub struct i32x8(pub(crate) [i32; 8]); ++ + impl std::fmt::Debug for i32x8 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut arr = [0; 8]; +@@ -67,6 +78,14 @@ + unsafe { + Self(lasx_xvreplgr2vr_w(val)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([val; 8]) ++ } + } + + #[inline] +@@ -83,6 +102,14 @@ + { + Self::splat(0) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self([0; 8]) ++ } + } + + #[inline] +@@ -99,6 +126,14 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ Self::load_unaligned(ptr) ++ } + } + + #[inline] +@@ -115,6 +150,18 @@ + { + Self(transmute(lasx_xvld::<0>(transmute(ptr)))) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for (i, r) in result.iter_mut().enumerate() { ++ *r = unsafe { *ptr.add(i) }; ++ } ++ Self(result) ++ } + } + + #[inline] +@@ -135,6 +182,16 @@ + unsafe { + lasx_xvst::<0>(transmute(self.0), transmute(ptr)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ unsafe { ++ for (i, v) in self.0.iter().enumerate() { ++ *ptr.add(i) = *v; ++ } ++ } + } + + fn reduce_sum(&self) -> i32 { +@@ -151,6 +208,14 @@ + { + self.as_array().iter().sum() + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ self.0.iter().sum() ++ } + } + + fn reduce_min(&self) -> i32 { +@@ -173,6 +238,18 @@ + unsafe { + Self(lasx_xvmin_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_min(rhs.0[i]); ++ } ++ Self(result) ++ } + } + + fn find(&self, val: i32) -> Option { +@@ -206,6 +283,18 @@ + } + } + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ if self.0[i] == val { ++ return Some(i as i32); ++ } ++ } ++ } + None + } + } +@@ -230,6 +319,18 @@ + unsafe { + Self(lasx_xvadd_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_add(rhs.0[i]); ++ } ++ Self(result) ++ } + } + } + +@@ -249,6 +350,16 @@ + unsafe { + self.0 = lasx_xvadd_w(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] = self.0[i].wrapping_add(rhs.0[i]); ++ } ++ } + } + } + +@@ -272,6 +383,18 @@ + unsafe { + Self(lasx_xvsub_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_sub(rhs.0[i]); ++ } ++ Self(result) ++ } + } + } + +@@ -291,6 +414,16 @@ + unsafe { + self.0 = lasx_xvsub_w(self.0, rhs.0); + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ for i in 0..8 { ++ self.0[i] = self.0[i].wrapping_sub(rhs.0[i]); ++ } ++ } + } + } + +@@ -314,6 +447,18 @@ + unsafe { + Self(lasx_xvmul_w(self.0, rhs.0)) + } ++ #[cfg(not(any( ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "loongarch64" ++ )))] ++ { ++ let mut result = [0i32; 8]; ++ for i in 0..8 { ++ result[i] = self.0[i].wrapping_mul(rhs.0[i]); ++ } ++ Self(result) ++ } + } + } + From a03e886c5ce1a1bc17e8c31d336c5495c9dea8ad Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 31 Oct 2026 00:55:35 +0100 Subject: [PATCH 15/17] rerun-sdk: fix the i32 min call in the 0.41.0 lance-linalg patch --- .../0.41.0/0003-lance-linalg-riscv64-simd-fallback.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/rerun-sdk/0.41.0/0003-lance-linalg-riscv64-simd-fallback.patch b/patches/rerun-sdk/0.41.0/0003-lance-linalg-riscv64-simd-fallback.patch index 91d7840650af..5ec028114f7c 100644 --- a/patches/rerun-sdk/0.41.0/0003-lance-linalg-riscv64-simd-fallback.patch +++ b/patches/rerun-sdk/0.41.0/0003-lance-linalg-riscv64-simd-fallback.patch @@ -1281,7 +1281,7 @@ Upstream-Status: To upstream [lance-linalg's per-arch SIMD structs (f32x8/f32x16 + { + let mut result = [0i32; 8]; + for i in 0..8 { -+ result[i] = self.0[i].wrapping_min(rhs.0[i]); ++ result[i] = self.0[i].min(rhs.0[i]); + } + Self(result) + } From 4fb3b1df8b9ec5e5373ef5f0c9aaef4d83a3f6b0 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 31 Oct 2026 16:15:16 +0100 Subject: [PATCH 16/17] rerun-sdk: add a 0.41.0 patch for the new re_protos build script re_protos/build.rs (new in 0.41.0) calls protoc_bin_vendored::protoc_bin_path()?, which has no riscv64 binary, so the whole build failed before compiling any Rust. Fall back to the system protoc and PROTOC_INCLUDE, which the workflow already provides. --- ...en-protoc-bin-vendored-has-no-binary.patch | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 patches/rerun-sdk/0.41.0/0004-re_protos-fall-back-to-the-system-protoc-when-protoc-bin-vendored-has-no-binary.patch diff --git a/patches/rerun-sdk/0.41.0/0004-re_protos-fall-back-to-the-system-protoc-when-protoc-bin-vendored-has-no-binary.patch b/patches/rerun-sdk/0.41.0/0004-re_protos-fall-back-to-the-system-protoc-when-protoc-bin-vendored-has-no-binary.patch new file mode 100644 index 000000000000..0eeb64a44b6b --- /dev/null +++ b/patches/rerun-sdk/0.41.0/0004-re_protos-fall-back-to-the-system-protoc-when-protoc-bin-vendored-has-no-binary.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: RISE Project CI +Date: Sat, 31 Oct 2026 00:00:00 +0000 +Subject: [PATCH] re_protos: fall back to the system protoc when + protoc-bin-vendored has no binary + +0.41.0's re_protos build script compiles the gRPC descriptor set with +protoc_bin_vendored::protoc_bin_path()?, which returns an error on a +target without a vendored binary (riscv64 included), failing the whole +build before any Rust is compiled. Fall back to $PROTOC (or protoc on +PATH) and to $PROTOC_INCLUDE (or /usr/include) when the vendored crate +has nothing for the host; the vendored binary is still preferred +wherever it exists. + +Upstream-Status: To upstream [not filed; this port may only touch riseproject-dev/python-wheels] +--- + crates/store/re_protos/build.rs | 11 ++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/crates/store/re_protos/build.rs b/crates/store/re_protos/build.rs +index 0d0bb38..f5792dd 100644 +--- a/crates/store/re_protos/build.rs ++++ b/crates/store/re_protos/build.rs +@@ -20,7 +20,14 @@ fn main() -> Result<(), Box> { + let output = PathBuf::from(std::env::var_os("OUT_DIR").ok_or("OUT_DIR is not set")?) + .join("rerun.v1alpha1.fds.bin"); + let temporary = output.with_extension("tmp"); +- let result = Command::new(protoc_bin_vendored::protoc_bin_path()?) ++ // protoc-bin-vendored ships no riscv64 binary; fall back to the protoc on PATH (or $PROTOC). ++ let protoc = protoc_bin_vendored::protoc_bin_path().unwrap_or_else(|_| { ++ PathBuf::from(std::env::var_os("PROTOC").unwrap_or_else(|| "protoc".into())) ++ }); ++ let include = protoc_bin_vendored::include_path().unwrap_or_else(|_| { ++ PathBuf::from(std::env::var_os("PROTOC_INCLUDE").unwrap_or_else(|| "/usr/include".into())) ++ }); ++ let result = Command::new(protoc) + .arg("--include_imports") + .arg("--include_source_info") + .arg("--descriptor_set_out") +@@ -28,7 +35,7 @@ fn main() -> Result<(), Box> { + .arg("-I") + .arg("proto") + .arg("-I") +- .arg(protoc_bin_vendored::include_path()?) ++ .arg(include) + .args(protos) + .output()?; + if !result.status.success() { +-- +2.43.0 + From d7833d2a309660261fc07bbfaa73e0e3e975e86e Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 31 Oct 2026 16:16:24 +0100 Subject: [PATCH 17/17] build-rerun-sdk: apply the re_protos protoc fallback patch when a version has one The patch added for 0.41.0 is applied by its own step, skipped for releases without it. --- .github/workflows/build-rerun-sdk.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/build-rerun-sdk.yml b/.github/workflows/build-rerun-sdk.yml index 77e5c7df7767..00ed33c97630 100644 --- a/.github/workflows/build-rerun-sdk.yml +++ b/.github/workflows/build-rerun-sdk.yml @@ -131,6 +131,17 @@ jobs: git apply python-wheels/patches/rerun-sdk/${{ env.RERUN_SDK_VERSION }}/0002-cargo-patch-lance-crates-for-riscv64.patch + # 0.41.0's re_protos/build.rs calls protoc_bin_vendored::protoc_bin_path()?, + # which has no riscv64 binary; the patch falls back to the system protoc + # installed below (PROTOC_INCLUDE points at its include dir). Earlier + # releases have no such patch. + - name: Patch re_protos to use the system protoc + run: | + patch_file="python-wheels/patches/rerun-sdk/${RERUN_SDK_VERSION}/0004-re_protos-fall-back-to-the-system-protoc-when-protoc-bin-vendored-has-no-binary.patch" + if [ -f "$patch_file" ]; then + git apply "$patch_file" + fi + # re_importer moved from crates/store/re_importer (0.37.x) to # crates/data_flow/re_importer (0.38.0+) upstream; CIBW_TEST_SOURCES # below needs its importer_mcap test-assets path to track whichever one