From d13060f72507f4c0a4bbd76d504974eb8fe9d39d Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 6 Apr 2023 19:05:38 +0300 Subject: [PATCH] move fold to vfold --- src/singeli/src/base.singeli | 4 ++-- src/singeli/src/count.singeli | 9 +++------ src/singeli/src/neon.singeli | 3 +++ src/singeli/src/squeeze.singeli | 2 +- src/singeli/src/vecfold.singeli | 18 ++++++------------ 5 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/singeli/src/base.singeli b/src/singeli/src/base.singeli index 39eb3005..af264639 100644 --- a/src/singeli/src/base.singeli +++ b/src/singeli/src/base.singeli @@ -184,8 +184,8 @@ def undefPromote{T, x:X & T==X} = T~~x def packQ{a} = packQ{tupsel{0,a}, tupsel{1,a}} def cvt{T, x:X & T==eltype{X}} = x -def min{a, b & knum{a} & knum{b}} = tern{ab, a, b} +def min{a, b & anyNum{a} & anyNum{b}} = tern{ab, a, b} diff --git a/src/singeli/src/count.singeli b/src/singeli/src/count.singeli index 89bd16e5..d7ae54c3 100644 --- a/src/singeli/src/count.singeli +++ b/src/singeli/src/count.singeli @@ -5,10 +5,7 @@ include './avx2' include 'util/tup' include './vecfold' -fn sum_vec{T==[32]i8}(v:T) = fold{+, [16]i16~~fold{+, unpackQ{v, T**0}}} -def minmax{c, a, b} = tern{c{cast_i{i8,a},cast_i{i8,b}}, a, b} -def min{a:i16, b:i16} = minmax{<, a, b} -def max{a:i16, b:i16} = minmax{>, a, b} +fn sum_vec{T==[32]i8}(v:T) = vfold{+, [16]i16~~fold{+, unpackQ{v, T**0}}} def inc{ptr, ind, v} = store{ptr, ind, v + load{ptr, ind}} def inc{ptr, ind} = inc{ptr, ind, 1} @@ -36,8 +33,8 @@ fn count{T}(tab:*usz, x:*T, n:u64, min_allowed:T) : T = { jv := load{xv}; mv := jv @for (xv over _ from 1 to b) { jv = min{jv, xv}; mv = max{mv, xv} } @for (x over _ from rv to r) { if (xmx) mx=x } - jt := fold{min, jv} - mt := fold{max, mv} + jt := vfold{min, jv} + mt := vfold{max, mv} if (jt < min_allowed) return{jt} if (mt > mx) mx = mt diff --git a/src/singeli/src/neon.singeli b/src/singeli/src/neon.singeli index 810a84d4..53575347 100644 --- a/src/singeli/src/neon.singeli +++ b/src/singeli/src/neon.singeli @@ -71,6 +71,9 @@ def fold_add {a:T & nvec{T}} = emit{eltype{T}, ntyp{'vaddv', T}, a} def fold_addw{a:T & nvec{T}} = emit{ty_dbl{eltype{T}}, ntyp{'vaddlv', T}, a} def fold_min {a:T & nvec{T} & elwidth{T}<=32} = emit{eltype{T}, ntyp{'vminv', T}, a} def fold_max {a:T & nvec{T} & elwidth{T}<=32} = emit{eltype{T}, ntyp{'vmaxv', T}, a} +def vfold{F, x:T & nvec{T} & match{F, min} & elwidth{T}<=32} = fold_min{x} +def vfold{F, x:T & nvec{T} & match{F, max} & elwidth{T}<=32} = fold_max{x} +def vfold{F, x:T & nvec{T} & match{F, +}} = fold_add{x} # TODO don't rely on regular stores being unaligned local def storeu{ptr:P, e:T} = store{ptr, 0, e} diff --git a/src/singeli/src/squeeze.singeli b/src/singeli/src/squeeze.singeli index 9b01d230..35348be3 100644 --- a/src/singeli/src/squeeze.singeli +++ b/src/singeli/src/squeeze.singeli @@ -69,7 +69,7 @@ fn squeeze{vw, X, CHR, B}(x0:*void, len:Size) : u32 = { def EV = tern{(width{E}*bulk == 64) & hasarch{'X86_64'}, EV2, [bulk]E} # fold with either Max or Bitwise Or, truncating/zero-extending to TE - def foldTotal{TE, x:T} = cast_i{TE, fold{|, x}} + def foldTotal{TE, x:T} = cast_i{TE, vfold{|, x}} def foldTotal{TE, x:T & hasarch{'AARCH64'}} = { if (elwidth{T}==64) { if (width{TE}==64 and bulk==2) cast_i{TE, half{x,0} | half{x,1}} diff --git a/src/singeli/src/vecfold.singeli b/src/singeli/src/vecfold.singeli index b123b596..330122eb 100644 --- a/src/singeli/src/vecfold.singeli +++ b/src/singeli/src/vecfold.singeli @@ -2,26 +2,20 @@ # Used by squeeze.singeli, count.singeli # Has to be included after util/tup because of name conflict -def fold{F, x:T} = { +def vfold{F, x:T} = { show{'WARNING: using fallback fold for ', F, T} def E = eltype{T} r:E = 0 each{{i} => { r = F{r, extract{x, i}} }, iota{vcount{T}}} r } -def fold{F, x:T & w128{T} & hasarch{'X86_64'}} = { +def vfold{F, x:T & w128{T} & hasarch{'X86_64'}} = { c:= x def EW = elwidth{T} if (EW<=64) c = F{c, shuf{[4]u32, c, 4b1032}} if (EW<=32) c = F{c, shuf{[4]u32, c, 4b2301}} - if (hasarch{'SSSE3'} and 0) { - if (EW<=16) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^2}}} - if (EW==8) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^1}}} - extract{c, 0} - } else { - if (EW<=16) c = F{c, shuf16Lo{c, 4b2301}} - if (EW==8) { v:=extract{[8]i16~~c, 0}; cast_i{eltype{T}, F{v, v>>8}} } - else extract{c, 0} - } + if (EW<=16) c = F{c, shuf16Lo{c, 4b2301}} + if (EW==8) { v:=extract{[8]i16~~c, 0}; F{cast_i{eltype{T}, v}, cast_i{eltype{T}, v>>8}} } + else extract{c, 0} } -def fold{F, x:T & w256{T} & hasarch{'X86_64'}} = fold{F, F{half{x, 0}, half{x, 1}}} +def vfold{F, x:T & w256{T} & hasarch{'X86_64'}} = vfold{F, F{half{x, 0}, half{x, 1}}}