oneVal/oneType/allSame → one_val/one_type/all_same

This commit is contained in:
dzaima 2025-02-01 21:41:01 +02:00
parent a3e33366df
commit 6f8b08bb1f
8 changed files with 19 additions and 18 deletions

View File

@ -36,8 +36,9 @@ The SIMD operations listed aren't guaranteed to be supported on all targets, nor
- `eachx{F, ...args}` - `each` but broadcasting non-tuples - `eachx{F, ...args}` - `each` but broadcasting non-tuples
- `undef{T}` - return register of type `T` with undefined value; maps over a tuple of types - `undef{T}` - return register of type `T` with undefined value; maps over a tuple of types
- `undef{T, n}` - a tuple of `n` different undefined registers - `undef{T, n}` - a tuple of `n` different undefined registers
- `oneVal{xs}` - assert that `xs` is a tuple of equivalent (as per `==`) items, and return the first - `one_val{xs}` - assert that `xs` is a tuple of equivalent (as per `same`) items, and return the first
- `oneType{xs}` - `oneVal` but over the types of the items - `one_type{xs}` - `oneVal` but over the types of the items
- `all_same{xs}` - whether all values of `xs` are the same
## Loops & branches ## Loops & branches

View File

@ -27,7 +27,7 @@ def any_int = match { {x:T}=>isint{T}; {x} => knum{x} and (x>>0) == x }
def elwidth{T} = width{eltype{T}} def elwidth{T} = width{eltype{T}}
def reinterpret{T, x:T} = x def reinterpret{T, x:T} = x
def export_tab{name, fs} = { v:*oneType{fs} = fs; export{name, v} } def export_tab{name, fs} = { v:*one_type{fs} = fs; export{name, v} }
oper &~ andnot infix none 35 oper &~ andnot infix none 35
def andnot{a, b:T if any_int{a} and isprim{T}} = a & ~b def andnot{a, b:T if any_int{a} and isprim{T}} = a & ~b
@ -82,15 +82,15 @@ def all{{...vs}} = tree_fold{&, vs}
def all{{}} = 1 def all{{}} = 1
def all{G, ...vs if kgen{G}} = if (all{each{{c}=>length{c}==0, vs}}) 1 else G{...each{select{.,0}, vs}} and all{G, ...each{slice{.,1}, vs}} def all{G, ...vs if kgen{G}} = if (all{each{{c}=>length{c}==0, vs}}) 1 else G{...each{select{.,0}, vs}} and all{G, ...each{slice{.,1}, vs}}
def oneVal{{h, ...t}} = { def one_val{{h, ...t}} = {
each{{c} => assert{same{c,h}}, t} each{{c} => assert{same{c,h}}, t}
h h
} }
def oneVal{{}} = {} def one_val{{}} = {}
def oneType{x} = oneVal{each{type, x}} def one_type{x} = one_val{each{type, x}}
def allSame{{h, ...t}} = all{is{h,.}, t} def all_same{{h, ...t}} = all{same{h,.}, t}
def allSame{{_}} = 1 def all_same{{_}} = 1
def allSame{{}} = 1 def all_same{{}} = 1
def try_same_type{_, default} = default def try_same_type{_, default} = default
def try_same_type{{h:T, ...t} if all{hastype{.,T}, t}, _} = T def try_same_type{{h:T, ...t} if all{hastype{.,T}, t}, _} = T
@ -188,7 +188,7 @@ def hom_to_int_ext{a:T} = tup{1, hom_to_int{a}} # tup{n,mask}; mask with each bi
def ctz_ext{{n,v}} = ctz{v}/n # ctz for a result of homMaskX def ctz_ext{{n,v}} = ctz{v}/n # ctz for a result of homMaskX
def hom_to_int{...vs if length{vs}>1} = { def hom_to_int{...vs if length{vs}>1} = {
def n = length{vs} def n = length{vs}
def [k]_ = oneType{vs} def [k]_ = one_type{vs}
def RT = ty_u{max{8,k*n}} def RT = ty_u{max{8,k*n}}
def sl{...a} = promote{RT, hom_to_int{...slice{vs,...a}}} def sl{...a} = promote{RT, hom_to_int{...slice{vs,...a}}}
def h = n/2 def h = n/2

View File

@ -120,7 +120,7 @@ def runChecks{'anyne', vals, M} = {
def arithProcess{F, run, overflow, M, is, cw, cx, TY} = { def arithProcess{F, run, overflow, M, is, cw, cx, TY} = {
def {values, checks} = flip{each{{w1, x1} => run{F, M, w1, x1}, cw, cx}} def {values, checks} = flip{each{{w1, x1} => run{F, M, w1, x1}, cw, cx}}
def ctype = oneVal{each{select{.,0}, checks}} def ctype = one_val{each{select{.,0}, checks}}
if (rare{runChecks{ctype, checks, M}}) overflow{select{is,0}*vcount{TY}} if (rare{runChecks{ctype, checks, M}}) overflow{select{is,0}*vcount{TY}}
each{{c} => TY~~c, values} each{{c} => TY~~c, values}
} }

View File

@ -19,7 +19,7 @@ local def loader{G} = {
} }
def proc{TG if kgen{TG}} = TG def proc{TG if kgen{TG}} = TG
def proc{vs if ktup{vs}} = { def proc{vs if ktup{vs}} = {
def S = oneType{vs} def S = one_type{vs}
def loader_vtg{Q, i} = { def loader_vtg{Q, i} = {
if (width{Q} == width{S}) Q~~select{vs,i} if (width{Q} == width{S}) Q~~select{vs,i}
else if (width{Q}*2 == width{S}) Q~~half{select{vs, i>>1}, i&1} else if (width{Q}*2 == width{S}) Q~~half{select{vs, i>>1}, i&1}
@ -53,7 +53,7 @@ def blend_halves{mode, E, nt, ni} = tup{nt, ni, loader{{TG} => {
# def me{'is', is:[_](u8)} = lo{'is', is} # def me{'is', is:[_](u8)} = lo{'is', is}
# def me{...is} = { # def me{...is} = {
# def [_]IE = oneType{is} # def [_]IE = one_type{is}
# def shl = if (IE==u8) __shl{u16} else __shl # def shl = if (IE==u8) __shl{u16} else __shl
# def bm = shl{is, width{IE}-1 - lb{nth}} # def bm = shl{is, width{IE}-1 - lb{nth}}
# each{{l,h} => blend_top{l,h,bm}, lo{is}, hi{is}} # each{{l,h} => blend_top{l,h,bm}, lo{is}, hi{is}}

View File

@ -87,7 +87,7 @@ def trn{x:T, y:T, 0 if nvec{T}} = emit{T, ntyp{'vtrn1', T}, x, y}
def trn{x:T, y:T, 1 if nvec{T}} = emit{T, ntyp{'vtrn2', T}, x, y} def trn{x:T, y:T, 1 if nvec{T}} = emit{T, ntyp{'vtrn2', T}, x, y}
def sel{L, x:T, i:I if lvec{L,16,8} and w128{T} and nvec{I, 8}} = vec_select{eltype{L}, x, i} def sel{L, x:T, i:I if lvec{L,16,8} and w128{T} and nvec{I, 8}} = vec_select{eltype{L}, x, i}
def sel{{...xs}, i:I if length{xs}>=1 and length{xs}<=4 and allSame{each{type,xs}} and lvec{oneType{xs},16,8} and nvec{I, 8}} = vec_select{xs, i} def sel{{...xs}, i:I if length{xs}>=1 and length{xs}<=4 and all_same{each{type,xs}} and lvec{one_type{xs},16,8} and nvec{I, 8}} = vec_select{xs, i}

View File

@ -289,7 +289,7 @@ def simd_plus_scan_part{x:*X, c:R, r:*R, len:(u64), i:(u64)} = {
def cr = eachx{+, widenFull{R, s1{...s0}}, cv} def cr = eachx{+, widenFull{R, s1{...s0}}, cv}
cv = toLast{select{cr, -1}} cv = toLast{select{cr, -1}}
assert{type{cv} == oneType{cr}} assert{type{cv} == one_type{cr}}
assert{vcount{type{cv}} * length{cr} == bulk} assert{vcount{type{cv}} * length{cr} == bulk}
each{{c:T, j} => store{*T~~(r+i), j, c}, cr, iota{length{cr}}} each{{c:T, j} => store{*T~~(r+i), j, c}, cr, iota{length{cr}}}

View File

@ -32,7 +32,7 @@ def wrapChk{cw0:VI, xlf, M} = {
def masked_multistore{r0, vs, M, end} = { # returns bumped-forwards r def masked_multistore{r0, vs, M, end} = { # returns bumped-forwards r
r:= r0 r:= r0
def left = if (M{0}) { left:ux = M{'count'} } else 0 def left = if (M{0}) { left:ux = M{'count'} } else 0
def lastMaskedStore = makeOptBranch{M{0}, tup{oneType{vs}}, {c} => { def lastMaskedStore = makeOptBranch{M{0}, tup{one_type{vs}}, {c} => {
storeBatch{r, 0, c, maskAfter{left}} storeBatch{r, 0, c, maskAfter{left}}
end{} end{}
}} }}
@ -153,7 +153,7 @@ export{'INDS_BUF_MAX_COPY', ux~~inds_buf_max}
}, select_rows_parts}}}} }, select_rows_parts}}}}
def exportP{T, n, vs} = { a:*T = vs; export{n, a} } def exportP{T, n, vs} = { a:*T = vs; export{n, a} }
exportP{u8, 'select_rows_max_indn', each{{row} => if (length{row}==0) 0 else oneVal{ each{select{.,1}, row}}, select_rows_parts}} exportP{u8, 'select_rows_max_indn', each{{row} => if (length{row}==0) 0 else one_val{ each{select{.,1}, row}}, select_rows_parts}}
exportP{u8, 'select_rows_min_logcsz', each{{row} => if (length{row}==0) 0 else lb{fold{min, each{select{.,0}, row}}}, select_rows_parts}} exportP{u8, 'select_rows_min_logcsz', each{{row} => if (length{row}==0) 0 else lb{fold{min, each{select{.,0}, row}}}, select_rows_parts}}
def select_rows_better = scan{{p,{v,i}} => if (length{v}==0) p else i, 0, each{tup, select_rows_parts, range{4}}} def select_rows_better = scan{{p,{v,i}} => if (length{v}==0) p else i, 0, each{tup, select_rows_parts, range{4}}}

View File

@ -11,7 +11,7 @@ def is_sNaN{x:[2](u64) if hasarch{'X86_64'} and not hasarch{'SSE4.2'}} = { # avo
} }
def any_sNaN{M, ...xs} = { def any_sNaN{M, ...xs} = {
def {any, are} = flip{each{is_sNaN, xs}} def {any, are} = flip{each{is_sNaN, xs}}
oneVal{any}{M{tree_fold{|, are}}} one_val{any}{M{tree_fold{|, are}}}
} }
def any_nonC32{M, x:[_](u64)} = any_hom{M{~inRangeLen{x, cbqn_c32Tag{}<<48, 1<<48}}} def any_nonC32{M, x:[_](u64)} = any_hom{M{~inRangeLen{x, cbqn_c32Tag{}<<48, 1<<48}}}