From: Jacob Lifshay Date: Fri, 22 Oct 2021 07:39:42 +0000 (-0700) Subject: update SimdScope to use vec_el_counts X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=22647a6345c983d917dfd9293ec295846a5b038f;p=ieee754fpu.git update SimdScope to use vec_el_counts --- diff --git a/src/ieee754/part/simd_scope.py b/src/ieee754/part/simd_scope.py index a7f355d7..38ac675a 100644 --- a/src/ieee754/part/simd_scope.py +++ b/src/ieee754/part/simd_scope.py @@ -2,8 +2,8 @@ # See Notices.txt for copyright information -from ieee754.part.util import (DEFAULT_FP_PART_COUNTS, - DEFAULT_INT_PART_COUNTS, +from ieee754.part.util import (DEFAULT_FP_VEC_EL_COUNTS, + DEFAULT_INT_VEC_EL_COUNTS, FpElWid, IntElWid, SimdMap) from nmigen.hdl.ast import Signal @@ -12,18 +12,25 @@ class SimdScope: """The global scope object for SimdSignal and friends Members: - * part_counts: SimdMap - a map from `ElWid` values `k` to the number of parts in an element - when `self.elwid == k`. Values should be minimized, since higher values - often create bigger circuits. + * vec_el_counts: SimdMap + a map from `ElWid` values `k` to the number of elements in a vector + when `self.elwid == k`. Example: - # here, an I8 element is 1 part wide - part_counts = {ElWid.I8: 1, ElWid.I16: 2, ElWid.I32: 4, ElWid.I64: 8} + vec_el_counts = SimdMap({ + IntElWid.I64: 1, + IntElWid.I32: 2, + IntElWid.I16: 4, + IntElWid.I8: 8, + }) Another Example: - # here, an F16 element is 1 part wide - part_counts = {ElWid.F16: 1, ElWid.BF16: 1, ElWid.F32: 2, ElWid.F64: 4} + vec_el_counts = SimdMap({ + FpElWid.F64: 1, + FpElWid.F32: 2, + FpElWid.F16: 4, + FpElWid.BF16: 4, + }) * simd_full_width_hint: int the default value for SimdLayout's full_width argument, the full number of bits in a SIMD value. @@ -35,13 +42,12 @@ class SimdScope: @classmethod def get(cls): - """get the current SimdScope. + """get the current SimdScope. raises a ValueError outside of any + SimdScope. Example: - SimdScope.get(None) is None - SimdScope.get() raises ValueError with SimdScope(...) as s: - SimdScope.get() is s + assert SimdScope.get() is s """ if len(cls.__SCOPE_STACK) > 0: retval = cls.__SCOPE_STACK[-1] @@ -58,35 +64,36 @@ class SimdScope: return False def __init__(self, *, simd_full_width_hint=64, elwid=None, - part_counts=None, elwid_type=IntElWid, scalar=False): - # TODO: add more arguments/members and processing for integration with + vec_el_counts=None, elwid_type=IntElWid, scalar=False): + assert isinstance(simd_full_width_hint, int) self.simd_full_width_hint = simd_full_width_hint if isinstance(elwid, (IntElWid, FpElWid)): elwid_type = type(elwid) - if part_counts is None: - part_counts = SimdMap({elwid: 1}) + if vec_el_counts is None: + vec_el_counts = SimdMap({elwid: 1}) assert issubclass(elwid_type, (IntElWid, FpElWid)) self.elwid_type = elwid_type scalar_elwid = elwid_type(0) - if part_counts is None: + if vec_el_counts is None: if scalar: - part_counts = SimdMap({scalar_elwid: 1}) + vec_el_counts = SimdMap({scalar_elwid: 1}) elif issubclass(elwid_type, FpElWid): - part_counts = DEFAULT_FP_PART_COUNTS + vec_el_counts = DEFAULT_FP_VEC_EL_COUNTS else: - part_counts = DEFAULT_INT_PART_COUNTS + vec_el_counts = DEFAULT_INT_VEC_EL_COUNTS - def check(elwid, part_count): + def check(elwid, vec_el_count): assert type(elwid) == elwid_type, "inconsistent ElWid types" - part_count = int(part_count) - assert part_count != 0 and (part_count & (part_count - 1)) == 0,\ - "part_counts values must all be powers of two" - return part_count - - self.part_counts = SimdMap.map_with_elwid(check, part_counts) - self.full_part_count = max(part_counts.values()) - assert self.simd_full_width_hint % self.full_part_count == 0,\ - "simd_full_width_hint must be a multiple of full_part_count" + vec_el_count = int(vec_el_count) + assert vec_el_count != 0 \ + and (vec_el_count & (vec_el_count - 1)) == 0,\ + "vec_el_counts values must all be powers of two" + return vec_el_count + + self.vec_el_counts = SimdMap.map_with_elwid(check, vec_el_counts) + self.full_el_count = max(self.vec_el_counts.values()) + assert self.simd_full_width_hint % self.full_el_count == 0,\ + "simd_full_width_hint must be a multiple of full_el_count" if elwid is not None: self.elwid = elwid elif scalar: @@ -99,5 +106,5 @@ class SimdScope: f" simd_full_width_hint={self.simd_full_width_hint},\n" f" elwid={self.elwid},\n" f" elwid_type={self.elwid_type},\n" - f" part_counts={self.part_counts},\n" - f" full_part_count={self.full_part_count})") + f" vec_el_counts={self.vec_el_counts},\n" + f" full_el_count={self.full_el_count})") diff --git a/src/ieee754/part/util.py b/src/ieee754/part/util.py index 095fb1b9..6a9bcb13 100644 --- a/src/ieee754/part/util.py +++ b/src/ieee754/part/util.py @@ -280,20 +280,20 @@ XLEN = SimdMap({ FpElWid.BF16: 16, }) -DEFAULT_FP_PART_COUNTS = SimdMap({ - FpElWid.F64: 4, +DEFAULT_FP_VEC_EL_COUNTS = SimdMap({ + FpElWid.F64: 1, FpElWid.F32: 2, - FpElWid.F16: 1, - FpElWid.BF16: 1, + FpElWid.F16: 4, + FpElWid.BF16: 4, }) -DEFAULT_INT_PART_COUNTS = SimdMap({ - IntElWid.I64: 8, - IntElWid.I32: 4, - IntElWid.I16: 2, - IntElWid.I8: 1, +DEFAULT_INT_VEC_EL_COUNTS = SimdMap({ + IntElWid.I64: 1, + IntElWid.I32: 2, + IntElWid.I16: 4, + IntElWid.I8: 8, }) _check_for_missing_elwidths("XLEN") -_check_for_missing_elwidths("DEFAULT_FP_PART_COUNTS", FpElWid) -_check_for_missing_elwidths("DEFAULT_INT_PART_COUNTS", IntElWid) +_check_for_missing_elwidths("DEFAULT_FP_VEC_EL_COUNTS", FpElWid) +_check_for_missing_elwidths("DEFAULT_INT_VEC_EL_COUNTS", IntElWid)